How to Boot iOS VMs on Macs Using vphone-cli: A Complete Guide
vphone-cli uses Apple's private Virtualization framework to boot iPhone virtual machines on macOS 15+ (Sequoia), supporting both GUI interactive mode and DFU recovery mode via command-line configuration.
This command-line tool, developed by Lakr233, provides a Swift-based interface for running iOS virtual machines on Apple silicon Macs. By leveraging private APIs and the VZVirtualMachine architecture, vphone-cli enables security researchers, jailbreak developers, and reverse engineers to boot, debug, and interact with iOS systems without physical hardware.
Prerequisites and System Requirements
Before running vphone-cli, ensure your environment meets these requirements:
- macOS 15+ (Sequoia) — required for the private Virtualization framework features
- Xcode 15+ — for compilation and private entitlement handling
- SIP and AMFI disabled — necessary for private API access to hardware model creation
- Prepared firmware bundle —
config.plistgenerated byfw_prepare.shcontaining the VM manifest
Boot Architecture Overview
The boot process in vphone-cli follows a modular architecture across several core source files:
| Component | Primary Role | Key Source File |
|---|---|---|
| Entry point | CLI argument parsing and app initialization | sources/vphone-cli/main.swift |
| Command definitions | Sub-command structure (boot, boot_dfu, install, record) |
sources/vphone-cli/VPhoneCLI.swift |
| VM builder | Hardware model, NVRAM, peripherals, and start logic | sources/vphone-cli/VPhoneVirtualMachine.swift |
| Lifecycle bridge | Connects CLI options to macOS app delegate | sources/vphone-cli/VPhoneAppDelegate.swift |
| Hardware model | Private PV=3 iPhone hardware construction | sources/vphone-cli/VPhoneHardwareModel.swift |
| Networking | Vsock control channel and network device setup | sources/VPhoneCore/VPhoneNetworking.swift |
| DFU patterns | Boot-stage logic for recovery mode | sources/VPhoneCore/VPhoneBootPatterns.swift |
Building vphone-cli from Source
Compile the project with private entitlements using the provided Makefile:
# Ensure SIP/AMFI are disabled before proceeding
make build
This invokes Swift Package Manager with the necessary private framework linkages and entitlements required for VPhoneHardwareModel.swift to create the PV=3 hardware model through dynamic library loading.
Standard Boot Process
Step 1: Argument Parsing in VPhoneCLI.swift
The boot sub-command, defined in sources/vphone-cli/VPhoneCLI.swift, accepts configuration through an ArgumentParser-driven interface. Key flags include:
--config— path to the firmware manifest (config.plist)--disk— main disk image path--nvram— NVRAM storage image--sep-storage— Secure Enclave processor storage--cpu-count— virtual CPU allocation--memory— RAM allocation (e.g.,8G)--variant— firmware variant (regular,dev, etc.)--rom— optional custom bootloader--debug-port— GDB stub listener port--no-vphoned— disable vsock control channel
Step 2: VM Construction in VPhoneVirtualMachine.swift
The VPhoneVirtualMachine class in sources/vphone-cli/VPhoneVirtualMachine.swift assembles a VZVirtualMachineConfiguration through these operations:
Hardware model creation — VPhoneHardware.createModel() instantiates a PV=3 iPhone-compatible hardware model using private initializers from VPhoneHardwareModel.swift
Machine identifier management — either loads an existing ECID/UDID from config.plist or generates a fresh VZMacMachineIdentifier for persistent identity
NVRAM configuration — writes boot arguments (serial=3 debug=0x104c04) to enable serial console output
Boot loader setup — configures VZMacOSBootLoader with optional custom ROM
Peripheral attachment:
- Graphics display with configurable resolution
- Audio device
- USB keyboard input
- Synthetic battery for power state simulation
- Optional SEP coprocessor for Secure Enclave operations
- Vsock-based guest control channel (unless
--no-vphoned) - GDB debug stub on auto-assigned or specified port
- PL011 UART serial port bridged to host stdin/stdout
Step 3: VM Start via VPhoneAppDelegate.swift
VPhoneAppDelegate.swift receives parsed options, instantiates VPhoneVirtualMachine, and calls start(forceDFU:). The NSApplication run-loop then drives the GUI window, menu bar, and optional screen recorder while delegating lifecycle events (guest stop, errors, network changes) to exit handlers.
Boot Modes and Command Examples
Regular GUI Boot
Launch an interactive iOS VM with full graphics and input:
vphone boot \
--config ./config.plist \
--disk ./Disk.img \
--nvram ./NVRAM.img \
--sep-storage ./SEPStorage.img \
--cpu-count 8 \
--memory 8G \
--variant regular
DFU Mode for Recovery Operations
Use boot_dfu or boot --force-dfu to enter DFU mode, enabling irecovery connections:
vphone boot_dfu \
--config ./config.plist \
--disk ./Disk.img \
--nvram ./NVRAM.img \
--variant dev
The forceDFU parameter triggers logic from VPhoneBootPatterns.swift, preparing the boot stages for recovery protocol communication through the virtual USB connection.
Custom ROM with Debug Stub
Attach a modified bootloader and expose a GDB server:
vphone boot \
--config ./config.plist \
--disk ./Disk.img \
--rom ./CustomROM.dmg \
--debug-port 6001
Headless Operation Without Control Channel
Disable the vsock daemon for minimal resource usage:
vphone boot \
--config ./config.plist \
--disk ./Disk.img \
--no-vphoned
Network Configuration
VPhoneNetworking.swift in sources/VPhoneCore/VPhoneNetworking.swift interprets the firmware manifest to configure:
- NAT networking — default isolated mode with outbound connectivity
- Bridged networking — direct physical interface attachment
- No networking — completely isolated VM
The vsock-based control channel provides a host-guest communication path for automation and state queries when not disabled with --no-vphoned.
Summary
vphone-clirequires macOS 15+, Xcode 15+, and disabled SIP/AMFI for private Virtualization framework access- Core boot flow:
main.swift→VPhoneCLI.swift→VPhoneAppDelegate.swift→VPhoneVirtualMachine.swift VPhoneVirtualMachine.swiftconstructs the complete VM configuration including PV=3 hardware model, NVRAM boot-args, peripherals, and GDB debug capabilities- Two primary boot modes: standard GUI operation (
boot) and DFU recovery mode (boot_dfu) - Serial console access via PL011 UART enables
irecoveryinteraction for jailbreak and security research workflows
Frequently Asked Questions
What macOS version is required to boot iOS VMs with vphone-cli?
macOS 15 Sequoia or later is required. The private Virtualization framework APIs that enable iPhone hardware model creation (PV=3) were introduced in this version and are not available on earlier releases.
Why must SIP and AMFI be disabled to use vphone-cli?
The tool relies on private APIs to instantiate VZMacHardwareModel with iPhone-specific characteristics through VPhoneHardwareModel.swift. Apple's System Integrity Protection and AMFI normally block these dynamic library invocations. Disabling them is mandatory for the hardware model creation to succeed.
How do I interact with a VM booted in DFU mode?
DFU mode exposes a virtual USB recovery interface. Connect standard tools like irecovery or custom debugging utilities to interact with the device. The PL011 UART serial port, bridged to the host terminal, also provides low-level boot output and command access depending on the NVRAM boot-args configuration.
Can vphone-cli run iOS VMs without a GUI?
Partially. While the tool requires an NSApplication run-loop (making it technically GUI-based), you can minimize graphical overhead with --no-vphoned to disable the vsock control channel. Full headless operation without any windowing system is not currently supported due to the AppKit-dependent lifecycle management in VPhoneAppDelegate.swift.
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 →