面向 iOS 的指令级动态二进制插桩框架(OSDI 2026)
原题:iLand: An Instruction-Level Dynamic Binary Instrumentation framework for iOS
一句话总结:由于非越狱 iOS 禁止 JIT 和 RWX 内存,iLand 把应用代码预先翻译成可解释的微操作,并让系统库原生执行;在 iPhone X 的 SPEC CPU 2017
train数据集上相对原生慢 15–90 倍,但比qemu-tci的 100–600 倍开销低 5–15 倍,同时使 64 个真实应用中的 60 个达到可用状态。
问题与动机
指令级动态二进制插桩(DBI)能在闭源程序运行时监控和修改控制流,是移动应用安全分析的重要基础。传统 DBI 依靠运行时生成代码和可执行代码缓存。非越狱 iOS 的代码签名与运行时加固禁止第三方应用使用 JIT、分配 RWX 页面或加载未签名库,因此 Android、桌面系统上的常见 DBI 方案无法直接迁移。
完整模拟整个进程也不现实。iOS 将系统库合并到 Dyld Shared Cache(DSC);论文测量的设备只有 6 GB RAM,而系统库映射可超过 3 GB。iLand 的目标是在标准沙盒应用内运行已解密的目标 IPA,不修改目标二进制,也尽量保留 UI、视频解码和网络等原生能力。
关键观察 / 隐含假设
- 观察 1:JIT 是 iOS DBI 的权限瓶颈,而非单纯的翻译性能瓶颈。 传统 DBI 的 Code Cache 需要 RWX 内存;iOS 第三方应用不能获得相应 entitlement(§2.2)。
- 依赖假设:AOT 生成的只读 IR 和预编译执行单元足以覆盖目标 Arm64 指令语义。
- 可能失效场景:目标程序依赖运行时生成代码、未覆盖的特殊指令,或需要对自修改代码保持原有语义时,静态翻译会受限。
- 观察 2:只解释应用代码、让系统库原生执行,能把大部分资源开销留在可接受范围内。 UI 渲染、媒体解码和加密等工作继续由原生库完成;64 个应用中 49 个核心功能完整可用,60 个至少达到可用状态(§9.4)。
- 依赖假设:应用代码与系统库之间的边界可以被可靠捕获,尤其是回调、虚函数、ObjC 动态派发和 Swift witness table。
- 可能失效场景:高频 N→I(native 到 interpreted)回调、复杂 Swift runtime 元数据或应用主动检测模拟环境时,性能和兼容性都会下降。
- 假设 1:保持目标应用的地址布局并虚拟化资源访问,足以维持透明性。 论文采用独立内存区和文件系统重定向,原始代码区保持只读映射(§7)。证据强度为中:49 个应用通过手工核心功能测试,但仍有 11 个部分失效、4 个异常终止。
核心方法
iLand 将每条 Arm64 指令翻译为由 16-bit opcode 和可选操作数组成的 IR。通用指令被拆成源寄存器搬运、具体运算和结果搬运等微操作(µ-op),执行单元预先编译在 RX 段内。寄存器搬运与运算解耦后,6,709 个手写汇编执行单元的总规模不超过 128 KB,避免为每种寄存器组合复制完整实现(§4.1)。翻译结果和偏移表放在只读、位置无关的文件中,运行时由 loader 映射。
解释器使用紧凑的三指令 dispatch loop:从 IR 取 opcode、加上执行单元基址、跳转到对应 µ-op。iLand 只保存 x10–x15,并把目标程序对这些寄存器的访问重定向到线程本地 shadow;选择依据是 Apple 工具链生成的 Arm64 二进制中寄存器使用模式(§4.2)。这一设计回应了移动端频繁模式切换的开销约束,但把正确性绑定到完整的寄存器重定向实现。
应用代码和系统库混合执行会产生难处理的 N→I 转换。iLand 为每个目标指令关联固定长度 trampoline,用共享代码页、数据页和 pc-relative 指令重建目标地址。返回地址、函数指针和 Block 参数在进入系统库前替换为 trampoline 地址;回到 trampoline 后重新进入解释器。该机制不需要 RWX 内存,也不保存每次调用的额外状态(§6.2)。
为覆盖不同回调路径,iLand 将静态地址修复、运行时拦截和信号兜底分层组合,处理 C++ 虚函数、ObjC 消息发送、Swift witness table、ObjC Block 和栈展开。漏捕获时通过 SIGSEGV/SIGBUS 恢复控制,但论文报告该路径最慢可达原生的约 1,000 倍,因此只作为 fallback(§6.3)。其上还实现虚拟文件系统、隔离内存和系统调用转发,使目标应用看到独立的 bundle 与数据容器。
设计取舍
- 解释换取合规性:iLand 放弃 JIT 生成的原生代码,获得标准沙盒可运行性;代价是在 SPEC CPU 2017 上比原生慢 15–90 倍,也明显慢于 JIT 型 Valgrind。
- 应用-only 模式换取内存空间:系统库继续原生执行,避免复制或解释数 GB 的 DSC;代价是 N→I 边界管理成为主要正确性风险。
- 共享 trampoline 换取无状态切换:固定长度、共享页面降低物理内存占用并避免每调用保存状态;代价是 loader、运行时拦截和异常处理需要深入依赖 iOS 私有 runtime 行为。
- 信号兜底换取覆盖率:信号机制避免静态枚举所有回调目标;代价是漏捕获路径的尾延迟和吞吐不可接受,且会放大应用异常行为。
实验与结果
- 在 iPhone X / iOS 16.7.7 上运行 8 个可移植的 SPEC CPU 2017 基准,使用
train而非ref数据集;iLand 相对原生慢 15–90 倍,Valgrind 慢 5–10 倍(§9.2,表 4)。 - 与跨平台运行的
qemu-tci比较相对原生的 slowdown:qemu-tci为 100–600 倍,iLand 为 15–90 倍,论文据此报告 5–15 倍优势,浮点基准更明显(§9.2)。该比较不是同一硬件上的绝对时间比较。 - 在 iPhone 14 Pro / iOS 17.3.1 上测试 64 个美国 App Store 高排名应用:49 个核心功能完整,11 个部分失效,4 个异常终止;60 个应用仍达到可用状态并支持 UI 交互(§9.4)。
- 对其中 60 个应用做动态追踪:24 个应用的二进制包含 SVC 指令,共 2,914 次出现;13 个应用调用未公开 API,其中 2 个调用被 TestFlight 自动审核明确拒绝(§9.5,表 6–7)。
- 15 个应用通过直接 SVC 调用访问系统文件或系统信息。论文还观察到运行时符号解析、生成二进制的
dlopen、ROP 控制流等四类规避 App Review 的手段(§9.5)。
论断—证据表
| 论断 | 证据 | 评测边界 | 置信度 |
|---|---|---|---|
| 预翻译 µ-op 解释可在无 JIT 的 iOS 沙盒内运行指令级 DBI | 架构与实现描述(§3–§6);能力比较(表 5) | Arm64、已解密 IPA、标准沙盒;未证明任意 iOS 二进制 | 强 |
| application-only emulation 能保留多数真实应用的交互功能 | 49/64 完整,60/64 可用(§9.4,附录表 A.1) | 64 个美国 App Store 应用,手工核心流程测试 | 中 |
| iLand 的解释效率优于 qemu-tci | slowdown 15–90 倍对比 100–600 倍(§9.2,表 4) | 不同平台和硬件,使用 SPEC train;非绝对性能对比 | 中 |
| 直接 SVC 是 App Review 难以发现的策略 | 24 个应用含 SVC,15 个访问系统文件,2 个 C API 在 TestFlight 被拒而 syscall 路径绕过(§9.5) | 60 个高排名应用,动态路径覆盖有限,Apple 审核行为可能变化 | 中 |
批判性分析
论证链条
论文的主要链条是闭合的:iOS 禁止 JIT,AOT µ-op 加解释器提供合规执行;完整模拟 DSC 过于昂贵,application-only emulation 降低内存与 CPU 压力;混合执行产生 N→I 问题,trampoline 和分层捕获机制负责恢复控制。SPEC 和真实应用结果分别覆盖了性能与兼容性。
但“保持原始功能和用户体验”的范围仍由手工测试定义。49 个应用的登录、浏览、搜索或视频流程不能证明长时间运行、后台任务、推送、复杂异常处理和所有安全敏感路径都保持透明。性能结论也主要来自无插桩 SPEC 基准;实际插桩插件、信号 fallback 和动态追踪的额外成本没有给出完整量化。
假设压力测试
解释器的优势依赖应用代码占比和库边界。若 workload 主要执行应用自身的数值计算,15–90 倍 slowdown 可能无法满足交互或后台 SLO;若库频繁回调应用,信号 fallback 会产生数量级开销。Swift 元数据、ObjC swizzling 和异常栈展开在不同编译器版本中的布局变化,也可能削弱静态捕获策略。
内存隔离依赖目标应用不通过裸指针探测 iLand 地址空间。论文默认这种探测通常触发崩溃,因此默认关闭对内存访问指令的拦截;恶意或主动反模拟应用可能专门利用这一假设。论文还依赖第三方取得解密 IPA,这一前提不适用于所有研究场景。
实验可信度
基准使用真实 Arm64 指令并控制了 CPU 降频,但只保留 8 个 SPEC 项目、采用较小的 train 数据集,不能代表移动应用的完整 workload。qemu-tci 的跨平台 slowdown 比较能说明数量级,却不能替代同设备对照。64 个应用覆盖 16 类,样本比合成基准更接近实际,但应用选择、版本和手工判定标准仍限制可复现性。App Review 结论依赖 2025 年样本和一次 TestFlight 测试,不能外推到 Apple 当前审核器的完整规则。
系统性缺陷
iLand 超过 300 KLOC,并包含 6,709 个手写汇编单元,维护和适配新 iOS/Arm64 特性的成本很高。loader 需要定位并调用如 notifyObjCMapped、_dyld_find_unwind_sections 等私有符号;这些依赖可能随系统版本变化。论文未系统测量多租户隔离、崩溃恢复、后台运行、能耗、观测工具本身对目标行为的影响,也未给出完整插桩成本和线程数扩展实验。
局限与后续工作
- 局限 1:11 个应用出现部分功能损失,4 个应用异常终止;论文将主要原因归于反监控或环境检测,但没有系统列出所有可隐藏的检测面。
- 局限 2:动态分析的路径覆盖有限;ObjC 私有 API 使用尚未深入分析,研究者需要手工完成注册和登录流程才能进入更深逻辑。
- 局限 3:与
qemu-tci的性能对照跨平台,且 SPEC 结果没有覆盖启用真实 instrumentation、信号 fallback 或高并发线程时的成本。 - 后续工作 1:在多个 iOS 版本、不同 SoC 和至少三类 Swift/ObjC 编译产物上测量 N→I 捕获成功率、信号 fallback 比例及 P99 延迟。
- 后续工作 2:构造包含后台任务、推送、异常栈展开、Swift witness table 和反模拟检查的应用套件,逐项验证透明性并报告失败原因。
- 后续工作 3:把 SVC 目标地址与参数关联到沙盒路径、私有 API 和敏感数据流,评估相较静态审核的新增召回率与误报率。