逆向工程实战手册 第 48 章

第 48 章 iOS 越狱与 Frida 生态深度

第 11 章讲了 iOS 基础逆向;本章深入 iOS 动态分析生态:越狱原理、Frida 在 iOS 的完整能力、ObjC Runtime 深度操作、以及免越狱(Frida Gadget)路线。iOS 逆向的深度取决于你对 ObjC Runtime 和越狱环境的理解。

📍 知识点地图 | 主题:iOS越狱与Frida | 前置:第11章 | 后续:— | 核心概念:越狱原理、ObjC深度操作、Gadget

48.1 iOS 安全体系(先懂边界)

┌─ 硬件层: 安全隔区(Secure Enclave,密钥硬件隔离)
├─ 引导链: 签名验证(iBoot → 内核,每层验签)
├─ 代码签名: 所有可执行文件必须签名(AMFI 强制)
├─ 沙盒: 每个 App 独立容器(权限隔离)
├─ Data Protection: 文件按 class 加密(锁定时不可读)
├─ JIT 权限: 只有系统 App 有(其他要绕过)
└─ SIP/代码注入保护: 默认禁止 dylib 注入

越狱的本质:突破代码签名和权限边界,获得 root 权限 + 任意代码执行 + 注入能力。

48.2 越狱原理分类

类型 原理 代表
基于漏洞的越狱 利用内核漏洞提权 各类公开越狱
永久越狱(untethered) 漏洞链可持久利用 罕见
半永久(semi-tethered) 重启后需重越狱 unc0ver/Taurine
checkm8(硬件) A5-A11 硬件漏洞(不可修复) checkra1n/Palera1n

对逆向的意义:越狱后得到 Frida 注入、root shell、插件系统(Cydia/Sileo)+ 各类逆向工具。

48.3 Frida 在 iOS 的完整能力

基础能力

frida-ps -U                         # 进程列表
frida-ios-dump -u com.example.app  # 解密 IPA(需越狱)
frida-trace -U -i "open*" com.app  # 函数 trace

ObjC 深度操作

// 1. 枚举类与方法
ObjC.enumerateLoadedClasses({...});       // 所有已加载类
ObjC.classes.ClassName.$methods;          // 某类全部方法

// 2. 创建动态调用(免写源码)
var cls = ObjC.classes.NSString;
cls.alloc().initWithString_("hello");     // 动态构造对象

// 3. Hook 类方法/实例方法
ObjC.classes.ClassName['-methodName:'].implementation = ...;

// 4. 遍历内存中的对象实例
ObjC.chooseSync(ObjC.classes.UIViewController);   // 找现有实例

// 5. 协议(Protocol)分析
ObjC.protocols['NSURLSessionDelegate'].$methods;  // 看协议要求

关键场景

□ 解密密文: Hook 加密函数打印明文(拿 key 那步可能都省了)
□ 绕过证书校验: Hook SecTrustEvaluateWithError / NSURLSession delegate
□ 绕过越狱检测: Hook fopen/NSFileManager/stat(检查路径)
□ 键盘钩子: UIApplication 事件流观察
□ 网络观察: Hook NSURLSession 发送/接收 → 全量请求记录

48.4 ObjC Runtime 深度(逆向加速器)

核心概念:
  Class(类对象): 方法列表(method list)+ 实例变量 + 协议
  Method: selector(方法名)+ IMP(实现指针)
  Runtime 动态性: 运行时可改 IMP(swizzle)→ Frida 原理之一

方法派发:
  objc_msgSend(receiver, selector, args)
  → 沿 isa → 类 → 父类 查找 method list → 找到 IMP 执行
  → 找不到 → forwardInvocation(消息转发,可劫持!)

逆向应用:
  class-dump 导出类结构(静态)
  runtime 遍历类/方法(动态,比静态全)
  swizzle 检测(防篡改样本会检查 IMP 是否被改)

48.5 免越狱路线(Frida Gadget)

原理: 不用越狱,直接把 frida-gadget.dylib 注入 IPA 重新签名
工具: objection patchipa / 手动注入 + codesign

流程:
  1. 获取 IPA(ipatool/Apple Configurator)
  2. 解密(有越狱机)或直接用企业包(未加密)
  3. objection patchipa --source app.ipa
  4. 重签名(自签名证书/免费 Apple ID)
  5. 安装到设备 → Frida 连接

局限:
  7 天签名过期(免费账号)
  部分环境变量注入被 hardened runtime 阻止
  无法调试系统进程

48.6 iOS 逆向专项工作流(综合)

1. 静态: class-dump + otool + Info.plist(第 11 章)
2. 动态(越狱): Frida 全面注入 + frida-ios-dump 解密
3. 动态(免越狱): Gadget 注入
4. 网络: mitmproxy + SSL 绕过
5. 存储: Keychain/App 容器/UserDefaults 分析
6. 反调试: PT_DENY_ATTACH 绕过(spawn 早期 hook)
7. 越狱检测绕过: Hook 检测点(第 11 章 + anti-detection-bypass)

48.7 iOS 恶意软件/风险 App 分析要点

□ 企业签名分发(无 App Store 审计)
□ 私有 API 使用(App Store 拒绝但企业包可以)
□ 证书滥用(分发恶意配置)
□ URL Scheme 劫持
□ 后台持久化(VoIP/推送滥用)
□ 键盘记录(键盘扩展)

动手练习

  1. 在越狱测试机上部署 Frida,用 ObjC.enumerateLoadedClasses 枚举一个 App 的所有类。
  2. ObjC.chooseSync 找到某个 ViewController 的内存实例,打印它的属性。
  3. 练习 frida-ios-dump 解密一个 App Store App(自备测试目标)。
  4. 用 objection patchipa 做一个免越狱 Hook 环境,测试基本 Hook。

深入阅读

  • 仓库:skills/mobile-reverse/SKILL.md(iOS 逆向四阶段)
  • 仓库:skills/mobile-reverse/references/ios-reverse-guide.md(iOS 专项深度)
  • 仓库:skills/mobile-reverse/references/frida-objection-deep.md(Frida 深度用法)
  • 仓库:skills/mobile-reverse/references/anti-detection-bypass.md(越狱检测绕过)
  • 实战案例:skills/field-journal/seed-009_ios-jailbreak-detect-bypass.md