substitute:被严重低估的免费运行时修改库,一篇看懂它的核心能力
【免费下载链接】substituteA free runtime modification library.项目地址: https://gitcode.com/gh_mirrors/su/substitute
如果你听说过"给正在运行的程序打补丁"这件事,那一定得认识substitute——这是一款完全免费的运行时修改库(Runtime Modification Library),专门在 macOS / Darwin 系统上对运行中的进程做函数 Hook、符号查找和动态注入。它最大的杀手锏是:既能改写机器码,也能在不触碰可执行内存的前提下修改导入表,还能安全地 Hook Objective-C 消息。下面用一篇短文带你快速看懂它的核心能力。
一分钟认识 substitute
substitute 的定位很简单:让你在程序运行过程中修改它的行为,而不必重新编译或重启目标进程。
它提供三大类核心 API,全部集中定义在 substitute.h 这个公共头文件里:
- 函数 Hook:把目标函数的入口"劫持"到你的替身函数
- 导入拦截:直接改写符号解析表,从根源上替换依赖
- Objective-C Hook:拦截 ObjC 消息分发,改写方法实现
💡 对新手来说,把它理解成"给活着的进程动手术"的工具就好——手术刀精准,而且不拆掉整个身体。
能力一:函数 Hook(改写机器码)
这是最经典的能力,对应函数substitute_hook_functions。
它做的事情是:
- 读取目标函数开头的机器码
- 生成一段"跳板"(trampoline)保存被覆盖的原始指令
- 把原函数入口改写成跳转到你的替身
- 通过
old_ptr让你随时能调回原始实现
最关键的一点是线程安全:它会在改写瞬间暂停其他线程,避免别的线程正好处在被改写的代码里。实现细节可见 hook-functions.c,配合内存操作模块 execmem.c 完成跨页面写入。
能力二:导入拦截(不碰可执行内存)
对应函数substitute_interpose_imports,实现在 interpose.c。
它走的是另一条路——不修改代码,而是改写GOT/PLT 导入表,让某个库在查找符号时拿到你指定的地址。这带来几个独特优势:
- ✅ 不需要可执行内存写入权限,沙盒环境(如 iOS / PaX MPROTECT)也能用
- ✅ 用原子指令完成,天然是线程安全的
- ✅ 不需要为每种 CPU 架构单独写代码
- ✅ 只影响单个库的"世界观",不波及整个程序
能力三:Objective-C 方法 Hook
对应函数substitute_hook_objc_message,实现在 objc.c。
它基于系统原生的class_replaceMethod做原子替换,并且贴心地自动生成"调用父类"的跳板——哪怕原方法根本没有实现,你也能拿到一个可调用的 IMP。对做 iOS/macOS 逆向和插件开发的工程师来说,这是最顺手的一把刀。
隐藏大招:动态注入 + 跨架构反汇编
除了 Hook,substitute 还能做到两件很多人不知道的事:
1. 跨进程动态注入通过 Mach 任务级接口,把代码注入到另一个正在运行的进程里,实现见 inject.c 与配套的 darwin-inject-asm.S。
2. 跨架构指令重写内置了 ARM、ARM64、x86、x86_64 四套反汇编器,能在跳板里忠实重放原始指令。相关实现分布在:
- arm/ 、 arm64/ 、 x86/
- 指令重写核心 transform-dis.c 与跳转分析 jump-dis.c
此外项目还带一层Substrate 兼容层(substrate-compat.c),让老插件代码能平滑迁移。
项目结构速览
substitute/ ├── lib/ # 核心库 │ ├── darwin/ # macOS 专属:注入、拦截、ObjC │ ├── arm/ arm64/ # ARM 架构反汇编 │ ├── x86/ # x86 架构反汇编 │ └── cbit/ # 内部队列/向量工具 ├── darwin-bootstrap/ # macOS 引导注入包(deb) ├── substrate/ # Substrate 兼容头文件 ├── test/ # 各能力单元测试 └── script/ # 构建/生成脚本如何获取与开始
获取仓库(如需克隆):
git clone https://gitcode.com/gh_mirrors/su/substitute建议的阅读路径:
- 先读 substitute.h,三大 API 一目了然
- 看 test-inject.c 和 test-hook-functions.c 理解用法
- 需要引导注入时参考 darwin-bootstrap/ 下的 launchd 注入与 posixspawn-hook.c
许可证说明(免费可商用)
substitute 采用LGPL 2.1+(附带静态链接例外),部分文件甚至处于公有领域(public domain)。也就是说,学习和商业使用基本没有门槛,详见 LICENSE.txt。
总结:为什么它被低估?
substitute 把"运行时修改"最容易踩的坑——线程安全、跳板生成、跨架构、沙盒兼容——全部封装成了干净的 C 接口。它没有铺天盖地的宣传,却是逆向、插件、调试工具圈里真正"能打"的底层基建。
- 🎯想 Hook 函数→
substitute_hook_functions - 🎯沙盒里改符号→
substitute_interpose_imports - 🎯Hook ObjC 方法→
substitute_hook_objc_message
下一篇,如果你想深入了解跳板机制和指令重写的细节,建议直接从 transform-dis.h 开始读源码。
【免费下载链接】substituteA free runtime modification library.项目地址: https://gitcode.com/gh_mirrors/su/substitute
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考