首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> 關於C++

API Hook 核心原理與實戰實現:從消息鉤子到 IAT 修改的完整指南

     編輯:關於C++

什麼是 Hook?

Windows 訊息驅動架構中,Hook 是插入訊息處理流程的「鉤子」,允許攔截、監控、修改系統或應用程式的訊息/函數調用。分類:

  • **系統級 Hook** (SetWindowsHookEx):13 種標準類型 (WH_KEYBOARD, WH_MOUSE, WH_GETMESSAGE 等),注入目標進程。
  • **API Hook (用戶級)**:修改目標進程 **IAT (Import Address Table)** 或 **Inline Hook** 重導特定 API 函數,非標準 Hook 類型,需結合 Hook 技術跨進程修改。

API Hook 核心難點:PE 格式與 IAT 修改

PE 載入過程簡述

  1. 載入器映射映像至進程空間,解析 **Import Directory (Data Directory[1])**。
  2. 遍歷 IMAGE_IMPORT_DESCRIPTOR 陣列,每個 DLL 對應一項。
  3. 兩個平行陣列:
OriginalFirstThunk (INT) → IMAGE_THUNK_DATA[] → IMAGE_IMPORT_BY_NAME (函數名/序號)
FirstThunk (IAT)       → IMAGE_THUNK_DATA[] → **運行時填入實際函數地址**

**關鍵洞察**:載入完成後,**IAT (FirstThunk) 存放真實函數地址**,修改 IAT 中目標函數對應項即可重導調用。

定位目標 API 在 IAT 中的位置


// 簡化邏輯:遍歷模組 Import Directory
PIMAGE_IMPORT_DESCRIPTOR pImport = ...;
while (pImport->Name) {
    char *dllName = (char*)RVA2VA(pImport->Name);
    if (_stricmp(dllName, "user32.dll") == 0) {
        PIMAGE_THUNK_DATA pINT = (PIMAGE_THUNK_DATA)RVA2VA(pImport->OriginalFirstThunk);
        PIMAGE_THUNK_DATA pIAT = (PIMAGE_THUNK_DATA)RVA2VA(pImport->FirstThunk);
        while (pINT->u1.AddressOfData) {
            PIMAGE_IMPORT_BY_NAME pName = (PIMAGE_IMPORT_BY_NAME)RVA2VA(pINT->u1.AddressOfData);
            if (strcmp((char*)pName->Name, "MessageBoxW") == 0) {
                // 找到目標:pIAT 指向的位置即為 IAT 條目
                // 修改 *pIAT = (ULONG_PTR)MyMessageBoxW;
            }
            ++pINT; ++pIAT;
        }
    }
    ++pImport;
}

實戰架構:DLL 注入 + Hook 線程 + IAT 修改

1. 共享記憶體段 (命名資料段)


// HookDll.cpp
#pragma data_seg("SHARE")
HINSTANCE g_hDll = NULL;
HHOOK g_hHook = NULL;
#pragma data_seg()
#pragma comment(linker, "/SECTION:SHARE,RWS")  // 讀寫共享

// HookDll.def
LIBRARY HookDll
EXPORTS
SetHook
Unhook
SECTIONS
SHARE READ WRITE SHARED

2. Hook 線程處理函數

LRESULT CALLBACK HookProc(int nCode, WPARAM wParam, LPARAM lParam) {
    if (nCode == HC_ACTION) {
        // 在目標進程上下文執行
        if (!g_hooked) {
            HookIAT("user32.dll", "MessageBoxW", (PROC)MyMessageBoxW);
            g_hooked = TRUE;
        }
    }
    return CallNextHookEx(g_hHook, nCode, wParam, lParam);
}

3. 自定義目標函數

int WINAPI MyMessageBoxW(HWND hWnd, LPCWSTR lpText, LPCWSTR lpCaption, UINT uType) {
    // 修改參數、記錄日誌、攔截調用
    return RealMessageBoxW(hWnd, lpText, L"Hooked!", uType);
}

4. 客戶端安裝/卸載 Hook

// Client.exe
DWORD tid = GetWindowThreadProcessId(hTargetWnd, NULL);
g_hHook = SetWindowsHookEx(WH_GETMESSAGE, HookProc, g_hDll, tid);
// ...
UnhookWindowsHookEx(g_hHook);

關鍵技術細節

Unicode vs ANSI:必須 Hook 正確後綴

MessageBox 實際導出為 MessageBoxA / MessageBoxW。目標程式呼叫哪個就 Hook 哪個,否則不生效。

修改時機:必須在目標進程上下文

  • Hook 線程運行於**目標進程地址空間**,此時修改 IAT 直接生效。
  • 若在客戶端進程修改目標進程 IAT,需 WriteProcessMemory 跨進程寫入,權限複雜且易被殺毒攔截。

恢復原狀:卸載時必須還原 IAT

void UnhookIAT() {
    *pIAT_Entry = (ULONG_PTR)RealMessageBoxW;  // 還原原地址
}

輔助工具推薦

  • PE Explorer / CFF Explorer:靜態分析 PE 結構、驗證 IAT 位置。
  • x64dbg / OllyDbg:動態調試、斷點驗證 Hook 生效、查看 IAT 運行時內容。
  • Dependency Walker:查看模組匯入表。

安全與防禦視角

現代替代方案

  • Microsoft Detours:成熟開源 Hook 庫,支援 x86/x64、交易式 Hook、自動處理指令重寫。
  • MinHook:輕量級、開源、支援佇列式 Hook。
  • Windows 10+ 系統機制:ETW (Event Tracing for Windows)、WPP 軟體追蹤、Kernel Callback — 官方可觀測性介面,無需 Hook。

總結

  1. API Hook 本質是**修改目標進程 IAT** 重導函數調用,核心難點在 PE 解析與跨進程注入。
  2. 標準流程:SetWindowsHookEx 注入 DLL → Hook 線程在目標進程解析 IAT → 修改目標 API 條目 → 卸載時還原。
  3. **必須處理**:Unicode/ANSI 區分、共享段同步、錯誤碼檢查、線程安全、卸載還原。
  4. 生產環境**優先使用 Detours/MinHook** 成熟庫,避免手寫 PE 解析的坑(延遲載入、綁定導入、轉發器、x64 RIP 相對寻址等)。
  5. 防禦端:啟用 CFG (Control Flow Guard)、CET (Control-flow Enforcement Technology)、EDR 行為監控,提升 Hook 攻擊成本。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
攻擊手法防禦對策
IAT Hook 竊取密碼/攔截加密關鍵 API 內聯檢查、IAT 完整性校驗 (CFG/CET)
Inline Hook (修改函數開頭指令)代碼完整性簽名、硬體斷點監控
DLL 注入 (SetWindowsHookEx / 遠程線程)簽名強制、PPL 保護進程、EDR 行為分析