Boot a Virtual iPhone via Apple's Virtualization.framework

Aug 29, 2026 06:02 AM - 6 hours ago 4

Boot a virtual iPhone via Apple's Virtualization.framework utilizing PCC investigation VM infrastructure.

poc

Host:

  • Apple Silicon
  • macOS 15+ (Sequoia)
  • Xcode + iOS SDK (cross-compiles the impermanent daemon)
  • SIP/AMFI relaxation to let backstage PV=3 entitlements pinch unsigned-binary

Dependencies:

brew instal [email protected] aria2 wget gnu-tar openssl@3 ldid-procursus sshpass keystone cmake libusb ipsw zstd
brew instal zqxwce/tap/vphone-cli
git clone --recurse-submodules https://github.com/Lakr233/vphone-cli.git ./scripts/setup_tools.sh # instal deps, build toolchain submodules, create the Python venv ./scripts/build.sh # build + motion vphone-cli, bundle the .app, cross-compile vphoned cd .build/vphone-cli.app/Contents/MacOS/ vphone-cli --help

One bid creates a VM end-to-end (download → spot → DFU reconstruct → CFW instal → first boot):

vphone-cli vm create myphone -V jb # -V / --variant vphone-cli vm motorboat myphone

vphone-cli vm create runs the full pipeline; the individual steps beneath fto you thrust it manually aliases re-run 1 stage.

vphone-cli vm database # database VMs (--json for scripting) vphone-cli vm info myphone # show 1 VM vphone-cli vm caller myphone # create an quiet bundle (cpu/mem/disk options) vphone-cli vm config myphone --cpu 8 --memory 8192 vphone-cli vm clone myphone myphone-2 # accelerated APFS clone, caller instrumentality identity vphone-cli vm export myphone --out myphone.tzst # zstd accelerated by default (--max = xz -9); --out whitethorn beryllium a dir (auto-names <vm>.tzst/.txz); skips reconstruct dir + staging files vphone-cli vm import myphone.tzst --name restored vphone-cli vm rename myphone iphone16 vphone-cli vm delete iphone16

Build a VM manually (what vm create automates)

vphone-cli vm caller myphone # 1. quiet bundle vphone-cli fw hole myphone --iphone-version 26.1 # 2. download + merge IPSWs vphone-cli fw spot myphone --variant jb # 3. spot the footwear chain vphone-cli vm motorboat myphone --dfu & # 4. footwear into DFU (background) vphone-cli reconstruct myphone --get-shsh # fetch SHSH vphone-cli reconstruct myphone # DFU restore vphone-cli vm extremity myphone # extremity the DFU boot vphone-cli cfw instal myphone --variant jb # 5. instal CFW (host-mount; asks for sudo) vphone-cli vm motorboat myphone # 6. first boot

Update to a newer iOS by pointing fw hole astatine an IPSW: --iphone-source /path/to.ipsw --cloudos-source /path/to.ipsw.

Five spot variants pinch expanding information bypass — walk 1 to --variant:

Variant Boot Chain CFW Notes
less 4 patches 2 phases Patchless — keeps iOS mitigations enabled
regular 42 patches 10 phases AMFI/SSV/Img4/TXM bypass
dev 53 patches 12 phases + TXM entitlement/debug bypass
jb 113 patches 14 phases + afloat jailbreak (Sileo, TrollStore auto-install connected first boot)
exp 141 patches 18 phases JB superset + anti-VM-detection investigation patches

See research/0_binary_patch_comparison.md for the per-component breakdown.

  • SSH (jailbreak): ssh -p 22222 mobile@<vm-ip> (password alpine)
  • SSH (regular/dev): ssh -p 22222 root@<vm-ip>
  • VNC: vnc://<vm-ip>:5901

Everything vphone-cli creates lives nether ~/.vphone/ — kept extracurricular the repo and the .app truthful the signed bundle stays portable. Redirect the full character pinch $VPHONE_ROOT:

Path Contents
~/.vphone/ The per-user information guidelines — override the full location pinch $VPHONE_ROOT.
~/.vphone/VMs/ VM bundles — 1 directory per VM. This is the library; override pinch $VPHONE_LIBRARY_ROOT.
~/.vphone/ipsws/ Downloaded iPhone + cloudOS IPSWs, cached and reused crossed VMs.
~/.vphone/tools/ Cached APFS seal-volume artifacts (apfs_sealvolume_<version>) fetched during fw prepare.
~/.vphone/debs/ Cached .deb packages the jb/exp CFW instal lays into the impermanent (Sileo, apt, …).
~/.vphone/venv/ Auto-provisioned Python situation (see Python runtime; override pinch $VPHONE_VENV_DIR).

Precedence: the per-item overrides ($VPHONE_LIBRARY_ROOT, $VPHONE_VENV_DIR) triumph complete $VPHONE_ROOT, which wins complete the ~/.vphone default. The ipsws/, tools/, and debs/ caches ever beryllium straight nether whichever guidelines is active.

Option A — afloat disable SIP, past disable AMFI via boot-arg (most permissive).

In Recovery (long-press powerfulness → Terminal):

csrutil disable csrutil allow-research-guests enable

Then reboot into macOS and group the AMFI boot-arg (needs SIP afloat disconnected to return effect):

sudo nvram boot-args="amfi_get_out_of_my_way=1 -v" # reboot after

Option B — support SIP connected (debug-only relaxed), past allowlist the binary pinch amfidont (leaves AMFI enabled system-wide).

In Recovery:

csrutil enable --without debug csrutil allow-research-guests enable

Then reboot into macOS and:

vphone-amfidont # .build/vphone-cli.app/Contents/Resources/vphone-amfidont for section builds
Host iPhone CloudOS
Mac16,11 27.0b2 17,3_18.6.2_22G100 26.1-23B85
Mac16,8 26.5.1 17,3_26.0_23A341 26.1-23B85
Mac16,8 26.5.1 17,3_26.0.1_23A355 26.1-23B85
Mac16,12 26.3 17,3_26.1_23B85 26.1-23B85
Mac16,12 26.3 17,3_26.3_23D127 26.1-23B85
Mac16,12 26.3 17,3_26.3_23D127 26.3-23D128
Mac16,12 26.3 17,3_26.3.1_23D8133 26.3-23D128
Mac16,11 26.2 17,3_26.4_23E246 26.4-23E5207q
Mac16,11 26.2 17,3_26.5_23F77 26.4-23E5207q
Mac16,11 27.0b2 17,3_26.5.2_23F84 26.4-23E5207q
Mac16,6 26.4.1 17,3_26.6_23G71 26.4-23E5207q
Mac16,11 27.0b2 17,3_26.6.1_23G83 26.4-23E5207q
Mac16,11 27.0b2 17,3_27.0_24A5380h 26.4-23E5207q
Mac16,6 26.4.1 17,3_27.0_24A5390f 26.4-23E5207q
Mac16,6 26.6.1 17,3_27.0_24A5408d 26.4-23E5207q
Mac16,11 27.0b2 17,3_27.0_24A5418b 26.4-23E5207q
Mac16,11 27.0b2 17,3_27.0_24A5424a 26.4-23E5207q

zsh: killed ./vphone-cli — AMFI/debug restrictions aren't bypassed; spot Prerequisites (amfi_get_out_of_my_way=1 aliases amfidont).

Virtualization is not disposable connected this hardware — your Mac is itself a VM; PV=3 impermanent footwear can't nest. Use a non-nested macOS 15+ host.

Stuck connected "Press location to continue" — link via VNC and right-click (two-finger click) to simulate the location button.

System apps won't install — during iOS setup, don't prime Japan aliases the EU arsenic your region (extra regulatory checks the VM can't satisfy); prime e.g. United States.

App crashes connected motorboat pinch EXC_GUARD / GUARD_TYPE_MACH_PORT — re-patch pinch vphone-cli fw spot <name> --variant <v> --force-exc-guard, past re-restore/install (#291). Always connected for iOS 18 bases.

Install a .ipa/.tipa — usage the moving VM's Install paper (drag-drop aliases record picker).

cfw instal hangs re-signing a strategy binary (e.g. Campo), representation climbing unbounded — known bug successful ldid-procursus up to 2.1.5-procursus7 (the existent Homebrew stable): bytes(uint64_t) calls __builtin_clzll(0) pinch nary zero-guard, which is undefined behavior, and connected this build resolves to a 0-length that underflows an unsigned loop antagonistic — ldid spins penning 1 byte astatine a clip into a increasing buffer alternatively of terminating. Triggered by any entitlements plist containing an integer worth of precisely 0 (some existent Apple strategy binaries person these). Fixed upstream but not yet successful a tagged release; rebuild from source: brew instal --HEAD ldid-procursus && brew nexus --overwrite ldid-procursus. Kill the hung ldid process first (sudo termination -9 <pid>) if you already deed it.

vphone-cli exposes a big power socket (<bundle>/vphone.sock) for programmatic power — screenshots, touch, swipes, hardware keys, clipboard — each action returning an inline screenshot for AI-driven E2E testing. See vphone-mcp for an MCP server wrapping it.

  • wh1te4ever/super-tart-vphone-writeup
More