# How vphone-cli Patches the iOS Boot Chain: A Technical Deep Dive

> Discover how vphone-cli patches the iOS boot chain. Explore binary patches to iBSS, iBEC, and LLB bootloaders, bypassing signatures and enabling serial output with Capstone and Keystone.

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

---

**TLDR:** vphone-cli modifies the iOS boot chain by applying binary patches to iBSS, iBEC, and LLB bootloader images using the `IBootPatcher` Python class, which leverages Capstone for disassembly and Keystone for assembly to bypass signature checks, enable serial output, and inject hypervisor code.

vphone-cli is an open-source virtualization tool that runs iOS inside Apple’s Virtualization.framework. To boot modified or development iOS environments, the tool must patch the iOS boot chain to disable security checks and enable debugging interfaces. The patching pipeline lives in `scripts/patchers/` and is orchestrated by the Makefile.

## Extracting the Boot Binaries from IPSW

The patching process begins with extracting raw bootloader images from an iOS firmware package. The helper script [`fw_prepare.sh`](https://github.com/Lakr233/vphone-cli/blob/main/fw_prepare.sh) extracts three critical components—**iBSS**, **iBEC**, and **LLB**—from the downloaded IPSW and places them in the `vm/` directory. These binaries form the sequential boot chain that initializes the device before the kernel loads.

The Makefile target `fw_prepare` automates this extraction, ensuring the virtual machine has the original Apple bootloaders ready for modification.

## The Core Patching Engine

At the heart of the process is the `IBootPatcher` class implemented in [`scripts/patchers/cfw_patch.py`](https://github.com/Lakr233/vphone-cli/blob/main/scripts/patchers/cfw_patch.py). This engine parses the raw ARM64 bootloader binaries and applies surgical modifications using two open-source frameworks:

- **Capstone** – Disassembles the binary to locate anchor instructions.
- **Keystone** – Assembles replacement instructions to inject at specific offsets.

The patcher searches for unique byte sequences or instruction patterns to establish virtual addresses, then overwrites them with patched variants. This approach ensures the modifications survive across different iOS builds as long as the anchor logic remains consistent.

## Critical Boot Chain Modifications

The specific patches applied to each bootloader stage are documented in [`research/iboot_patches.md`](https://github.com/Lakr233/vphone-cli/blob/main/research/iboot_patches.md). These modifications alter the boot flow to enable virtualization and debugging.

### Serial Label Replacement

The patcher replaces generic separator banners (e.g., `"===...==="`) in iBSS, iBEC, and LLB with human-readable strings like `"Loaded iBSS"` and `"Loaded iBEC"`. This helps identify the current boot stage when reading serial output.

### Image4 Signature Validation Bypass

To skip code signature checks, the patcher targets the `image4_validate_property_callback` function. By forcing this function to always return success, the bootloader loads patched kernels and root filesystems without verifying cryptographic signatures. This is essential for booting modified iOS images.

### Boot Arguments Injection

The tool patches the default `"%s"` boot-args format string to `"serial=3 -v debug=0x2014e %s"`. This injection enables **serial console output** (serial=3), **verbose boot logging** (-v), and specific debug flags (debug=0x2014e), allowing developers to monitor the boot process in real-time.

### Root Filesystem Verification Bypass

Several conditional branches within LLB are rewritten to ignore root filesystem signature checks. Additionally, a panic handler triggered by failed boot integrity checks is neutralized, allowing the system to boot with a modified rootfs.

## Jailbreak and Experimental Variants

Beyond the base patches, vphone-cli supports extended modification sets for specific use cases.

### Jailbreak Extensions

When building the `jailbreak` target, the `IBootJBPatcher` class (in [`scripts/patchers/cfw_patch_jb.py`](https://github.com/Lakr233/vphone-cli/blob/main/scripts/patchers/cfw_patch_jb.py)) extends the base patch set. A critical addition is the **Skip generate_nonce** patch for iBSS, which disables random AP nonce generation. This enables deterministic DFU restores required for jailbreaking.

### Experimental Hypervisor Injection

For the `experimental` variant, additional scripts inject a hidden hypervisor into the boot chain:

- `scripts/patchers/cfw_patch_hv_vmm_*.py` – Injects the `hv_vmm` hypervisor and related DSC patches.
- [`scripts/patchers/cfw_patch_iomfb_force_kern.py`](https://github.com/Lakr233/vphone-cli/blob/main/scripts/patchers/cfw_patch_iomfb_force_kern.py) – Forces kernel-mode IOMFB driver loading.
- [`scripts/patchers/cfw_patch_iomfb_swapend.py`](https://github.com/Lakr233/vphone-cli/blob/main/scripts/patchers/cfw_patch_iomfb_swapend.py) – Swaps endian handling for IOMFB compatibility.
- [`scripts/patchers/cfw_patch_jetsam.py`](https://github.com/Lakr233/vphone-cli/blob/main/scripts/patchers/cfw_patch_jetsam.py) – Applies jetsam-related patches for memory management stability.

These patches allow the virtual iPhone to run with a full hypervisor layer beneath iOS.

## Build Orchestration

The Makefile provides specific targets to execute the patching pipeline:

```bash

# Extract binaries from IPSW

make fw_prepare

# Apply standard boot chain patches

make fw_patch

# Apply jailbreak-specific extensions

make fw_patch_jb

# Apply experimental hypervisor patches

make fw_patch_exp

# Build and launch the virtual machine

make build
make boot

```

The `fw_patch` target invokes [`scripts/fw_patch.py`](https://github.com/Lakr233/vphone-cli/blob/main/scripts/fw_patch.py), which orchestrates the `IBootPatcher` logic. After patching, the modified binaries remain in `vm/` where [`VPhoneVirtualMachine.swift`](https://github.com/Lakr233/vphone-cli/blob/main/VPhoneVirtualMachine.swift) loads them into the Virtualization.framework guest.

## Summary

- vphone-cli extracts **iBSS**, **iBEC**, and **LLB** from IPSW files using [`fw_prepare.sh`](https://github.com/Lakr233/vphone-cli/blob/main/fw_prepare.sh) and stores them in `vm/`.
- The **`IBootPatcher`** class in [`scripts/patchers/cfw_patch.py`](https://github.com/Lakr233/vphone-cli/blob/main/scripts/patchers/cfw_patch.py) applies binary patches using Capstone and Keystone.
- **Key patches** include Image4 signature bypass, boot-args injection, and rootfs verification removal.
- **Jailbreak variants** use `IBootJBPatcher` to disable nonce generation and enable DFU restore capabilities.
- **Experimental builds** inject the `hv_vmm` hypervisor using dedicated patcher scripts.
- The Makefile orchestrates extraction and patching via `make fw_prepare` and `make fw_patch`.

## Frequently Asked Questions

### What is the iOS boot chain and why does vphone-cli need to patch it?

The iOS boot chain consists of three sequential stages: iBSS (iBoot Single Stage), iBEC (iBoot Epoch II), and LLB (Low-Level Bootloader). These stages verify and load the kernel. vphone-cli patches this chain to disable cryptographic signature checks and enable serial debugging, which are required to boot modified or jailbroken iOS images inside a virtual machine.

### How does IBootPatcher locate the correct bytes to modify in iBoot binaries?

`IBootPatcher` uses the **Capstone** disassembly framework to analyze the ARM64 machine code and locate specific anchor instructions. Once identified, it uses **Keystone** to assemble replacement instructions. The anchor points and byte offsets are documented in [`research/iboot_patches.md`](https://github.com/Lakr233/vphone-cli/blob/main/research/iboot_patches.md), allowing the script to find patch locations even across minor iOS version differences.

### What distinguishes the jailbreak patch flow from the regular patching flow?

The regular flow applies base patches for debugging and serial output. The jailbreak flow (triggered by `make fw_patch_jb`) additionally invokes [`scripts/patchers/cfw_patch_jb.py`](https://github.com/Lakr233/vphone-cli/blob/main/scripts/patchers/cfw_patch_jb.py), which instantiates `IBootJBPatcher` to apply patches like **Skip generate_nonce**. This disables random AP nonce generation, enabling deterministic restores required for jailbreak exploits.

### Where are the specific patch offsets and byte sequences documented?

All patch specifications—including virtual addresses, original bytes, and patched bytes—are cataloged in [`research/iboot_patches.md`](https://github.com/Lakr233/vphone-cli/blob/main/research/iboot_patches.md). This document details each modification to iBSS, iBEC, and LLB, including the logic for finding anchor points and the specific changes made to functions like `image4_validate_property_callback`.