# How the Boot Chain Patching Pipeline Works in vphone-cli

> Explore the vphone-cli boot chain patching pipeline. This automation framework extracts, patches, injects daemons, and repackages iOS firmware for CFW. Learn how it works.

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

---

**The boot chain patching pipeline in vphone-cli is a multi-stage automation framework that extracts iOS firmware Cryptexes, applies binary patches via a Python disassembly engine, injects custom launch daemons, and repackages the image into a bootable Custom Firmware (CFW) using Makefile-driven orchestration.**

The **boot chain patching pipeline** in the [Lakr233/vphone-cli](https://github.com/Lakr233/vphone-cli) repository transforms a standard iOS firmware image into a jailbreak-capable virtual machine disk. This process combines shell scripting, Python-based binary instrumentation using Capstone and Keystone engines, and macOS Virtualization.framework integration. Understanding this pipeline reveals how the tool circumvents iOS security mechanisms to enable virtualized development and research environments.

## Firmware Preparation and Cryptex Extraction

The pipeline begins with [`scripts/fw_prepare.sh`](https://github.com/Lakr233/vphone-cli/blob/main/scripts/fw_prepare.sh), which handles IPSW acquisition and decryption. This script performs the initial firmware decomposition required for all subsequent patching stages.

The script executes the following critical operations:

- Downloads the target iOS IPSW and parses `BuildManifest.plist` to identify build identifiers
- Extracts the **SystemOS** and **AppOS Cryptex** DMGs from the IPSW archive
- Decrypts the SystemOS DMG using the AEA key via `aea decrypt`
- Mounts the Cryptex images at temporary mount points under `<VM_DIR>/System/Cryptexes/OS` and `…/App`

These decrypted Cryptexes provide the writable baseline upon which the CFW installer applies modifications.

## Binary Patching Framework Architecture

At the core of the pipeline sits [`scripts/patchers/cfw.py`](https://github.com/Lakr233/vphone-cli/blob/main/scripts/patchers/cfw.py), a Python dispatcher that consolidates all binary modification logic. This framework utilizes **Capstone** for disassembly-based anchor discovery and **Keystone** for assembling replacement instruction bytes, ensuring patches remain functional across iOS version updates.

Individual patch modules expose standardized `patch_*` functions that receive file paths or DSC (dyld shared cache) directories. The script parses sub-commands invoked by the installer, such as:

- `patch-seputil` → handled by [`cfw_patch_seputil.py`](https://github.com/Lakr233/vphone-cli/blob/main/cfw_patch_seputil.py)
- `patch-iomfb-swapend` → handled by [`cfw_patch_iomfb_swapend.py`](https://github.com/Lakr233/vphone-cli/blob/main/cfw_patch_iomfb_swapend.py)
- `patch-launchd-cache-loader` → NOPs cache validation checks
- `patch-mobileactivationd` → forces activation success

A typical invocation from the installation script specifies the target directory and patch-specific parameters:

```bash
$PYTHON3 "$SCRIPT_DIR/patchers/cfw.py" patch-iomfb-swapend "$DSC_DIR" --target-size 0x560

```

## CFW Installation Pipeline

The [`scripts/cfw_install.sh`](https://github.com/Lakr233/vphone-cli/blob/main/scripts/cfw_install.sh) script orchestrates the seven-stage installation flow. Each stage modifies specific binaries or installs components into the mounted VM disk image, with automatic backup and re-signing operations between steps.

**Stage 1: Cryptex Installation**
Copies the prepared SystemOS and AppOS Cryptexes into the VM rootfs and creates necessary `dyld` symlinks.

**Stage 2: seputil Patching**
Calls `cfw.py patch-seputil` to replace the gigalocker UUID with a deterministic value (`AA`), bypassing hardware-bound entitlement checks.

**Stage 3: GPU Driver Installation**
Unpacks `AppleParavirtGPUMetalIOGPUFamily.bundle` into the appropriate System/Library extensions path.

**Stage 4: Jailbreak Toolchain Deployment**
Installs `iosbinpack64`, containing user-land utilities like **dropbear** (SSH server) and TrollStore components.

**Stage 5: launchd_cache_loader Patching**
Applies `cfw.py patch-launchd-cache-loader` to NOP out the cache-validation check, allowing modified shared caches to load.

**Stage 6: mobileactivationd Patching**
Executes `cfw.py patch-mobileactivationd` to force activation success regardless of device eligibility or SIM status.

**Stage 7: LaunchDaemon Injection**
Installs `vphoned`, `dropbear`, and `trollvnc` LaunchDaemons, then injects them into `launchd.plist` to ensure persistence across reboots.

During stages 2 through 6, the installer creates `*.bak` backups of original binaries and re-signs modified binaries using `ldid` with the provided `signcert.p12` certificate:

```bash
ldid -S -M "-K/path/to/cfw_input/signcert.p12" /mnt1/usr/libexec/seputil

```

## Variant-Specific Build Targets

The top-level **Makefile** defines convenience targets that parameterize the patching intensity. Each target invokes [`fw_prepare.sh`](https://github.com/Lakr233/vphone-cli/blob/main/fw_prepare.sh) followed by [`cfw_install.sh`](https://github.com/Lakr233/vphone-cli/blob/main/cfw_install.sh) with different patch sets:

- **`make fw_patch`** — Regular variant applying 52 patches for basic virtualization support
- **`make fw_patch_dev`** — Development variant adding the RPC-server daemon across 12 additional phases
- **`make fw_patch_jb`** — Jailbreak variant with 127 patches including kernel-level sandbox bypasses
- **`make fw_patch_exp`** — Experimental variant combining jailbreak patches with research modifications (hypervisor VMM renaming, DT identity spoofing)

After CFW generation, the Makefile provides `make boot` and `make boot_dfu` targets to launch the VM using the patched image.

## Kernel-Level DSC Patches

When building Jailbreak or Experimental variants, the pipeline applies additional kernel-level patches directly to the **dyld shared cache (DSC)** pages. These modifications target specific system daemons and hypervisor symbols:

- **`patch-watchdogd`** — Forces the `hv_vmm_present` sysctl to report VM status, preventing hardware-specific watchdog panics
- **`patch-diskimagesiod`** — Enables DDI auto-mount on iOS 27+ builds
- **`patch-hv-vmm-dsc`** — Rewrites DSC symbols to rename the hypervisor VMM identifier

Modified DSC pages undergo re-attestation via `cs_validate` to satisfy code signing requirements during the boot process.

## Boot Execution Flow

The final stage leverages [`sources/vphone-cli/VPhoneVirtualMachine.swift`](https://github.com/Lakr233/vphone-cli/blob/main/sources/vphone-cli/VPhoneVirtualMachine.swift) to instantiate an Apple Virtualization.framework `VZVirtualMachine`. The boot process consumes the prepared disk image containing:

- Patched system binaries (`seputil`, `launchd_cache_loader`, `mobileactivationd`)
- Injected LaunchDaemons providing SSH and VNC access
- Modified DSC with corrected size/slide metadata for the target iOS version

Running `make boot` initializes the virtual device, which boots from the patched CFW image and exposes the custom daemons on their configured ports.

## Practical Usage Examples

Execute the complete pipeline for a jailbreak-enabled virtual iPhone:

```bash

# Prepare, patch, and install jailbreak variant

make fw_patch_jb

# Launch the virtual machine

make boot

```

Apply a specific patch manually for debugging or custom builds:

```bash

# Adjust IOMobileFramebuffer payload size for iOS 26.0 compatibility

scripts/patchers/cfw.py patch-iomfb-swapend /path/to/DSC/dir --target-size 0x560

# Re-sign a manually patched binary

ldid -S -M "-Kcfw_input/signcert.p12" /mnt1/usr/libexec/seputil

```

Boot into DFU mode for OTA restoration procedures:

```bash
make boot_dfu

```

## Summary

- The pipeline starts with [`scripts/fw_prepare.sh`](https://github.com/Lakr233/vphone-cli/blob/main/scripts/fw_prepare.sh) decrypting and extracting iOS Cryptexes from the IPSW.
- [`scripts/patchers/cfw.py`](https://github.com/Lakr233/vphone-cli/blob/main/scripts/patchers/cfw.py) serves as the central patching engine, using Capstone/Keystone for durable binary modifications.
- [`scripts/cfw_install.sh`](https://github.com/Lakr233/vphone-cli/blob/main/scripts/cfw_install.sh) executes a seven-stage installation, patching critical binaries like `seputil` and `mobileactivationd` while injecting SSH/VNC daemons.
- Makefile targets (`fw_patch`, `fw_patch_jb`, `fw_patch_exp`) provide variant-specific patch collections ranging from 52 to 127 modifications.
- All patched binaries are re-signed with `ldid` using `signcert.p12` before the [`VPhoneVirtualMachine.swift`](https://github.com/Lakr233/vphone-cli/blob/main/VPhoneVirtualMachine.swift) wrapper boots the image via Virtualization.framework.

## Frequently Asked Questions

### What does the seputil patch accomplish in the boot chain?

The `patch-seputil` module replaces the gigalocker UUID with a deterministic `AA` value. According to the source code in [`cfw_patch_seputil.py`](https://github.com/Lakr233/vphone-cli/blob/main/cfw_patch_seputil.py), this modification disables hardware-bound entitlement verification, allowing the virtual machine to bypass checks that would normally fail on non-physical devices during the Secure Enclave initialization phase.

### How does vphone-cli ensure patches survive across iOS updates?

The patching framework in [`cfw.py`](https://github.com/Lakr233/vphone-cli/blob/main/cfw.py) uses **Capstone** disassembly to locate patch anchors dynamically rather than relying on static memory offsets. When Apple modifies binary layouts in new iOS versions, the disassembler identifies instruction patterns (such as specific branch targets or validation sequences) and calculates the correct offset for the replacement payload assembled by **Keystone**.

### What distinguishes the Jailbreak variant from the Regular variant?

The Regular variant (`make fw_patch`) applies 52 patches focused on virtualization compatibility and basic tool injection. The Jailbreak variant (`make fw_patch_jb`) applies 127 patches, adding kernel-level modifications that disable sandbox restrictions, patch credential management daemons, and modify the hypervisor detection sysctl (`hv_vmm_present`) to enable full root access and unsigned code execution.

### Can I apply individual patches without running the full pipeline?

Yes. The [`cfw.py`](https://github.com/Lakr233/vphone-cli/blob/main/cfw.py) script accepts direct sub-command invocations for single-patch applications. You must manually mount the Cryptex DMG and provide the target path or DSC directory. After patching, manually re-sign the binary using `ldid` with the `signcert.p12` certificate to maintain code signature validity, as the automated [`cfw_install.sh`](https://github.com/Lakr233/vphone-cli/blob/main/cfw_install.sh) normally handles this step.