How to Install Custom Firmware (CFW) with vphone-cli: Complete Technical Guide
TLDR: vphone-cli installs Custom Firmware (CFW) by mounting the virtual iPhone’s Disk.img on the host, copying patched system files and Cryptexes onto APFS volumes, and atomically switching the boot snapshot to the modified "live" volume using a coordinated two-script workflow.
Installing Custom Firmware on a virtual iPhone requires precise manipulation of APFS containers and system binaries. The Lakr233/vphone-cli project automates this complex process through a dual-stage shell script architecture that handles disk attachment, binary patching, and snapshot management. This guide explains exactly how CFW installation works, from mounting the raw disk image to flipping the boot snapshot for persistent modifications.
CFW Installation Architecture
The installation process is orchestrated by two distinct scripts that separate host-level disk operations from guest-level system modifications.
Host-Side Orchestration Script
The scripts/cfw_install_host.sh script manages the host-level disk attachment and snapshot switching. According to the source code, it performs the following operations:
- Attaches the VM’s Disk.img as a raw block device using macOS disk utilities
- Identifies the APFS container and locates the System volume within the virtual disk
- Re-executes with root privileges (required for owners-honored mounts)
- Invokes the appropriate variant-specific installer based on the
--variantflag - Flips the boot snapshot offline using
tools/apfs_snap_rename.pyafter the installer completes, ensuring the VM boots the freshly-patched volume on next launch
Variant-Specific Installer
The scripts/cfw_install.sh (default "regular" variant) executes the actual system modifications inside the mounted APFS volumes. This script leverages scripts/patchers/cfw.py to extract Cryptexes from the IPSW’s BuildManifest and performs comprehensive system patching.
Step-by-Step Installation Process
Prerequisites and Initial Setup
Before installing CFW, the virtual machine must be in a restored state with the Disk.img created from a valid IPSW. Ensure the VM is powered off to prevent file system corruption during mounting.
# Prepare a restored VM (run once)
make restore # Downloads an IPSW and creates vm/Disk.img
make poweroff # Ensures the VM is not running
Mounting and Modifying the Disk Image
The host script attaches Disk.img as a raw block device and determines the correct APFS container. It requires root privileges to mount the System volume with owners honored.
# Install the regular CFW (default variant)
sudo scripts/cfw_install_host.sh
# Or use the Makefile shortcut: make cfw_install
The script automatically selects the installation variant. You can specify alternative variants using command-line flags:
sudo scripts/cfw_install_host.sh --variant jb # Jailbreak CFW
sudo scripts/cfw_install_host.sh --variant dev # Development CFW
sudo scripts/cfw_install_host.sh --variant exp # Experimental CFW
Binary Patching and System Injection
Once the System volume is mounted, scripts/cfw_install.sh performs the following modifications as implemented in scripts/patchers/cfw.py:
- Cryptex Extraction: Extracts system Cryptexes from the IPSW BuildManifest and copies them to the appropriate APFS volume locations
- Binary Patching: Modifies several critical system binaries including
seputil,launchd_cache_loader, andmobileactivationd(preserving original backups with.bakextensions) - iOS 27 Compatibility: Optionally patches iOS-27-specific components such as
diskimagesiod, IOMFB size parameters, and DSC maxSlide values - Symbolic Link Creation: Establishes required
dyldsymlinks for dynamic library loading
Driver and Daemon Deployment
The installer injects additional system components not present in the stock IPSW:
- GPU Acceleration: Installs the AppleParavirtGPUMetalIOGPUFamily driver for paravirtualized graphics support
- Jailbreak Environment: Deploys
iosbinpack64containing jailbreak user-land binaries - Host Communication: Compiles and signs the vphoned Objective-C daemon using the private signing certificate bundled in
scripts/cfw_input/ - Launch Daemon Injection: Modifies
launchd.plistto register additional services includingdropbear(SSH),trollvnc(VNC), andrpcserver_ios
Boot Snapshot Switching
After file modifications complete, scripts/cfw_install_host.sh invokes tools/apfs_snap_rename.py to atomically switch the APFS boot snapshot from the recovery image to the live, modified system volume. This operation makes the CFW installation persistent and bootable.
Booting the Modified System
Once the snapshot is switched, boot the virtual iPhone to access the CFW environment:
make boot
The system boots into the modified volume with SSH available on port 22222 using the default password alpine.
Idempotent Installation Behavior
The vphone-cli CFW installation is designed to be idempotent. Running the installation script multiple times safely reuses already-extracted Cryptexes, re-signs binaries from their *.bak copies, and overwrites existing files without corruption. This allows for iterative development and testing of custom firmware modifications.
Summary
- vphone-cli uses a two-stage installation process:
scripts/cfw_install_host.shhandles disk attachment and snapshot switching, whilescripts/cfw_install.shperforms binary patching - The host script requires root privileges to mount APFS volumes with owners honored and uses
tools/apfs_snap_rename.pyto flip the boot snapshot - Binary patching via
scripts/patchers/cfw.pymodifies critical components likeseputil,launchd_cache_loader, andmobileactivationdwhile preserving backups - The installer deploys additional drivers (AppleParavirtGPUMetalIOGPUFamily), jailbreak tools (
iosbinpack64), and the vphoned communication daemon - Installation supports multiple variants (
--variant jb,dev,exp) selectable via command-line flags - The process is idempotent, allowing safe re-installation without re-extracting Cryptexes
Frequently Asked Questions
What file system does vphone-cli modify during CFW installation?
vphone-cli modifies the APFS (Apple File System) volumes contained within the virtual iPhone's Disk.img. Specifically, it mounts the System volume to inject Cryptexes, patched binaries, and launch daemons, then uses tools/apfs_snap_rename.py to switch the boot snapshot from the recovery image to the modified live volume.
Why does the CFW installation require root privileges?
Root privileges are required for owners-honored mounts of the APFS volumes. When the host script scripts/cfw_install_host.sh attaches Disk.img, it must mount the virtual iPhone's file system with full ownership permissions to preserve Unix permissions, extended attributes, and special file modes (like setuid binaries) during the copy and patching operations.
Which binaries does the CFW patcher modify?
According to scripts/patchers/cfw.py, the patcher modifies several critical system binaries including seputil, launchd_cache_loader, and mobileactivationd, along with their backups. For iOS 27 compatibility, it also patches diskimagesiod, adjusts IOMFB size parameters, and modifies DSC maxSlide values. All modifications preserve the original files with .bak extensions for safe recovery.
Can I install multiple CFW variants on the same Disk.img?
Yes, the installation process is idempotent and supports switching between variants using the --variant flag (options include jb for jailbreak, dev for development, and exp for experimental). Running sudo scripts/cfw_install_host.sh --variant [type] will re-patch the existing installation with the selected variant's specific modifications, reusing already-extracted Cryptexes and re-signing binaries from their preserved *.bak copies.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →