应用层低级键盘钩子
在应用层可以使用 SetWindowsHookEx
挂载 低级键盘钩子
,来实现屏蔽键盘按键的功能
1 2 3 4 5 6
| HHOOK WINAPI SetWindowsHookEx( _In_ int idHook, _In_ HOOKPROC lpfn, _In_ HINSTANCE hMod, _In_ DWORD dwThreadId );
|
其中参数 idhook
设置为 WH_KEYBOARD_LL
时,表明挂载 低级键盘钩子
,参数 dwThreadId
为想要HOOK
的线程ID,设置为0时,表示HOOK所有的线程。低级键盘钩子
的回调函数为
1 2 3 4 5
| LRESULT CALLBACK LowLevelKeyboardProc( _In_ int nCode, _In_ WPARAM wParam, _In_ LPARAM lParam );
|
参数 nCode
的值为 HC_ACTION
时表示 wParam
和 lParam
有效,参数 wParam
为键盘相关消息,出现
的值为 WM_KEYDOWN
WM_KEYUP
WM_SYSKEYDOWN
WM_SYSKEYUP
几种,表明按键的行为,参数 lParam
为
具体按键信息,是一个 KBDLLHOOKSTRUCT
类型的结构体
1 2 3 4 5 6 7
| typedef struct tagKBDLLHOOKSTRUCT { DWORD vkCode; DWORD scanCode; DWORD flags; DWORD time; ULONG_PTR dwExtraInfo; } KBDLLHOOKSTRUCT, *PKBDLLHOOKSTRUCT, *LPKBDLLHOOKSTRUCT;
|
参数 vkCode
表示虚拟按键码信息,可以在头文件 WinUser.h
中找到定义,这里就不再列出。
注册和卸载低级键盘钩子
当HOOK所有线程时,实际是作为DLL模块注入到所有的程序中,来进行的HOOK操作。
一般情况下,32位的DLL注入到32位程序中,64位的DLL注入到64位程序中,不能互相注入。
使用 低级键盘钩子
时,只需要写32位DLL,而64位的程序,系统通过消息处理,间接实现按键过滤。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
| #pragma data_seg(".shared") HHOOK g_hHook = NULL; BOOL g_bEnable = FALSE; #pragma data_seg() #pragma comment(linker, "/section:.shared,rws")
LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam) { if ((g_bEnable) && (nCode == HC_ACTION)) { switch (wParam) { case WM_KEYDOWN: case WM_SYSKEYDOWN: case WM_KEYUP: case WM_SYSKEYUP: { PKBDLLHOOKSTRUCT pKbd = (PKBDLLHOOKSTRUCT)lParam; BOOL bAltPress = (pKbd->flags & LLKHF_ALTDOWN) != 0; BOOL bCtrlPress = (GetKeyState(VK_CONTROL) & 0x8000) != 0; if (bAltPress && (pKbd->vkCode == VK_F4)) return TRUE; if (bAltPress && (pKbd->vkCode == VK_TAB)) return TRUE; if (bAltPress && (pKbd->vkCode == VK_ESCAPE)) return TRUE; if (bCtrlPress && (pKbd->vkCode == VK_ESCAPE)) return TRUE; if (bCtrlPress && bAltPress && (pKbd->vkCode == VK_DELETE)) return TRUE; } break; } } return CallNextHookEx(g_hHook, nCode, wParam, lParam); }
BOOL SetKeyboardHookDll() { g_hHook = SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardProc, (HINSTANCE)GetModuleHandle("KbdHook.dll"), 0); if (g_hHook == NULL) return FALSE; return TRUE; }
BOOL UnKeyboardHookDll() { return UnhookWindowsHookEx(g_hHook); }
|
需要注意的是,调用DLL并执行HOOK的程序,在HOOK以后不能退出,否则导致HOOK的DLL被卸载。
或者也可以把HOOK的相关函数直接写到EXE程序中,把EXE自身作为DLL模块注入到所有线程中。