iOS 逆向专题:注入工具#
🔥 前言#
“注入”不是一个单独命令,而是一条由 Mach-O 修改、动态库加载、签名、进程权限和运行时初始化组成的链。
cyinject、yololib、insert_dylib、optool、install_name_tool处在不同环节,不能把名字列在一起就当成同类替代品。本专题只讲原理、证据和自有 Lab 边界,不提供对第三方 App 的注入或防护绕过步骤。
一、先理解动态库为什么会被加载 🔼 🔽#
1.1、加载链条#
flowchart LR
M[Mach-O Load Commands] --> D[dyld 解析依赖]
D --> P[路径解析与平台检查]
P --> C[代码签名与权限检查]
C --> L[映射动态库]
L --> I[初始化函数 / Runtime 注册]任何一个环节不满足,结果都可能是启动失败、镜像未加载、签名无效或进程被系统终止。
1.2、三种完全不同的“注入”语境#
| 语境 | 发生时机 | 本质 |
|---|---|---|
| 构建期链接 | 编译自己的 App | Linker 正常写入依赖 |
| 文件期改写 | App 未运行 | 修改 Mach-O Load Command 后重新签名 |
| 运行期加载 | 进程已启动 | 调试器、加载 API 或特定系统环境让进程加载镜像 |
讨论工具前必须先说清是哪一种,否则同一句“把 dylib 注入进去”可能对应完全不同的安全条件。
二、工具地图#
2.1、它们分别做什么#
| 工具 | 主要位置 | 关键认识 |
|---|---|---|
install_name_tool | 文件期依赖编辑 | Apple 工具链的一部分,用于修改已有动态库标识和依赖路径;不是万能注入器 |
| insert_dylib | 文件期 Load Command 改写 | 向 Mach-O 增加动态库加载命令;项目较老,现代签名与 arm64e 条件需另行验证 |
| optool | 文件期 Mach-O 操作 | 能查看或修改依赖;旧工具输出不能代替当前 vtool / otool 验证 |
| yololib | 文件期 dylib 命令插入 | 历史工具,常见文章与旧系统环境绑定 |
cyinject | 运行期加载 | 常出现在早期 Cycript / 越狱调试材料中,依赖特定进程权限和系统环境 |
工具“能改文件”不等于改完能在当前 iOS 启动。平台 Slice、Load Command 空间、路径、签名、Entitlements、Hardened Runtime 和系统策略都会参与判定。
2.2、为什么 install_name_tool 不等于 insert_dylib#
install_name_tool 擅长修改已经存在的 LC_ID_DYLIB、依赖路径和 RPath。向一个没有预留空间的 Mach-O 新增加载命令,需要处理 Header 空间、偏移和签名失效等额外问题。两者不能只按“都能改动态库路径”归为同一能力。
三、代码签名为什么总出现在注入问题里#
3.1、修改一个字节都会改变签名覆盖内容#
Mach-O 的代码签名会覆盖代码页及相关元数据。文件期工具改变 Load Command 后,原签名通常不再成立。重新签名也不是“让任何文件合法运行”,它还受到 Provisioning Profile、Team、Entitlements、Bundle 结构和目标设备信任链约束。
3.2、常见失败层次#
| 现象 | 优先检查 |
|---|---|
code object is not signed at all | 签名是否存在、Bundle 是否完整 |
code signature invalid | 文件是否在签名后又被修改 |
Library not loaded | LC_LOAD_*、RPath、实际文件位置 |
| 架构不匹配 | App 与 dylib 的 Slice / 平台 |
| 启动即终止 | Entitlements、平台政策、Hardened Runtime、设备日志 |
四、自有 Lab 的安全学习路线#
4.1、优先使用正常链接建立基准#
1、创建自己的 App 和自己的 Dynamic Framework。
2、通过 Xcode 正常链接并 Embed & Sign。
3、使用只读命令记录依赖和签名。
xcrun otool -L "/path/to/ReverseLab"
xcrun otool -l "/path/to/ReverseLab"
codesign --verify --deep --strict --verbose=2 "/path/to/ReverseLab.app"4、运行 App,使用 LLDB 的 image list 确认镜像真实加载。
5、改变自己 Framework 的名称或 Embed 配置,观察构建期错误与运行期错误有何不同。
这条路线能学到 dyld、RPath、签名和镜像加载的核心知识,不需要从第三方二进制改写开始。
4.2、文件期工具只做隔离副本实验#
如果研究 insert_dylib、optool 或 yololib 的文件结构行为:
- 只复制自己的未发布 Lab 产物。
- 修改前后分别计算 SHA-256。
- 用
otool -l/llvm-objdump对比 Load Command。 - 不连接真实账号和生产后端。
- 不把结果重新分发给第三方。
- 把“文件成功修改”和“系统允许运行”分别记录。
本专题刻意不写可直接复用于第三方 App 的操作命令。
五、今天应该怎样看待这些旧工具#
5.1、读旧教程时的翻译表#
| 旧教程句子 | 现代阅读方式 |
|---|---|
| “插入 dylib 就完成了” | 只完成文件结构变化,尚未验证路径、签名、权限和运行 |
| “重签一下即可” | 需要明确签名身份、Profile、Entitlements 和目标环境 |
| “在任意进程加载” | 现代系统受进程权限、平台安全策略和调试授权约束 |
| “命令执行无报错” | 只能证明工具退出码,不能证明 Mach-O 或 App 正确 |
5.2、工具活跃度也是证据的一部分#
很多注入工具诞生于较早的 iOS、Mach-O 和越狱生态。使用前应查看仓库最后提交、Issue、支持架构和许可证,并用当前 Apple 工具交叉验证。历史价值不等于当前生产适用性。
六、学完标准与资料#
6.1、学完应该会什么#
你应能解释文件期与运行期注入的区别,读懂 LC_LOAD_DYLIB / LC_RPATH,说明修改 Mach-O 为什么破坏签名,并用自有 Framework Lab 验证 dyld 加载链,而不是只会复制一条旧命令。