iat hook 的核心是修改调用方模块的导入地址表中指向目标函数的指针,而非查找函数本身;需解析其导入表、定位对应 dll 的 firstthunk 所指 iat 条目,比对函数名或序号,并在修改前调整内存页权限为可写、写入后及时恢复,同时确保代理函数调用约定一致、正确缓存原函数地址,以避免崩溃、递归或被 edr 检测。

怎么定位目标 DLL 的 IAT 条目
关键不是“找函数”,而是“找调用方模块里存的函数地址指针”。IAT 是 PE 加载器在内存中为每个模块维护的一张表,记录了该模块调用的外部函数地址(比如 user32.dll 的 MessageBoxA)。要挂钩,必须先拿到调用方模块(比如你的主程序或某个插件 DLL)的 IAT 中对应项的地址。
实操建议:
- 用
ImageDirectoryEntryToData+IMAGE_DIRECTORY_ENTRY_IMPORT解析调用方模块的导入表,逐个遍历IMAGE_THUNK_DATA数组 - 对每个导入 DLL(如
"kernel32.dll"),再遍历其FirstThunk指向的 IAT 条目,比对函数名(通过IMAGE_IMPORT_BY_NAME)或序号 - 注意:如果目标模块启用了延迟加载(
IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT),IAT 位置在另一张表里,不能只查标准导入表 - 调试时可用 x64dbg 或 Process Hacker 查看目标进程的“IAT”视图,确认函数地址是否已解析(非零值),避免 hook 未解析的桩(0x0)
怎么安全地修改 IAT 内存权限并写入新地址
IAT 所在页默认是只读(PAGE_READONLY),直接写会触发访问违规。必须先改页保护,写完再恢复——但这个过程不是原子的,多线程下有竞态风险。
实操建议:
- 用
VirtualQuery获取 IAT 地址所在页的基址和当前保护标志 - 用
VirtualProtect将整页设为PAGE_READWRITE;不要只改单字节,Windows 最小保护粒度是页(通常 4KB) - 写入前,确保目标函数指针是合法的可执行地址(检查
IsBadReadPtr已过时,改用VirtualQuery确认内存状态) - 写入后立即调用
VirtualProtect恢复原保护(如PAGE_READONLY),否则可能被 ASLR 或 EDR 检测为可疑行为 - 若目标进程开启 CFG(Control Flow Guard),新地址必须通过
__guard_check_icall_fptr校验,否则间接调用会崩溃;此时需配合 CFG bypass 或改用更底层的 inline hook
为什么 hook 后调用原函数经常崩溃或返回错误
常见原因是没正确还原调用约定或栈平衡。IAT hook 替换的是函数指针,调用时 CPU 完全按原函数签名执行,你自己的代理函数必须 1:1 兼容 ABI。
通过 SSH 隧道从 Android 设备在互联网上对 Windows PC 实现完整远程控制的设置与使用指南,适用于远程桌面访问、安全 RDP 等。
实操建议:
- 代理函数声明必须和原函数完全一致:调用约定(
__stdcall还是__cdecl)、参数类型、返回值。例如WriteFile是WINAPI(即__stdcall),代理函数也必须加__stdcall - 不要在代理函数里直接调用原地址——原地址此时已被你覆盖,会导致递归调用。必须在 patch 前用
GetProcAddress或手动解析导出表拿到原始函数地址,并缓存到全局变量 - 若原函数是内联展开或编译器优化掉的(如某些 CRT 函数),IAT 可能根本没引用它,hook 失效;此时需检查实际调用点是否走 IAT(反汇编确认)
- 部分系统 DLL(如
ntdll.dll)使用导出转发(forwarder),IAT 存的是转发字符串(如 "NTDLL.RtlAllocateHeap"),不是真实地址,需额外解析转发目标
怎样避免被 EDR/AV 检测到 IAT 修改
现代安全软件会轮询监控 IAT 页面的写操作、校验 PE 导入表一致性,或 Hook VirtualProtect 等 API。纯 IAT hook 在生产环境极易被识别。
实操建议:
- 避免在主线程、初始化阶段集中修改多个 IAT 条目;分散到不同时间点,或在目标函数首次调用前一刻再 patch
- 不调用
VirtualProtect直接改写,改用硬件断点或SetThreadContext注入短指令(如mov eax, imm32; jmp eax)跳转,绕过内存保护检测 - 修改后主动调用
FlushInstructionCache,防止 CPU 指令流水线缓存旧指令 - 最关键的细节:IAT 地址本身可能被 EDR 钩住(如 hook
LoadLibrary后扫描新模块导入表),所以最好在目标模块加载完成后再延迟几毫秒执行 hook
真正难的不是改一个指针,而是让所有线程都看到一致的新地址,同时不触发任何一道防护的阈值判断。实际工程中,往往需要结合 EAT hook、inline hook 和 syscall 直接调用做 fallback。
大量免费API接口:立即使用
涵盖生活服务API、金融科技API、企业工商API、等相关的API接口服务。免费API接口可安全、合规地连接上下游,为数据API应用能力赋能!










