
PolyHook 实战指南3 步完成你的第一个 C 函数钩子【免费下载链接】PolyHookx86/x64 C Hooking Library项目地址: https://gitcode.com/gh_mirrors/po/PolyHookPolyHook 把 x86/x64 的 6 种函数钩子Hook方式塞进了一个头文件内联钩子、IAT 钩子、虚表钩子、VEH 钩子。适合想在 Windows 上做函数级监控、游戏逆向与安全审计的 C 工程师。 它解决什么问题三类绕不开的真实痛点在函数入口处拦一下——参数先进你的代码放不放行你说了算——这就是钩子Hook。在 Windows 上做函数 Hook基本绕不开三类场景游戏逆向 / 客户端分析目标函数是编译好的机器码源码拿不到。你想知道它调了什么、传了什么参数只能把目标模块开头的几条指令截到自己手里。痛点是得自己数指令长度、手写跳转切错半个字节就崩。函数级监控与审计你想给WriteProcessMemory、CreateProcess这类调用加参数日志。痛点是同一个 API 有走导入表和内部直调两种到达路径钩子方式选错就漏报。安全分析 / 反反调试目标会扫描你打的代码补丁。痛点是你需要一种一个字节都不改就能触发拦截的办法。PolyHook 的价值在于算指令长度、修相对跳转、挂起线程这些最易写错的活它都替你干了。 最快上手3 步装好跑通第一个函数 Hook仓库是头文件实现header-only不需要自己编译出库克隆代码git clone https://gitcode.com/gh_mirrors/po/PolyHook找齐两样东西主头文件 PolyHook/PolyHook.hpp以及仓库自带的反汇编引擎预编译库 Capstone/msvc/x64 用x64/Release/capstone.libx86 用x86/下对应版本。VS 工程配三处仓库根目录加进包含目录这样能写#include PolyHook/PolyHook.hppCapstone/include加进包含目录capstone.lib加进链接器。头文件里已有#pragma comment(lib, ...)自动引用你只负责让它找得到库。最小可运行示例——拦截MessageBoxA改完文案再交回原函数#include PolyHook/PolyHook.hpp // 头文件即库 #include windows.h typedef int(WINAPI* tMsgBox)(HWND, LPCSTR, LPCSTR, UINT); tMsgBox g_origMsgBox; // 必须存原函数钩子里还要借它继续干活 // 签名和 MessageBoxA 完全一致这里改参数然后交回原实现 int WINAPI MsgBoxPatcher(HWND h, LPCSTR text, LPCSTR cap, UINT type) { return g_origMsgBox(h, 被拦截了, cap, type); } int main() { // x64 下是 X64Detourx86 下是 X86Detour宏自动选同名直接用 auto detour std::make_sharedPLH::Detour(); detour-SetupHook((BYTE*)MessageBoxA, (BYTE*)MsgBoxPatcher); if (!detour-Hook()) // 会失败函数太小等别当 void 用 return 1; g_origMsgBox detour-GetOriginaltMsgBox(); MessageBoxA(nullptr, 你好, 测试, MB_OK); // 这次先进钩子 detour-UnHook(); // 退出前交还现场 }6 种钩子的完整可跑示例都在 PolyHook/Tests.cpp照着抄即可。提醒这个仓库是 V1 头文件实现README 指向的 V2polyhook2是维护版API 基本一致本文步骤两者都适用。不想手动配库也可以走 vcpkg 装polyhook2:x86-windows。⚙️ 核心机制拆解4 种钩子各管一摊事内联钩子写法Detour最常见的函数拦截是什么把目标函数开头几条完整指令改成跳转指到你的处理函数被覆盖的原指令搬进一块单独分配的跳板trampoline跳板尾部再跳回原函数剩余部分全程由 Capstone 反汇编并自动修正 RIP/EIP 相对寻址和条件跳转。什么时候用要拦截任意函数本模块的或别的模块导出的且原实现之后还得能正常调用。注意x64 会优先在目标 ±2GB 内分配跳板分配不到才退化成 6 字节跳转函数开头太小时Hook()直接返回 false记得查GetLastError()的严重级别。IAT 钩子IATHook只动导入表不碰一行代码是什么不改任何代码把导入地址表IATPE 文件里记录本模块调用了谁家的 API的地址表中对应函数的地址换成你的钩子。什么时候用拦截 kernel32、gdi32 等导入 API只关心本进程走 IAT 的调用路径要最稳、最轻。注意拦不到绕过 IAT 的内部直调目标模块必须带原始导入表OriginalFirstThunk否则直接报不支持。虚表级钩子VFuncSwap / VTableSwap只改对象不改函数体是什么两个档位——VFuncSwap 只替换虚函数表vtable里的一个槽位VTableSwap 把整个虚表复制一份、把对象的虚表指针换成副本还能用HookAdditional一次挂多个方法。什么时候用目标是虚函数且只想影响特定对象函数本体一个字节都不动。注意VFuncSwap 改的是共享虚表会影响所有同类实例要按对象隔离就用 VTableSwap。VEH 钩子VEHHook靠触发异常实现零代码改动是什么在目标地址故意制造异常INT3 断点、硬件断点、保护页三种触发器Windows 的顶层异常回调——矢量异常处理程序VEH——抓到后把指令指针改指你的处理函数再撤掉触发器。什么时候用目标会扫描代码补丁或你要求一个字节都不改的拦截。注意回调里必须调GetProtectionObject()恢复触发机制否则断点/保护页一直挂着、反复触发不能在调试器下跑保护页方式若目标与处理函数落在同一内存页会误触发。️ 实战避坑6 组错误做法 → 正确做法对照错误钩子里直接返回固定值不调原函数。正确用GetOriginalT()存好原函数指针钩子干完活再转发过去。否则整条业务链断在你手里。错误把Hook()当 void默认必成功。正确查返回值失败时看GetLastError()严重度分 Warning / Critical / UnRecoverable 三级遇到 UnRecoverable 就换钩子类型或换钩点。错误手算前 5 个字节覆盖函数头。正确永远让库用 Capstone 按整条指令数长度。手写跳转切半个字节必崩。错误只想拦某个对象的虚函数却用了 VFuncSwap。正确那会改到所有同类实例共享的虚表按对象隔离用 VTableSwap。错误VEH 回调里忘了恢复触发机制。正确回调第一行就调GetProtectionObject()它负责把 INT3/保护页还原防止钩子自己触发自己。错误钩住极短函数或系统关键路径还让钩子常驻不撤。正确选稳定、足够长的函数做钩点让 Detour 对象活到进程退出析构会自动 UnHook退出前显式UnHook()交还现场。 生态搭配谁来补齐哪块短板Capstone反汇编引擎补该覆盖多少字节这块短板。内联钩子最忌讳切半条指令PolyHook 靠它反汇编函数头、修正相对寻址仓库已自带各配置预编译库Capstone/msvc/开箱即用。Microsoft Detours微软官方钩子库补交叉验证短板。需要确认 PolyHook 的重定位是否正确、或要挂系统级调用时拿它做对照和兜底。UnicornCPU 模拟器补不敢在真机跑短板。跳板和重定位结果可以先在模拟的 CPU 上跑一遍验证不用拿真实程序冒险。vcpkg补手动配依赖短板。一条命令装polyhook2:x86-windowsV2 及其依赖齐活。收尾一句话总结 你的下一步PolyHook 把算指令长度、修相对跳转、挂起线程这些最容易写错的活全接走了你只剩两件事选对钩子类型写好回调——如果你一直在找一款能直接进工程的 x64 函数 Hook 库到这里就齐了。下一步打开 PolyHook/Tests.cpp照着第一个 Detour 用例在你自己的工程里跑一遍MessageBoxA拦截。跑通了再碰真正的目标。【免费下载链接】PolyHookx86/x64 C Hooking Library项目地址: https://gitcode.com/gh_mirrors/po/PolyHook创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考