什麼是 Hook?
Windows 訊息驅動架構中,Hook 是**插入訊息處理流程的回呼機制**。系統維護一組鉤子鏈,訊息傳遞時依序呼叫各鉤子程序,允許攔截、修改、丟棄、記錄訊息。SetWindowsHookEx 安裝,CallNextHookEx 傳遞,UnhookWindowsHookEx 移除。
Hook 類型(部分)
| 類型 | 常數 | 用途 |
| 鍵盤 | WH_KEYBOARD / WH_KEYBOARD_LL | 攔截按鍵、熱鍵、鍵盤記錄器 |
| 滑鼠 | WH_MOUSE / WH_MOUSE_LL | 攔截點擊、移動、自動化測試 |
| 訊息 | WH_GETMESSAGE / WH_CALLWNDPROC | 監控/修改視窗訊息流 |
| Shell | WH_SHELL | 監控 Shell 事件(視窗建立/銷毀、任務列) |
| CBT | WH_CBT | 視窗建立/銷毀/移動/大小變化前通知 |
全域 Hook (LL 除外) 需放在 DLL 中,以便注入目標進程位址空間。
API Hook:另一種「Hook」
非官方 Hook 類型,而是**修改目標函式入口點指令(如 JMP/CALL)重導向至自訂函式**的技術。用途:
- 修正系統 API Bug / 相容性修補。
- 監控/記錄 API 呼叫參數、返回值。
- 實作沙箱、防毒、DRM、熱修補。
API Hook 核心步驟 (x86 32-bit 範例)
- 定位目標函式地址:
GetProcAddress(GetModuleHandle("user32.dll"), "MessageBoxA")。
- 備份原始指令:讀取前 5-6 位元組(足容納一條
JMP rel32)。
- 計算跳轉偏移:
offset = my_func - (target_addr + 5)。
- 修改記憶體保護:
VirtualProtect(target_addr, len, PAGE_EXECUTE_READWRITE, &old)。
- 寫入 JMP 指令:
BYTE jmp[5] = {0xE9, offset_lo, offset_hi, ...}; memcpy(target_addr, jmp, 5)。
- 恢復保護:
VirtualProtect(..., old, &dummy)。
- 自訂函式內呼叫原函式:執行備份指令 →
JMP target_addr+5(蹦床/Trampoline)。
跨進程 Hook:DLL 注入
OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid)
VirtualAllocEx(hProc, NULL, dll_path_len, MEM_COMMIT, PAGE_READWRITE)
WriteProcessMemory(hProc, remote_mem, dll_path, len, NULL)
CreateRemoteThread(hProc, NULL, 0, (LPTHREAD_START_ROUTINE)LoadLibraryA, remote_mem, 0, NULL)
- DLL
DllMain 中執行 SetWindowsHookEx 或 API Hook 邏輯。
64 位元與現代防護挑戰
- x64 相對跳轉
JMP rel32 範圍 ±2GB,若目標超出需用 FF 25 [RIP+offset] 間接跳轉(14 位元組)。
- PatchGuard (Kernel Patch Protection):核心模式 Hook 會導致系統崩潰 (BSOD)。
- Control Flow Guard (CFG):間接呼叫目標必須在合法表單中,Hook 需註冊目標。
- ETW / Windows Defender ATP:行為監控會偵測可疑記憶體修改、遠端執行緒建立。
合法替代方案(優先考慮)
| 需求 | 官方/支援機制 |
| 檔案/註冊表/程序監控 | File System Filter Driver, Registry Callback, ETW, WMI |
| 網路封包過濾 | WFP (Windows Filtering Platform) Callout Driver |
| 應用相容性修補 | Application Compatibility Toolkit (ACT) / Shims |
| 函式攔截測試 | Detours (Microsoft Research), MinHook, 依賴注入框架 |
| 熱修補 | Windows Hotpatching (可修補函式需編譯器支援 /hotpatch) |
總結
Hook 技術威力強大但風險極高。**訊息 Hook** 是官方支援的擴充點;**API Hook** 屬於非文件化、易碎、易被安全機制攔截的「灰色地帶」。現代 Windows 開發應**優先尋找官方回呼/過濾/驅動模型**,實在無替代方案時,才謹慎使用成熟庫 (MinHook, Detours) 實施 API Hook,並做好相容性測試與簽名驗證。**絕不在生產環境濫用 Hook 技術。**
- 上一篇文章: C++ 參考類型 深度解析:本質、const 參考延長壽命陷阱與最佳實踐
- 下一篇文章: C++ 運算子多載 基礎與回傳值語義:友元 vs 成員、左值/右值回傳
Copyright ©
程式碼之家 All Rights Reserved