API Hooking - 键盘钩子
0x00 引言
0. 什么是键盘钩子?
键盘钩子,通过监听和筛选 Windows 中发生的事件,并回调到自己的程序中,可以实现按键的记录。
1. 将会使用的 API
SetWindowsHook(Ex)(A)(W)
UnHookWindowsHookEx
2. 概述实现方式
先使用 SetWindowsHookEx 设置一个全局钩子,并捕获键盘输入,实现 记录键盘 或 拦截 的效果。
0x01 开始编写代码!
安装钩子
使用 Visual Studio (我使用的是 2022,您用其他 IDE 也是可以的)新建一个 C++ 控制台项目,并插入以下代码:
HHOOK g_hHook = NULL; // 钩子的句柄,定义为全局变量便于后续卸载 void SetHook() { HINSTANCE hInstance = GetModuleHandleW(NULL); g_hHook = SetWindowsHookExW(WH_KEYBOARD_LL, KeyboardProc, hInstance, 0); if (g_hHook == NULL) { MessageBox(NULL, L"Failed to install hook!", L"Error", MB_ICONERROR); } }
代码解析:
HINSTANCE hInstance = GetModuleHandleW(NULL);
获取当前的模块句柄,为之后做准备(NULL 表示获取当前句柄,附着在当前进程中)。
SetWindowsHookExW(WH_KEYBOARD_LL, KeyboardProc, hInstance, 0)
设置全局钩子,WH_KEYBOARD_LL 表示监听键盘事件(查看所有挂钩描述类型),KeyboardProc 表示事件发生后的回调,hInstance 表示模块句柄(上面已经获取过了当前的模块句柄,故直接引用),0 表示线程 ID,附着在当前线程。
KeyboardProc 函数方法:
LRESULT CALLBACK KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
之后,请在主函数中使用消息循环,阻止控制台程序退出:
// 消息循环 MSG msg; while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); }
MessageBox(NULL, L"Failed to install hook!", L"Error", MB_ICONERROR)
如果 g_hHook == NULL (挂钩失败)时,弹出信息框“Failed to install hook!”,告知用户挂钩失败。
您可以参照这个 KeyboardProc:
LRESULT CALLBACK KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam) { std::cout << "Key: " << nCode << endl; // 输出键码 if (wParam == WM_KEYDOWN || wParam == WM_SYSKEYDOWN) { return 1; // 阻止按键 } return CallNextHookEx(hHook, nCode, wParam, lParam); }
CallNextHookEx(hHook, nCode, wParam, lParam)
继续下一个,表示不阻止这次按键,键盘按键正常工作。
return 1
阻止按键,用户按下的按键将不会生效(亲测除了 Windows - L 和 Ctrl - Alt - Delete 以外其他按键都能拦截)
卸载钩子
程序退出或停止挂钩键盘时,请运行 UnhookWindowsHookEx 卸载钩子。例如:
UnhookWindowsHookEx(g_hHook); // g_hHook 是以前定义的钩子,卸载前注意检查如果不是 NULL 才卸载。
效果如下:
(当我试图按下截图快捷键时发现被阻止了,哈哈)
嗯,使用这个 API 您也是可以 监听 和 拦截 鼠标的移动的(((
GDWare你qq咋“注销”了
?