固件补丁管线
固件补丁管线
vphone-cli 的固件补丁管线(FirmwarePatcher)负责把原版 iPhone + cloudOS(PCC)两份 IPSW 加工成能在 Virtualization.framework 研究 VM 上启动的混合固件。整条管线分两大步:fw prepare(备料)与 fw patch_<variant>(打补丁)。
第一步:fw prepare
make fw_prepare
fw prepare 完成固件的下载、解包与合并:
- 下载 IPSW:分别获取 iPhone 与 cloudOS 两份 IPSW,支持断点续传与本地缓存(缓存命中可离线重跑)。
- 解包:
unzip解进缓存目录后克隆到工作目录,并清理陈旧的*Restore*目录。 - cloudOS 合并进 iPhone 树:cloudOS 的 kernelcache、
Firmware/子目录(agx/all_flash/ane/dfu/pmp)与散置 im4p 覆盖进 iPhone 树;*.dmg与 trustcache 保留 iPhone 版。 - 生成 hybrid BuildManifest:合并两份固件的身份信息,产出混合
BuildManifest.plist与Restore.plist,供 DFU restore 使用——VM 在 DFU 下自认 cloudOS research 设备,而文件系统来自 iPhone 侧。
第二步:fw patch_<variant>
make fw_patch_dev # 以 dev 变体为例;其余见「固件变体全解」
补丁阶段对 VM 目录下最新的 *Restore*/ 目录原地修改启动链组件:
| 组件类别 | 路径位置 | 被打补丁的文件 |
|---|---|---|
| dfu | *Restore*/Firmware/dfu/ |
iBSS、iBEC |
| all_flash | *Restore*/Firmware/all_flash/ |
LLB、DeviceTree |
| txm | *Restore*/Firmware/ |
TXM |
| kernelcache | *Restore*/ |
内核缓存 |
每个组件会被透明地解包(IM4P)→ 按变体串联补丁器 → 按原容器结构重打包写回。补丁点全部经 Capstone 反汇编动态定位,不硬编码偏移;每个补丁都会记录进 VM bundle 内的 patch_report.json,可用于审计与回归比对。
patcher 构建:make patcher_build
fw_patch* 系列 target 实际调用的是一个 debug、未签名的 patcher 二进制:
make patcher_build # 产出 .build/debug/vphone-cli
为什么单独存在:固件补丁是纯用户态文件操作,不需要虚拟化相关的私有 entitlements,因此不需要签名(也就不触发 amfi 检查);debug 构建比 release 快得多,改补丁代码时迭代成本低。相对的,make build 产出的 release 签名二进制是留给真正跑虚拟化的路径(make boot 等)的——不要拿 swift build 裸产物去启动 VM。
固件配对表:单一数据源
iPhone IPSW 与 cloudOS IPSW 的配对关系集中维护在仓库的:
config/firmware_catalog.json
- 新增或更新配对只改这个 JSON,不改任何代码;
fw prepare默认取其中的defaultPairing作为固件源。 - 该文件会随发布 App 一起打包(
Contents/Resources/config/),GUI 与 CLI 读到的是同一份。
Manager 的 Firmware 面板
如果你使用 vphone-manager GUI,侧栏的 Firmware 面板提供了图形化的镜像管理:
- 浏览配对表中的固件条目
- 直接下载对应 IPSW 镜像(走与
fw prepare相同的缓存) - 查看本地已缓存 / 已解包的固件状态
面板下载的镜像与命令行管线完全互通,可以混用。
典型工作流
make patcher_build # 1. 构建未签名 patcher(补丁代码改动后重跑)
make fw_prepare # 2. 下载 + 合并固件(有缓存则秒过)
make fw_patch_dev # 3. 按 dev 变体打补丁
注意事项:
fw patch是原地修改,重复跑同一变体是安全的(有干净备份与幂等设计),但跨变体重打前建议确认*Restore*目录状态。- kernelcache 在首次打补丁前会保存一次性
.orig备份,供后续cfw kernel-patch从干净源开始,避免二次补丁污染。 - 想单独重打某个组件,可用 standalone patch target:
make dt_patch/gpu_patch/sensor_patch/sim_patch。
深入阅读
- 各启动链补丁器的实现细节:仓库
docs/bootchain-patchers.md - CFW 安装阶段(补丁之后、首启之前):仓库
docs/cfw-installers.md