How to Use vphone-cli to Create and Manage Virtual iOS Machines
vphone-cli is a Swift-based command-line tool that leverages Apple's Virtualization.framework to orchestrate the complete lifecycle of virtual iOS machines, from firmware preparation and binary patching to DFU restoration and host-guest communication.
The vphone-cli tool from the Lakr233/vphone-cli repository enables security researchers and developers to run fully functional iOS virtual machines on macOS. Written in Swift and built on top of Apple's Virtualization.framework, it automates the complex pipeline required to bypass Apple-only protections (AMFI, TXM) and boot modified firmware in a virtualized environment.
Understanding the vphone-cli Architecture
The tool implements a six-stage pipeline to transform stock iOS firmware into a bootable virtual machine. Each stage corresponds to specific Swift modules in the codebase:
- VM Bundle Creation – Implemented in
VPhoneVMCreateCommandwithinsources/vphone-cli/VPhoneVMCLI.swift, this stage initializes the VM container with configuration, disk images, and metadata. - Firmware Preparation – The
fw preparecommand (defined insources/vphone-cli/VPhoneFWCLI.swift) downloads iPhone IPSW files, merges cloudOS components, and extracts necessary binaries. - Boot-Chain Patching – Located in
sources/FirmwarePatcher/, modules likeKernelJBPatcher.swiftandTXMPatcher.swiftapply binary patches to bypass security mechanisms. - DFU Restore –
sources/vphone-cli/VPhoneRestoreCLI.swifthandles restoring patched firmware onto the VM via vsock using thevphonedguest daemon. - Custom Firmware Installation –
sources/vphone-cli/VPhoneCFWCLI.swiftmanages host-mounting CFW, re-signing binaries, and installing packages like Sileo. - VM Launch –
sources/vphone-cli/VPhoneVirtualMachine.swiftandVPhoneVirtualMachineView.swiftinitialize the GUI window and expose touch, keyboard, and clipboard integration.
The entry point in sources/vphone-cli/main.swift uses Apple's ArgumentParser library to dispatch commands to these modules. All VM state persists under ~/.vphone/ unless overridden by the $VPHONE_ROOT environment variable.
Creating Your First Virtual iOS Machine
The fastest way to use vphone-cli is the automated creation command, which executes the entire pipeline in sequence:
vphone-cli vm create myphone -V jb
This single command creates a VM bundle named "myphone" with the jailbreak variant (jb), automatically running fw prepare, fw patch, DFU restore, CFW installation, and the first boot. Available variants include less, regular, dev, jb, and exp, with each adding progressively more patches to bypass security features.
Step-by-Step Manual Workflow
For granular control over the virtualization process, execute each stage individually using the corresponding sub-commands:
# Initialize an empty VM bundle
vphone-cli vm new myphone
# Download and prepare firmware for iOS 26.1
vphone-cli fw prepare myphone --iphone-version 26.1
# Apply developer variant patches (disables certain AMFI checks)
vphone-cli fw patch myphone --variant dev
# Boot into DFU mode for firmware restoration
vphone-cli vm launch myphone --dfu &
# Fetch SHSH blobs for signing verification
vphone-cli restore myphone --get-shsh
# Perform DFU restore with patched firmware
vphone-cli restore myphone
# Stop the DFU boot process
vphone-cli vm stop myphone
# Install custom firmware with developer patches
vphone-cli cfw install myphone --variant dev
# Launch the virtual iPhone with GUI
vphone-cli vm launch myphone
Each command maps to specific functions in the CLI source files. For example, fw patch invokes the patcher modules in sources/FirmwarePatcher/ to modify kernelcache and other boot objects, while restore communicates with the guest daemon vphoned through vsock sockets.
Configuring VM Networking and Resources
Modify VM settings using the vm config command before launching. The tool supports three networking modes: NAT (default), bridged, or disabled.
# Configure bridged networking on interface en0
vphone-cli vm config myphone --network bridged --bridgeInterface en0
# View VM metadata in JSON format for scripting
vphone-cli vm info myphone --json
# List all existing VM bundles with resource allocation
vphone-cli vm list
These operations are handled by VPhoneVMCLI.swift, which wraps VZVirtualMachineConfiguration from Virtualization.framework to apply hardware settings persistently to the bundle.
Programmatic Control via Host Socket
Running VMs expose a Unix domain socket at <bundle>/vphone.sock that enables programmatic interaction. The VPhoneControl.swift module implements the host-side vsock client that communicates with the guest vphoned daemon.
# Take a screenshot via the control socket
cat /path/to/bundle/vphone.sock | nc -U - <<'EOF'
{"type":"screenshot"}
EOF > screenshot.png
This socket interface supports touch events, keyboard input, clipboard synchronization, and display capture, allowing automation frameworks to interact with the virtual iOS device without GUI manipulation.
Exporting and Importing VM Bundles
Transfer virtual machines between hosts using compressed archives:
# Export with ZSTD compression for efficient storage
vphone-cli vm export myphone --out myphone.tzst
# Import on another machine
vphone-cli vm import myphone.tzst --name restored
The export functionality preserves the complete VM state including disk images, firmware patches, and configuration metadata stored in the bundle directory.
Summary
- vphone-cli automates iOS virtualization through a pipeline of firmware preparation, patching, restoration, and launch stages implemented across specialized Swift modules.
- The tool stores VM bundles under
~/.vphone/(configurable via$VPHONE_ROOT) and usesArgumentParserinmain.swiftto handle CLI dispatch. - Five firmware variants (
less,regular,dev,jb,exp) provide increasing levels of security bypass via binary patchers likeKernelJBPatcher.swiftandTXMPatcher.swift. - Host-guest communication occurs through a Unix socket (
vphone.sock) managed byVPhoneControl.swift, enabling screenshot capture, input injection, and automation. - VMs support NAT, bridged, or disabled networking modes configured through
vm config, and can be exported/imported using ZSTD-compressed archives.
Frequently Asked Questions
What hardware is required to run vphone-cli?
vphone-cli requires a Mac with Apple Silicon (M1 or later) and macOS 12.0 or newer to leverage the Virtualization.framework. You must also disable System Integrity Protection (SIP) and AMFI to allow the tool to load patched kernels and modified trust caches, as documented in the repository's README prerequisites.
How do the firmware variants (less, regular, dev, jb, exp) differ?
Each variant applies a specific set of binary patches defined in sources/FirmwarePatcher/. The less variant applies minimal patches, while regular disables basic security checks. The dev variant enables developer debugging features, jb (jailbreak) bypasses code signing and enables root access, and exp includes experimental patches that may affect stability. The patch comparison matrix in research/0_binary_patch_comparison.md details exactly which bytes are modified in each boot object.
Can I automate vphone-cli in shell scripts or CI pipelines?
Yes. All vphone-cli commands return appropriate exit codes and support JSON output via the --json flag (available on vm info and similar commands). The tool is designed for scriptability, with the host-control socket (vphone.sock) providing a programmatic interface for touch injection and screenshot capture without GUI dependencies, making it suitable for automated iOS testing workflows.
How does vphone-cli handle iOS version updates?
Use vphone-cli fw prepare with the --iphone-version flag to download and stage new IPSW files for an existing VM bundle. After preparation, you must re-run fw patch to apply your selected variant's patches to the new firmware, then perform a DFU restore using vphone-cli restore. The CFW installation step (cfw install) ensures user-space modifications like package managers persist across firmware updates.
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 →