通过 Apple 的 Virtualization.framework 启动虚拟 iPhone
Boot a Virtual iPhone via Apple's Virtualization.framework

原始链接: https://github.com/Lakr233/vphone-cli

本指南概述了如何使用 `vphone-cli` 工具在 Apple Silicon 上引导虚拟化 iPhone。 **设置:** 通过 Homebrew 安装依赖项,克隆存储库,并运行 `./scripts/build.sh` 以编译工具链并打包应用程序。 **使用:** 该工具将整个虚拟化流程简化为一条命令: `vphone-cli vm create -V jb` 此命令可处理下载、打补丁、DFU 恢复以及自定义固件 (CFW) 的安装。各步骤也可手动执行以进行精细控制。可用的补丁版本从 "less"(最小化补丁)到 "exp"(反虚拟机检测及安全绕过)不等。 **主要功能:** * **存储:** 虚拟机数据位于 `~/.vphone/`,可通过 `$VPHONE_ROOT` 进行重定向。 * **交互:** 通过 SSH (端口 22222) 或 VNC (端口 5901) 访问虚拟机。 * **自动化:** 主机控制套接字 (`vphone.sock`) 支持程序化交互,包括截图和模拟输入,适用于人工智能驱动的测试。 **要求:** 需要一台运行 macOS 15+ 的物理主机。为处理 Apple 的 AMFI 安全机制,用户必须禁用 SIP 并设置 `amfi_get_out_of_my_way` 启动参数,或使用 `vphone-amfidont` 工具将二进制文件加入白名单。设置时请确保地区设置为美国,以避免监管问题。

GitHub 用户 lakr233 的一个新项目出现在 Hacker News 上,展示了利用苹果原生 `Virtualization.framework` 引导启动虚拟 iPhone 的能力。 社区讨论强调了该项目在逆向工程和测试方面的潜力。评论者阐明了该方法与标准 Xcode 模拟器之间的关键技术区别:模拟器为了节省资源,直接在宿主机上使用原生指令集运行应用;而真正的虚拟化则运行独立的内核和用户空间,提供了更真实的运行环境。 讨论还涉及了苹果的“私有云端计算”(Private Cloud Compute,简称 PCC),这是近日 Reddit 上讨论的一个话题。参与者指出,即将推出的 iOS 和 macOS 版本将允许开发者通过 Swift 直接调用 PCC,从而可能为应用程序集成基于云端的推理能力。
相关文章

原文

Boot a virtual iPhone via Apple's Virtualization.framework using PCC research VM infrastructure.

poc

Host:

Dependencies:

brew install [email protected] aria2 wget gnu-tar openssl@3 ldid-procursus sshpass keystone cmake libusb ipsw zstd
brew install zqxwce/tap/vphone-cli
git clone --recurse-submodules https://github.com/Lakr233/vphone-cli.git

./scripts/setup_tools.sh      # install deps, build toolchain submodules, create the Python venv
./scripts/build.sh            # build + sign vphone-cli, bundle the .app, cross-compile vphoned

cd .build/vphone-cli.app/Contents/MacOS/
vphone-cli --help

One command creates a VM end-to-end (download → patch → DFU restore → CFW install → first boot):

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

vphone-cli vm launch myphone

vphone-cli vm create runs the whole pipeline; the individual steps below let you drive it manually or re-run one stage.

vphone-cli vm list                         # list VMs (--json for scripting)
vphone-cli vm info myphone                  # show one VM
vphone-cli vm new myphone                   # create an empty bundle (cpu/mem/disk options)
vphone-cli vm config myphone --cpu 8 --memory 8192
vphone-cli vm clone myphone myphone-2       # fast APFS clone, fresh device identity
vphone-cli vm export myphone --out myphone.tzst   # zstd fast by default (--max = xz -9); --out may be a dir (auto-names <vm>.tzst/.txz); skips restore 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 new myphone                              # 1. empty bundle
vphone-cli fw prepare myphone --iphone-version 26.1     # 2. download + merge IPSWs
vphone-cli fw patch myphone --variant jb                # 3. patch the boot chain

vphone-cli vm launch myphone --dfu &                    # 4. boot into DFU (background)
vphone-cli restore myphone --get-shsh                   #    fetch SHSH
vphone-cli restore myphone                              #    DFU restore
vphone-cli vm stop myphone                              #    stop the DFU boot

vphone-cli cfw install myphone --variant jb             # 5. install CFW (host-mount; asks for sudo)
vphone-cli vm launch myphone                            # 6. first boot

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

Five patch variants with increasing security bypass — pass one 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 + full jailbreak (Sileo, TrollStore auto-install on first boot)
exp 141 patches 18 phases JB superset + anti-VM-detection research 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 under ~/.vphone/ — kept outside the repo and the .app so the signed bundle stays portable. Redirect the whole tree with $VPHONE_ROOT:

Path Contents
~/.vphone/ The per-user data root — override the entire location with $VPHONE_ROOT.
~/.vphone/VMs/ VM bundles — one directory per VM. This is the library; override with $VPHONE_LIBRARY_ROOT.
~/.vphone/ipsws/ Downloaded iPhone + cloudOS IPSWs, cached and reused across VMs.
~/.vphone/tools/ Cached APFS seal-volume artifacts (apfs_sealvolume_<version>) fetched during fw prepare.
~/.vphone/debs/ Cached .deb packages the jb/exp CFW install lays into the guest (Sileo, apt, …).
~/.vphone/venv/ Auto-provisioned Python environment (see Python runtime; override with $VPHONE_VENV_DIR).

Precedence: the per-item overrides ($VPHONE_LIBRARY_ROOT, $VPHONE_VENV_DIR) win over $VPHONE_ROOT, which wins over the ~/.vphone default. The ipsws/, tools/, and debs/ caches always sit directly under whichever root is active.

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

In Recovery (long-press power → Terminal):

csrutil disable
csrutil allow-research-guests enable

Then reboot into macOS and set the AMFI boot-arg (needs SIP fully off to take effect):

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

Option B — keep SIP on (debug-only relaxed), then allowlist the binary with 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 local 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; see Prerequisites (amfi_get_out_of_my_way=1 or amfidont).

Virtualization is not available on this hardware — your Mac is itself a VM; PV=3 guest boot can't nest. Use a non-nested macOS 15+ host.

Stuck on "Press home to continue" — connect via VNC and right-click (two-finger click) to simulate the home button.

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

App crashes on launch with EXC_GUARD / GUARD_TYPE_MACH_PORT — re-patch with vphone-cli fw patch <name> --variant <v> --force-exc-guard, then re-restore/install (#291). Always on for iOS 18 bases.

Install a .ipa/.tipa — use the running VM's Install menu (drag-drop or file picker).

cfw install hangs re-signing a system binary (e.g. Campo), memory climbing unbounded — known bug in ldid-procursus up to 2.1.5-procursus7 (the current Homebrew stable): bytes(uint64_t) calls __builtin_clzll(0) with no zero-guard, which is undefined behavior, and on this build resolves to a 0-length that underflows an unsigned loop counter — ldid spins writing one byte at a time into a growing buffer instead of terminating. Triggered by any entitlements plist containing an integer value of exactly 0 (some real Apple system binaries have these). Fixed upstream but not yet in a tagged release; rebuild from source: brew install --HEAD ldid-procursus && brew link --overwrite ldid-procursus. Kill the hung ldid process first (sudo kill -9 <pid>) if you already hit it.

vphone-cli exposes a host control socket (<bundle>/vphone.sock) for programmatic control — 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.

联系我们 contact @ memedata.com