用 REA 解剖 iOS IPA:4 步从哈希清单走到 dylib 加载追踪
【免费下载链接】reaReverse engineer anything with agents, from app behavior down to native binaries.项目地址: https://gitcode.com/GitHub_Trending/rea2/rea
输入是一份 iOS 应用的 .ipa 文件。不执行目标代码的一行,REA(面向 AI Agent 的逆向工程工具)静态走完三步:哈希认证清单、bundle(Apple 应用容器)结构图谱、Mach-O(Apple 平台二进制格式)动态库加载追踪,最后给出三份可核查的结论——包内容是否被改动、组件归属哪个应用根、每条 dylib 依赖落在哪个文件。
IPA 文件树为什么不能直接信:先建立哈希证据
unzip解包只留下一堆路径。内容是否被动过、条目是否可读、组件归属哪个应用,树里都看不见。所以第一步是产出一条inventory_artifact(库存证据记录),后续所有结论都要能回指到它:
root_sha256:根文件的哈希指纹,整条链路的唯一锚点;nodes:各组件的内容派生格式、架构与可执行位;occurrences:每条出现的逻辑路径、声明大小和哈希校验状态;limitations:无法核实的条目写在这里,而不是被静默丢弃。
iOS IPA 库存步骤:生成 inventory_artifact 认证清单
每个文件都有名字,却没有一个能证明它没被动过。执行库存命令,输出落到证据包:
rea inspect-artifact My.ipa --evidence_output evidence.json --json接受的输入是 IPA、DMG、ZIP、macOS.app目录。输出里的关键事实:
- 每个节点只报内容派生格式,同一份字节在不同路径拥有独立角色;
- 无法读取的加密成员进
unavailable_components,整体覆盖度降级为partial; - 提供的页面能重建完整库存时覆盖度为
complete-within-inventory,否则为partial; partial只表示"部分未知",不表示"确实缺失"。
这条证据记录只登记观察到的事实。它不解释 plist 或签名语义,也不声称任何运行时行为。
用 project-apple-application-graph 投影 bundle 结构图谱
文件树说清了位置,说不清归属。哪些组件属于应用,哪些只是安装器杂物,投影命令一次给出:
rea project-apple-application-graph '{"inventory_evidence":[<inventory_artifact Evidence>]}'应用根按输入形态识别:
| 输入形态 | 识别出的应用根 |
|---|---|
| IPA | 每个Payload/<Name>.app各是一个根 |
.app目录 | 被库存的目录本身 |
| 含应用的目录 / ZIP / DMG | 每个最外层<Name>.app(后接Contents/) |
DMG 的清单路径形如<image>.dmg/<Volume>/<Name>.app;APK、ASAR 等其他格式会被直接拒为输入错误。
布局分三类:macos-deep(含Contents/,可执行文件在Contents/MacOS/)、versioned-framework(含Versions/,按每个真实版本目录分析)、shallow(两者皆无,典型 iOS 形态,凭根下Info.plist判定为ios平台)。
角色按路径约定归类,全部自动:
*.appex→app-extension,*.xpc→xpc-service;*.framework→framework,*.systemextension→system-extension;Contents/Library/LoginItems/*.app→login-item;Contents/Library/LaunchServices/下的文件计入特权助手。
登录项和特权助手是启动项与提权入口的高频藏身处,排查"应用还悄悄装了什么"直接看这份角色列表。实现见 src/application/apple/AppleApplicationService.ts,工具契约见 src/contracts/applicationToolContracts.ts。
用 trace-dylib-resolution 追踪 Mach-O 动态库加载
知道包里有什么之后,还要知道每条 dylib 加载最终命中哪个文件。这一步模拟 dyld(macOS 动态链接加载器)的解析规则,纯 TypeScript 解析 Mach-O / FAT 头,不依赖 Apple 工具,非 macOS 主机上也能跑:
rea trace-dylib-resolution MyApp.app --jsonbundle 内每个可执行文件(主程序、XPC 服务、扩展、登录项、助手)都是独立进程根,各自持有@executable_path。搜索按@executable_path、@loader_path、@rpath链展开,跟随符号链接,架构分级兼容(x86_64h进程可加载x86_64)。
每条依赖边列出所有尝试过的候选路径及其结果:resolved、absent、architecture-missing、not-loadable、platform-mismatch、outside-target、escapes-target、undetermined。整条边的四级判定如下:
| 边状态 | 含义 |
|---|---|
resolved | 根内有一个镜像成功加载,且更早的候选均可定论 |
conditional | 根内可解析,但更早的根外候选可能抢占 |
unresolved | 根内候选确定缺失或不可用 |
undetermined | 候选在根外或依赖运行环境,无法定论 |
这是静态模型,不读取目标设备的 CPU,也不证明设备会执行哪个 slice;
required-load-unresolved等 findings 是推导出的推断,不是观察到的事实。
想核对实际汇编、验证清单预测的加载顺序,可配合 Hopper 等反汇编引擎,流程见 docs/native-investigation.md。
iOS 应用结构结论复核:哪些不能直接下
结构结论都建立在"路径 + 哈希"上。以下表述必须用专门工具复核后再使用:
CFBundleExecutable、URL Scheme、权限描述:投影不读 plist 语义,对 bundle 的info_plist_path用inspect_plist;- entitlement 等签名声明:对可执行候选用
inspect_signature核查; earlier-rpath-candidate-absent只是路径级推断,dyld 实际加载哪个镜像要凭签名元数据二次确认;- AppleDouble 侧车(
._*、__MACOSX/)是清单事实,但被排除在 bundle 角色与解剖之外,别误计成应用组件。
完整语义与状态表见 docs/apple-application-analysis.md。
全链路速查表:命令、输入与输出
| 步骤 | 命令 | 输入 | 输出 |
|---|---|---|---|
| 库存认证 | rea inspect-artifact My.ipa --evidence_output evidence.json --json | IPA / DMG / ZIP /.app | inventory_artifact证据:哈希、格式、limitations |
| 结构投影 | rea project-apple-application-graph '{"inventory_evidence":[<inventory_artifact Evidence>]}' | 库存证据 | 应用根、bundles布局、角色、桥接假设 |
| 加载追踪 | rea trace-dylib-resolution MyApp.app --json | .app或 Mach-O 可执行文件 | dyld 候选路径与四级判定、findings |
| 语义复核 | rea inspect-plist <path>/inspect_signature | info_plist_path/ 可执行候选 | plist 取值、签名声明 |
【免费下载链接】reaReverse engineer anything with agents, from app behavior down to native binaries.项目地址: https://gitcode.com/GitHub_Trending/rea2/rea
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考