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

> Discover vphone-cli, a macOS utility for automating virtual iPhone creation and management. This guide covers Virtualization.framework, firmware patching, and DFU restoration.

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

---

**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`](https://github.com/Lakr233/vphone-cli/blob/main/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`](https://github.com/Lakr233/vphone-cli/blob/main/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`](https://github.com/Lakr233/vphone-cli/blob/main/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`](https://github.com/Lakr233/vphone-cli/blob/main/scripts/patchers/cfw.py) and [`scripts/fw_prepare.sh`](https://github.com/Lakr233/vphone-cli/blob/main/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`](https://github.com/Lakr233/vphone-cli/blob/main/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:

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

```

As implemented in [`VPhoneVirtualMachine.swift`](https://github.com/Lakr233/vphone-cli/blob/main/VPhoneVirtualMachine.swift) (lines 36-44), the configuration sets NVRAM boot arguments to enable serial output:

```swift
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:

```swift
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`](https://github.com/Lakr233/vphone-cli/blob/main/VPhoneVirtualMachine.swift) implement this as follows:

```swift
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`](https://github.com/Lakr233/vphone-cli/blob/main/VPhoneIPAInstaller.swift) module handles drag-and-drop IPA installation by extracting, re-signing, and deploying apps over the vsock control channel, while [`VPhoneMenuController.swift`](https://github.com/Lakr233/vphone-cli/blob/main/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:

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

```

Reference: [`README.md`](https://github.com/Lakr233/vphone-cli/blob/main/README.md) lines 44-50 document the quick-start workflow.

### Re-patching with Different Variants

To apply experimental patches to an existing VM:

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

```

Reference: Firmware patch command described in [`README.md`](https://github.com/Lakr233/vphone-cli/blob/main/README.md) lines 72-76.

### Runtime Battery Control via Swift API

Adjust the synthetic battery programmatically using the control client:

```swift
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:

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

```

Reference: Automation API documented in [`README.md`](https://github.com/Lakr233/vphone-cli/blob/main/README.md) lines 96-99.

## Key Implementation Files

| Component | File Path | Purpose |
|-----------|-----------|---------|
| CLI Entry | [`sources/vphone-cli/VPhoneCLI.swift`](https://github.com/Lakr233/vphone-cli/blob/main/sources/vphone-cli/VPhoneCLI.swift) | Argument parsing and sub-command dispatch |
| VM Core | [`sources/vphone-cli/VPhoneVirtualMachine.swift`](https://github.com/Lakr233/vphone-cli/blob/main/sources/vphone-cli/VPhoneVirtualMachine.swift) | Hardware configuration, machine identifiers, synthetic battery |
| UI Controller | [`sources/vphone-cli/VPhoneWindowController.swift`](https://github.com/Lakr233/vphone-cli/blob/main/sources/vphone-cli/VPhoneWindowController.swift) | macOS window management and menu extensions |
| IPA Installation | [`sources/vphone-cli/VPhoneIPAInstaller.swift`](https://github.com/Lakr233/vphone-cli/blob/main/sources/vphone-cli/VPhoneIPAInstaller.swift) | Application sideloading over vsock |
| Hardware Model | [`sources/vphone-cli/VPhoneHardwareModel.swift`](https://github.com/Lakr233/vphone-cli/blob/main/sources/vphone-cli/VPhoneHardwareModel.swift) | PV=3 hardware model generation |
| Firmware Patcher | [`scripts/patchers/cfw.py`](https://github.com/Lakr233/vphone-cli/blob/main/scripts/patchers/cfw.py) | Binary patch application for kernels and SEP |
| CFW Installer | [`scripts/cfw_install_jb.sh`](https://github.com/Lakr233/vphone-cli/blob/main/scripts/cfw_install_jb.sh) | Patched firmware installation (requires sudo) |
| Package Manifest | [`Package.swift`](https://github.com/Lakr233/vphone-cli/blob/main/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`](https://github.com/Lakr233/vphone-cli/blob/main/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`](https://github.com/Lakr233/vphone-cli/blob/main/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`](https://github.com/Lakr233/vphone-cli/blob/main/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`](https://github.com/Lakr233/vphone-cli/blob/main/VPhoneVirtualMachine.swift) configuration must be instantiated separately for each running instance.

### Is vphone-cli legal to use for iOS security research?

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.