IAT(Import Address Table)Hook 是一种 通过修改导入表中的函数地址来实现 API 劫持 的技术,适合针对当前进程的 API 替换,不依赖于 DLL 注入或系统级钩子。
本例目标
劫持 CreateFileW(或 CreateFileA)函数:
🛠 步骤 1:声明 CreateFile 函数指针
点击查看代码
#include <windows.h>
#include <iostream>typedef HANDLE(WINAPI* PFN_CreateFileW)(LPCWSTR lpFileName,DWORD dwDesiredAccess,DWORD dwShareMode,LPSECURITY_ATTRIBUTES lpSecurityAttributes,DWORD dwCreationDisposition,DWORD dwFlagsAndAttributes,HANDLE hTemplateFile
);PFN_CreateFileW OriginalCreateFileW = nullptr;
点击查看代码
HANDLE WINAPI HookedCreateFileW(LPCWSTR lpFileName,DWORD dwDesiredAccess,DWORD dwShareMode,LPSECURITY_ATTRIBUTES lpSecurityAttributes,DWORD dwCreationDisposition,DWORD dwFlagsAndAttributes,HANDLE hTemplateFile
) {std::wcout << L"[IAT-HOOK] 拦截到 CreateFileW:" << lpFileName << std::endl;// 可以替换文件路径示例// lpFileName = L"C:\\Hooked.txt";return OriginalCreateFileW(lpFileName,dwDesiredAccess,dwShareMode,lpSecurityAttributes,dwCreationDisposition,dwFlagsAndAttributes,hTemplateFile);
}
点击查看代码
void HookIAT_CreateFileW() {// 获取模块基址(当前 exe)HMODULE hModule = GetModuleHandle(NULL);if (!hModule) return;// 获取 DOS 和 PE 头PIMAGE_DOS_HEADER dosHeader = (PIMAGE_DOS_HEADER)hModule;PIMAGE_NT_HEADERS ntHeader = (PIMAGE_NT_HEADERS)((BYTE*)hModule + dosHeader->e_lfanew);// 获取 Import Directory 表IMAGE_DATA_DIRECTORY importDir = ntHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT];if (!importDir.VirtualAddress) return;PIMAGE_IMPORT_DESCRIPTOR importDesc = (PIMAGE_IMPORT_DESCRIPTOR)((BYTE*)hModule + importDir.VirtualAddress);// 遍历导入表for (; importDesc->Name != 0; importDesc++) {LPCSTR moduleName = (LPCSTR)((BYTE*)hModule + importDesc->Name);if (_stricmp(moduleName, "KERNEL32.dll") != 0)continue;// 找到 FirstThunk(IAT 表)PIMAGE_THUNK_DATA pThunk = (PIMAGE_THUNK_DATA)((BYTE*)hModule + importDesc->FirstThunk);for (; pThunk->u1.Function != 0; pThunk++) {FARPROC* ppFunc = (FARPROC*)&pThunk->u1.Function;if (*ppFunc == (FARPROC)GetProcAddress(GetModuleHandleA("kernel32.dll"), "CreateFileW")) {// 保存原始函数OriginalCreateFileW = (PFN_CreateFileW)*ppFunc;// 修改内存保护属性为可写DWORD oldProtect;VirtualProtect(ppFunc, sizeof(FARPROC), PAGE_EXECUTE_READWRITE, &oldProtect);// 替换函数指针*ppFunc = (FARPROC)HookedCreateFileW;// 恢复保护VirtualProtect(ppFunc, sizeof(FARPROC), oldProtect, &oldProtect);std::cout << "[OK] CreateFileW IAT Hook 成功" << std::endl;return;}}}
}
点击查看代码
void TestCreateFile() {HANDLE hFile = CreateFileW(L"C:\\Windows\\System32\\notepad.exe",GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,0,NULL);if (hFile != INVALID_HANDLE_VALUE) {std::cout << "[Test] CreateFile 成功打开文件" << std::endl;CloseHandle(hFile);} else {std::cout << "[Test] CreateFile 打开失败,错误码: " << GetLastError() << std::endl;}
}
点击查看代码
int main() {HookIAT_CreateFileW(); // 执行 HookTestCreateFile(); // 测试调用return 0;
}
| 应用场景 | 举例说明 |
|---|---|
| 🛡️ 安全防护 / 防作弊 | 拦截游戏中的 CreateFile、ReadProcessMemory,防止外挂注入 |
| 🪝 软件注入 / 插件系统 | 替换 LoadLibrary、CreateFile,控制哪些 DLL/文件能被加载/访问 |
| 🧪 逆向分析 / 恶意软件行为监控 | Hook CreateProcess、WriteFile,观察病毒行为 |
| 🔧 动态调试 / 热更新模块 | 把原本导入的函数指向你自己的函数,做动态替换 |
| 🗃️ 日志审计 / 文件访问记录 | 拦截 CreateFileW,打印访问的文件名到日志中 |
| 🧩 程序透明代理 / 沙箱隔离 | 拦截网络类 API(如 connect、send),做透明代理 |
原来调用系统 API:
CreateFileW(L"c:\\secret.txt", ...);
Hook 后:
点击查看代码
HookedCreateFileW() {std::wcout << "有人试图访问 secret.txt!拦截!" << std::endl;return INVALID_HANDLE_VALUE;
}
