赞
踩
利用HOOK技术来做一个键盘记录器,看看一天下来,我们点击了多少次键盘,哪些键的使用频率最高。
实现功能:
使用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 + "");
- }
-
- }
实现效果:
由简入繁,拿来即用
更多精彩,请搜索公众号:Csharp 小记
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。