如何快速上手substitute:5分钟完成你的第一个函数Hook

发布时间:2026/8/22 15:09:13
如何快速上手substitute:5分钟完成你的第一个函数Hook 如何快速上手substitute5分钟完成你的第一个函数Hook【免费下载链接】substituteA free runtime modification library.项目地址: https://gitcode.com/gh_mirrors/su/substitutesubstitute 是一款免费的运行时修改库runtime modification library它的核心能力就是函数 Hook在程序运行过程中动态把某个函数偷梁换柱成你自己的实现同时还能随时调回原始函数。本教程面向新手带你用 5 分钟完成人生第一个函数 Hook并搞懂它的三种 Hook 方式和常见错误码。什么是 substitute它有什么用简单打个比方正常调用getpid()会返回真实的进程号Hook 之后你可以让它返回任意值而调用方完全无感知。substitute 主要提供三类能力函数 Hook直接改写目标函数的机器码入口是最通用的 Hook 方式符号导入劫持Interpose修改 GOT/PLT 表让某库看到的函数变脸且不需要可执行内存权限ObjC 方法 Hook基于 Objective-C 运行时天然线程安全还能方便地调用父类实现此外它还支持动态注入——把一份 dylib 注入到任意已运行的进程中在 macOS / iOS 逆向、调试和辅助开发场景非常实用。 提示该仓库目前处于非维护状态见 README.md但作为学习 Hook 原理的经典实现代码质量极高依然值得精读。第 1 步获取 substitute 源码打开终端执行一条命令即可git clone https://gitcode.com/gh_mirrors/su/substitute项目的对外 API 全部集中在一个头文件里lib/substitute.h新手只需关注这 3 个函数API作用一句话总结substitute_hook_functions改写函数机器码最通用什么函数都能 Hooksubstitute_interpose_imports改写导入表不改代码改地址substitute_hook_objc_messageHook ObjC 方法iOS/macOS 开发首选第 2 步认识 Hook 的数据结构substitute 的设计非常简洁你要 Hook 什么、替换成什么都装进一个结构体struct substitute_function_hook { void *function; /* 要 Hook 的原函数 */ void *replacement; /* 你的替代函数 */ void *old_ptr; /* 可选传出调用原函数的指针 */ };其中最妙的是第三个字段old_ptrHook 成功后你可以拿到一个跳板trampoline通过它随时调用原始实现——这就是所谓的无侵入式包装。第 3 步完成你的第一个 Hook项目自带了一份绝佳的学习样例test/test-hook-functions.c。它的思路是 Hook 掉getpid()让返回值翻倍static pid_t (*old_getpid)(); static pid_t hook_getpid() { return old_getpid() * 2; /* 原值 x 2 */ } /* 注册 Hook 并生效必须在主线程调用 */ substitute_hook_functions(hooks, 4, NULL, 0);编译运行后你会看到这样的效果getpid() 12345 /* Hook 前真实进程号 */ getpid() 24690 /* Hook 后翻倍了 */恭喜你的第一个函数 Hook 已经生效 三种 Hook 方式怎么选 新手最常见的困惑我该用哪个 API记住这张决策表能改代码权限、目标函数已知→ 用substitute_hook_functions最通用沙盒环境 / 不能执行动态写码→ 用substitute_interpose_imports改 GOT对沙盒友好参考 test/test-interpose.c目标是 Objective-C 方法→ 用substitute_hook_objc_message线程安全、可自动调用父类实现常见错误码速查表substitute 的错误码定义在 lib/substitute.h 中且内置了substitute_strerror()可以把错误码转成可读文字。新手最常踩的 3 个坑错误码原因解决办法SUBSTITUTE_ERR_FUNC_TOO_SHORT目标函数太短函数头没几条指令就 return 了换一个更长的目标函数SUBSTITUTE_ERR_NOT_ON_MAIN_THREAD不在主线程调用 Hook回到主线程再调用这是防死锁的设计SUBSTITUTE_ERR_VM内存读写/执行权限申请失败检查系统是否禁止进程写入可执行内存进阶玩法向运行中的进程动态注入除了在自己进程里 Hooksubstitute 还能把整个 dylib 注入到另一个正在运行的进程中核心 API 是substitute_dlopen_in_pid用法可参考 test/test-inject.c。注入相关的实现位于 lib/darwin/inject.c想深入理解注入原理可以从这里读起。项目结构导览最后用一张表帮你快速熟悉仓库lib/substitute.h全部公开 API新手必读lib/darwin/macOS/iOS 平台实现注入、ObjC Hook、内存操作test/每个功能都配有可运行的测试用例是最好的教程substrate/Substrate 兼容层方便迁移旧代码configure构建脚本入口写在最后从 clone 仓库到跑通第一个getpid()Hook整个过程确实只需要 5 分钟。建议接下来的学习路线是通读 test/ 目录下的测试用例每个都是独立可运行的小教程尝试 Hook 你自己项目里的一个函数再挑战 ObjC 方法 Hook 或动态注入掌握 substitute你就拿到了打开 iOS/macOS 动态调试与逆向世界的第一把钥匙 ️【免费下载链接】substituteA free runtime modification library.项目地址: https://gitcode.com/gh_mirrors/su/substitute创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考