What is vphone-cli? A Complete Guide to Virtual iPhone Boot Automation on macOS

vphone-cli is a Swift 6.0 command-line utility that creates and manages fully functional virtual iPhones on macOS 15+ using Apple's Virtualization.framework, automating firmware patching, DFU restoration, and custom firmware installation.

vphone-cli transforms iOS development and security research by enabling developers to run genuine iPhone firmware inside macOS virtual machines. Built entirely in Swift 6.0 using the Swift Package Manager, this open-source tool orchestrates the complete lifecycle of a virtual iOS device—from downloading IPSW files and applying binary patches to booting an interactive VM with full hardware emulation.

Core Architecture of vphone-cli

The vphone-cli codebase follows a layered architecture that separates CLI parsing, VM orchestration, firmware preparation, and guest communication. Each layer leverages specific Apple frameworks and private APIs accessed through the Dynamic library to avoid Objective-C bridging.

Command-Line Interface and Routing

The entry point resides in sources/vphone-cli/VPhoneCLI.swift, which implements the argument parser and sub-command routing. This module handles commands such as vm create, fw patch, cfw install, and vm launch, forwarding options to the core logic layers.

VM Orchestration and Hardware Configuration

The VPhoneVirtualMachine.swift file contains the primary orchestration logic, configuring VZVirtualMachineConfiguration with hardware models, auxiliary storage, graphics, audio, networking, and serial consoles. According to the source code in lines 46-51, the boot loader uses VZMacOSBootLoader with optional custom ROM injection via Dynamic.

Machine Identifier Persistence: To ensure stable ECID/UDID across reboots, lines 54-84 generate or load a persistent VZMacMachineIdentifier, storing the manifest in the VM configuration directory.

Guest-Side Communication Daemon

A companion daemon named vphoned runs inside the iOS VM, exposing a vsock-based JSON control channel for host-guest interaction. The host-side client implementation in VPhoneControl.swift communicates with the daemon (implemented in scripts/vphoned/vphoned_clipboard.m) to handle touch events, clipboard synchronization, and screenshot capture.

Firmware Patch Pipeline

The Python-based patch pipeline in scripts/patchers/cfw.py and scripts/fw_prepare.sh automates firmware preparation. This pipeline downloads IPSWs, merges CloudOS components, and applies hierarchical binary patches ranging from 5 to 141 patches depending on the selected variant. The research/0_binary_patch_comparison.md documents the specific byte-level modifications applied to kernels and SEP firmware.

Virtual Machine Configuration Internals

vphone-cli constructs VM configurations using private Virtualization.framework APIs through the Dynamic library, enabling features unavailable in standard macOS virtualization.

Hardware Model and NVRAM Configuration

The tool creates a hardware model with PV=3 using private APIs:

let hwModel = try VPhoneHardware.createModel()
let machineIdentifier: VZMacMachineIdentifier
var manifest = try VPhoneVirtualMachineManifest.load(from: options.configURL)

As implemented in VPhoneVirtualMachine.swift (lines 36-44), the configuration sets NVRAM boot arguments to enable serial output:

let bootArgs = "serial=3 debug=0x104c04"
Dynamic(auxStorage)._setDataValue(bootArgsData,
    forNVRAMVariableNamed: "boot-args", error: nil)

Synthetic Battery Implementation

To provide realistic power state emulation, lines 49-60 configure a synthetic battery source:

let source = Dynamic._VZMacSyntheticBatterySource()
source.setCharge(100.0)
source.setConnectivity(1) // charging state
let batteryConfig = Dynamic._VZMacBatteryPowerSourceDeviceConfiguration()
batteryConfig.setSource(source.asObject)
Dynamic(config)._setPowerSourceDevices([batteryObj])

This ensures the guest iOS sees a fully charged, charging device regardless of host power state.

Kernel Debugging Support

When debugging is required, vphone-cli attaches a GDB stub to the virtual machine. Lines 61-73 in VPhoneVirtualMachine.swift implement this as follows:

if let kernelDebugPort = options.kernelDebugPort {
    let debugStub = Dynamic._VZGDBDebugStubConfiguration(port: kernelDebugPort)
    Dynamic(config)._setDebugStub(debugStub.asObject)
}

Primary Use Cases for vphone-cli

One-Command VM Creation: The vphone-cli vm create <name> -V jb command automates the entire workflow—firmware download, patching, DFU restore, custom firmware installation, and first boot.

Manual Pipeline Control: Users can repeat individual stages, such as re-patching a VM after kernel updates using vphone-cli fw patch, without recreating the entire virtual machine.

Interactive Debugging: The tool supports kernel-level debugging via GDB stubs, synthetic battery adjustments at runtime, and host-guest control through the vsock channel.

Application Testing and Installation: The VPhoneIPAInstaller.swift module handles drag-and-drop IPA installation by extracting, re-signing, and deploying apps over the vsock control channel, while VPhoneMenuController.swift manages screen recording and location simulation.

Practical Code Examples

Creating and Launching a Jailbroken VM

Execute the following to create a new virtual iPhone named "myphone" with jailbreak support:

vphone-cli vm create myphone -V jb
vphone-cli vm launch myphone

Reference: README.md lines 44-50 document the quick-start workflow.

Re-patching with Different Variants

To apply experimental patches to an existing VM:

vphone-cli fw patch myphone --variant exp --force

Reference: Firmware patch command described in README.md lines 72-76.

Runtime Battery Control via Swift API

Adjust the synthetic battery programmatically using the control client:

let control = VPhoneControl(vmName: "myphone")
control.setBattery(charge: 75.0, connectivity: 2) // 75% and disconnected

Capturing Screenshots via Unix Socket

Request screenshots through the MCP wrapper using curl:

curl -X POST -d '{"cmd":"screenshot"}' \
    --unix-socket ~/.vphone/VMs/myphone/vphone.sock http://localhost/

Reference: Automation API documented in README.md lines 96-99.

Key Implementation Files

Component File Path Purpose
CLI Entry sources/vphone-cli/VPhoneCLI.swift Argument parsing and sub-command dispatch
VM Core sources/vphone-cli/VPhoneVirtualMachine.swift Hardware configuration, machine identifiers, synthetic battery
UI Controller sources/vphone-cli/VPhoneWindowController.swift macOS window management and menu extensions
IPA Installation sources/vphone-cli/VPhoneIPAInstaller.swift Application sideloading over vsock
Hardware Model sources/vphone-cli/VPhoneHardwareModel.swift PV=3 hardware model generation
Firmware Patcher scripts/patchers/cfw.py Binary patch application for kernels and SEP
CFW Installer scripts/cfw_install_jb.sh Patched firmware installation (requires sudo)
Package Manifest Package.swift SwiftPM dependencies including Dynamic library

All user data resides under ~/.vphone/ unless overridden by the $VPHONE_ROOT environment variable.

Summary

  • vphone-cli is a Swift 6.0 utility that automates virtual iPhone creation on macOS 15+ using Virtualization.framework and private APIs via the Dynamic library.
  • The tool manages the complete firmware lifecycle: IPSW download, binary patching (via Python scripts), DFU restoration, and custom firmware installation.
  • VM persistence relies on stable VZMacMachineIdentifier generation stored in VPhoneVirtualMachine.swift (lines 54-84).
  • Advanced features include synthetic battery emulation, GDB debug stubs, and vsock-based host-guest communication through the vphoned daemon.
  • All configuration and VM state are stored in ~/.vphone/, with granular control available through sub-commands like vm create, fw patch, and cfw install.

Frequently Asked Questions

What are the system requirements for running vphone-cli?

vphone-cli requires macOS 15 or later and utilizes Apple's Virtualization.framework, which necessitates Apple Silicon (ARM64) hardware. The tool requires sudo privileges for custom firmware installation and sufficient storage space for IPSW files and VM images, typically stored under ~/.vphone/.

How does vphone-cli handle firmware patching and variants?

The scripts/patchers/cfw.py script applies a hierarchy of binary patches to downloaded IPSW firmware, with variant-specific modifications ranging from 5 to 141 patches. Variants like jb (jailbreak) or exp (experimental) determine which patches are applied to components including the kernel, SEP, and boot chain, as documented in research/0_binary_patch_comparison.md.

Can multiple virtual iPhones run simultaneously?

While vphone-cli supports creating multiple VM instances under ~/.vphone/VMs/, running them simultaneously depends on available system resources and Virtualization.framework limitations. Each VM requires dedicated CPU cores, memory, and graphics resources; the VPhoneVirtualMachine.swift configuration must be instantiated separately for each running instance.

vphone-cli operates within legal gray areas common to iOS virtualization tools. It uses private Apple APIs accessed through the open-source Dynamic library and modifies proprietary IPSW firmware. While useful for security research and app development, users should ensure compliance with Apple's Software License Agreement and local laws regarding firmware modification and virtualization.

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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →