如何用 REA 完成 iOS 应用 IPA 逆向工程结构解剖的完整实战
【免费下载链接】reaReverse engineer anything with agents, from app behavior down to native binaries.项目地址: https://gitcode.com/GitHub_Trending/rea2/rea
手里只有一个 IPA(Apple 的应用分发封装格式)。解开它,你能得到一棵完整的文件树——但这棵树回答不了:内容是否被动过、某个文件属于哪个.appbundle(macOS/iOS 上把可执行文件、资源、配置打包在一起的应用容器)、哪些嵌套组件会随应用启动。REA 是一款面向 AI Agent 的逆向工程工具,它把这条链路全程静态走完——IPA/DMG 认证清单、bundle 结构投影、Mach-O(Apple 平台二进制格式)动态库加载追踪,不运行目标应用的一行代码。下面按三个阶段把这条链路走完。
阶段一:先建一份带哈希指纹的认证清单
文件树只记录了路径,没记录完整性。所以 IPA 逆向工程的第一步不是读文件,而是对 IPA 做一次库存操作(inventory),给每个组件打上内容指纹:
rea inspect-artifact MyApp.ipa --json产物是一条inventory_artifact证据记录,关键字段:
root_sha256/root_format:根文件的哈希指纹与格式(ipa、dmg等);nodes:每个组件的格式、架构、可执行位、内容状态;occurrences:每条出现的逻辑路径、声明大小、哈希校验状态(如verified);limitations:无法核实的条目显式写进这个字段,而不是被悄悄丢掉。
提示:这份清单只记录观察到的事实——路径、哈希、权限位。它不解释 plist 或签名语义,因此后面每个结论都能回指到清单里某条具体的哈希。
阶段二:把文件树投影成 bundle 结构图谱
清单回答"有什么",但不回答"结构是什么"。把上一阶段的清单证据交给投影命令,文件树就变成一张带精确路径、内容哈希和解剖信息的应用结构图:
rea project-apple-application-graph '{"inventory_evidence":[<inventory_artifact Evidence>]}'每个 IPA / DMG /.app做无执行投影,输出精确路径、内容哈希、检测到的格式、bundle 解剖信息,以及基于路径的桥接假设(JavaScript ↔ 原生配对)。实现位于 src/application/apple/AppleApplicationService.ts,工具契约见 src/contracts/applicationToolContracts.ts。
应用根按输入形态识别:
- IPA:每个
Payload/<Name>.app各是一个应用根; .app目录:被库存的目录本身;- 含应用的目录 / ZIP / DMG:每个最外层
<Name>.app(后接Contents/)。
bundles部分逐个报告每个应用根及其全部嵌套 bundle 的parent_path、layout、info_plist_path、executable_candidates(可执行候选)和signing_paths(签名路径)。布局分三类:
| 布局 | 含义 | 内容目录 |
|---|---|---|
macos-deep | 含Contents/ | Contents/,可执行文件在Contents/MacOS/ |
versioned-framework | 含Versions/ | 每个真实Versions/<version>/版本目录 |
shallow | 无上述结构 | bundle 目录本身,凭根Info.plist判定为ios平台 |
隐藏启动项与提权入口藏在角色字段里。REA 按路径约定(role_basis: "path-convention")自动把嵌套组件归类:*.appex是app-extension(应用扩展)、*.xpc是xpc-service(XPC 服务)、*.framework是framework、*.systemextension是system-extension(系统扩展),Contents/Library/LoginItems/下是login-item(登录项),Contents/Library/LaunchServices/下是特权助手(privileged helper)。登录项和特权助手是提权点的高频藏身处,想排查"这个应用还悄悄装了什么",直接看角色列表即可。
边界提醒:角色是路径推断,不是运行时观察。一个组件位于
LoginItems/不等于它在运行时实际执行。
阶段三:追踪 Mach-O 动态库的加载命中路径
"每条 dylib 加载最终命中哪个文件",答案在 dyld(macOS 动态链接加载器)解析规则的模拟里。bundle 内每个可执行单元(主程序、XPC 服务、扩展、登录项、助手)都是独立的进程根(process root),拥有各自的@executable_path:
rea trace-dylib-resolution MyApp.app --jsonREA 用纯 TypeScript 解析 Mach-O / FAT 头与加载命令,不依赖 Apple 工具,在非 macOS 系统上也能运行。它模拟 dyld 的解析规则:@executable_path、@loader_path、@rpath搜索链,符号链接跟随,以及分级架构兼容(x86_64h进程可加载x86_64)。每条依赖边都会列出所有尝试过的候选路径及结果(resolved、absent、architecture-missing、platform-mismatch、escapes-target等),再给出四级判定:
| 状态 | 含义 |
|---|---|
resolved | 根内有一个镜像成功加载 |
conditional | 根内可解析,但更早的根外候选若存在于运行系统则优先 |
unresolved | 根内所有候选确定缺失或不可用 |
undetermined | 有候选在根外或依赖运行环境,无法定论 |
静态预测还可以用反汇编引擎二次核对:
rea analyze MyApp.app --provider hopper对 IPA 内的原生二进制,用 Hopper 或 Ghidra 查看实际汇编,核对清单预测的加载顺序——图中 Hopper 的 Python 命令栏正在执行 REA 的桥接脚本,反汇编视图停留在入口点与__LINKEDIT段边界:
trace_dylib_resolution在原生调查流程中的位置见 docs/native-investigation.md。
常见坑与排查
- DMG 投影标记为
partial且缺少子卷信息:DMG 子卷清单依赖原生 macOS 挂载适配器。先确认宿主机挂载能力,只拿到根身份时缺失状态保持未知,不要用partial结果推断 bundle 不存在。 - 清单里出现
unavailable_components:加密压缩成员读不出字节,条目带encryption标记,整体覆盖度降为partial。用外部工具先解密归档,再重新做库存操作。 - 投影结果的
bridge_candidate_coverage显示omitted > 0:桥接假设候选数组最多序列化 2 MiB,超出时保留确定前缀并报告 total / emitted / omitted 三个计数,覆盖度降级为partial。先看omitted数量,再决定是否需要拆小分析单元。 - 期望某个 framework 被识别成某技术栈却落空:运行时家族提示只匹配完整路径段,
React.framework、Flutter.framework、hermes.framework会命中,而Preact.framework、MyApp.framework不会。家族提示是清单推导的猜测,不是观察到的加载行为。 - 版本化 framework 的
info_plist_path是null:符号链接(如Versions/Current)不展开,投影按真实Versions/<version>/目录描述框架;存在多个真实版本目录时 plist 归属保持未知,附 limitation 说明原因。 trace-dylib-resolution对系统库报undetermined属于正常边界:根外绝对路径(如/usr/lib/libSystem.B.dylib)不做宿主机核查,macOS 11 及以后多数系统库位于 dyld 共享缓存而非磁盘。findings是推导出的未决发现,不是观察到的运行时行为。
速查
| 命令 / 工具 | 输入 | 得到什么 |
|---|---|---|
rea inspect-artifact | IPA / DMG / ZIP /.app目录 | 带哈希指纹、格式与可执行位的inventory_artifact证据 |
rea project-apple-application-graph | inventory_artifact证据 | 应用根识别、bundles解剖、桥接假设 |
rea trace-dylib-resolution | .app或 Mach-O 可执行文件 | dyld 加载解析图与未决发现 |
rea inspect-plist/inspect_signature | info_plist_path/ 可执行候选 | plist 字段取值与签名声明 |
边界提醒:这套链路输出的是观察事实,不是语义解释。任何"应用声明了某权限""签名包含某 entitlement"的表述,都必须回到
inspect_plist/inspect_signature的结果上复核。
完整的语义与状态表见项目内 docs/apple-application-analysis.md;首次使用前请阅读 docs/installation.md 完成安装与 Provider 配置。
【免费下载链接】reaReverse engineer anything with agents, from app behavior down to native binaries.项目地址: https://gitcode.com/GitHub_Trending/rea2/rea
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考