MonkeyDev 实战：给非越狱机上的 App 注入自己的代码
MonkeyDev 解决什么问题iOS 逆向有个天然矛盾：tweak 需要越狱环境，但目标 App 检测越狱；真机不越狱又没法注入代码。MonkeyDev 给出的方案是重打包注入——把 hook 代码编译成 dylib，塞进脱壳后的 IPA，修改 Mach-O 的加载命令让它启动时自动加载，重签名装回非越狱机。等于把 App 和你的分析代码打包成一个"合体版"安装包，在非越狱设备上实现 tweak 的效果。环境搭建与标准流程# 安装（依赖 theos） git clone https://github.com/AloneMonkey/MonkeyDev.git # 按 wiki 配置 theos 路径 # Xcode 新建工程时选 MonkeyDev 模板：Logos Tweak / CaptainHook 等工程结构里两个关键目录：TargetApp/：放脱壳后的 IPA（砸壳方法见 frida-ios-dump 篇）代码文件：写 Logos hook 代码Build 一下，MonkeyDev 自动完成：解包 IPA → 注入 dylib → 插入 LC_LOAD_DYLIB → 重签名 → 安装到设备。核心能力：Logos hook OC 方法// Tweak.x %hook SignManager - (id)getSign:(id)arg1 { NSLog(@"[MonkeyDev] getSign 入参: %@", arg1); id result = %orig; NSLog(@"[MonkeyDev] getSign 返回: %@", result); return result; } %end // 构造函数里做初始化 %ctor { NSLog(@"[MonkeyDev] dylib 已注入"); }Xcode 真机运行，控制台直接看到 App 运行中签名方法的每次调用。在非越狱机上实现了 Frida 的核心能力。精髓一：class-dump 头文件是 MonkeyDev 的弹药库MonkeyDev 工程支持导入 class-dump 出的头文件，然后直接 hook 私有类：// 导入砸壳时 class-dump 的头文件 #import "SignManager.h" // 或者运行时按名字 hook（不知道头文件时） %hook NSClassFromString(@"SignManager")配合头文件，App 的内部结构（私有类、私有方法）全部可 hook——这是 MonkeyDev 相对纯 Frida 的优势：编译期类型检查 + IDE 补全，写复杂 hook 逻辑效率高得多。精髓二：重签名的坑重签名是失败高发区：证书描述文件要匹配：用开发者账号的 development 证书 + 包含目标设备的描述文件。企业证书可以装任意设备但有吊销风险bundle id 冲突：原 App 的 bundle id 被苹果签名绑定，重打包要改成自己证书能签的 id（MonkeyDev 默认处理）entitlements 丢失：推送、钥匙串共享等能力依赖 entitlements，重签名时丢了会导致对应功能异常——MonkeyDev 会保留大部分，但 App Group 类的要手动检查iOS 15+ 的签名加强：部分系统版本对重签名包的校验更严，装不上时换 AltStore/Sideloadly 侧载方案精髓三：什么时候选 MonkeyDev 而不是 Frida场景选择快速验证某个方法的行为Frida（即连即调）复杂 hook 逻辑、需要持久运行MonkeyDev（编译型，稳定）非越狱设备MonkeyDev（唯一解）需要修改 UI/加调试面板MonkeyDev（能加完整 ViewController）批量协议模拟都不是，走 Frida RPC 或算法还原MonkeyDev 的杀手锏是能给 App 加调试 UI——比如在 App 里插一个悬浮窗，实时显示签名结果、一键导出 cookie。长期分析一个 App 时，这种"内嵌调试器"的体验无与伦比。总结MonkeyDev = 重打包注入，非越狱机实现 tweak 能力输入是脱壳 IPA，输出是注入 dylib 的重签名包class-dump 头文件 + Logos = 带 IDE 支持的 hook 开发重签名是主要坑点，entitlements 和 bundle id 要检查交流微信：run1255