前言
使用 ShellHook
监控窗口消息不需要注入DLL,但是存在着无法抓取子窗口的缺陷,
所以这里使用 SetWindowsHookEx
注入DLL的方式来监控 WH_CBT
消息。
HOOK代码实现
关于 SetWindowsHookEx
的用法,在 低级键盘钩子
文章中曾经介绍过,这里直接给出代码,
注意32位DLL只能注入到32位程序中,64位DLL只能注入到64位程序中,所以在64位系统中,
如果想要监控所有的程序,需要32位程序和64位程序都要进行DLL注入。
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
| #pragma data_seg(".shared") HHOOK g_hHook = NULL; BOOL g_bEnable = FALSE; #pragma data_seg() #pragma comment(linker, "/section:.shared,rws")
LRESULT CALLBACK CbtHookProc(int nCode, WPARAM wParam, LPARAM lParam) { if ((g_bEnable) && (nCode == HCBT_ACTIVATE)) { char szTitle[260] = { 0 }; GetWindowText((HWND)wParam, szTitle, 512); if (strcmp(szTitle, "Internet 协议 (TCP/IP) 属性") == 0) { SendMessage((HWND)wParam, WM_CLOSE, NULL, NULL); } } return CallNextHookEx(g_hHook, nCode, wParam, lParam); }
BOOL SetHookDll() { g_hHook = SetWindowsHookEx( WH_CBT, CbtHookProc, (HINSTANCE)GetModuleHandle("CbtHook.dll"), 0); if (g_hHook == NULL) return FALSE; return TRUE; }
BOOL UnHookDll() { return UnhookWindowsHookEx(g_hHook); }
|
WM_CBT消息
在 WM_CBT
中监控各种窗口行为,如果Code值小于0,则必须调用 CallNextHookEx
继续传递消息。
1 2 3 4 5 6 7 8 9 10 11
| #define HCBT_MOVESIZE 0 #define HCBT_MINMAX 1 #define HCBT_QS 2 #define HCBT_CREATEWND 3 #define HCBT_DESTROYWND 4 #define HCBT_ACTIVATE 5 #define HCBT_CLICKSKIPPED 6 #define HCBT_KEYSKIPPED 7 #define HCBT_SYSCOMMAND 8 #define HCBT_SETFOCUS 9
|
在如下几种行为中,可以通过返回 0值
来允许本次操作,返回 1值
来阻止本次操作。
1 2 3 4 5 6 7
| HCBT_ACTIVATE (5) HCBT_CREATEWND (3) HCBT_DESTROYWND (4) HCBT_MINMAX (1) HCBT_MOVESIZE (0) HCBT_SETFOCUS (9) HCBT_SYSCOMMAND (8)
|
更多的信息可以通过如下链接来了解:
https://docs.microsoft.com/en-us/previous-versions/windows/desktop/legacy/ms644977(v=vs.85)