reverse-skills-max: initial public release (restored, redacted, hardened)

This commit is contained in:
baradok609hecl1pq6qi
2026-10-20 02:17:15 +03:00
commit da24c2bd20
2227 changed files with 443931 additions and 0 deletions

View File

@@ -0,0 +1,127 @@
---
name: re-ios
description: >
iOS 应用分析:Mach-O、class-dump、越狱环境。
触发词:ios逆向、ipa、class-dump、越狱
capabilities: [macho-parser]
---
# iOS 应用分析
## 何时使用 / 何时不用
- 用:拿到 IPA / 已安装 iOS 应用,需要看 Mach-O 结构、OC 类结构、代码签名、越狱环境动态分析
- 用:App Store 加密二进制需要脱壳
- 不用:目标只是 Mach-O 结构 / load commands(直接走 [[re-format-macho]])
- 不用:需要运行时 hook / 绕过(走 [[re-frida]])
- 不用:无越狱、无受管设备时的动态分析场景(静态先行,动态受限说明见坑 3)
## 工具准备
静态分析(解包 / class-dump / otool)可免沙箱;动态(越狱设备 / 模拟器 / 受管设备)按 [[re-analyze/platform-tips]] 最高原则在受控环境执行。
### unzip / zipinfo —— ipa 解包
- Linux: `apt install unzip` / `dnf install unzip` / `pacman -S unzip`
- macOS: 自带 /usr/bin/unzip;Windows/WSL: WSL 内 Linux 版
- 验证: `unzip -v`
### class-dump —— OC 头文件导出
- macOS: 官方仓库 nygard/class-dump 最新 release 3.4 仅源码无预编译二进制——源码构建(xcodebuild)使用;`brew install class-dump` 公式已从 homebrew-core 下架(2026 实测 formulae.brew.sh 无此公式),不再可用
- 替代: class-dump-swift(mxms0/class-dump-swift)同样支持 OC 与 Swift 类/方法导出,源码构建(依赖 LLVM + make,非 Swift 工具链)——Swift 目标优先用它
- Linux/Windows: 无官方版;用 class-dump-swift 源码编译(依赖 LLVM + make,非 Swift 工具链),或在 macOS 虚拟机 / 远程 macOS 上执行
- 验证: `class-dump --help`(输出 usage 即可)
### otool —— Mach-O 结构 / 符号查看(Apple 自带)
- macOS: `xcode-select --install`(Xcode Command Line Tools)
- Linux 替代: `llvm-otool`(`apt install llvm` / `brew install llvm`)
- 验证: `otool -h /bin/ls`
### idevice 工具链(libimobiledevice)—— 设备识别 / 信息
- macOS: `brew install libimobiledevice`(含 idevice_id / ideviceinfo / ideviceinstaller)
- Linux: `apt install libimobiledevice-utils`(Debian/Ubuntu);Arch: `pacman -S libimobiledevice`
- 验证: `idevice_id -l` 列出已连接设备 UDID;`ideviceinfo` 输出设备型号/iOS 版本/UDID
### 越狱环境(可选)
- 越狱工具:unc0ver / checkra1n / palera1n(按设备型号与 iOS 版本选择),越狱后安装 OpenSSH + 包管理器(Sileo / Cydia)
- 验证: `ssh root@<设备IP>` 能登录
- 未越狱但需真机:Apple 开发者账号签名安装(免费账号签名 7 天有效,见坑 2);越狱环境专项(tweak 开发/越狱检测)见 [[re-ios-jb]]
### iOS FairPlay 解密 / 脱壳(backend 按环境选择)
App Store 加密应用的解密后端按目标 iOS 与越狱版本选择已适配当前 Frida API 的维护实现,没有跨版本通用的单一工具。
- 前置:越狱设备 + frida-server(见 [[re-frida]] 工具准备)+ usbmuxd 转发
- 选型:先 `frida --version` 与设备 frida-server 版本对齐,再选与该 Frida 世代兼容的 dumper。Frida 17 起移除了静态 `Module` 查找/枚举 API(见 [[re-frida]] 常见坑),仍依赖这些旧 API 的 dumper 在 Frida 17 下直接报错
- legacy / 参考实现:`AloneMonkey/frida-ios-dump` 的 Frida agent 使用 `Module.ensureInitialized`、静态 `Memory.read*`、`Module.findExportByName(null, …)`、`Process.enumerateModulesSync`——这些 API 在 Frida 17 已移除,该仓库更适合作为脱壳算法与 Mach-O 重组逻辑的参考;直接使用需搭配 Frida 16 及以下的 frida-server,或自行按新版 API 移植
- 另一路线:基于 `mremap_encrypted` 的实现(UnFairPlay / unfaird 一类),不依赖 frida 运行时插桩,按目标 iOS 版本评估可用性
- 设备通道:macOS `brew install libusbmuxd`(原 usbmuxd 公式已改名);Linux `apt install usbmuxd`(Debian/Ubuntu,含 iproxy);Arch `pacman -S libusbmuxd`
- 验证: `iproxy -h`(转发工具可用性);选定 dumper 按其自身 `-h` 输出确认参数
## 操作步骤
按顺序执行,每步记下结果(证据路径 + sha256,见 [[re-triage]])。
1. **ipa 解包与签名检查**:
```sh
unzip app.ipa -d app/
file app/Payload/*.app/* # 确认主二进制是 arm64 Mach-O
codesign -dv app/Payload/*.app/ 2>&1 # 签名类型(Apple Distribution / Development / adhoc)
otool -l app/Payload/*.app/ | grep -B1 -A4 LC_ENCRYPTION_INFO # 查 cryptid
```
`cryptid 1` = App Store 加密,磁盘上代码是密文,先脱壳(步骤 5)再继续。
- 包结构速览:`Payload/<App>.app/` 是主二进制与资源;`SwiftSupport/` 是系统 Swift 库(模拟器包常见);`embedded.mobileprovision` 是签名描述文件(macOS 上 `security cms -D -i` 可读 entitlement 与过期时间)
- `file` 确认主二进制是 arm64/arm64e 真机架构——x86_64 模拟器产物无动态分析价值,直接跳过
2. **class-dump 头文件**:
```sh
class-dump -H app/Payload/*.app/ -o headers/
```
类名 / 方法名 / 属性即大部分业务接口,先看 headers 再进反编译。加密二进制先脱壳(步骤 5)再 dump,否则只得到壳的类。Swift 方法不进 OC 头文件(见坑 4)。
3. **二进制走 [[re-format-macho]]**:
```sh
otool -h app/Payload/*.app/ # 架构 / cputype
otool -L app/Payload/*.app/ # 依赖 dylib(framework 清单)
```
结构、load commands、入口、段、签名按 [[re-format-macho]] 步骤执行;Swift 二进制用 `strings -n 6` 找符号与错误消息辅助定位。
4. **越狱环境动态调试**:
```sh
iproxy 2222 22 & # usbmuxd 转发设备 ssh 到本机 2222
ssh -p 2222 root@127.0.0.1 # 登录越狱设备
```
设备上启动目标 App;断点 / 单步调试经 debugserver + lldb(见 [[re-lldb]]);hook / 绕过优先 [[re-frida]](frida-server 安装见该技能)。
5. **脱壳(FairPlay 解密)**:
```sh
frida --version # 主机 Frida 世代——选 dumper 前先定
iproxy 2222 22 &
<选定 dumper> <BundleID 或 App 名> # 按目标 iOS / Frida 版本选维护实现,拉取并解密
file <输出>.ipa
otool -l <输出>/Payload/*.app/ | grep -A4 LC_ENCRYPTION_INFO # 确认 cryptid 0
```
思路:从已解密的内存镜像读取 Mach-O 头与段,重组为解密 ipa。dumper 必须与主机 `frida --version` 及设备 frida-server 的世代匹配(见工具准备);脱壳产物回到步骤 1-3 复跑。
## 跨域联合
- [[re-mobile]]:工作流第 2 步(iOS 分支)固定调用本技能
- 二进制解析 → [[re-format-macho]];断点调试 → [[re-lldb]];插桩 / 绕过 / 脱壳执行 → [[re-frida]]
- 本技能被 [[re-analyze]] 的 triage「移动 App 分析」路径调用(re-mobile → re-ios)
- 桌面 macOS 生态(签名/entitlements/Secure Enclave)→ [[re-macos]]
- Swift 层分析(mangling/witness table)→ [[re-swift]]
- 越狱环境专项(tweak 分析与开发、越狱检测识别绕过)→ [[re-ios-jb]]
## 常见坑与陷阱
- **App Store 加密二进制直接分析**:现象——class-dump 无输出 / otool 结构残缺、反编译只见壳;原因——`cryptid 1` 加密,磁盘上的代码是密文;对策——步骤 1 先查 LC_ENCRYPTION_INFO,加密先按步骤 5 脱壳
- **签名失效无法安装**:现象——重打包 / 修改后真机安装报"无法验证 App"或无法安装;原因——签名与内容不一致,或免费证书 7 天过期;对策——`codesign -f -s -` adhoc 重签(仅自签场景)或重新用开发者证书签名;免费账号到期重新安装
- **无越狱 → 动态分析受限**:现象——没有越狱设备,脱壳 / lldb attach / frida 全不可用;原因——iOS 沙盒与签名强制限制动态调试;对策——静态分析先行(步骤 1-3),动态转模拟器(需不加密应用)或受管设备(Apple Configurator 部署 + 开发证书),实在不行只做静态
- **Swift 方法不进 class-dump 头**:现象——类头文件里找不到业务方法;原因——Swift 不导出 OC 运行时元数据;对策——`strings` / `swift-demangle` 找符号,逻辑分析靠 [[re-format-macho]] + 反编译([[re-binary-core]])
- **class-dump 对 arm64e 二进制报错**:现象——class-dump 崩溃或输出为空;原因——arm64e 指针签名(PAC)干扰元数据遍历;对策——换新版 class-dump / class-dump-swift,或先脱壳再 dump
- **拿到模拟器产物当真机分析**:现象——`file` 显示主二进制是 x86_64,动态分析全不可用;原因——分发方给了模拟器包(常带 SwiftSupport/);对策——步骤 1 用 `file` 确认 arm64/arm64e 真机架构,模拟器产物跳过
- **class-dump 装不上(brew 公式下架)**:现象——`brew install class-dump` 报 No available formula;原因——homebrew-core 已移除该公式(2026 实测);对策——nygard/class-dump 源码构建,或换 class-dump-swift(见工具准备)

View File

@@ -0,0 +1,99 @@
# iOS 应用分析命令速查与操作序列
工具族分四层:解包与签名检查(unzip/file/codesign/otool)、头文件导出(class-dump / class-dump-swift)、设备通道(usbmuxd 的 iproxy + libimobiledevice 的 idevice_*)、FairPlay 解密/脱壳(按环境选 backend + [[re-frida]])。命令与参数以官方文档为准(nygard/class-dump、mxms0/class-dump-swift、libimobiledevice、所选 dumper 的仓库文档)。
## 命令族速查
### 解包与签名检查
- `unzip app.ipa -d app/` 解包 ipa(zip 格式)
- `file app/Payload/*.app/*` 确认主二进制架构(arm64 / arm64e 真机;x86_64 为模拟器产物)
- `codesign -dv <App.app> 2>&1` 签名类型(Apple Distribution / Development / adhoc)与 Team ID
- `codesign -d --entitlements - <App.app> 2>&1` 导出 entitlements(调试/绕过前看权限面)
- `security cms -D -i app/Payload/*.app/embedded.mobileprovision` 读描述文件(macOS;含证书过期时间与设备白名单)
- `otool -l <App.app> | grep -B1 -A4 LC_ENCRYPTION_INFO` 查加密标记(cryptid 1 = App Store 加密)
### class-dump / class-dump-swift(OC/Swift 头文件)
- `class-dump -H <App.app> -o headers/` 导出 OC 类头文件(方法/属性/协议)
- `class-dump-swift -H <App.app> -o headers/` Swift + OC 元数据(Swift 目标优先)
- `class-dump --help` 验证;class-dump 3.4 仅源码(xcodebuild 构建),class-dump-swift 源码构建(依赖 LLVM + make,非 Swift 工具链)
### otool / llvm-otool(Mach-O 结构)
- `otool -h <App.app>` 架构 / cputype;`otool -L <App.app>` 依赖 dylib / framework 清单
- `otool -l <App.app>` 全部 load commands;`otool -ov <App.app>` OC 运行时段(objc_classlist 等)
- Linux 替代: `llvm-otool`(`apt install llvm` / `brew install llvm`),参数与 otool 兼容
- 深解析(段/入口/签名)走 [[re-format-macho]]
### idevice 工具链(设备通道)
- `idevice_id -l` 列出已连接设备 UDID;`ideviceinfo` 设备型号/iOS 版本/序列号类信息
- `iproxy 2222 22 &` 把设备 22 端口(SSH)转发到本机 2222(usbmuxd 提供)
- `ssh -p 2222 root@127.0.0.1` 经转发登录越狱设备(默认密码 alpine)
- `ideviceinstaller -l` 列出设备已装应用(含 Bundle ID,脱壳取 ID 用)
### 脱壳(FairPlay 解密,backend 按环境选)
- `frida --version` 与设备 frida-server 对齐后,再选兼容该 Frida 世代的 dumper——Frida 17 移除静态 `Module` 查找/枚举 API,依赖它的旧 dumper 直接报错([[re-frida]] 常见坑)
- legacy 参考实现 `AloneMonkey/frida-ios-dump`:agent 使用旧 Frida API(`Module.ensureInitialized` / 静态 `Memory.read*` / `Module.findExportByName(null, …)` / `Process.enumerateModulesSync`),需 Frida 16 及以下或自行移植——保留作脱壳算法与 Mach-O 重组逻辑的参考
- 另一路线:基于 `mremap_encrypted` 的实现(UnFairPlay / unfaird 一类),不依赖运行时插桩,按目标 iOS 版本评估
- 前置:越狱设备 + frida-server(见 [[re-frida]])+ usbmuxd 转发;选定 dumper 按其 `-h` 输出确认参数(BundleID / App 名、frida-server 端口等)
## 常用操作序列(组合套路)
### 1. IPA 静态分析标准流(解包 → 签名 → 加密判定 → 头文件 → 结构)
```
unzip app.ipa -d app/
file app/Payload/*.app/* # arm64 真机架构确认
codesign -dv app/Payload/*.app/ 2>&1 # 签名类型
otool -l app/Payload/*.app/ | grep -B1 -A4 LC_ENCRYPTION_INFO # cryptid
class-dump -H app/Payload/*.app/ -o headers/ # OC 类先看
otool -L app/Payload/*.app/ # framework 依赖
# cryptid 1 → 先脱壳(序列 3)再 dump 头文件;结构细节转 [[re-format-macho]]
```
### 2. 越狱设备动态调试(转发 → 登录 → hook/调试)
```
iproxy 2222 22 &
ssh -p 2222 root@127.0.0.1 # 登录越狱设备
# 设备上启动目标 App
# hook/绕过 → frida([[re-frida]],frida-server 同源安装)
# 断点/单步 → debugserver + lldb([[re-lldb]] 远程)
```
### 3. App Store 加密应用脱壳闭环(选 backend → dump → 确认 → 复跑静态)
```
frida --version # 先定 Frida 世代,选匹配的 dumper
iproxy 2222 22 &
<选定 dumper> <BundleID> # 拉取并解密(backend 按目标 iOS / Frida 版本选)
file <输出>.ipa
otool -l <输出>/Payload/*.app/ | grep -A4 LC_ENCRYPTION_INFO # 确认 cryptid 0
# 脱壳产物回到序列 1 复跑(class-dump / otool / [[re-format-macho]])
```
### 4. 受管设备/无越狱静态兜底(边界处理)
```
# 无越狱:静态先行(序列 1)
# 需动态:模拟器(仅不加密应用)或受管设备(Apple Configurator 部署 + 开发证书)
# 目标仅 App Store 加密且无越狱 → 动态面放弃,静态面以符号/字符串兜底
strings -n 6 <App.app> | grep -iE 'http|api|key' # 加密二进制里字符串仍可读(代码区外)
```
## 实现教训(内化)
- 先看 `cryptid` 再决定后续:加密二进制上 class-dump/反编译全是壳,先脱壳省一轮返工
- headers 是业务接口的第一张地图:OC 类名/方法名基本等于功能清单,先扫 headers 再进反编译定位
- iproxy 转发后 ssh 直接连 127.0.0.1,别把设备 IP 当目标地址(转发才是稳定通道)
- 越狱检测类目标:先静态找检测点([[re-ios-jb]] 越狱检测方法论),再决定 frida 绕过或动态侧对策,别上来就全家桶 hook
- 模拟器产物(x86_64)直接跳过:真机动态面(frida/lldb)全部不适用,浪费时间
## 使用注意
- 静态可免沙箱;越狱设备/模拟器动态分析按 [[re-analyze/platform-tips]] 最高原则在受控环境执行
- 每步产物(解密 ipa、头文件、签名信息)对照 [[re-triage]] 入档;结论写 [[re-analyze/analysis-contract]]
- 免费开发者签名 7 天过期——签名相关结果注明时间戳,避免误判

View File

@@ -0,0 +1,41 @@
# iOS 应用分析工具特有坑与边界
## 签名与安装坑组
- **免费签名 7 天失效**:免费 Apple ID 签名应用 7 天过期——长时间分析先确认签名有效期(`security cms -D -i embedded.mobileprovision` 读过期时间),别把「签名过期无法安装」误判成「补丁/重打包失败」
- **重打包后签名与内容不一致**:改过二进制必须重新签名(`codesign -f -s -` adhoc 仅自签场景,或开发者证书),否则真机报「无法验证 App」;adhoc 签名只覆盖本机自装,与原始签名并存场景看安装方式
- **entitlements 影响运行**:重签时丢失原始 entitlements(如 keychain-access-groups、aps-environment)会改变行为——`codesign -d --entitlements -` 先导出原始项,重签带上
- **免费账号签名的限制**:免费账号无 App Group/推送等能力,且签名 7 天——需要完整能力的场景用付费开发者账号或受管设备
## 加密与脱壳坑组
- **cryptid 判定必须看 LC_ENCRYPTION_INFO 段**:`codesign` 结果不能说明加密状态,只有 `otool -l` 里的 LC_ENCRYPTION_INFO(cryptid 0/1)为准——解包后先跑这一步再规划
- **脱壳依赖越狱 + dumper/Frida 世代匹配**:脱壳工具对 frida-server 版本敏感——Frida 17 移除了静态 `Module` 查找/枚举 API,依赖旧 API 的 dumper agent 直接报错;dump 失败先核对 [[re-frida]] 工具准备与 `frida --version` 的世代对应;A12+ 设备 arm64e 上 frida 需对应架构的 server
- **脱壳产物 cryptid 0 但代码仍怪**:解密后的 Mach-O 可能残留加密 stub 或 section 顺序异常——正常现象,以实际反编译结果为准;个别应用有反 dump 检测(重启后重新加密),一次 dump 不成功多试几次并保持进程存活
- **无越狱拿不到加密应用**:App Store 加密二进制在无越狱/无受管设备上无法脱壳——静态分析(字符串/符号)先行,动态面明确放弃(SKILL.md 坑 3)
## class-dump 工具族坑组
- **arm64e(PAC)干扰元数据遍历**:class-dump 对 arm64e 崩溃/空输出——换新版或 class-dump-swift,或先脱壳;PAC 是设备 A12+ 真机产物,模拟器/老设备无此问题
- **Swift 方法不进 OC 头文件**:Swift 类不导出 OC 运行时元数据——`strings`/`swift-demangle` 找符号,或直接用 class-dump-swift 导 Swift 声明(SKILL.md 坑 4)
- **brew 公式已下架**:`brew install class-dump` 2026 年起报 No available formula(homebrew-core 移除);nygard/class-dump 最新 release 3.4 只有源码——按工具准备走源码构建或 class-dump-swift,别在 brew 上反复折腾
- **加密二进制上 dump 只得到壳类**:`cryptid 1` 时先脱壳再 dump——顺序反了输出永远是壳的类(SKILL.md 坑 1)
## 越狱环境坑组
- **默认 ssh 密码是 alpine**:OpenSSH 装好后不设置就是 root/alpine;设备侧改掉,但分析环境记录当前凭据
- **usbmuxd 转发失败先看服务**:Linux 上 `systemctl status usbmuxd` / 手动 `usbmuxd -f` 确认守护进程;`iproxy` 报绑定失败换本地端口
- **越狱检测目标行为跳变**:样本检测越狱环境(Cydia 路径、fork 检测、沙盒逃逸探测)后降级/退出——先静态识别检测点([[re-ios-jb]]),再决定绕过或调整观察方式;越狱环境本身也是证据链一部分,记录设备与越狱工具版本
## 版本差异
- **class-dump(nygard/class-dump)**:最新 3.4(2022 年后未更新),仅源码;`brew install class-dump` 已不可用。替代 class-dump-swift(mxms0/class-dump-swift)长期未更新(2017 年后无提交),用前先评估,支持 Swift
- **usbmuxd → libusbmuxd(homebrew)**:macOS `brew install usbmuxd` 已失效(公式改名),用 `brew install libusbmuxd`;Linux 上 Debian/Ubuntu 包名仍是 `usbmuxd`(含 iproxy),Arch 为 `libusbmuxd`
- **frida-ios-dump(legacy)**:`AloneMonkey/frida-ios-dump` 的 agent 依赖 Frida 16 及以下的静态 `Module` / 静态 `Memory` API,在 Frida 17 下不可用——保留作脱壳算法与 Mach-O 重组逻辑的参考;直接使用需旧 Frida 或自行移植,当前默认按目标 iOS / 越狱版本选已适配当前 Frida 的维护实现([[re-frida]] 常见坑「Frida 17 移除静态 Module 查找/枚举 API」)
- **越狱工具与 iOS 版本**:unc0ver(iOS 11.0-14.8,A7-A14 分档;末版 v8.0.2/2022 已停更)、palera1n(checkm8 设备全系)、Dopamine(iOS 15-16 系)——按设备型号与 iOS 版本选择,工具版本不匹配装不上或半越狱
## 使用注意
- 静态分析可免沙箱([[re-analyze/platform-tips]] 最高原则);越狱设备动态分析在受控环境执行
- 脱壳产物/头文件/签名信息 sha256 与时间戳存档([[re-triage]]);结论写 [[re-analyze/analysis-contract]]
- 版本相关行为(越狱工具、frida、签名规则)以目标版本实际表现为准