# What Post-Restore Patches Are Applied by vphone-cli?

> Discover the single post-restore patch vphone-cli applies. It rewrites device-tree identity properties like model and compatible strings to align virtual devices with hardware identifiers.

- Repository: [Lakr/vphone-cli](https://github.com/Lakr233/vphone-cli)
- Tags: internals
- Published: 2026-09-09

---

**vphone-cli applies exactly one post-restore patch that rewrites the device-tree (DT) identity properties—model, target-type, and compatible strings—after the iOS restore completes to align the virtual device with experimental hardware identifiers.**

The `Lakr233/vphone-cli` repository provides tooling for virtualized iPhone environments, including a sophisticated patching pipeline that handles firmware modifications at different stages. While most patches are injected into the IPSW before the restore process begins, **vphone-cli post-restore patches** serve a specific purpose: modifying the live filesystem's device-tree after iBoot validation has completed. Only one such patch exists in the codebase, targeting the device-tree binary stored in the restored root filesystem.

## The Device-Tree Identity Rewrite (EXP-JB-6)

The sole post-restore modification performed by vphone-cli is the **device-tree identity rewrite**, designated as step **EXP-JB-6** in the installation pipeline. This patch edits three critical properties of the root device-tree node to spoof hardware identifiers without breaking the restore process.

### Why Post-Restore Timing Matters

During a normal restore, iBoot's "restore-mode" validator checks the DT's `model` and `target-type` against the signed BuildManifest. If these values differ from what the firmware expects, the restore aborts. The three DT edits performed by vphone-cli are **not** fatal to the boot process, allowing them to be applied safely after the restore finishes, just before the virtual machine boots the root filesystem.

### The Three Critical Property Changes

The post-restore patch updates the following root node properties in `/mnt5/<boot-hash>/usr/standalone/firmware/devicetree.img4` (or `.im4p`):

- **`root/model`** — Changes from the generic value (e.g., `iPhone99,11`) to `iPhone17,3`, making the device appear as a real iPhone model to services that read `hw.model`.
- **`root/target-type`** — Switches from `VPHONE600` to `D47`, aligning the target-type with the experimental hardware identifier used by the EXP variant.
- **`root/compatible`** — Re-orders the compatible strings from `["VPHONE600AP", "*", "AppleVirtualPlatformARM"]` to `["D47AP", "VPHONE600AP", "AppleVirtualPlatformARM"]`. This ensures `D47AP` is reported as the board identifier while keeping the original `VPHONE600AP` entry for kernel-kext binding.

These edits are applied **in-place**, preserving the original compression (LZFSE) and image layout. The operation is idempotent—re-running it on an already-patched DT results in no changes.

## Source Code Implementation

The post-restore patch is implemented across multiple files in the repository, with both Python and Swift variants handling the DT binary format.

### Python Implementation

The primary implementation resides in [`scripts/patchers/cfw_patch_post_restore_dt.py`](https://github.com/Lakr233/vphone-cli/blob/main/scripts/patchers/cfw_patch_post_restore_dt.py). This script parses the DT binary, performs the three property updates, and handles IMG4 container logic. It is invoked automatically during the EXP installation process.

### Swift Counterpart

The file [`sources/FirmwarePatcher/DeviceTree/DeviceTreePatcher.swift`](https://github.com/Lakr233/vphone-cli/blob/main/sources/FirmwarePatcher/DeviceTree/DeviceTreePatcher.swift) contains a Swift parser/serializer used by the VM tooling. While the Python script performs the actual post-restore modification, the Swift code provides the same parsing capabilities and references the EXP-JB-6 step in its documentation.

### Installation Pipeline Integration

The installation script [`scripts/cfw_install_exp.sh`](https://github.com/Lakr233/vphone-cli/blob/main/scripts/cfw_install_exp.sh) lists this operation explicitly as step **EXP-JB-6**: "post-restore DT identity rewrite (root model …)". Research documentation in [`research/txm_jb_patches.md`](https://github.com/Lakr233/vphone-cli/blob/main/research/txm_jb_patches.md) and [`research/0_binary_patch_comparison.md`](https://github.com/Lakr233/vphone-cli/blob/main/research/0_binary_patch_comparison.md) further describes the patch's role in the experimental variant.

## Manual Execution and Technical Details

You can run the post-restore DT patch manually using the Python script to verify changes before applying them.

### Dry-Run Execution

```bash

# Run the post-restore DT patch manually (dry-run)

$ ./scripts/patchers/cfw_patch_post_restore_dt.py /mnt5/<hash>/usr/standalone/firmware/devicetree.img4 --dry-run
[.] /mnt5/.../devicetree.img4: IMG4  desc='...'  payload_compression='LZFSE'
[.] DT blob: 12345 bytes
[+] model: 'iPhone99,11' -> 'iPhone17,3'
[+] target-type: 'VPHONE600' -> 'D47'
[+] compatible: ['VPHONE600AP', '*', 'AppleVirtual PlatformARM'] -> ['D47AP', 'VPHONE600AP', 'AppleVirtualPlatformARM']
[+] wrote /mnt5/.../devicetree.img4

```

### Swift API Usage

```swift
// Swift side – DeviceTreePatcher parses the DT similarly
let dt = DeviceTreePatcher(data: dtData)
dt.patchRootModel(to: "iPhone17,3")
dt.patchRootTargetType(to: "D47")
dt.reorderRootCompatible(to: ["D47AP", "VPHONE600AP", "AppleVirtualPlatformARM"])

```

## Pre-Restore vs. Post-Restore Patches

Understanding the distinction between patching stages clarifies why the device-tree modification occurs after restoration:

- **Pre-restore patches** (applied during firmware-patching): kernel DSC patches, camera patches, watchdogd changes, build-version spoofing, and other modifications that must be embedded in the IPSW before iBoot validation.
- **Post-restore patches**: Only the device-tree identity rewrite, which must occur after iBoot validates the BuildManifest but before the kernel boots.

No other post-restore patches are defined in the repository; all remaining modifications are applied during the firmware-patch stage to ensure they are cryptographically signed and validated correctly.

## Summary

- vphone-cli contains **only one post-restore patch**: the device-tree identity rewrite (EXP-JB-6).
- The patch modifies three properties in `devicetree.img4`: `model` (to `iPhone17,3`), `target-type` (to `D47`), and `compatible` (to prioritize `D47AP`).
- Implementation lives in [`scripts/patchers/cfw_patch_post_restore_dt.py`](https://github.com/Lakr233/vphone-cli/blob/main/scripts/patchers/cfw_patch_post_restore_dt.py) with a Swift counterpart in [`sources/FirmwarePatcher/DeviceTree/DeviceTreePatcher.swift`](https://github.com/Lakr233/vphone-cli/blob/main/sources/FirmwarePatcher/DeviceTree/DeviceTreePatcher.swift).
- The patch is applied to `/mnt5/<boot-hash>/usr/standalone/firmware/devicetree.img4` after restore completion to avoid iBoot validation failures.
- All other patches (kernel, camera, watchdogd) are applied pre-restore during IPSW creation.

## Frequently Asked Questions

### Can the post-restore patch be applied multiple times safely?

**Yes.** The device-tree patch is idempotent. Running [`cfw_patch_post_restore_dt.py`](https://github.com/Lakr233/vphone-cli/blob/main/cfw_patch_post_restore_dt.py) on an already-patched DT binary detects the current values and produces no net changes, making it safe to execute repeatedly without corrupting the filesystem.

### What file path does the post-restore patch modify?

**The patch targets `devicetree.img4` (or `.im4p`) located under `/mnt5/<boot-hash>/usr/standalone/firmware/`** on the restored root filesystem. The script preserves the original LZFSE compression and IMG4 container structure while editing the binary in-place.

### Why must the device-tree patch occur after the restore instead of before?

**iBoot validates the device-tree's `model` and `target-type` against the signed BuildManifest during the restore process.** If these values were modified pre-restore, the validation would fail and abort the installation. Since the post-restore changes are non-fatal to boot, they can be safely injected after iBoot validation completes but before the kernel launches.

### Are there any other post-restore patches besides the device-tree rewrite?

**No.** According to the source analysis of `Lakr233/vphone-cli`, all other modifications—including kernel DSC patches, camera system adjustments, watchdogd changes, and build-version spoofing—are applied during the pre-restore firmware-patching stage. The device-tree identity rewrite is the sole modification performed after the restore completes.