
SafetyHook MidHook进阶如何在函数执行中途捕获并改写任意CPU寄存器【免费下载链接】safetyhookC23 procedure hooking library.项目地址: https://gitcode.com/gh_mirrors/sa/safetyhookSafetyHook 是一款 C23 过程钩子procedure hooking库支持 Windows / Linux 的 x86 与 x86_64 平台。它最独特的 MidHook 能力是让你可以在函数执行到任意一条指令的中途插入钩子并在回调里安全地读取和改写任意 CPU 寄存器。本文带你完整掌握这项进阶功能。 MidHook 和 InlineHook 有什么区别SafetyHook 的 MidHook 类源码位于include/safetyhook/mid_hook.hpp建立在 InlineHook 之上但目标地址的含义完全不同类型钩子位置回调时机能拿到什么InlineHook函数入口函数开始执行前调用参数 原函数跳板MidHook函数内任意指令地址执行到该指令的中途完整 CPU 寄存器快照Context一句话理解InlineHook 是在门口拦人MidHook 是走到房间任意角落都能拦人。你甚至可以把钩子下在函数末尾的ret指令上在函数即将返回的那一刻修改返回值。⚙️ MidHook 的工作原理保存 → 处理 → 恢复MidHook 内部会分配一段约 391 字节的汇编存根stub核心流程写在这几个汇编文件中src/mid_hook.x86_64-windows.asmsrc/mid_hook.x86_64-linux.asmsrc/mid_hook.x86_32.asm执行到被钩的指令时存根按 4 步操作可参考 mid_hook.x86_64-linux.asm保存现场把全部 16 个通用寄存器rax、rbx…r15、rflags 依次压栈再用movdqu保存 16 个 XMM 寄存器并把原始 rip、rsp 记入栈中调用你的处理器把这块寄存器快照区的指针作为Context参数传给你写的回调函数恢复现场处理器返回后存根把 XMM、通用寄存器、rflags 全部弹回 CPU ——你在回调里改过的寄存器值会原样生效续跑原函数跳回 trampoline 中保存的原指令字节函数从被钩处继续执行。这就是改写寄存器能成立的原因寄存器先被搬到内存改完再搬回去。 Context一张完整的 CPU 快照MidHook 回调的唯一参数是 Context 结构include/safetyhook/context.hpp它按架构提供两套字段64 位Context64整数寄存器rax、rcx、rdx、rbx、rbp、rsp、r8~r15、rip浮点寄存器xmm0~xmm15联合体可按u32[4]、f32[4]、f64[2]等视图读写标志位rflags32 位Context32对应eax、ecx、esp、eip等。⚠️ 两个必须知道的关键约定rip指向 trampoline内含被替换的原指令不是下一条原指令不要直接对rip乱写rsp只读直接改无效。需要操纵栈时使用trampoline_rsp并保证栈顶是你想让 rip 恢复到的地址。 快速上手3 步改写返回值下面是最小完整示例官方示例见 midhook.cpp#include safetyhook.hpp SAFETYHOOK_NOINLINE int add_42(int a) { return a 42; } // 处理器函数签名固定为void (SafetyHookContext) void my_handler(SafetyHookContext ctx) { ctx.rax 1337; // 改写返回值寄存器 } int main() { std::println(hook前: {}, add_42(2)); // 44 SafetyHookMid hook safetyhook::create_mid(add_42, my_handler); std::println(hook后: {}, add_42(3)); // 1337 hook.reset(); // 恢复原函数 std::println(恢复后: {}, add_42(4)); // 46 }要点create_mid是 easy APIinclude/safetyhook/easy.hpp失败时返回空对象不用手动查错误需要精细错误处理时用SafetyHookMid::create它返回std::expectedMidHook, ErrorSafetyHookMid、SafetyHookContext等别名统一在 safetyhook.hpp 中声明把钩子下在ret指令上而非函数入口就能在最后时刻改写返回值官方示例正是逐条反汇编add_42直到找到0xC3ret的机器码再建钩子。 进阶玩法改写函数入参与 XMM 寄存器改输入参数x64 下第一参数寄存器Windows 是rcxLinux 是rdiSysV ABI。官方单元测试mid_hook.cpp演示了改参数让add_42(1)返回 1337void hook_args(SafetyHookContext ctx) { #if SAFETYHOOK_OS_WINDOWS ctx.rcx 1337 - 42; #else ctx.rdi 1337 - 42; #endif }改浮点参数XMM 寄存器float 型参数在xmm0里同一个 Context 结构就能改void hook_float(SafetyHookContext ctx) { ctx.xmm0.f32[0] 1337.0f - 0.42f; }可以看到 MidHook 的覆盖面整数寄存器、浮点寄存器、标志位、栈trampoline_rsp都可以读写这让它能做参数篡改、返回值伪造、条件跳转改写配合rflags等经典用途。️ 运行时启用 / 禁用钩子不想一创建就生效传StartDisabled标志之后随时enable()/disable()SafetyHookMid hook safetyhook::create_mid( add_42, my_handler, SafetyHookMid::StartDisabled); hook.enable(); // 生效 hook.disable(); // 暂停 hook.reset(); // 彻底移除析构时也会自动执行测试用例test/mid_hook.cpp中验证了完整的创建(禁用) → 启用 → 禁用 → 移除生命周期函数行为在每一步都精确可预期。️ 为什么 MidHook 是安全的这是 SafetyHook 名字的由来也是它区别于往内存里写个 jmp 就走的野路子钩子库的核心建钩/删钩时暂停所有其他线程避免有线程正跑在被改写的代码上自动修复受影响线程的指令指针把恰好停在钩子区域的线程挪开修复被搬移指令的相对偏移比如lea rax, [rip0x1234]、jmp 0x1234短分支会自动拓宽为近分支底层使用现代反汇编引擎 Zydis 保证指令边界切分正确。这些逻辑分散在src/inline_hook.cpp、src/os.windows.cpp、src/os.linux.cpp中。⚠️ 新手常见坑位清单处理器签名写错MidHook 处理器必须是void (*)(Context)不能带返回值、不能是成员函数在 Linux 上钩短函数小函数可能没有对齐填充直接按字节找ret会钩到下一个函数的序言。编译目标时加-falign-functions32留出填充字节官方示例注释中明确提示了这一点乱改rsp直接赋值无效用trampoline_rsp在处理器里长时间持有钩子状态处理器运行在被钩函数的线程上下文里尽量快速返回别在里面做阻塞操作。 相关文件导航文件说明include/safetyhook/mid_hook.hppMidHook 类create / enable / disable / resetinclude/safetyhook/context.hppContext64 / Context32 寄存器快照结构include/safetyhook/easy.hppcreate_mid 便捷 APIinclude/safetyhook.hpp顶层头文件与安全别名example/midhook.cpp钩住 ret 改写返回值的完整示例test/mid_hook.cpp改寄存器 / 改 XMM / 启停生命周期测试src/mid_hook.x86_64-linux.asm等汇编存根保存-处理-恢复全过程src/mid_hook.cpp存根分配与 trampoline 地址回填amalgamate.py/CMakeLists.txt单文件聚合构建 / CMake 工程想要上手项目克隆仓库即可git clone https://gitcode.com/gh_mirrors/sa/safetyhook✅ 小结MidHook 是 SafetyHook 进阶能力中威力最大的一招在函数执行的任意指令处截停 CPU通过 Context 结构拿到包括 XMM 在内的全部寄存器快照改完之后由内置存根精确恢复现场并续跑原函数。配合其线程安全的钩子生命周期管理你可以放心地实现参数改写、返回值伪造、执行流控制等高级插桩需求。下一步建议直接通读example/midhook.cpp和test/mid_hook.cpp亲手改几个寄存器感受中途截停的魔力。【免费下载链接】safetyhookC23 procedure hooking library.项目地址: https://gitcode.com/gh_mirrors/sa/safetyhook创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考