☰
iOS 应用包里到底藏了什么?不越狱、不运行,给 IPA 做三道静态体检
2026/10/16 6:27:26 网站建设 项目流程

iOS 应用包里到底藏了什么?不越狱、不运行,给 IPA 做三道静态体检

【免费下载链接】reaReverse engineer anything with agents, from app behavior down to native binaries.项目地址: https://gitcode.com/GitHub_Trending/rea2/rea

拿到一份来路不明的 IPA:装不上机,也越不了狱。用 REA(面向 AI Agent 的逆向工程工具)做 iOS 逆向工程的静态部分:只读包、不执行任何代码,把 IPA 解析、应用结构分析、Mach-O(Apple 平台的原生二进制格式)动态库加载链一次看全。

📦 拿到一份装不了的 IPA,先问什么?

渠道存疑、没开发签名,跑起来又怕带毒——先问三个问题:包有没有被人改过?启动时到底会拉起哪些组件?每个动态库最终落到哪个文件? 越狱和动态调试都用不上时,答案只能从"完全不动它"的静态检查里找。 把整份 IPA 当成一次体检:先出整包底账,再核启动阵容,最后追每条动态库的去向。 三道检查全程只读,做完你手里有一份可回溯的书面结论。

🧾 它可信吗:给 IPA 做一份完整性认证清单

结论先行:第一道体检是整包认证——对 IPA、DMG、ZIP 或 macOS.app目录执行库存操作,产出一条inventory_artifact(带哈希指纹的整包库存证据)记录,后面每句结论都能回到这张底账上核对。

字段记录什么体检意义
nodes每个文件的格式、架构、可执行位、内容状态分出谁是真二进制、谁只是资源
occurrences每个逻辑路径的声明大小与哈希校验状态(verified等)同一份内容出现在几个位置,逐个有数
root_sha256/root_format根文件的哈希指纹与格式(ipa、dmg等)拿它和官方渠道的包对指纹,先确认"是不是同一个包"
limitations无法核实的项目,如实列出查不到的地方不装懂,静默忽略等于造假

清单只记观察事实:不解析 plist,不判签名语义。 这是刻意划出的边界——底账管"包里有什么",语义问题留给下一节和专门的工具。

🧭 它启动时会带谁上场:一条命令画出 bundle 结构图谱

结论:把上一节的 inventory_artifact 交给一条命令,整包里每个应用根和它名下的嵌套bundle(Apple 平台上独立成组的容器目录)全部摆出来,还按路径习惯自动分好了角色。

rea project-apple-application-graph '{"inventory_evidence":[<inventory_artifact Evidence>]}'

应用根不是猜的,按库存根的类型定:

库存根长什么样应用根落在哪备注
IPA每个Payload/<Name>.app标准 iOS 安装包布局
.app目录目录本身目录型库存一律当独立根,哪怕缺Contents/
含应用的目录 / ZIP / DMG每个最外层<Name>.app(带Contents/)DMG 形如<image>.dmg/<Volume>/<Name>.app

只有 DMG 根身份、缺子清单时,覆盖度如实标记为partial,缺失即"未知"而不是"没有";APK、ASAR 这类库存直接按输入错误拒绝,避免张冠李戴。

三种 bundle 布局,对应三种读法

bundles 列表给出每个应用根及其全部嵌套 bundle:info_plist_path、executable_candidates(可执行候选)、signing_paths(签名路径)。布局分三类:

  • macos-deep:含Contents/,可执行文件位于Contents/MacOS/
  • versioned-framework:含Versions/,逐个真实版本目录分析
  • shallow:两者皆无;带Info.plist就判为ios平台,典型 iOS 应用形态

角色按路径惯例自动归类

先看高危位置:Contents/Library/LoginItems/下的登录项、Contents/Library/LaunchServices/下的特权助手单列;再按惯例归类,*.appex(应用扩展)、*.xpc、*.framework、*.systemextension各归其位。 这批角色正是隐藏启动项和提权点的高发位置,审查时优先过一遍。 AppleDouble 侧车文件(._*、__MACOSX/)算进清单事实,但排除在 bundle 角色与解剖组件之外。 实现见 AppleApplicationService.ts,工具契约定义在同目录的 applicationToolContracts.ts 中。

🩺 它的动态库到底加载到哪:Mach-O 加载链静态解析

结论:前两道回答"包里有什么、谁会上场",这一道回答"每条 dylib 声明最终命中哪个文件"——纯头文件级解析,一个字节都不执行。

rea trace-dylib-resolution MyApp.app --json

解析用纯 TypeScript 完成 Mach-O / FAT 头与加载命令,不依赖 Apple 工具,非 macOS 机器上也能跑。 它按 dyld 的规则展开搜索链:@executable_path指向进程根可执行文件所在目录,@loader_path指向持有该加载命令的镜像目录,@rpath先试加载方自己的LC_RPATH,再沿加载链逐级上溯到进程根;符号链接在根内跟随,x86_64h进程还能兼容加载x86_64切片。

每条依赖边都列出试过的候选及结果(resolved、absent、architecture-missing、escapes-target等),整条边再汇总成四级判定:

判定什么情况出现审查时怎么读
resolved根内的镜像能加载,且没有更靠前的候选悬而未决加载去向确定
conditional根内能解析,但根外的更早候选(如/usr/lib/swift)在真实系统上存在时会抢先按"可能换镜像"复核
unresolved所有候选在根内明确缺失或不可用该依赖加载会失败
undetermined无根内命中,且存在根外或依赖环境的候选取决于运行环境,如实标注

想核对实际汇编,可以把清单预测的加载顺序交给 Hopper 等反汇编引擎做交叉验证:

它在原生调查流程中的位置见 native-investigation.md。

🧰 边界与换工具时机:体检单故意不写的两件事

结论:这套体检刻意停在"包内事实",语义和声明类问题要换工具补位,别在底账上找不存在的答案。

  • 不解析 plist 语义:要看CFBundleExecutable、URL Scheme、权限描述,对 bundle 的info_plist_path用inspect_plist
  • 不核查签名:对可执行候选用inspect_signature查签名声明
  • 桥接假设(JavaScript ↔ 原生配对)最多序列化 2 MiB,超出时结果携带bridge_candidate_coverage报告省略数量,整体覆盖度降为partial
  • 目录型.app一律视为独立根;DMG 子卷清单依赖原生 macOS 挂载适配器,缺适配器时只能拿到根身份

换工具的时机只有一个标准:你问的问题,当前工具明说"不归我管"。静态体检的分工是照实记录,不是全知全能。

字段语义与状态表的完整版见 apple-application-analysis.md;第一次用 REA 先按 installation.md 完成安装与 Provider 配置。三道检查做完,一份 IPA 的完整性、启动阵容、动态库去向全部有据可查——这就是不越狱、不运行也能看清 iOS 应用包的全部底牌。

【免费下载链接】reaReverse engineer anything with agents, from app behavior down to native binaries.项目地址: https://gitcode.com/GitHub_Trending/rea2/rea

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询