正规的装饰行业网站建设公司推广文章的注意事项
一、Windows消息机制与Hook的底层原理
1.1 Windows事件传递机制
-
消息队列结构:每个GUI线程维护
MSG
队列,系统通过PostMessage
和SendMessage
传递事件 -
消息循环流程:
GetMessage
->TranslateMessage
->DispatchMessage
-
Hook插入点:Hook通过
SetWindowsHookEx
在消息处理链中插入自定义处理层
1.2 Hook链工作模型
原始消息流:
[系统] -> [应用消息队列] -> [窗口过程WndProc]安装Hook后:
[系统] -> [Hook处理函数] -> [其他Hook] -> [应用消息队列] -> [窗口过程]
1.3 关键API
HHOOK SetWindowsHookEx([in] int idHook,[in] HOOKPROC lpfn,[in] HINSTANCE hmod,[in] DWORD dwThreadId
);
[in] idHook
类型:int
要安装的挂钩过程的类型。(文章最后有列出)[in] lpfn
类型:HOOKPROC
指向挂钩过程的指针。 如果 dwThreadId 参数为零或指定由其他进程创建的线程的标识符,则 lpfn 参数必须指向 DLL 中的挂钩过程。 否则,lpfn 可以指向与当前进程关联的代码中的挂钩过程。[in] hmod
类型:HINSTANCE
DLL 的句柄,其中包含由 lpfn 参数指向的挂钩过程。 如果 dwThreadId 参数指定由当前进程创建的线程,并且挂钩过程位于与当前进程关联的代码中,则必须将 hMod 参数设置为 NULL。[in] dwThreadId
类型:DWORD
要与之关联的挂钩过程的线程的标识符。 对于桌面应用,如果此参数为零,则挂钩过程与调用线程在同一桌面上运行的所有现有线程相关联。 有关 Windows 应用商店应用,请参阅“备注”部分。返回值
类型:HHOOK
如果函数成功,则返回值为挂钩过程的句柄。
如果函数失败,则返回值 NULL。 若要获取扩展的错误信息,请调用 GetLastError。BOOL UnhookWindowsHookEx([in] HHOOK hhk
);
参数
[in] hhk
类型: HHOOK
要移除的挂钩的句柄。 此参数是由先前调用 SetWindowsHookEx 获取的挂钩句柄。返回值
类型: BOOL
如果该函数成功,则返回值为非零值。
如果函数失败,则返回值为零。 要获得更多的错误信息,请调用 GetLastError。
二、全局Hook与DLL注入技术详解
2.1 跨进程Hook实现原理
-
DLL注入强制加载:通过
SetWindowsHookEx
的第三个参数指定DLL路径 -
内存映射机制:Hook DLL会被加载到所有目标进程的地址空间
-
共享数据段:使用
#pragma data_seg
创建共享内存区域
2.2 DLL代码示例(共享数据区)
// 共享内存声明
#pragma data_seg(".SHARED")
HHOOK g_hHook = NULL;
#pragma data_seg()
#pragma comment(linker, "/SECTION:.SHARED,RWS")// 导出函数
extern "C" __declspec(dllexport) LRESULT CALLBACK HookProc(int code, WPARAM wParam, LPARAM lParam) {if (code == HC_ACTION) {// 处理逻辑}return CallNextHookEx(g_hHook, code, wParam, lParam);
}
2.3 注入器核心代码
// 远程线程注入
HANDLE hThread = CreateRemoteThread(hProcess, NULL, 0,(LPTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandle(L"kernel32"), "HookDLL.dll",0, NULL);
2.4 键盘记录示例
// 全局Hook句柄存储
HHOOK g_hKeyboardHook = nullptr;// 键盘事件处理函数
LRESULT CALLBACK KeyboardProc(int code, WPARAM wParam, LPARAM lParam) {if (code == HC_ACTION) {BYTE keyState[256];GetKeyboardState(keyState);WORD charCode;char buffer[16] = {0};if (ToAscii(wParam, (lParam >> 16) & 0xFF, keyState, &charCode, 0) == 1) {sprintf(buffer, "%c", charCode);OutputDebugStringA(buffer); // 输出到调试器}}return CallNextHookEx(g_hKeyboardHook, code, wParam, lParam);
}// 安装全局键盘Hook
void InstallKeyboardHook() {g_hKeyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, KeyboardProc, GetModuleHandle(NULL), 0);
}// 卸载Hook
void UninstallHook() {if (g_hKeyboardHook) {UnhookWindowsHookEx(g_hKeyboardHook);g_hKeyboardHook = nullptr;}
}
2.5 鼠标记录实列
HHOOK g_hMouseHook = nullptr;LRESULT CALLBACK MouseProc(int code, WPARAM wParam, LPARAM lParam) {if (code >= 0) {MSLLHOOKSTRUCT* pMouse = (MSLLHOOKSTRUCT*)lParam;// 拦截右键点击if (wParam == WM_RBUTTONDOWN) {MessageBox(NULL, L"右键点击被拦截!", L"提示", MB_OK);return 1; // 阻止事件传递}// 记录坐标if (wParam == WM_MOUSEMOVE) {POINT pt = pMouse->pt;TCHAR buf[50];wsprintf(buf, L"坐标: (%d, %d)", pt.x, pt.y);SetWindowText(GetConsoleWindow(), buf);}}return CallNextHookEx(g_hMouseHook, code, wParam, lParam);
}// 安装低层级鼠标Hook
void InstallMouseHook() {g_hMouseHook = SetWindowsHookEx(WH_MOUSE_LL, MouseProc, GetModuleHandle(NULL), 0);
}
三、内核级Hook技术初探
3.1 驱动开发基础
-
WDM模型:Windows Driver Model基础架构
-
过滤驱动:通过
IoCreateDevice
创建过滤设备对象 -
IRP拦截:拦截
IRP_MJ_DEVICE_CONTROL
控制码
3.2 键盘过滤驱动示例
NTSTATUS DriverEntry(PDRIVER_OBJECT drvObj, PUNICODE_STRING regPath) {// 创建设备对象IoCreateDevice(..., &deviceObject);// 设置IRP处理函数drvObj->MajorFunction[IRP_MJ_READ] = FilterRead;// 绑定键盘设备栈IoAttachDeviceToDeviceStack(...);return STATUS_SUCCESS;
}NTSTATUS FilterRead(PDEVICE_OBJECT devObj, PIRP irp) {// 获取原始按键数据KEYBOARD_INPUT_DATA* pData = (KEYBOARD_INPUT_DATA*)irp->AssociatedIrp.SystemBuffer;// 修改按键值(示例:禁用F1键)if (pData->MakeCode == 0x3B) { // F1键扫描码pData->MakeCode = 0; // 清零处理}return IoCallDriver(nextDevObj, irp);
}
四、高级Hook应用:API函数拦截
4.1 Inline Hook原理
-
指令替换:修改目标函数头5字节为
jmp
跳转指令 -
跳板代码:保存原始字节并重定向到自定义函数
-
执行流程:
原函数 -> jmp到Hook函数 -> 执行代理逻辑 -> 跳回原函数
4.2 Detours库实战
#include <detours.h>// 目标API函数指针
typedef BOOL (WINAPI* TrueMessageBox)(HWND, LPCWSTR, LPCWSTR, UINT);
TrueMessageBox OriginalMessageBox = MessageBox;// Hook处理函数
BOOL WINAPI HookedMessageBox(HWND hWnd, LPCWSTR text, LPCWSTR caption, UINT type) {// 修改消息框文本return OriginalMessageBox(hWnd, L"被Hook修改的内容", caption, type);
}// 安装Hook
void InstallHook() {DetourTransactionBegin();DetourUpdateThread(GetCurrentThread());DetourAttach(&(PVOID&)OriginalMessageBox, HookedMessageBox);DetourTransactionCommit();
}
五、Hook调试与反检测技术
5.1 调试技巧
-
双机调试:使用WinDbg通过串口/USB调试内核Hook
-
调试器标记检测:
if (IsDebuggerPresent()) {MessageBox(NULL, L"检测到调试器!", L"警告", MB_ICONWARNING); }
5.2 反Hook检测方法
// 检查函数头部指令
bool CheckHook(LPVOID funcAddr) {BYTE* pCode = (BYTE*)funcAddr;return (*pCode == 0xE9); // 检查是否包含jmp指令
}// 定时校验关键函数
if (CheckHook(MessageBox)) {TerminateProcess(GetCurrentProcess(), 0);
}
六、性能优化与最佳实践
6.1 回调函数优化准则
-
避免阻塞操作:严禁在Hook回调中进行文件I/O等耗时操作
-
异步处理机制:使用线程池处理复杂逻辑
-
内存管理:使用无锁队列传递数据
6.2 现代Hook技术演进
-
用户模式APC注入:
QueueUserAPC
实现精准线程控制 -
ETW(Event Tracing for Windows):监控系统事件的新方法
-
内核回调:
PsSetLoadImageNotifyRoutine
监控模块加载
附录:推荐工具集
-
Microsoft Detours:专业的Hook库
-
WinDbg Preview:内核级调试工具
-
Process Monitor:实时监控系统活动
-
x64dbg:开源逆向工程调试器
HOOK类型表
idHook | 意义 |
---|---|
WH_CALLWNDPROC 4 | 安装一个挂钩过程,用于在系统将其发送到目标窗口过程之前监视消息。 有关详细信息,请参阅 CallWndProc 挂钩过程。 |
WH_CALLWNDPROCRET 12 | 安装一个挂钩过程,用于在目标窗口过程处理消息后监视消息。 有关详细信息,请参阅 [HOOKPROC 回调函数](nc-winuser-hookproc.md) 挂钩过程。 |
WH_CBT 5 | 安装一个挂钩过程,用于接收对 CBT 应用程序有用的通知。 有关详细信息,请参阅 [CBTProc](/windows/win32/winmsg/cbtproc) 挂钩过程。 |
WH_DEBUG 9 | 安装用于调试其他挂钩过程的挂钩过程。 有关详细信息,请参阅 DebugProc 挂钩过程。 |
WH_FOREGROUNDIDLE 11 | 安装将在应用程序前台线程即将处于空闲状态时调用的挂钩过程。 此挂钩可用于在空闲时间执行低优先级任务。 有关详细信息,请参阅 ForegroundIdleProc 挂钩过程。 |
WH_GETMESSAGE 3 | 安装一个挂钩过程,用于监视发布到消息队列的消息。 有关详细信息,请参阅 GetMsgProc 挂钩过程。 |
WH_JOURNALPLAYBACK 1 | 警告 Windows 11 及更新:不支持日记挂钩 API。 建议改用 SendInput TextInput API。 安装一个挂钩过程,该挂钩过程发布以前由 WH_JOURNALRECORD 挂钩过程记录的消息。 有关详细信息,请参阅 JournalPlaybackProc 挂钩过程。 |
WH_JOURNALRECORD 0 | 警告 Windows 11 及更新:不支持日记挂钩 API。 建议改用 SendInput TextInput API。 安装一个挂钩过程,用于记录发布到系统消息队列的输入消息。 此挂钩可用于录制宏。 有关详细信息,请参阅 JournalRecordProc 挂钩过程。 |
WH_KEYBOARD 2 | 安装监视击键消息的挂钩过程。 有关详细信息,请参阅 KeyboardProc 挂钩过程。 |
WH_KEYBOARD_LL 13 | 安装用于监视低级别键盘输入事件的挂钩过程。 有关详细信息,请参阅 LowLevelKeyboardProc 挂钩过程。 |
WH_MOUSE 7 | 安装监视鼠标消息的挂钩过程。 有关详细信息,请参阅 MouseProc 挂钩过程。 |
WH_MOUSE_LL 14 | 安装一个挂钩过程,用于监视低级别鼠标输入事件。 有关详细信息,请参阅 LowLevelMouseProc 挂钩过程。 |
WH_MSGFILTER -1 | 安装一个挂钩过程,用于监视对话框、消息框、菜单或滚动条中输入事件生成的消息。 有关详细信息,请参阅 MessageProc 挂钩过程。 |
WH_SHELL 10 | 安装一个挂钩过程,用于接收对 shell 应用程序有用的通知。 有关详细信息,请参阅 [ShellProc](/windows/win32/winmsg/shellproc) 挂钩过程。 |
WH_SYSMSGFILTER 6 | 安装一个挂钩过程,用于监视对话框、消息框、菜单或滚动条中输入事件生成的消息。 挂钩过程监视与调用线程位于同一桌面中的所有应用程序的消息。 有关详细信息,请参阅 SysMsgProc 挂钩过程。 |