mirror of
https://github.com/Lakr233/vphone-cli.git
synced 2026-09-02 02:34:29 +00:00
docs: rewrite README make-free + re-translate ko/ja/zh
- README.md rewritten around the vphone-cli binary (no make): tested-env
matrix, two-path SIP/AMFI setup, firmware variants, commands, short flags,
and a Python-runtime section covering the auto-provisioned venv / portability
- docs/README_{ko,ja,zh}.md regenerated as full translations mirroring it
Co-Authored-By: Claude Opus 4.8 <[email protected]>
Claude-Session: https://claude.ai/code/session_01Y4VDqWf5pVakcFLqB23CKe
This commit is contained in:
committed by
zqxwce
co-authored by
Claude Opus 4.8
parent
37ee2943c6
commit
d5283b4186
@@ -4,6 +4,8 @@
|
||||
|
||||
Boot a virtual iPhone via Apple's Virtualization.framework using PCC research VM infrastructure.
|
||||
|
||||
Everything runs through the single `vphone-cli` binary — create, patch, restore, install, boot, and manage VMs. No `make` needed after building.
|
||||
|
||||

|
||||
|
||||
## Tested Environments
|
||||
@@ -24,351 +26,184 @@ Boot a virtual iPhone via Apple's Virtualization.framework using PCC research VM
|
||||
| Mac16,11 27.0b2 | `17,3_27.0_24A5380h` | `26.4-23E5207q` |
|
||||
| Mac16,6 25.4.1 | `17,3_27.0_24A5390f` | `26.4-23E5207q` |
|
||||
|
||||
iOS <= 26.0.1 use the 26.1 PCC vphone600 stack plus the CFW-time `IOMobileFramebuffer` SwapEnd payload-size patch.
|
||||
iOS ≤ 26.0.1 use the 26.1 PCC vphone600 stack plus the CFW-time `IOMobileFramebuffer` SwapEnd payload-size patch. iOS 27.0 uses the 26.4 PCC vphone600 stack plus the CFW-time force-kern `IOMobileFramebuffer` present-path patch and the dyld shared-cache `maxSlide` fit.
|
||||
|
||||
iOS 27.0 uses the 26.4 PCC vphone600 stack plus the CFW-time force-kern `IOMobileFramebuffer` present-path patch and the dyld shared-cache `maxSlide` fit.
|
||||
|
||||
**Note:** GPU/Metal acceleration does not work on iOS 18.x — the 18.x Metal/IOGPU framework has no paravirtualized GPU implementation, so Metal-rendered content (web pages, images, wallpaper) does not render. Touch, networking, and apps work normally.
|
||||
> **Note:** GPU/Metal acceleration does not work on iOS 18.x — the 18.x Metal/IOGPU framework has no paravirtualized GPU implementation, so Metal-rendered content (web pages, images, wallpaper) does not render. Touch, networking, and apps work normally.
|
||||
|
||||
## Firmware Variants
|
||||
|
||||
Five patch variants are available with increasing levels of security bypass:
|
||||
Five patch variants with increasing security bypass — pass one to `--variant`:
|
||||
|
||||
| Variant | Boot Chain | CFW | Make Targets |
|
||||
| ---------------- | :------------: | :--------: | ----------------------------------- |
|
||||
| **Patchless** | 4 patches | 2 phases | `fw_patch_less` + `boot_less` |
|
||||
| **Regular** | 42 patches | 10 phases | `fw_patch` + `cfw_install` |
|
||||
| **Development** | 53 patches | 12 phases | `fw_patch_dev` + `cfw_install_dev` |
|
||||
| **Jailbreak** | 113 patches | 14 phases | `fw_patch_jb` + `cfw_install_jb` |
|
||||
| **Experimental** | 141 patches | 18 phases | `fw_patch_exp` + `cfw_install_exp` |
|
||||
| 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 |
|
||||
|
||||
> JB finalization (symlinks, Sileo, apt, TrollStore) runs automatically on first boot via `/cores/vphone_jb_setup.sh` LaunchDaemon. Monitor progress: `/var/log/vphone_jb_setup.log`.
|
||||
|
||||
> **Experimental (EXP)** is a JB superset that patches the kernel and DSC to make some Apple services think the device is not a VM, while keeping VM-specific services (graphics passthrough, compute/accel fast paths) working correctly. Other variants are deliberately NOT affected.
|
||||
|
||||
See [research/0_binary_patch_comparison.md](./research/0_binary_patch_comparison.md) for the detailed per-component breakdown.
|
||||
See [`research/0_binary_patch_comparison.md`](./research/0_binary_patch_comparison.md) for the per-component breakdown.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
**Host OS:** macOS 15+ (Sequoia) is required for PV=3 virtualization.
|
||||
**Host:** macOS 15+ (Sequoia), a non-nested Mac (Virtualization.framework can't nest). The private PV=3 entitlements + unsigned-binary workflow need SIP/AMFI relaxed. Pick **one** of these two paths — the SIP setting and the AMFI setting go together, don't mix them:
|
||||
|
||||
**Configure SIP/AMFI** — required for private Virtualization.framework entitlements and unsigned binary workflows.
|
||||
|
||||
Boot into Recovery (long press power button), open Terminal, then choose one setup path:
|
||||
|
||||
- **Option 1: Fully disable SIP + AMFI boot-arg (most permissive)**
|
||||
|
||||
In Recovery:
|
||||
|
||||
```bash
|
||||
csrutil disable
|
||||
csrutil allow-research-guests enable
|
||||
```
|
||||
|
||||
After restarting into macOS:
|
||||
|
||||
```bash
|
||||
sudo nvram boot-args="amfi_get_out_of_my_way=1 -v"
|
||||
```
|
||||
|
||||
Restart once more.
|
||||
|
||||
- **Option 2: Keep SIP mostly enabled, disable only debug restrictions, use [`amfidont`](https://github.com/zqxwce/amfidont) or [`amfree`](https://github.com/retX0/amfree)**
|
||||
|
||||
In Recovery:
|
||||
|
||||
```bash
|
||||
csrutil enable --without debug
|
||||
csrutil allow-research-guests enable
|
||||
```
|
||||
|
||||
After restarting into macOS:
|
||||
|
||||
```bash
|
||||
# Using amfidont:
|
||||
xcrun python3 -m pip install amfidont
|
||||
sudo amfidont --path [PATH_TO_VPHONE_DIR]
|
||||
|
||||
# OR Using amfree:
|
||||
brew install retX0/tap/amfree
|
||||
sudo amfree --path [PATH_TO_VPHONE_DIR]
|
||||
```
|
||||
|
||||
Repo helper (for amfidont):
|
||||
|
||||
```bash
|
||||
make amfidont_allow_vphone
|
||||
```
|
||||
|
||||
This helper computes the current signed `vphone-cli` CDHash and uses the
|
||||
URL-encoded project path form observed by `AMFIPathValidator`.
|
||||
|
||||
> The Patchless variant requires either the use of option 1 or amfidont with the `-S` flag (`sudo amfidont -S --path [PATH_TO_VPHONE_DIR]`)
|
||||
|
||||
**Install dependencies:**
|
||||
|
||||
*You will need both brew dependencies and Git Submodule dependencies.*
|
||||
|
||||
1. Brew dependencies:
|
||||
**Option A — fully disable SIP, then disable AMFI via boot-arg (most permissive).** In Recovery (long-press power → Terminal):
|
||||
|
||||
```bash
|
||||
brew install aria2 wget gnu-tar openssl@3 ldid-procursus sshpass keystone libusb ipsw zstd
|
||||
csrutil disable
|
||||
csrutil allow-research-guests enable
|
||||
```
|
||||
|
||||
`scripts/fw_prepare.sh` prefers `aria2c` for faster multi-connection downloads and falls back to `curl` or `wget` when needed.
|
||||
Then reboot into macOS and set the AMFI boot-arg (needs SIP fully off to take effect):
|
||||
|
||||
2. Git Submodules
|
||||
```bash
|
||||
sudo nvram boot-args="amfi_get_out_of_my_way=1 -v" # reboot after
|
||||
```
|
||||
|
||||
**Submodules** — this repo uses git submodules for resources, vendored Swift deps, and toolchain sources under `scripts/repos/`. Clone with:
|
||||
**Option B — keep SIP on (debug-only relaxed), then allowlist the binary with amfidont** (leaves AMFI enabled system-wide). In Recovery:
|
||||
|
||||
```bash
|
||||
csrutil enable --without debug
|
||||
csrutil allow-research-guests enable
|
||||
```
|
||||
|
||||
Then reboot into macOS and allowlist the repo with [`amfidont`](https://github.com/zqxwce/amfidont) (or [`amfree`](https://github.com/retX0/amfree)):
|
||||
|
||||
```bash
|
||||
sudo amfidont --path <repo>
|
||||
```
|
||||
|
||||
> The `less` (patchless) variant needs Option A, or Option B with `amfidont -S` (`sudo amfidont -S --path <repo>`).
|
||||
|
||||
**Dependencies:**
|
||||
|
||||
```bash
|
||||
git clone --recurse-submodules https://github.com/Lakr233/vphone-cli.git
|
||||
brew install [email protected] aria2 wget gnu-tar openssl@3 ldid-procursus sshpass keystone libusb ipsw zstd
|
||||
```
|
||||
|
||||
(A modern `python3` — 3.11+ — is required; the app builds its own Python environment from it, see [Python runtime](#python-runtime).)
|
||||
|
||||
## Build
|
||||
|
||||
Two one-time bootstrap scripts (a compiled binary can't build itself), then everything is `vphone-cli`:
|
||||
|
||||
```bash
|
||||
./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
|
||||
```
|
||||
|
||||
Put the binary on your `PATH` so the examples below work verbatim:
|
||||
|
||||
```bash
|
||||
cd .build/release
|
||||
vphone-cli --help
|
||||
```
|
||||
|
||||
## Quick Start
|
||||
|
||||
```bash
|
||||
make setup_machine # full automation through "First Boot" (includes restore/CFW)
|
||||
# options: NON_INTERACTIVE=1 SUDO_PASSWORD=...
|
||||
# LESS=1 for patchless variant (- AMFI, SSV, Img4, TXM bypasses)
|
||||
# DEV=1 for dev variant (+ TXM entitlement/debug bypasses)
|
||||
# JB=1 for jailbreak variant (+ full security bypass)
|
||||
# EXP=1 for experimental variant (JB + research patches: hv_vmm rename, DT identity, post-restore rewrite)
|
||||
# SPOOF_BUILD=<id> (EXP only) Rewrite SystemVersion.plist ProductBuildVersion to <id>, e.g. 23F77
|
||||
# export FORCE_EXC_GUARD=1 before running to force-enable the EXC_GUARD disable
|
||||
# patch on bases that don't need it to boot (see FAQ: EXC_GUARD crash on launch)
|
||||
```
|
||||
|
||||
## Manual Setup
|
||||
One command creates a VM end-to-end (download → patch → DFU restore → CFW install → first boot):
|
||||
|
||||
```bash
|
||||
make setup_tools # install brew deps, build trustcache + insert_dylib, create Python venv (pymobiledevice3, aria2c included)
|
||||
make build # build + sign vphone-cli
|
||||
make vm_new # create VM directory with manifest (config.plist)
|
||||
# options: CPU=8 MEMORY=8192 DISK_SIZE=64
|
||||
make fw_prepare # download IPSWs, extract, merge, generate manifest
|
||||
make fw_patch # patch boot chain (regular variant)
|
||||
# or: sudo make fw_patch_less # patchless variant (- AMFI, SSV, Img4, TXM bypasses)
|
||||
# or: make fw_patch_dev # dev variant (+ TXM entitlement/debug bypasses)
|
||||
# or: make fw_patch_jb # jailbreak variant (+ full security bypass)
|
||||
# or: make fw_patch_exp # experimental variant (JB + research stack)
|
||||
# add FORCE_EXC_GUARD=1 to fw_patch/fw_patch_jb/fw_patch_exp to force-enable the
|
||||
# EXC_GUARD (Mach port guard) disable patch on bases that don't need it to boot —
|
||||
# see FAQ: "My app crashes on launch with EXC_GUARD / GUARD_TYPE_MACH_PORT"
|
||||
vphone-cli vm create myphone -V jb # -V / --variant
|
||||
```
|
||||
|
||||
### Cleaning
|
||||
With no source flags it downloads a default tested iPhone + cloudOS pair. To choose specific firmware, pass **`-i`/`--iphone-source`** and **`-c`/`--cloudos-source`** — each takes either a **URL** or a **local `.ipsw` path** (see [Tested Environments](#tested-environments) for known-good pairs):
|
||||
|
||||
```bash
|
||||
make clean # remove build/tooling artifacts only
|
||||
make clean CLEAN_VM=1 # also remove vm/ after confirmation
|
||||
make clean CLEAN_IPSW=1 # also remove ipsws/ after confirmation
|
||||
# from local IPSWs
|
||||
vphone-cli vm create myphone -V jb \
|
||||
-i ~/ipsws/iPhone17,3_26.1_23B85_Restore.ipsw \
|
||||
-c ~/ipsws/cloudOS_26.1-23B85.ipsw
|
||||
|
||||
# or from URLs — downloaded and cached under ~/.vphone/ipsws
|
||||
vphone-cli vm create myphone -V jb \
|
||||
-i "https://updates.cdn-apple.com/.../iPhone17,3_26.1_23B85_Restore.ipsw" \
|
||||
-c "https://updates.cdn-apple.com/private-cloud-compute/<id>"
|
||||
```
|
||||
|
||||
Default clean never removes `vm/` or `ipsws/`.
|
||||
|
||||
### VM Configuration
|
||||
|
||||
Starting from v1.0, VM configuration is stored in `vm/config.plist`. Set CPU, memory, and disk size during VM creation:
|
||||
The CFW-install stage needs root (host disk mount) and will prompt for `sudo`; pass `-s <pw>` (`--sudo-password`) to run unattended. Add `-v` to watch the restore (pmd3 log, colorized), `-vv` for pmd3 debug detail, `-vvv` for vphone-cli's internal trace. Then boot it:
|
||||
|
||||
```bash
|
||||
# Create VM with custom configuration
|
||||
make vm_new CPU=16 MEMORY=16384 DISK_SIZE=128
|
||||
|
||||
# Boot automatically reads from config.plist
|
||||
make boot
|
||||
vphone-cli vm launch myphone
|
||||
```
|
||||
|
||||
The manifest stores all VM settings (CPU, memory, screen, ROMs, storage) and is compatible with [security-pcc's VMBundle.Config format](https://github.com/apple/security-pcc).
|
||||
VMs live in a **library** at `~/.vphone/VMs/` (override any command with `--library-root <dir>`). Run any VM command with no name (e.g. `vphone-cli vm launch`) to pick from a menu of your VMs.
|
||||
|
||||
## Restore
|
||||
## Commands
|
||||
|
||||
You'll need **two terminals** for the restore process. Keep terminal 1 running while using terminal 2.
|
||||
`vphone-cli vm create` runs the whole pipeline; the individual steps below let you drive it manually or re-run one stage.
|
||||
|
||||
### Manage
|
||||
|
||||
```bash
|
||||
# terminal 1
|
||||
make boot_dfu # boot VM in DFU mode (keep running)
|
||||
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.tar.xz # xz -9; skips restore dir + staging files
|
||||
vphone-cli vm import --in myphone.tar.xz --name restored
|
||||
vphone-cli vm rename myphone iphone16
|
||||
vphone-cli vm delete iphone16
|
||||
```
|
||||
|
||||
### Build a VM manually (what `vm create` automates)
|
||||
|
||||
```bash
|
||||
# terminal 2
|
||||
make restore_get_shsh # fetch SHSH blob
|
||||
make restore # flash firmware via pymobiledevice3 restore backend
|
||||
# or: make restore_offline # offline restore (decrypts AEA images in place, uses cached .shsh blob)
|
||||
# for the first time should be ran with internet access for AEA decryption
|
||||
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
|
||||
```
|
||||
|
||||
## Install Custom Firmware
|
||||
Update to a newer iOS by pointing `fw prepare` at an IPSW: `--iphone-source /path/to.ipsw --cloudos-source /path/to.ipsw`.
|
||||
|
||||
Once the restore completes, stop the DFU boot in terminal 1 (Ctrl+C) so the VM is
|
||||
fully powered off. The installer mounts the VM's `Disk.img` on the host, places
|
||||
all CFW files, and flips the boot snapshot offline — no DFU, ramdisk, or SSH — so
|
||||
it needs exclusive access to the disk.
|
||||
## Running & Connecting
|
||||
|
||||
```bash
|
||||
# terminal 2 (re-execs under sudo automatically)
|
||||
make cfw_install
|
||||
# or: make cfw_install_dev # development variant
|
||||
# or: make cfw_install_jb # jailbreak variant
|
||||
# or: make cfw_install_exp # experimental variant (JB + research stack)
|
||||
# or: SPOOF_BUILD=23F77 make cfw_install_exp # additionally rewrite ProductBuildVersion
|
||||
# or: FORCE_DSC_MAXSLIDE=1 make cfw_install # force DSC maxSlide=0 on a non-27 base (any variant; 27 does this automatically)
|
||||
```
|
||||
`vphone-cli vm launch <name>` opens the VM window; `vphone-cli vm stop <name>` shuts it down. The guest runs an SSH server (dropbear) on port `22222` and VNC on `5901`, reachable over the VM's NAT IP (find it with `arp -a` on `bridge100`):
|
||||
|
||||
## First Boot
|
||||
- **SSH (jailbreak):** `ssh -p 22222 mobile@<vm-ip>` (password `alpine`)
|
||||
- **SSH (regular/dev):** `ssh -p 22222 root@<vm-ip>`
|
||||
- **VNC:** `vnc://<vm-ip>:5901`
|
||||
|
||||
With the DFU boot stopped and CFW installed, boot the VM normally:
|
||||
For the `jb`/`exp` variants, Sileo and TrollStore are installed automatically on first boot (monitor `/var/log/vphone_jb_setup.log`).
|
||||
|
||||
```bash
|
||||
make boot
|
||||
```
|
||||
## Python runtime
|
||||
|
||||
After `cfw_install_jb`, the jailbreak variant will have **Sileo** and **TrollStore** available on first boot. You can use Sileo to install `openssh-server` for SSH access.
|
||||
|
||||
For the regular/development variant, the VM gives you a **direct console**. When you see `bash-4.4#`, press Enter and run these commands to initialize the shell environment and generate SSH host keys:
|
||||
|
||||
```bash
|
||||
export PATH='/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/bin/X11:/usr/games:/iosbinpack64/usr/local/sbin:/iosbinpack64/usr/local/bin:/iosbinpack64/usr/sbin:/iosbinpack64/usr/bin:/iosbinpack64/sbin:/iosbinpack64/bin'
|
||||
|
||||
mkdir -p /var/dropbear
|
||||
cp /iosbinpack64/etc/profile /var/profile
|
||||
cp /iosbinpack64/etc/motd /var/motd
|
||||
|
||||
# generate SSH host keys (required for SSH to work)
|
||||
dropbearkey -t rsa -f /var/dropbear/dropbear_rsa_host_key
|
||||
dropbearkey -t ecdsa -f /var/dropbear/dropbear_ecdsa_host_key
|
||||
|
||||
shutdown -h now
|
||||
```
|
||||
|
||||
> **Note:** Without the host key generation step, dropbear (SSH server) will accept connections but immediately close them because it has no keys to perform the SSH handshake.
|
||||
|
||||
## Subsequent Boots
|
||||
|
||||
```bash
|
||||
make boot
|
||||
```
|
||||
|
||||
In a separate terminal, start usbmux forward tunnels:
|
||||
|
||||
```bash
|
||||
python3 -m pymobiledevice3 usbmux forward 2222 22222 # SSH (dropbear)
|
||||
python3 -m pymobiledevice3 usbmux forward 2222 22 # SSH (JB: if you install openssh-server from Sileo)
|
||||
python3 -m pymobiledevice3 usbmux forward 5901 5901 # VNC
|
||||
python3 -m pymobiledevice3 usbmux forward 5910 5910 # RPC
|
||||
```
|
||||
|
||||
Connect via:
|
||||
|
||||
- **SSH (JB):** `ssh -p 2222 mobile@127.0.0.1` (password: `alpine`)
|
||||
- **SSH (Regular/Dev):** `ssh -p 2222 root@127.0.0.1` (password: `alpine`)
|
||||
- **VNC:** `vnc://127.0.0.1:5901`
|
||||
- [**RPC:**](http://github.com/doronz88/rpc-project) `rpcclient -p 5910 127.0.0.1`
|
||||
|
||||
## VM Backup & Switch
|
||||
|
||||
Save and switch between multiple VM environments (e.g. different iOS builds or firmware variants). Backups are stored in `vm.backups/` using `rsync --sparse` for efficient sparse disk handling.
|
||||
|
||||
```bash
|
||||
make vm_backup NAME=26.1-clean # save current VM
|
||||
rm -rf vm && make vm_new # start fresh for a different build
|
||||
# ... fw_prepare, fw_patch, restore, cfw_install, boot
|
||||
make vm_backup NAME=26.3-jb # save the new one too
|
||||
make vm_list # list all saved backups
|
||||
make vm_switch NAME=26.1-clean # swap between them
|
||||
```
|
||||
|
||||
> **Note:** Always stop the VM before backup/switch/restore.
|
||||
A few steps (DFU restore, IPSW handling) run through Python. On first use,
|
||||
vphone-cli provisions a self-contained venv at `~/.vphone/venv` from a modern
|
||||
host `python3` (3.11+) using the bundled `requirements.txt` — so the signed
|
||||
`.app` is **portable**: copy it anywhere (e.g. `/Applications`) and it runs
|
||||
without the repo. Provisioning is automatic; run `vphone-cli setup` to do it
|
||||
up front. Point at a specific interpreter with `VPHONE_PYTHON=/path/to/python3`,
|
||||
or relocate the venv with `VPHONE_VENV_DIR=/path`.
|
||||
|
||||
## FAQ
|
||||
|
||||
> **Before anything else — run `git pull` to make sure you have the latest version.**
|
||||
**`zsh: killed ./vphone-cli`** — AMFI/debug restrictions aren't bypassed; see [Prerequisites](#prerequisites) (`amfi_get_out_of_my_way=1` or `amfidont`).
|
||||
|
||||
**Q: I get `zsh: killed ./vphone-cli` when trying to run it.**
|
||||
**`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.
|
||||
|
||||
AMFI/debug restrictions are not bypassed correctly. Choose one setup path:
|
||||
**Stuck on "Press home to continue"** — connect via VNC and right-click (two-finger click) to simulate the home button.
|
||||
|
||||
- **Option 1 (full AMFI disable):**
|
||||
**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.
|
||||
|
||||
```bash
|
||||
sudo nvram boot-args="amfi_get_out_of_my_way=1 -v"
|
||||
```
|
||||
**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](https://github.com/Lakr233/vphone-cli/issues/291)). Always on for iOS 18 bases.
|
||||
|
||||
- **Option 2 (debug restrictions only):**
|
||||
use Recovery mode `csrutil enable --without debug` (no full SIP disable), then install/load [`amfidont`](https://github.com/zqxwce/amfidont) or [`amfree`](https://github.com/retX0/amfree) while keeping AMFI otherwise enabled.
|
||||
For this repo, `make amfidont_allow_vphone` packages the required encoded-path
|
||||
and CDHash allowlist startup (if using amfidont).
|
||||
|
||||
**Q: `make boot` / `make boot_dfu` starts and then fails with `VZErrorDomain Code=2 "Virtualization is not available on this hardware."`**
|
||||
|
||||
The host itself is running inside an Apple virtual machine, so nested
|
||||
Virtualization.framework guest boot is unavailable. Run the boot flow on a
|
||||
non-nested macOS 15+ host instead. `make boot_host_preflight` will show this as
|
||||
`Model Name: Apple Virtual Machine 1` with `kern.hv_vmm_present=1`.
|
||||
`make boot` / `make boot_dfu` now fail fast through `boot_binary_check` before
|
||||
attempting VM startup on that kind of host.
|
||||
|
||||
**Q: System apps (App Store, Messages, etc.) won't download or install.**
|
||||
|
||||
During iOS setup, do **not** select **Japan** or **European Union** as your region. These regions enforce additional regulatory checks (e.g., sideloading disclosures, camera shutter requirements) that the virtual machine cannot satisfy, which prevents system apps from being downloaded and installed. Choose any other region (e.g., United States) to avoid this issue.
|
||||
|
||||
**Q: I'm stuck on the "Press home to continue" screen.**
|
||||
|
||||
Connect via VNC (`vnc://127.0.0.1:5901`) and right-click anywhere on the screen (two-finger click on a Mac trackpad). This simulates the home button press.
|
||||
|
||||
**Q: How do I get SSH access?**
|
||||
|
||||
Install `openssh-server` from Sileo (available on the jailbreak variant after first boot).
|
||||
|
||||
**Q: SSH doesn't work after installing openssh-server.**
|
||||
|
||||
Reboot the VM. The SSH server will start automatically on the next boot.
|
||||
|
||||
**Q: Can I install `.tipa` files?**
|
||||
|
||||
Yes. The install menu supports both `.ipa` and `.tipa` packages. Drag and drop or use the file picker.
|
||||
|
||||
**Q: My app crashes on launch with `EXC_GUARD` / `GUARD_TYPE_MACH_PORT` (e.g. `KOBJECT_REPLY_PORT_SEMANTICS`).**
|
||||
|
||||
Some third-party apps that bundle a crash-reporting or RASP SDK call `task_swap_exception_ports()` on launch to install their own exception handler. On bases where this isn't required for the VM itself to boot, the research kernel can enforce that as a fatal Mach port guard violation instead of the silent/non-fatal behavior production iOS exhibits for this call pattern (see [issue #291](https://github.com/Lakr233/vphone-cli/issues/291)).
|
||||
|
||||
Re-patch with the guard disable force-enabled, then re-flash:
|
||||
|
||||
```bash
|
||||
make fw_prepare # reset to pristine firmware first
|
||||
make fw_patch_jb FORCE_EXC_GUARD=1 # or fw_patch / fw_patch_exp
|
||||
# ... boot_dfu, restore_get_shsh, restore, cfw_install_jb, boot as usual
|
||||
```
|
||||
|
||||
This is always on automatically for iOS 18 bases (needed there to boot at all) — the flag only matters for other bases where an app hits this specific crash.
|
||||
|
||||
**Q: Can I update to a newer iOS version?**
|
||||
|
||||
Yes. Override `fw_prepare` with the IPSW URL for the version you want:
|
||||
|
||||
```bash
|
||||
export IPHONE_SOURCE=/path/to/some_os.ipsw
|
||||
export CLOUDOS_SOURCE=/path/to/some_os.ipsw
|
||||
make fw_prepare
|
||||
make fw_patch
|
||||
```
|
||||
|
||||
Our patches are applied via binary analysis, not static offsets, so newer versions should work. If something breaks, ask AI for help.
|
||||
|
||||
**Q: I used `restore_offline` and I am stuck in the setup screen**
|
||||
|
||||
The device is trying to contact apple for the setup, and you are probably not connected to the internet if you used `restore_offline`.
|
||||
You can bypass most of the setup screen by making the device supervised:
|
||||
|
||||
```bash
|
||||
python3 -m pymobiledevice3 profile supervise vphone
|
||||
```
|
||||
**Install a `.ipa`/`.tipa`** — use the running VM's Install menu (drag-drop or file picker).
|
||||
|
||||
## Automation
|
||||
|
||||
vphone-cli exposes a host control socket (`vm/vphone.sock`) for programmatic VM interaction — screenshots, touch injection, swipe gestures, hardware keys, and clipboard. Every action returns a compact grayscale screenshot inline, enabling AI-driven E2E testing workflows.
|
||||
|
||||
See [vphone-mcp](https://github.com/pluginslab/vphone-mcp) for an MCP server that wraps this socket with high-level tools (open apps by name, navigate back, scroll, type text) usable from Claude Code or Claude Desktop.
|
||||
`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](https://github.com/pluginslab/vphone-mcp) for an MCP server wrapping it.
|
||||
|
||||
## Acknowledgements
|
||||
|
||||
|
||||
+119
-242
@@ -2,13 +2,15 @@
|
||||
|
||||
# vphone-cli
|
||||
|
||||
Apple の Virtualization.framework と PCC の研究用 VM インフラを使用して、仮想 iPhone を起動するためのツール
|
||||
PCC リサーチ VM インフラストラクチャを使用し、Apple の Virtualization.framework 経由で仮想 iPhone を起動します。
|
||||
|
||||
すべての処理は単一の `vphone-cli` バイナリを通じて実行されます — VM の作成、パッチ適用、復元、インストール、起動、管理。ビルド後は `make` は不要です。
|
||||
|
||||

|
||||
|
||||
## 検証済み環境
|
||||
## 動作確認済み環境
|
||||
|
||||
| ホスト | iPhone | CloudOS |
|
||||
| ホスト | 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` |
|
||||
@@ -24,303 +26,178 @@ Apple の Virtualization.framework と PCC の研究用 VM インフラを使用
|
||||
| Mac16,11 27.0b2 | `17,3_27.0_24A5380h` | `26.4-23E5207q` |
|
||||
| Mac16,6 25.4.1 | `17,3_27.0_24A5390f` | `26.4-23E5207q` |
|
||||
|
||||
iOS 27.0 は 26.4 PCC vphone600 スタックに加えて、CFW 時の force-kern `IOMobileFramebuffer` present-path パッチと dyld 共有キャッシュの `maxSlide` 調整を使用します。
|
||||
iOS ≤ 26.0.1 では 26.1 PCC vphone600 スタックと、CFW 適用時の `IOMobileFramebuffer` SwapEnd ペイロードサイズパッチを使用します。iOS 27.0 では 26.4 PCC vphone600 スタックと、CFW 適用時の force-kern `IOMobileFramebuffer` present-path パッチ、および dyld shared-cache の `maxSlide` フィットを使用します。
|
||||
|
||||
**注意:** iOS 18.x では Metal/GPU アクセラレーションは動作しません。18.x の Metal/IOGPU フレームワークに準仮想化 GPU の実装が存在しないため、Metal でレンダリングされるコンテンツ(Web ページ、画像、壁紙)は表示されません。タッチ、ネットワーク、アプリは正常に動作します。
|
||||
> **注意:** GPU/Metal アクセラレーションは iOS 18.x では動作しません — 18.x の Metal/IOGPU フレームワークには準仮想化 GPU 実装がないため、Metal でレンダリングされるコンテンツ(Web ページ、画像、壁紙)は描画されません。タッチ、ネットワーク、アプリは正常に動作します。
|
||||
|
||||
## ファームウェアバリアント
|
||||
|
||||
セキュリティバイパスのレベルが異なる5つのパッチバリアントが利用可能です:
|
||||
セキュリティバイパスの度合いが段階的に増す 5 つのパッチバリアント — いずれか 1 つを `--variant` に渡します:
|
||||
|
||||
| バリアント | ブートチェーン | CFW | Make ターゲット |
|
||||
| ------------- | :----------------: | :----------: | -------------------------------------------- |
|
||||
| **Patchless** | 4 パッチ | 2 フェーズ | `fw_patch_less` + `boot_less` |
|
||||
| **通常版** | 42 パッチ | 10 フェーズ | `fw_patch` + `cfw_install` |
|
||||
| **開発版** | 53 パッチ | 12 フェーズ | `fw_patch_dev` + `cfw_install_dev` |
|
||||
| **脱獄版** | 113 パッチ | 14 フェーズ | `fw_patch_jb` + `cfw_install_jb` |
|
||||
| **実験版** | 脱獄 + EXP 専用 | 脱獄 + EXP | `fw_patch_exp` + `cfw_install_exp` |
|
||||
| バリアント | ブートチェーン | CFW | 備考 |
|
||||
| ------------ | ----------- | --------- | ----------------------------------------------------------------- |
|
||||
| `less` | 4 patches | 2 phases | パッチなし — iOS の緩和策を有効なまま維持 |
|
||||
| `regular` | 42 patches | 10 phases | AMFI/SSV/Img4/TXM バイパス |
|
||||
| `dev` | 53 patches | 12 phases | + TXM エンタイトルメント/デバッグバイパス |
|
||||
| `jb` | 113 patches | 14 phases | + 完全な脱獄(Sileo、TrollStore を初回起動時に自動インストール) |
|
||||
| `exp` | 141 patches | 18 phases | JB のスーパーセット + VM 検出対策リサーチパッチ |
|
||||
|
||||
> JB最終設定(シンボリックリンク、Sileo、apt、TrollStore)は `/cores/vphone_jb_setup.sh` LaunchDaemon により初回起動時に自動実行されます。進捗確認:`/var/log/vphone_jb_setup.log`。
|
||||
|
||||
> **実験版(EXP)** は脱獄版の上位集合で、リサーチブランチの実験的パッチを追加で実行します:カーネルの `hv_vmm_present` sysctl リネーム + カーネル内部呼び出し元の改変(`KernelEXPPatcher`)、サインインブラックリスト付きの DSC バイト5改変 + スロット再認証、watchdogd 精密 2 命令パッチ(EXP-JB-3.5)、fw_patch 時点での DeviceTree アイデンティティプロパティ 8 件、復元後の DT アイデンティティ書き換え(EXP-JB-6)、`SPOOF_BUILD=<id>` によるオプトイン式の `SystemVersion.plist` `ProductBuildVersion` 書き換え(EXP-JB-7)。他のバリアントは意図的に影響を受けません。
|
||||
|
||||
詳細なコンポーネントごとの内訳については [research/0_binary_patch_comparison.md](../research/0_binary_patch_comparison.md) を参照してください。
|
||||
コンポーネントごとの内訳については [`research/0_binary_patch_comparison.md`](../research/0_binary_patch_comparison.md) を参照してください。
|
||||
|
||||
## 前提条件
|
||||
|
||||
**ホストOS:** PV=3 仮想化には macOS 15+(Sequoia)が必要です。
|
||||
**ホスト:** macOS 15+ (Sequoia)、ネストされていない Mac(Virtualization.framework はネストできません)。プライベートな PV=3 エンタイトルメント + 未署名バイナリのワークフローには SIP/AMFI の緩和が必要です。以下の 2 つの方法から **1 つ** を選んでください — SIP の設定と AMFI の設定はセットです。混在させないでください:
|
||||
|
||||
**SIP/AMFIの設定** — プライベートな Virtualization.framework の entitlement と未署名バイナリのワークフローに必要です。
|
||||
|
||||
復旧モードで起動し(電源ボタンを長押し)、ターミナルを開いて、以下のいずれかの方法を選択します:
|
||||
|
||||
- **方法 1:SIP を完全に無効化 + AMFI boot-arg(最も制限が少ない)**
|
||||
|
||||
復旧モードで:
|
||||
|
||||
```bash
|
||||
csrutil disable
|
||||
csrutil allow-research-guests enable
|
||||
```
|
||||
|
||||
通常の macOS に再起動した後:
|
||||
|
||||
```bash
|
||||
sudo nvram boot-args="amfi_get_out_of_my_way=1 -v"
|
||||
```
|
||||
|
||||
もう一度再起動します。
|
||||
|
||||
- **方法 2:SIP はほぼ有効のまま、デバッグ制限のみ無効化、[`amfidont`](https://github.com/zqxwce/amfidont) または [`amfree`](https://github.com/retX0/amfree) を使用**
|
||||
|
||||
復旧モードで:
|
||||
|
||||
```bash
|
||||
csrutil enable --without debug
|
||||
csrutil allow-research-guests enable
|
||||
```
|
||||
|
||||
通常の macOS に再起動した後:
|
||||
|
||||
```bash
|
||||
# amfidont の場合:
|
||||
xcrun python3 -m pip install amfidont
|
||||
sudo amfidont --path [PATH_TO_VPHONE_DIR]
|
||||
|
||||
# または amfree の場合:
|
||||
brew install retX0/tap/amfree
|
||||
sudo amfree --path [PATH_TO_VPHONE_DIR]
|
||||
```
|
||||
|
||||
このリポジトリでは、`make amfidont_allow_vphone` を実行すると
|
||||
`amfidont` 用のエンコード済みパスと CDHash の許可設定をまとめて行えます。
|
||||
|
||||
> Patchless バリアントでは、方法 1 か、`-S` フラグ付きの amfidont(`sudo amfidont -S --path [PATH_TO_VPHONE_DIR]`)が必要です。
|
||||
|
||||
**依存関係のインストール:**
|
||||
**オプション A — SIP を完全に無効化し、boot-arg で AMFI を無効化する(最も緩い)。** リカバリーモードで(電源ボタン長押し → ターミナル):
|
||||
|
||||
```bash
|
||||
brew install aria2 wget gnu-tar openssl@3 ldid-procursus sshpass keystone libusb ipsw zstd
|
||||
csrutil disable
|
||||
csrutil allow-research-guests enable
|
||||
```
|
||||
|
||||
`scripts/fw_prepare.sh` は高速な多重接続ダウンロードのために `aria2c` を優先し、必要に応じて `curl` または `wget` にフォールバックします。
|
||||
その後 macOS で再起動し、AMFI の boot-arg を設定します(有効化には SIP を完全に無効化する必要があります):
|
||||
|
||||
**Submodules** — このリポジトリはリソース、Swift 依存、`scripts/repos/` 配下のツールチェーンソースに git submodule を使用しています。クローン時に以下を使用してください:
|
||||
```bash
|
||||
sudo nvram boot-args="amfi_get_out_of_my_way=1 -v" # 後で再起動
|
||||
```
|
||||
|
||||
**オプション B — SIP を有効なまま(デバッグのみ緩和)にし、amfidont でバイナリを許可リストに追加する**(AMFI はシステム全体で有効なまま)。リカバリーモードで:
|
||||
|
||||
```bash
|
||||
csrutil enable --without debug
|
||||
csrutil allow-research-guests enable
|
||||
```
|
||||
|
||||
その後 macOS で再起動し、[`amfidont`](https://github.com/zqxwce/amfidont)(または [`amfree`](https://github.com/retX0/amfree))でリポジトリを許可リストに追加します:
|
||||
|
||||
```bash
|
||||
sudo amfidont --path <repo>
|
||||
```
|
||||
|
||||
> `less`(パッチなし)バリアントにはオプション A、またはオプション B に `amfidont -S` を組み合わせたもの(`sudo amfidont -S --path <repo>`)が必要です。
|
||||
|
||||
**依存関係:**
|
||||
|
||||
```bash
|
||||
git clone --recurse-submodules https://github.com/Lakr233/vphone-cli.git
|
||||
brew install [email protected] aria2 wget gnu-tar openssl@3 ldid-procursus sshpass keystone libusb ipsw zstd
|
||||
```
|
||||
|
||||
(最新の `python3` — 3.11+ — が必要です。アプリはそこから独自の Python 環境を構築します。[Python ランタイム](#python-ランタイム) を参照してください。)
|
||||
|
||||
## ビルド
|
||||
|
||||
一度きりのブートストラップスクリプトが 2 つあります(コンパイル済みバイナリは自分自身をビルドできないため)。その後はすべて `vphone-cli` で行います:
|
||||
|
||||
```bash
|
||||
./scripts/setup_tools.sh # 依存関係のインストール、ツールチェーンのサブモジュールのビルド、Python venv の作成
|
||||
./scripts/build.sh # vphone-cli のビルド + 署名、.app のバンドル、vphoned のクロスコンパイル
|
||||
```
|
||||
|
||||
以下の例をそのまま実行できるように、バイナリを `PATH` に追加します:
|
||||
|
||||
```bash
|
||||
cd .build/release
|
||||
vphone-cli --help
|
||||
```
|
||||
|
||||
## クイックスタート
|
||||
|
||||
```bash
|
||||
make setup_machine # 初回起動までを完全自動化(復元/CFWを含む)
|
||||
# オプション:NON_INTERACTIVE=1 SUDO_PASSWORD=...
|
||||
# LESS=1 で patchless バリアント(- AMFI, SSV, Img4, TXM バイパス)
|
||||
# DEV=1 で開発バリアント(+ TXM entitlement/デバッグバイパス)
|
||||
# JB=1 で脱獄バリアント(dev + 完全セキュリティバイパス)
|
||||
# EXP=1 で実験バリアント(脱獄 + リサーチパッチ: hv_vmm リネーム、DT アイデンティティ、復元後書き換え)
|
||||
# SPOOF_BUILD=<id>(EXP 限定)SystemVersion.plist の ProductBuildVersion を <id> に書き換え、例: 23F77
|
||||
```
|
||||
|
||||
## 手動セットアップ
|
||||
1 つのコマンドで VM をエンドツーエンドで作成します(ダウンロード → パッチ → DFU 復元 → CFW インストール → 初回起動):
|
||||
|
||||
```bash
|
||||
make setup_tools # brew 依存関係のインストール、trustcache + insert_dylib のビルド、Python venv 作成(pymobiledevice3/aria2c を含む)
|
||||
make build # vphone-cli のビルド + 署名
|
||||
make vm_new # VM ディレクトリとマニフェスト(config.plist)の作成
|
||||
# オプション:CPU=8 MEMORY=8192 DISK_SIZE=64
|
||||
make fw_prepare # IPSW のダウンロード、抽出、マージ、マニフェスト生成
|
||||
make fw_patch # ブートチェーンのパッチ当て(通常バリアント)
|
||||
# または: sudo make fw_patch_less # patchless バリアント(- AMFI, SSV, Img4, TXM バイパス)
|
||||
# または: make fw_patch_dev # 開発バリアント(+ TXM entitlement/デバッグバイパス)
|
||||
# または: make fw_patch_jb # 脱獄バリアント(dev + 完全セキュリティバイパス)
|
||||
# または: make fw_patch_exp # 実験バリアント(脱獄 + リサーチパッチスタック)
|
||||
vphone-cli vm create myphone -V jb # -V / --variant
|
||||
```
|
||||
|
||||
### クリーンアップ
|
||||
ソースフラグを指定しない場合、動作確認済みのデフォルトの iPhone + cloudOS ペアがダウンロードされます。特定のファームウェアを選ぶには **`-i`/`--iphone-source`** と **`-c`/`--cloudos-source`** を渡します — それぞれ **URL** または **ローカルの `.ipsw` パス** のいずれかを取ります(既知の良好なペアについては [動作確認済み環境](#動作確認済み環境) を参照):
|
||||
|
||||
```bash
|
||||
make clean # ビルド/ツール関連の生成物のみ削除
|
||||
make clean CLEAN_VM=1 # 確認後、vm/ も削除
|
||||
make clean CLEAN_IPSW=1 # 確認後、ipsws/ も削除
|
||||
# ローカルの IPSW から
|
||||
vphone-cli vm create myphone -V jb \
|
||||
-i ~/ipsws/iPhone17,3_26.1_23B85_Restore.ipsw \
|
||||
-c ~/ipsws/cloudOS_26.1-23B85.ipsw
|
||||
|
||||
# または URL から — ~/.vphone/ipsws 以下にダウンロードしてキャッシュ
|
||||
vphone-cli vm create myphone -V jb \
|
||||
-i "https://updates.cdn-apple.com/.../iPhone17,3_26.1_23B85_Restore.ipsw" \
|
||||
-c "https://updates.cdn-apple.com/private-cloud-compute/<id>"
|
||||
```
|
||||
|
||||
通常の clean では `vm/` や `ipsws/` は削除されません。
|
||||
|
||||
### VM 設定
|
||||
|
||||
v1.0 から、VM 設定は `vm/config.plist` に保存されます。VM 作成時に CPU、メモリ、ディスクサイズを設定します:
|
||||
CFW インストール段階は root 権限(ホストディスクのマウント)が必要で、`sudo` の入力を求めます。無人で実行するには `-s <pw>`(`--sudo-password`)を渡します。復元の様子を見るには `-v`(pmd3 ログ、カラー表示)、pmd3 のデバッグ詳細には `-vv`、vphone-cli の内部トレースには `-vvv` を追加します。その後、起動します:
|
||||
|
||||
```bash
|
||||
# カスタム設定で VM を作成
|
||||
make vm_new CPU=16 MEMORY=16384 DISK_SIZE=128
|
||||
|
||||
# 起動時に config.plist から設定を自動読み込み
|
||||
make boot
|
||||
vphone-cli vm launch myphone
|
||||
```
|
||||
|
||||
マニフェストファイルはすべての VM 設定(CPU、メモリ、画面、ROM、ストレージ)を保存し、[security-pcc の VMBundle.Config 形式](https://github.com/apple/security-pcc) と互換性があります。
|
||||
VM は `~/.vphone/VMs/` にある **ライブラリ** に保存されます(任意のコマンドで `--library-root <dir>` によって上書き可能)。VM コマンドを名前なしで実行すると(例: `vphone-cli vm launch`)、VM のメニューから選択できます。
|
||||
|
||||
## 復元
|
||||
## コマンド
|
||||
|
||||
復元プロセスには **2つのターミナル** が必要です。ターミナル 2 を使用している間、ターミナル 1 を実行し続けてください。
|
||||
`vphone-cli vm create` はパイプライン全体を実行します。以下の個別ステップを使うと、手動で操作したり 1 つの段階を再実行したりできます。
|
||||
|
||||
### 管理
|
||||
|
||||
```bash
|
||||
# ターミナル 1
|
||||
make boot_dfu # DFUモードでVMを起動(実行したままにする)
|
||||
vphone-cli vm list # VM の一覧表示(スクリプト用に --json)
|
||||
vphone-cli vm info myphone # 1 つの VM を表示
|
||||
vphone-cli vm new myphone # 空のバンドルを作成(cpu/mem/disk オプション)
|
||||
vphone-cli vm config myphone --cpu 8 --memory 8192
|
||||
vphone-cli vm clone myphone myphone-2 # 高速 APFS クローン、新しいデバイスアイデンティティ
|
||||
vphone-cli vm export myphone --out myphone.tar.xz # xz -9; 復元ディレクトリ + ステージングファイルをスキップ
|
||||
vphone-cli vm import --in myphone.tar.xz --name restored
|
||||
vphone-cli vm rename myphone iphone16
|
||||
vphone-cli vm delete iphone16
|
||||
```
|
||||
|
||||
### VM を手動でビルドする(`vm create` が自動化する処理)
|
||||
|
||||
```bash
|
||||
# ターミナル 2
|
||||
make restore_get_shsh # SHSH blob の取得
|
||||
make restore # pymobiledevice3 restore バックエンドでファームウェアを焼き込み
|
||||
# または: make restore_offline # オフライン復元(AEA イメージをその場で復号し、キャッシュ済み .shsh blob を使用)
|
||||
# 初回は AEA 復号のためインターネット接続が必要です
|
||||
vphone-cli vm new myphone # 1. 空のバンドル
|
||||
vphone-cli fw prepare myphone --iphone-version 26.1 # 2. IPSW のダウンロード + マージ
|
||||
vphone-cli fw patch myphone --variant jb # 3. ブートチェーンにパッチ適用
|
||||
|
||||
vphone-cli vm launch myphone --dfu & # 4. DFU で起動(バックグラウンド)
|
||||
vphone-cli restore myphone --get-shsh # SHSH を取得
|
||||
vphone-cli restore myphone # DFU 復元
|
||||
vphone-cli vm stop myphone # DFU 起動を停止
|
||||
|
||||
vphone-cli cfw install myphone --variant jb # 5. CFW をインストール(ホストマウント; sudo を要求)
|
||||
vphone-cli vm launch myphone # 6. 初回起動
|
||||
```
|
||||
|
||||
## カスタムファームウェアのインストール
|
||||
新しい iOS に更新するには、`fw prepare` を IPSW に向けます: `--iphone-source /path/to.ipsw --cloudos-source /path/to.ipsw`。
|
||||
|
||||
復元が完了したら、ターミナル 1 の DFU 起動を停止(Ctrl+C)して VM を完全に電源オフにします。インストーラは VM の `Disk.img` をホスト側でマウントし、すべての CFW ファイルを配置してブートスナップショットをオフラインで切り替えます(DFU / Ramdisk / SSH は不要)。そのためディスクへの排他アクセスが必要です。
|
||||
## 実行と接続
|
||||
|
||||
```bash
|
||||
# ターミナル 2(自動的に sudo で再実行されます)
|
||||
make cfw_install
|
||||
# または: make cfw_install_dev # 開発バリアント
|
||||
# または: make cfw_install_jb # 脱獄バリアント
|
||||
# または: make cfw_install_exp # 実験バリアント(脱獄 + リサーチパッチスタック)
|
||||
# または: SPOOF_BUILD=23F77 make cfw_install_exp # ProductBuildVersion も書き換え
|
||||
# または: FORCE_DSC_MAXSLIDE=1 make cfw_install # 27 以外のベースで DSC maxSlide=0 を強制(全バリアント対応、27 は自動)
|
||||
```
|
||||
`vphone-cli vm launch <name>` は VM のウィンドウを開き、`vphone-cli vm stop <name>` はシャットダウンします。ゲストはポート `22222` で SSH サーバー(dropbear)を、`5901` で VNC を実行しており、VM の NAT IP 経由でアクセスできます(`bridge100` 上で `arp -a` を実行して確認):
|
||||
|
||||
## 初回起動
|
||||
- **SSH(脱獄):** `ssh -p 22222 mobile@<vm-ip>`(パスワード `alpine`)
|
||||
- **SSH(regular/dev):** `ssh -p 22222 root@<vm-ip>`
|
||||
- **VNC:** `vnc://<vm-ip>:5901`
|
||||
|
||||
DFU 起動を停止し CFW をインストールしたら、VM を通常起動します:
|
||||
`jb`/`exp` バリアントでは、Sileo と TrollStore が初回起動時に自動的にインストールされます(`/var/log/vphone_jb_setup.log` で監視)。
|
||||
|
||||
```bash
|
||||
make boot
|
||||
```
|
||||
## Python ランタイム
|
||||
|
||||
`cfw_install_jb` 実行後、脱獄バリアントでは初回起動時に **Sileo** と **TrollStore** が利用可能になります。Sileo から `openssh-server` をインストールして SSH アクセスを有効にできます。
|
||||
いくつかのステップ(DFU 復元、IPSW 処理)は Python を通じて実行されます。初回使用時、vphone-cli はバンドルされた `requirements.txt` を使用して、最新のホスト `python3`(3.11+)から `~/.vphone/venv` に自己完結型の venv をプロビジョニングします — そのため署名済みの `.app` は **ポータブル** です。任意の場所(例: `/Applications`)にコピーすればリポジトリなしで動作します。プロビジョニングは自動ですが、事前に行うには `vphone-cli setup` を実行します。特定のインタプリタを指定するには `VPHONE_PYTHON=/path/to/python3`、venv の場所を変更するには `VPHONE_VENV_DIR=/path` を使用します。
|
||||
|
||||
通常版/開発版では、VM に**直接繋がるコンソール**が開きます。`bash-4.4#` と表示されたら、Enter を押し、シェル環境を初期化して SSH ホストキーを生成するために以下のコマンドを実行します:
|
||||
## FAQ
|
||||
|
||||
```bash
|
||||
export PATH='/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/bin/X11:/usr/games:/iosbinpack64/usr/local/sbin:/iosbinpack64/usr/local/bin:/iosbinpack64/usr/sbin:/iosbinpack64/usr/bin:/iosbinpack64/sbin:/iosbinpack64/bin'
|
||||
**`zsh: killed ./vphone-cli`** — AMFI/デバッグ制限がバイパスされていません。[前提条件](#前提条件) を参照してください(`amfi_get_out_of_my_way=1` または `amfidont`)。
|
||||
|
||||
mkdir -p /var/dropbear
|
||||
cp /iosbinpack64/etc/profile /var/profile
|
||||
cp /iosbinpack64/etc/motd /var/motd
|
||||
**`Virtualization is not available on this hardware`** — お使いの Mac 自体が VM です。PV=3 ゲスト起動はネストできません。ネストされていない macOS 15+ ホストを使用してください。
|
||||
|
||||
# SSHホストキーの生成(SSHを機能させるために必要)
|
||||
dropbearkey -t rsa -f /var/dropbear/dropbear_rsa_host_key
|
||||
dropbearkey -t ecdsa -f /var/dropbear/dropbear_ecdsa_host_key
|
||||
**「Press home to continue」で止まる** — VNC で接続し、右クリック(2 本指クリック)してホームボタンをシミュレートします。
|
||||
|
||||
shutdown -h now
|
||||
```
|
||||
**システムアプリがインストールできない** — iOS のセットアップ中に、地域として日本や EU を選ばないでください(VM が満たせない追加の規制チェックが入ります)。例えば United States を選択してください。
|
||||
|
||||
> **注意:** ホストキー生成手順を行わないと、dropbear(SSH サーバー)は接続を受け付けますが、SSH ハンドシェイクを実行するためのキーがないためすぐに切断されます。
|
||||
**アプリが起動時に `EXC_GUARD` / `GUARD_TYPE_MACH_PORT` でクラッシュする** — `vphone-cli fw patch <name> --variant <v> --force-exc-guard` で再パッチし、再度復元/インストールしてください([#291](https://github.com/Lakr233/vphone-cli/issues/291))。iOS 18 ベースでは常に有効です。
|
||||
|
||||
## 2回目以降の起動
|
||||
**`.ipa`/`.tipa` をインストールする** — 実行中の VM の Install メニューを使用します(ドラッグ&ドロップまたはファイルピッカー)。
|
||||
|
||||
```bash
|
||||
make boot
|
||||
```
|
||||
## 自動化
|
||||
|
||||
別のターミナルで usbmux 転送トンネルを開始します:
|
||||
|
||||
```bash
|
||||
python3 -m pymobiledevice3 usbmux forward 2222 22222 # SSH(dropbear)
|
||||
python3 -m pymobiledevice3 usbmux forward 2222 22 # SSH(脱獄版:Sileo で openssh-server を入れた場合)
|
||||
python3 -m pymobiledevice3 usbmux forward 5901 5901 # VNC
|
||||
python3 -m pymobiledevice3 usbmux forward 5910 5910 # RPC
|
||||
```
|
||||
|
||||
以下で接続します:
|
||||
|
||||
- **SSH(脱獄版):** `ssh -p 2222 mobile@127.0.0.1` (パスワード: `alpine`)
|
||||
- **SSH(通常版/開発版):** `ssh -p 2222 root@127.0.0.1` (パスワード: `alpine`)
|
||||
- **VNC:** `vnc://127.0.0.1:5901`
|
||||
- [**RPC:**](http://github.com/doronz88/rpc-project) `rpcclient -p 5910 127.0.0.1`
|
||||
|
||||
## VM バックアップと切り替え
|
||||
|
||||
複数の VM 環境(異なる iOS ビルドやファームウェアバリアントなど)を保存して切り替えることができます。バックアップは `vm.backups/` に保存され、`rsync --sparse` でスパースディスクイメージを効率的に処理します。
|
||||
|
||||
```bash
|
||||
make vm_backup NAME=26.1-clean # 現在の VM を保存
|
||||
rm -rf vm && make vm_new # 新しいビルド用に初期化
|
||||
# ... fw_prepare, fw_patch, restore, cfw_install, boot
|
||||
make vm_backup NAME=26.3-jb # 新しい VM も保存
|
||||
make vm_list # すべてのバックアップを一覧表示
|
||||
make vm_switch NAME=26.1-clean # バックアップ間を切り替え
|
||||
```
|
||||
|
||||
> **注意:** バックアップ/切り替え/復元の前に必ず VM を停止してください。
|
||||
|
||||
## よくある質問 (FAQ)
|
||||
|
||||
> **何よりもまず — `git pull` を実行して最新バージョンであることを確認してください**
|
||||
|
||||
**Q: 実行しようとすると `zsh: killed ./vphone-cli` と表示されます**
|
||||
|
||||
AMFI/デバッグ制限が正しくバイパスされていません。以下のいずれかの方法を選択してください:
|
||||
|
||||
- **方法 1(AMFI を完全に無効化):**
|
||||
|
||||
```bash
|
||||
sudo nvram boot-args="amfi_get_out_of_my_way=1 -v"
|
||||
```
|
||||
|
||||
- **方法 2(デバッグ制限のみ無効化):**
|
||||
復旧モードで `csrutil enable --without debug`(完全な SIP 無効化は不要)を使用し、[`amfidont`](https://github.com/zqxwce/amfidont) または [`amfree`](https://github.com/retX0/amfree) をインストール/ロードして AMFI のその他の機能は有効のままにします。
|
||||
このリポジトリでは、`make amfidont_allow_vphone` により `amfidont` で必要なエンコード済みパスと CDHash の許可設定を自動で行えます。
|
||||
|
||||
**Q: `make boot` / `make boot_dfu` が `VZErrorDomain Code=2 "Virtualization is not available on this hardware."` で失敗します**
|
||||
|
||||
ホスト自体が Apple 仮想マシン上で動作しているため、ネストされた Virtualization.framework のゲスト起動は利用できません。ネストされていない macOS 15+ ホストで実行してください。`make boot_host_preflight` ではこの状態を `Model Name: Apple Virtual Machine 1` と `kern.hv_vmm_present=1` として確認できます。現在は `boot_binary_check` により、該当ホストでは起動前に早期失敗します。
|
||||
|
||||
**Q: システムアプリ(App Store、メッセージなど)がダウンロード・インストールできません**
|
||||
|
||||
iOS の初期設定時に、地域として**日本**または**欧州連合**を選択**しないでください**。これらの地域では追加の規制チェック(サイドローディングの開示、カメラのシャッター音など)が適用されますが、仮想マシンではこれらの要件を満たせないため、システムアプリのダウンロードおよびインストールができなくなります。この問題を回避するには、他の地域(例: 米国)を選択してください。
|
||||
|
||||
**Q: "Press home to continue" の画面から進めません**
|
||||
|
||||
VNC経由で接続し(`vnc://127.0.0.1:5901`)、画面の任意の場所を右クリック(Mac のトラックパッドでは 2 本指クリック)してください。これによりホームボタンの押下がシミュレートされます。
|
||||
|
||||
**Q: SSH アクセスを有効にするには?**
|
||||
|
||||
Sileo から `openssh-server` をインストールしてください(脱獄バリアントの初回起動後に利用可能)。
|
||||
|
||||
**Q: openssh-server をインストールしても SSH が動作しません。**
|
||||
|
||||
VM を再起動してください。次回起動時に SSH サーバーが自動的に開始されます。
|
||||
|
||||
**Q: `.tipa` ファイルをインストールできますか?**
|
||||
|
||||
はい。インストールメニューは `.ipa` と `.tipa` パッケージの両方に対応しています。ドラッグ&ドロップまたはファイルピッカーを使用してください。
|
||||
|
||||
**Q: もっと新しいiOSバージョンにアップデートできますか?**
|
||||
|
||||
はい。`fw_prepare` に希望するバージョンの IPSW URL を指定することでできます:
|
||||
|
||||
```bash
|
||||
export IPHONE_SOURCE=/path/to/some_os.ipsw
|
||||
export CLOUDOS_SOURCE=/path/to/some_os.ipsw
|
||||
make fw_prepare
|
||||
make fw_patch
|
||||
```
|
||||
|
||||
私たちのパッチは静的なオフセットではなくバイナリ解析によって適用されるため、新しいバージョンでも動作するはずです。何か壊れた場合は AI に聞いてください。
|
||||
|
||||
**Q: `restore_offline` を使ったらセットアップ画面で進めなくなりました**
|
||||
|
||||
セットアップ中に Apple への接続が必要ですが、`restore_offline` を使った場合はインターネットに接続されていない可能性があります。
|
||||
デバイスを監視対象(supervised)にすることで、セットアップ画面の多くを回避できます:
|
||||
|
||||
```bash
|
||||
python3 -m pymobiledevice3 profile supervise vphone
|
||||
```
|
||||
`vphone-cli` はプログラムによる制御のためにホスト制御ソケット(`<bundle>/vphone.sock`)を公開します — スクリーンショット、タッチ、スワイプ、ハードウェアキー、クリップボード — 各アクションは AI 駆動の E2E テスト用にインラインのスクリーンショットを返します。それをラップする MCP サーバーについては [vphone-mcp](https://github.com/pluginslab/vphone-mcp) を参照してください。
|
||||
|
||||
## 謝辞
|
||||
|
||||
|
||||
+124
-241
@@ -2,11 +2,13 @@
|
||||
|
||||
# vphone-cli
|
||||
|
||||
PCC 리서치 VM 인프라와 Apple의 Virtualization.framework를 사용하여 가상 iPhone을 부팅합니다.
|
||||
PCC 리서치 VM 인프라를 사용하여 Apple의 Virtualization.framework로 가상 iPhone을 부팅합니다.
|
||||
|
||||
모든 것은 단일 `vphone-cli` 바이너리를 통해 실행됩니다 — VM 생성, 패치, 복원, 설치, 부팅, 관리. 빌드 후에는 `make`가 필요하지 않습니다.
|
||||
|
||||

|
||||
|
||||
## 테스트된 환경
|
||||
## 테스트 환경
|
||||
|
||||
| Host | iPhone | CloudOS |
|
||||
| --------------- | --------------------- | --------------- |
|
||||
@@ -24,304 +26,185 @@ PCC 리서치 VM 인프라와 Apple의 Virtualization.framework를 사용하여
|
||||
| Mac16,11 27.0b2 | `17,3_27.0_24A5380h` | `26.4-23E5207q` |
|
||||
| Mac16,6 25.4.1 | `17,3_27.0_24A5390f` | `26.4-23E5207q` |
|
||||
|
||||
iOS 27.0은 26.4 PCC vphone600 스택에 더해 CFW 단계의 force-kern `IOMobileFramebuffer` present-path 패치와 dyld 공유 캐시 `maxSlide` 조정을 사용합니다.
|
||||
iOS ≤ 26.0.1은 26.1 PCC vphone600 스택에 더해 CFW 단계의 `IOMobileFramebuffer` SwapEnd 페이로드 크기 패치를 사용합니다. iOS 27.0은 26.4 PCC vphone600 스택에 더해 CFW 단계의 force-kern `IOMobileFramebuffer` present-path 패치와 dyld 공유 캐시 `maxSlide` 조정을 사용합니다.
|
||||
|
||||
**참고:** iOS 18.x에서는 Metal/GPU 가속이 작동하지 않습니다. 18.x의 Metal/IOGPU 프레임워크에 반가상화 GPU 구현이 없기 때문에 Metal로 렌더링되는 콘텐츠(웹 페이지, 이미지, 배경화면)가 표시되지 않습니다. 터치, 네트워크, 앱은 정상적으로 작동합니다.
|
||||
> **참고:** iOS 18.x에서는 GPU/Metal 가속이 작동하지 않습니다 — 18.x의 Metal/IOGPU 프레임워크에 반가상화 GPU 구현이 없기 때문에 Metal로 렌더링되는 콘텐츠(웹 페이지, 이미지, 배경화면)가 표시되지 않습니다. 터치, 네트워크, 앱은 정상적으로 작동합니다.
|
||||
|
||||
## 펌웨어 변형
|
||||
|
||||
보안 우회 수준이 다른 5가지 패치 변형을 사용할 수 있습니다:
|
||||
보안 우회 수준이 점점 강해지는 5가지 패치 변형이 있습니다 — 하나를 `--variant`에 전달하세요:
|
||||
|
||||
| 변형 | 부트 체인 | CFW | Make 타겟 |
|
||||
| -------------- | :---------------: | :--------: | ------------------------------------------- |
|
||||
| **Patchless** | 4 패치 | 2 페이즈 | `fw_patch_less` + `boot_less` |
|
||||
| **일반** | 42 패치 | 10 페이즈 | `fw_patch` + `cfw_install` |
|
||||
| **개발** | 53 패치 | 12 페이즈 | `fw_patch_dev` + `cfw_install_dev` |
|
||||
| **탈옥** | 113 패치 | 14 페이즈 | `fw_patch_jb` + `cfw_install_jb` |
|
||||
| **실험** | 탈옥 + EXP 전용 | 탈옥 + EXP | `fw_patch_exp` + `cfw_install_exp` |
|
||||
| 변형 | 부트 체인 | CFW | 참고 |
|
||||
| ------------ | ----------- | --------- | --------------------------------------------------------------- |
|
||||
| `less` | 4 patches | 2 phases | Patchless — iOS 완화 기능을 활성 상태로 유지 |
|
||||
| `regular` | 42 patches | 10 phases | AMFI/SSV/Img4/TXM 우회 |
|
||||
| `dev` | 53 patches | 12 phases | + TXM 권한/디버그 우회 |
|
||||
| `jb` | 113 patches | 14 phases | + 전체 탈옥 (Sileo, TrollStore가 첫 부팅 시 자동 설치) |
|
||||
| `exp` | 141 patches | 18 phases | JB 상위 집합 + VM 탐지 방지 연구 패치 |
|
||||
|
||||
> JB 최종 설정(심볼릭 링크, Sileo, apt, TrollStore)은 `/cores/vphone_jb_setup.sh` LaunchDaemon을 통해 첫 번째 부팅 시 자동으로 실행됩니다. 진행 상황 확인: `/var/log/vphone_jb_setup.log`.
|
||||
|
||||
> **실험(EXP)** 변형은 탈옥 변형의 상위 집합으로, 연구 브랜치의 실험적 패치를 추가로 실행합니다: 커널 `hv_vmm_present` sysctl 이름 변경 + 커널 내부 호출자 변조(`KernelEXPPatcher`), 로그인 블랙리스트가 있는 DSC 바이트 5 변조 + 슬롯 재인증, watchdogd 정밀 2개 명령어 패치(EXP-JB-3.5), 펌웨어 패치 단계의 DeviceTree 식별 속성 8개, 복원 후 DT 식별 재작성(EXP-JB-6), 그리고 `SPOOF_BUILD=<id>`를 통한 옵트인 `SystemVersion.plist` `ProductBuildVersion` 재작성(EXP-JB-7). 다른 변형은 의도적으로 영향을 받지 않습니다.
|
||||
|
||||
컴포넌트별 상세 분류는 [research/0_binary_patch_comparison.md](../research/0_binary_patch_comparison.md)를 참조하세요.
|
||||
컴포넌트별 상세 분류는 [`research/0_binary_patch_comparison.md`](../research/0_binary_patch_comparison.md)를 참조하세요.
|
||||
|
||||
## 사전 요구 사항
|
||||
|
||||
**호스트 OS:** PV=3 가상화를 위해 macOS 15+(Sequoia)가 필요합니다.
|
||||
**호스트:** macOS 15+ (Sequoia), 중첩되지 않은 Mac (Virtualization.framework는 중첩할 수 없습니다). Private PV=3 권한 + 서명되지 않은 바이너리 워크플로우에는 SIP/AMFI 완화가 필요합니다. 다음 두 가지 방법 중 **하나**를 선택하세요 — SIP 설정과 AMFI 설정은 함께 가야 하므로 섞지 마세요:
|
||||
|
||||
**SIP/AMFI 설정** — Private Virtualization.framework 권한과 서명되지 않은 바이너리 워크플로우에 필요합니다.
|
||||
|
||||
복구 모드(전원 버튼 길게 누르기)로 부팅한 후 터미널을 열고, 다음 중 하나를 선택합니다:
|
||||
|
||||
- **방법 1: SIP 완전 비활성화 + AMFI boot-arg (가장 관대)**
|
||||
|
||||
복구 모드에서:
|
||||
|
||||
```bash
|
||||
csrutil disable
|
||||
csrutil allow-research-guests enable
|
||||
```
|
||||
|
||||
macOS로 다시 시작한 후:
|
||||
|
||||
```bash
|
||||
sudo nvram boot-args="amfi_get_out_of_my_way=1 -v"
|
||||
```
|
||||
|
||||
한 번 더 재시작합니다.
|
||||
|
||||
- **방법 2: SIP은 대부분 활성 유지, 디버그 제한만 비활성화, [`amfidont`](https://github.com/zqxwce/amfidont) 또는 [`amfree`](https://github.com/retX0/amfree) 사용**
|
||||
|
||||
복구 모드에서:
|
||||
|
||||
```bash
|
||||
csrutil enable --without debug
|
||||
csrutil allow-research-guests enable
|
||||
```
|
||||
|
||||
macOS로 다시 시작한 후:
|
||||
|
||||
```bash
|
||||
# amfidont 사용:
|
||||
xcrun python3 -m pip install amfidont
|
||||
sudo amfidont --path [PATH_TO_VPHONE_DIR]
|
||||
|
||||
# 또는 amfree 사용:
|
||||
brew install retX0/tap/amfree
|
||||
sudo amfree --path [PATH_TO_VPHONE_DIR]
|
||||
```
|
||||
|
||||
이 저장소에서는 `make amfidont_allow_vphone`으로 `amfidont`에 필요한
|
||||
인코딩 경로와 CDHash 허용 설정을 한 번에 적용할 수 있습니다.
|
||||
|
||||
> Patchless 변형은 방법 1 또는 `-S` 플래그를 포함한 amfidont(`sudo amfidont -S --path [PATH_TO_VPHONE_DIR]`)가 필요합니다.
|
||||
|
||||
**의존성(Dependencies) 설치:**
|
||||
**방법 A — SIP를 완전히 비활성화한 후, boot-arg로 AMFI를 비활성화 (가장 관대).** 복구 모드에서 (전원 버튼 길게 누르기 → 터미널):
|
||||
|
||||
```bash
|
||||
brew install aria2 wget gnu-tar openssl@3 ldid-procursus sshpass keystone libusb ipsw zstd
|
||||
csrutil disable
|
||||
csrutil allow-research-guests enable
|
||||
```
|
||||
|
||||
`scripts/fw_prepare.sh` 는 더 빠른 다중 연결 다운로드를 위해 `aria2c` 를 우선 사용하고, 필요하면 `curl` 또는 `wget` 으로 폴백합니다.
|
||||
그런 다음 macOS로 재부팅하고 AMFI boot-arg를 설정합니다 (적용되려면 SIP가 완전히 꺼져 있어야 합니다):
|
||||
|
||||
**Submodules** — 이 저장소는 리소스, Swift 의존성, `scripts/repos/` 아래 툴체인 소스를 git submodule로 관리합니다. 클론 시 다음 명령어를 사용하세요:
|
||||
```bash
|
||||
sudo nvram boot-args="amfi_get_out_of_my_way=1 -v" # 이후 재부팅
|
||||
```
|
||||
|
||||
**방법 B — SIP 유지 (디버그만 완화), 그런 다음 amfidont로 바이너리를 허용 목록에 추가** (AMFI는 시스템 전체에서 활성 상태 유지). 복구 모드에서:
|
||||
|
||||
```bash
|
||||
csrutil enable --without debug
|
||||
csrutil allow-research-guests enable
|
||||
```
|
||||
|
||||
그런 다음 macOS로 재부팅하고 [`amfidont`](https://github.com/zqxwce/amfidont) (또는 [`amfree`](https://github.com/retX0/amfree))로 저장소를 허용 목록에 추가합니다:
|
||||
|
||||
```bash
|
||||
sudo amfidont --path <repo>
|
||||
```
|
||||
|
||||
> `less` (patchless) 변형은 방법 A, 또는 `amfidont -S`를 포함한 방법 B(`sudo amfidont -S --path <repo>`)가 필요합니다.
|
||||
|
||||
**의존성:**
|
||||
|
||||
```bash
|
||||
git clone --recurse-submodules https://github.com/Lakr233/vphone-cli.git
|
||||
brew install [email protected] aria2 wget gnu-tar openssl@3 ldid-procursus sshpass keystone libusb ipsw zstd
|
||||
```
|
||||
|
||||
(최신 `python3` — 3.11+ — 이 필요합니다; 앱은 이를 사용하여 자체 Python 환경을 빌드합니다. [Python 런타임](#python-런타임)을 참조하세요.)
|
||||
|
||||
## 빌드
|
||||
|
||||
두 개의 일회성 부트스트랩 스크립트(컴파일된 바이너리는 스스로를 빌드할 수 없습니다)를 실행하면, 그 다음부터는 모든 것이 `vphone-cli`입니다:
|
||||
|
||||
```bash
|
||||
./scripts/setup_tools.sh # 의존성 설치, 툴체인 서브모듈 빌드, Python venv 생성
|
||||
./scripts/build.sh # vphone-cli 빌드 및 서명, .app 번들 생성, vphoned 크로스 컴파일
|
||||
```
|
||||
|
||||
아래 예제가 그대로 작동하도록 바이너리를 `PATH`에 추가하세요:
|
||||
|
||||
```bash
|
||||
cd .build/release
|
||||
vphone-cli --help
|
||||
```
|
||||
|
||||
## 빠른 시작
|
||||
|
||||
```bash
|
||||
make setup_machine # "First Boot"까지의 전체 과정 자동화 (복원/커스텀 펌웨어 포함)
|
||||
# 옵션: NON_INTERACTIVE=1 SUDO_PASSWORD=...
|
||||
# LESS=1 Patchless 변형 (- AMFI, SSV, Img4, TXM 우회)
|
||||
# DEV=1 개발 변형 (+ TXM 권한/디버그 우회)
|
||||
# JB=1 탈옥 변형 (dev + 전체 보안 우회)
|
||||
# EXP=1 실험 변형 (탈옥 + 연구 패치: hv_vmm 이름 변경, DT 식별, 복원 후 재작성)
|
||||
# SPOOF_BUILD=<id> (EXP 전용) SystemVersion.plist의 ProductBuildVersion을 <id>로 재작성, 예: 23F77
|
||||
```
|
||||
|
||||
## 수동 설정
|
||||
하나의 명령으로 VM을 처음부터 끝까지 생성합니다 (다운로드 → 패치 → DFU 복원 → CFW 설치 → 첫 부팅):
|
||||
|
||||
```bash
|
||||
make setup_tools # brew 의존성 설치, trustcache + insert_dylib 빌드, Python venv 생성(pymobiledevice3/aria2c 포함)
|
||||
make build # vphone-cli 빌드 및 서명
|
||||
make vm_new # VM 디렉토리 및 매니페스트(config.plist) 생성
|
||||
# 옵션: CPU=8 MEMORY=8192 DISK_SIZE=64
|
||||
make fw_prepare # IPSW 다운로드, 추출, 병합, manifest 생성
|
||||
make fw_patch # 부트 체인 패치 (일반 변형)
|
||||
# 또는: sudo make fw_patch_less # Patchless 변형 (- AMFI, SSV, Img4, TXM 우회)
|
||||
# 또는: make fw_patch_dev # 개발 변형 (+ TXM 권한/디버그 우회)
|
||||
# 또는: make fw_patch_jb # 탈옥 변형 (dev + 전체 보안 우회)
|
||||
# 또는: make fw_patch_exp # 실험 변형 (탈옥 + 연구 패치 스택)
|
||||
vphone-cli vm create myphone -V jb # -V / --variant
|
||||
```
|
||||
|
||||
### 정리
|
||||
소스 플래그가 없으면 기본적으로 테스트된 iPhone + cloudOS 쌍을 다운로드합니다. 특정 펌웨어를 선택하려면 **`-i`/`--iphone-source`**와 **`-c`/`--cloudos-source`**를 전달하세요 — 각각 **URL** 또는 **로컬 `.ipsw` 경로**를 받습니다 (검증된 쌍은 [테스트 환경](#테스트-환경)을 참조하세요):
|
||||
|
||||
```bash
|
||||
make clean # 빌드/도구 산출물만 삭제
|
||||
make clean CLEAN_VM=1 # 확인 후 vm/ 도 삭제
|
||||
make clean CLEAN_IPSW=1 # 확인 후 ipsws/ 도 삭제
|
||||
# 로컬 IPSW에서
|
||||
vphone-cli vm create myphone -V jb \
|
||||
-i ~/ipsws/iPhone17,3_26.1_23B85_Restore.ipsw \
|
||||
-c ~/ipsws/cloudOS_26.1-23B85.ipsw
|
||||
|
||||
# 또는 URL에서 — 다운로드되어 ~/.vphone/ipsws 아래에 캐시됨
|
||||
vphone-cli vm create myphone -V jb \
|
||||
-i "https://updates.cdn-apple.com/.../iPhone17,3_26.1_23B85_Restore.ipsw" \
|
||||
-c "https://updates.cdn-apple.com/private-cloud-compute/<id>"
|
||||
```
|
||||
|
||||
기본 clean은 `vm/` 또는 `ipsws/` 를 삭제하지 않습니다.
|
||||
|
||||
### VM 설정
|
||||
|
||||
v1.0부터 VM 설정은 `vm/config.plist`에 저장됩니다. VM 생성 시 CPU, 메모리, 디스크 크기를 설정하세요:
|
||||
CFW 설치 단계는 root(호스트 디스크 마운트)가 필요하며 `sudo`를 요청합니다; 무인 실행을 위해서는 `-s <pw>`(`--sudo-password`)를 전달하세요. 복원 과정을 보려면 `-v`(pmd3 로그, 색상 표시), pmd3 디버그 상세 정보는 `-vv`, vphone-cli의 내부 추적은 `-vvv`를 추가하세요. 그런 다음 부팅합니다:
|
||||
|
||||
```bash
|
||||
# 사용자 정의 설정으로 VM 생성
|
||||
make vm_new CPU=16 MEMORY=16384 DISK_SIZE=128
|
||||
|
||||
# 부팅 시 config.plist에서 설정 자동 로드
|
||||
make boot
|
||||
vphone-cli vm launch myphone
|
||||
```
|
||||
|
||||
매니페스트 파일은 모든 VM 설정(CPU, 메모리, 화면, ROM, 저장소)을 저장하며 [security-pcc의 VMBundle.Config 형식](https://github.com/apple/security-pcc)과 호환됩니다.
|
||||
VM은 `~/.vphone/VMs/`의 **라이브러리**에 저장됩니다 (어떤 명령이든 `--library-root <dir>`로 재정의할 수 있습니다). 이름 없이 VM 명령을 실행하면 (예: `vphone-cli vm launch`) VM 목록 메뉴에서 선택할 수 있습니다.
|
||||
|
||||
## 복원
|
||||
## 명령어
|
||||
|
||||
복원 프로세스를 위해 **두 개의 터미널**이 필요합니다. 터미널 2를 사용하는 동안 터미널 1을 계속 실행 상태로 두세요.
|
||||
`vphone-cli vm create`는 전체 파이프라인을 실행합니다; 아래 개별 단계들을 사용하면 수동으로 진행하거나 한 단계만 다시 실행할 수 있습니다.
|
||||
|
||||
### 관리
|
||||
|
||||
```bash
|
||||
# 터미널 1
|
||||
make boot_dfu # VM을 DFU 모드로 부팅 (계속 실행 유지)
|
||||
vphone-cli vm list # VM 목록 표시 (스크립팅용 --json)
|
||||
vphone-cli vm info myphone # VM 하나 표시
|
||||
vphone-cli vm new myphone # 빈 번들 생성 (cpu/mem/disk 옵션)
|
||||
vphone-cli vm config myphone --cpu 8 --memory 8192
|
||||
vphone-cli vm clone myphone myphone-2 # 빠른 APFS 복제, 새로운 기기 식별자
|
||||
vphone-cli vm export myphone --out myphone.tar.xz # xz -9; restore 디렉토리 + 스테이징 파일 건너뜀
|
||||
vphone-cli vm import --in myphone.tar.xz --name restored
|
||||
vphone-cli vm rename myphone iphone16
|
||||
vphone-cli vm delete iphone16
|
||||
```
|
||||
|
||||
### VM 수동 빌드 (`vm create`가 자동화하는 작업)
|
||||
|
||||
```bash
|
||||
# 터미널 2
|
||||
make restore_get_shsh # SHSH blob 가져오기
|
||||
make restore # pymobiledevice3 restore 백엔드로 펌웨어 플래싱
|
||||
# 또는: make restore_offline # 오프라인 복원 (AEA 이미지를 제자리에서 복호화하고 캐시된 .shsh blob 사용)
|
||||
# 최초 1회는 AEA 복호화를 위해 인터넷 연결이 필요합니다
|
||||
vphone-cli vm new myphone # 1. 빈 번들
|
||||
vphone-cli fw prepare myphone --iphone-version 26.1 # 2. IPSW 다운로드 + 병합
|
||||
vphone-cli fw patch myphone --variant jb # 3. 부트 체인 패치
|
||||
|
||||
vphone-cli vm launch myphone --dfu & # 4. DFU로 부팅 (백그라운드)
|
||||
vphone-cli restore myphone --get-shsh # SHSH 가져오기
|
||||
vphone-cli restore myphone # DFU 복원
|
||||
vphone-cli vm stop myphone # DFU 부팅 중지
|
||||
|
||||
vphone-cli cfw install myphone --variant jb # 5. CFW 설치 (호스트 마운트; sudo 요청)
|
||||
vphone-cli vm launch myphone # 6. 첫 부팅
|
||||
```
|
||||
|
||||
## 커스텀 펌웨어 설치
|
||||
최신 iOS로 업데이트하려면 `fw prepare`를 IPSW로 지정하세요: `--iphone-source /path/to.ipsw --cloudos-source /path/to.ipsw`.
|
||||
|
||||
복원이 완료되면 터미널 1의 DFU 부팅을 중단(Ctrl+C)하여 VM을 완전히 종료합니다. 설치 프로그램은 VM의 `Disk.img`를 호스트에 마운트하여 모든 CFW 파일을 배치하고 부팅 스냅샷을 오프라인으로 전환합니다(DFU / 램디스크 / SSH 불필요). 따라서 디스크에 대한 독점 액세스가 필요합니다.
|
||||
## 실행 및 연결
|
||||
|
||||
```bash
|
||||
# 터미널 2 (자동으로 sudo로 재실행됨)
|
||||
make cfw_install
|
||||
# 또는: make cfw_install_dev # 개발 변형
|
||||
# 또는: make cfw_install_jb # 탈옥 변형
|
||||
# 또는: make cfw_install_exp # 실험 변형 (탈옥 + 연구 패치 스택)
|
||||
# 또는: SPOOF_BUILD=23F77 make cfw_install_exp # 추가로 ProductBuildVersion 재작성
|
||||
# 또는: FORCE_DSC_MAXSLIDE=1 make cfw_install # 27 이외 베이스에서 DSC maxSlide=0 강제 (모든 변형, 27은 자동)
|
||||
```
|
||||
`vphone-cli vm launch <name>`은 VM 창을 엽니다; `vphone-cli vm stop <name>`은 종료합니다. 게스트는 포트 `22222`에서 SSH 서버(dropbear)를, `5901`에서 VNC를 실행하며, VM의 NAT IP로 접근할 수 있습니다 (`bridge100`에서 `arp -a`로 찾으세요):
|
||||
|
||||
## 첫 부팅
|
||||
- **SSH (탈옥):** `ssh -p 22222 mobile@<vm-ip>` (비밀번호 `alpine`)
|
||||
- **SSH (regular/dev):** `ssh -p 22222 root@<vm-ip>`
|
||||
- **VNC:** `vnc://<vm-ip>:5901`
|
||||
|
||||
DFU 부팅을 중단하고 CFW를 설치한 후, VM을 정상 부팅합니다:
|
||||
`jb`/`exp` 변형의 경우, Sileo와 TrollStore가 첫 부팅 시 자동으로 설치됩니다 (`/var/log/vphone_jb_setup.log`로 모니터링).
|
||||
|
||||
```bash
|
||||
make boot
|
||||
```
|
||||
## Python 런타임
|
||||
|
||||
`cfw_install_jb` 실행 후 탈옥 변형은 첫 번째 부팅 시 **Sileo**와 **TrollStore**를 사용할 수 있습니다. Sileo에서 `openssh-server`를 설치하여 SSH 접근을 활성화할 수 있습니다.
|
||||
|
||||
일반/개발 변형의 경우, VM에서 **direct console**이 나타납니다. `bash-4.4#`이 보이면 엔터를 누르고 다음 명령어를 실행하여 쉘 환경을 초기화하고 SSH 호스트 키를 생성하세요:
|
||||
|
||||
```bash
|
||||
export PATH='/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/bin/X11:/usr/games:/iosbinpack64/usr/local/sbin:/iosbinpack64/usr/local/bin:/iosbinpack64/usr/sbin:/iosbinpack64/usr/bin:/iosbinpack64/sbin:/iosbinpack64/bin'
|
||||
|
||||
mkdir -p /var/dropbear
|
||||
cp /iosbinpack64/etc/profile /var/profile
|
||||
cp /iosbinpack64/etc/motd /var/motd
|
||||
|
||||
# SSH 호스트 키 생성 (SSH 작동에 필수)
|
||||
dropbearkey -t rsa -f /var/dropbear/dropbear_rsa_host_key
|
||||
dropbearkey -t ecdsa -f /var/dropbear/dropbear_ecdsa_host_key
|
||||
|
||||
shutdown -h now
|
||||
```
|
||||
|
||||
> **참고:** 호스트 키 생성 단계를 거치지 않으면 dropbear(SSH 서버)가 연결을 수락하더라도 SSH 핸드셰이크를 수행할 키가 없어 즉시 연결을 종료합니다.
|
||||
|
||||
## 이후 부팅
|
||||
|
||||
```bash
|
||||
make boot
|
||||
```
|
||||
|
||||
별도의 터미널에서 usbmux 포워딩 터널을 시작합니다:
|
||||
|
||||
```bash
|
||||
python3 -m pymobiledevice3 usbmux forward 2222 22222 # SSH (dropbear)
|
||||
python3 -m pymobiledevice3 usbmux forward 2222 22 # SSH (탈옥: Sileo에서 openssh-server를 설치한 경우)
|
||||
python3 -m pymobiledevice3 usbmux forward 5901 5901 # VNC
|
||||
python3 -m pymobiledevice3 usbmux forward 5910 5910 # RPC
|
||||
```
|
||||
|
||||
다음을 통해 연결합니다:
|
||||
|
||||
- **SSH (탈옥):** `ssh -p 2222 mobile@127.0.0.1` (password: `alpine`)
|
||||
- **SSH (일반/개발):** `ssh -p 2222 root@127.0.0.1` (password: `alpine`)
|
||||
- **VNC:** `vnc://127.0.0.1:5901`
|
||||
- [**RPC:**](http://github.com/doronz88/rpc-project) `rpcclient -p 5910 127.0.0.1`
|
||||
|
||||
## VM 백업 및 전환
|
||||
|
||||
여러 VM 환경(예: 다른 iOS 빌드 또는 펌웨어 변형)을 저장하고 전환할 수 있습니다. 백업은 `vm.backups/`에 저장되며 `rsync --sparse`를 사용하여 희소 디스크 이미지를 효율적으로 처리합니다.
|
||||
|
||||
```bash
|
||||
make vm_backup NAME=26.1-clean # 현재 VM 저장
|
||||
rm -rf vm && make vm_new # 새로운 빌드를 위해 초기화
|
||||
# ... fw_prepare, fw_patch, restore, cfw_install, boot
|
||||
make vm_backup NAME=26.3-jb # 새 VM도 저장
|
||||
make vm_list # 모든 백업 목록 보기
|
||||
make vm_switch NAME=26.1-clean # 백업 간 전환
|
||||
```
|
||||
|
||||
> **참고:** 백업/전환/복원 전에 반드시 VM을 중지하세요.
|
||||
일부 단계(DFU 복원, IPSW 처리)는 Python을 통해 실행됩니다. 최초 사용 시,
|
||||
vphone-cli는 번들된 `requirements.txt`를 사용하여 최신 호스트 `python3`(3.11+)로부터
|
||||
`~/.vphone/venv`에 독립적인 venv를 프로비저닝합니다 — 따라서 서명된
|
||||
`.app`은 **이식 가능**합니다: 어디든(예: `/Applications`) 복사하면 저장소
|
||||
없이도 실행됩니다. 프로비저닝은 자동으로 이루어집니다; 미리 실행하려면 `vphone-cli setup`을
|
||||
실행하세요. 특정 인터프리터를 지정하려면 `VPHONE_PYTHON=/path/to/python3`을,
|
||||
venv 위치를 변경하려면 `VPHONE_VENV_DIR=/path`를 사용하세요.
|
||||
|
||||
## FAQ
|
||||
|
||||
> **무엇보다 먼저 — `git pull`을 실행하여 최신 버전인지 확인하세요.**
|
||||
**`zsh: killed ./vphone-cli`** — AMFI/디버그 제한이 우회되지 않았습니다; [사전 요구 사항](#사전-요구-사항)을 참조하세요 (`amfi_get_out_of_my_way=1` 또는 `amfidont`).
|
||||
|
||||
**Q: 실행하려고 하면 `zsh: killed ./vphone-cli` 오류가 발생합니다.**
|
||||
**`Virtualization is not available on this hardware`** — Mac 자체가 VM입니다; PV=3 게스트 부팅은 중첩할 수 없습니다. 중첩되지 않은 macOS 15+ 호스트를 사용하세요.
|
||||
|
||||
AMFI/디버그 제한이 올바르게 우회되지 않았습니다. 다음 중 하나를 선택하세요:
|
||||
**"Press home to continue"에서 멈춤** — VNC로 접속하여 우클릭(두 손가락 클릭)으로 홈 버튼을 시뮬레이션하세요.
|
||||
|
||||
- **방법 1 (AMFI 완전 비활성화):**
|
||||
**시스템 앱이 설치되지 않음** — iOS 초기 설정 시 지역으로 일본이나 EU를 선택하지 마세요 (VM이 충족할 수 없는 추가 규제 검사가 있습니다); 예를 들어 United States를 선택하세요.
|
||||
|
||||
```bash
|
||||
sudo nvram boot-args="amfi_get_out_of_my_way=1 -v"
|
||||
```
|
||||
**앱이 실행 시 `EXC_GUARD` / `GUARD_TYPE_MACH_PORT`로 충돌** — `vphone-cli fw patch <name> --variant <v> --force-exc-guard`로 다시 패치한 다음, 다시 복원/설치하세요 ([#291](https://github.com/Lakr233/vphone-cli/issues/291)). iOS 18 베이스에서는 항상 켜져 있습니다.
|
||||
|
||||
- **방법 2 (디버그 제한만 비활성화):**
|
||||
복구 모드에서 `csrutil enable --without debug`(완전한 SIP 비활성화 없음)를 사용한 다음, [`amfidont`](https://github.com/zqxwce/amfidont) 또는 [`amfree`](https://github.com/retX0/amfree)를 설치/로드하여 AMFI의 나머지 기능은 활성 상태로 유지합니다.
|
||||
이 저장소에서는 `make amfidont_allow_vphone`으로 `amfidont`에 필요한 인코딩 경로와 CDHash 허용 설정을 자동 적용할 수 있습니다.
|
||||
**`.ipa`/`.tipa` 설치** — 실행 중인 VM의 Install 메뉴를 사용하세요 (드래그 앤 드롭 또는 파일 선택기).
|
||||
|
||||
**Q: `make boot` / `make boot_dfu` 실행 시 `VZErrorDomain Code=2 "Virtualization is not available on this hardware."`로 실패합니다.**
|
||||
## 자동화
|
||||
|
||||
호스트 자체가 Apple 가상 머신에서 실행 중이기 때문에, 중첩된 Virtualization.framework 게스트 부팅은 지원되지 않습니다. 중첩이 아닌 macOS 15+ 호스트에서 실행하세요. `make boot_host_preflight`에서 `Model Name: Apple Virtual Machine 1` 및 `kern.hv_vmm_present=1`로 이를 확인할 수 있습니다. 현재는 이런 호스트에서 `boot_binary_check`가 VM 시작 전에 빠르게 실패 처리합니다.
|
||||
`vphone-cli`는 프로그래밍 방식 제어를 위한 호스트 제어 소켓(`<bundle>/vphone.sock`)을 노출합니다 — 스크린샷, 터치, 스와이프, 하드웨어 키, 클립보드 — 각 동작은 AI 주도 E2E 테스트를 위해 인라인 스크린샷을 반환합니다. 이를 감싸는 MCP 서버는 [vphone-mcp](https://github.com/pluginslab/vphone-mcp)를 참조하세요.
|
||||
|
||||
**Q: 시스템 앱(App Store, 메시지 등)을 다운로드하거나 설치할 수 없습니다.**
|
||||
|
||||
iOS 초기 설정 시 지역을 **일본** 또는 **유럽 연합**으로 선택하지 **마세요**. 이 지역에서는 추가적인 규제 검사(사이드로딩 공개, 카메라 셔터음 등)가 적용되는데, 가상 머신은 이러한 요건을 충족할 수 없어 시스템 앱의 다운로드 및 설치가 불가능합니다. 이 문제를 피하려면 다른 지역(예: 미국)을 선택하세요.
|
||||
|
||||
**Q: "Press home to continue" 화면에서 멈췄습니다.**
|
||||
|
||||
VNC(`vnc://127.0.0.1:5901`)로 접속하여 화면의 아무 곳이나 우클릭(Mac 트랙패드에서는 두 손가락 클릭)하세요. 이것이 홈 버튼 누르기를 시뮬레이션합니다.
|
||||
|
||||
**Q: SSH 접근을 활성화하려면?**
|
||||
|
||||
Sileo에서 `openssh-server`를 설치하세요 (탈옥 변형 첫 부팅 후 사용 가능).
|
||||
|
||||
**Q: openssh-server를 설치했는데 SSH가 작동하지 않습니다.**
|
||||
|
||||
VM을 재부팅하세요. 다음 부팅 시 SSH 서버가 자동으로 시작됩니다.
|
||||
|
||||
**Q: `.tipa` 파일을 설치할 수 있나요?**
|
||||
|
||||
네. 설치 메뉴는 `.ipa`와 `.tipa` 패키지를 모두 지원합니다. 드래그 앤 드롭 또는 파일 선택기를 사용하세요.
|
||||
|
||||
**Q: 최신 iOS 버전으로 업데이트할 수 있나요?**
|
||||
|
||||
네. `fw_prepare`를 원하는 버전의 IPSW URL로 덮어쓰세요:
|
||||
|
||||
```bash
|
||||
export IPHONE_SOURCE=/path/to/some_os.ipsw
|
||||
export CLOUDOS_SOURCE=/path/to/some_os.ipsw
|
||||
make fw_prepare
|
||||
make fw_patch
|
||||
```
|
||||
|
||||
저희의 패치는 정적 오프셋이 아닌 바이너리 분석을 통해 적용되므로, 최신 버전에서도 작동할 것입니다. 만약 문제가 발생하면 AI에게 도움을 요청하세요.
|
||||
|
||||
**Q: `restore_offline`를 사용했더니 설정 화면에서 진행이 멈췄습니다**
|
||||
|
||||
설정 과정에서 Apple 서버에 연결을 시도하는데, `restore_offline`를 사용한 경우 인터넷에 연결되어 있지 않을 가능성이 큽니다.
|
||||
기기를 supervised 상태로 만들면 설정 화면의 대부분을 우회할 수 있습니다:
|
||||
|
||||
```bash
|
||||
python3 -m pymobiledevice3 profile supervise vphone
|
||||
```
|
||||
|
||||
## 감사 인사
|
||||
## 감사의 말
|
||||
|
||||
- [wh1te4ever/super-tart-vphone-writeup](https://github.com/wh1te4ever/super-tart-vphone-writeup)
|
||||
|
||||
+119
-242
@@ -2,13 +2,15 @@
|
||||
|
||||
# vphone-cli
|
||||
|
||||
通过 Apple 的 Virtualization.framework 使用 PCC 研究虚拟机基础设施引导虚拟 iPhone。
|
||||
使用 PCC 研究虚拟机基础设施,通过 Apple 的 Virtualization.framework 启动一台虚拟 iPhone。
|
||||
|
||||
所有操作都通过单个 `vphone-cli` 二进制文件完成——创建、打补丁、恢复、安装、启动以及管理虚拟机。构建完成后无需再使用 `make`。
|
||||
|
||||

|
||||
|
||||
## 测试环境
|
||||
|
||||
| 主机 | iPhone 系统 | CloudOS |
|
||||
| 宿主机 | 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` |
|
||||
@@ -24,303 +26,178 @@
|
||||
| Mac16,11 27.0b2 | `17,3_27.0_24A5380h` | `26.4-23E5207q` |
|
||||
| Mac16,6 25.4.1 | `17,3_27.0_24A5390f` | `26.4-23E5207q` |
|
||||
|
||||
iOS 27.0 使用 26.4 PCC vphone600 栈,并额外应用 CFW 阶段的 force-kern `IOMobileFramebuffer` present-path 补丁与 dyld 共享缓存 `maxSlide` 适配。
|
||||
iOS ≤ 26.0.1 使用 26.1 PCC vphone600 栈,外加 CFW 阶段的 `IOMobileFramebuffer` SwapEnd 载荷大小补丁。iOS 27.0 使用 26.4 PCC vphone600 栈,外加 CFW 阶段的强制内核 `IOMobileFramebuffer` present-path 补丁以及 dyld 共享缓存 `maxSlide` 适配。
|
||||
|
||||
**注意:** iOS 18.x 上 Metal/GPU 加速无法工作——18.x 的 Metal/IOGPU 框架缺少半虚拟化 GPU 实现,因此由 Metal 渲染的内容(网页、图片、壁纸)无法显示。触摸、网络和应用可正常使用。
|
||||
> **注意:** GPU/Metal 加速在 iOS 18.x 上无法工作——18.x 的 Metal/IOGPU 框架没有半虚拟化 GPU 实现,因此由 Metal 渲染的内容(网页、图片、壁纸)不会显示。触控、网络和应用可正常工作。
|
||||
|
||||
## 固件变体
|
||||
|
||||
提供五种补丁变体,安全绕过级别逐步递增:
|
||||
五种补丁变体,安全绕过程度递增——将其中之一传给 `--variant`:
|
||||
|
||||
| 变体 | 启动链 | 自定义固件 | Make 目标 |
|
||||
| -------------- | :--------------: | :--------: | ------------------------------------------- |
|
||||
| **Patchless** | 4 个补丁 | 2 个阶段 | `fw_patch_less` + `boot_less` |
|
||||
| **常规版** | 42 个补丁 | 10 个阶段 | `fw_patch` + `cfw_install` |
|
||||
| **开发版** | 53 个补丁 | 12 个阶段 | `fw_patch_dev` + `cfw_install_dev` |
|
||||
| **越狱版** | 113 个补丁 | 14 个阶段 | `fw_patch_jb` + `cfw_install_jb` |
|
||||
| **实验版** | 越狱 + EXP 专属 | 越狱 + EXP | `fw_patch_exp` + `cfw_install_exp` |
|
||||
| 变体 | 引导链 | CFW | 说明 |
|
||||
| ------------ | ----------- | --------- | ------------------------------------------------- |
|
||||
| `less` | 4 patches | 2 phases | 无补丁——保持 iOS 缓解措施启用 |
|
||||
| `regular` | 42 patches | 10 phases | 绕过 AMFI/SSV/Img4/TXM |
|
||||
| `dev` | 53 patches | 12 phases | + 绕过 TXM 授权/调试 |
|
||||
| `jb` | 113 patches | 14 phases | + 完整越狱(首次启动时自动安装 Sileo、TrollStore)|
|
||||
| `exp` | 141 patches | 18 phases | JB 超集 + 反虚拟机检测研究补丁 |
|
||||
|
||||
> 越狱最终配置(符号链接、Sileo、apt、TrollStore)通过 `/cores/vphone_jb_setup.sh` LaunchDaemon 在首次启动时自动运行。查看进度:`/var/log/vphone_jb_setup.log`。
|
||||
各组件的详细拆解见 [`research/0_binary_patch_comparison.md`](../research/0_binary_patch_comparison.md)。
|
||||
|
||||
> **实验版(EXP)** 是越狱版的超集,额外运行研究分支中的实验性补丁:内核 `hv_vmm_present` sysctl 重命名 + 内核内部调用者改写(`KernelEXPPatcher`)、带登录黑名单的 DSC 字节 5 改写 + slot 重新认证、watchdogd 精准 2 条指令补丁(EXP-JB-3.5)、固件补丁阶段的 8 项 DeviceTree 身份属性、还原后 DT 身份重写(EXP-JB-6)、以及通过 `SPOOF_BUILD=<id>` 可选启用的 `SystemVersion.plist` `ProductBuildVersion` 改写(EXP-JB-7)。其他变体不受影响。
|
||||
## 前置条件
|
||||
|
||||
详见 [research/0_binary_patch_comparison.md](../research/0_binary_patch_comparison.md) 了解各组件的详细分项对比。
|
||||
**宿主机:** macOS 15+(Sequoia),一台非嵌套的 Mac(Virtualization.framework 无法嵌套)。私有 PV=3 授权 + 未签名二进制的工作流需要放宽 SIP/AMFI。请从以下两条路径中选择**一条**——SIP 设置和 AMFI 设置是配套的,不要混用:
|
||||
|
||||
## 先决条件
|
||||
|
||||
**主机系统:** PV=3 虚拟化要求 macOS 15+(Sequoia)。
|
||||
|
||||
**配置 SIP/AMFI** —— 需要私有的 Virtualization.framework 权限和未签名二进制文件工作流。
|
||||
|
||||
重启到恢复模式(长按电源键),打开终端,选择以下任一设置方式:
|
||||
|
||||
- **方式 1:完全禁用 SIP + AMFI boot-arg(最宽松)**
|
||||
|
||||
在恢复模式中:
|
||||
|
||||
```bash
|
||||
csrutil disable
|
||||
csrutil allow-research-guests enable
|
||||
```
|
||||
|
||||
重新启动回 macOS 后:
|
||||
|
||||
```bash
|
||||
sudo nvram boot-args="amfi_get_out_of_my_way=1 -v"
|
||||
```
|
||||
|
||||
再重启一次。
|
||||
|
||||
- **方式 2:保持 SIP 大部分启用,仅禁用调试限制,使用 [`amfidont`](https://github.com/zqxwce/amfidont) 或 [`amfree`](https://github.com/retX0/amfree)**
|
||||
|
||||
在恢复模式中:
|
||||
|
||||
```bash
|
||||
csrutil enable --without debug
|
||||
csrutil allow-research-guests enable
|
||||
```
|
||||
|
||||
重新启动回 macOS 后:
|
||||
|
||||
```bash
|
||||
# 使用 amfidont:
|
||||
xcrun python3 -m pip install amfidont
|
||||
sudo amfidont --path [PATH_TO_VPHONE_DIR]
|
||||
|
||||
# 或使用 amfree:
|
||||
brew install retX0/tap/amfree
|
||||
sudo amfree --path [PATH_TO_VPHONE_DIR]
|
||||
```
|
||||
|
||||
在本仓库中,可以运行 `make amfidont_allow_vphone` 一次性配置
|
||||
`amfidont` 所需的编码路径与 CDHash 允许项。
|
||||
|
||||
> Patchless 变体要求使用方式 1,或带 `-S` 参数的 amfidont(`sudo amfidont -S --path [PATH_TO_VPHONE_DIR]`)。
|
||||
|
||||
**安装依赖:**
|
||||
**方案 A——完全禁用 SIP,然后通过 boot-arg 禁用 AMFI(最宽松)。** 在恢复模式下(长按电源键 → 终端):
|
||||
|
||||
```bash
|
||||
brew install aria2 wget gnu-tar openssl@3 ldid-procursus sshpass keystone libusb ipsw zstd
|
||||
csrutil disable
|
||||
csrutil allow-research-guests enable
|
||||
```
|
||||
|
||||
`scripts/fw_prepare.sh` 会优先使用 `aria2c` 进行更快的多连接下载,必要时再回退到 `curl` 或 `wget`。
|
||||
然后重启进入 macOS 并设置 AMFI boot-arg(需要 SIP 完全关闭才能生效):
|
||||
|
||||
**Submodules** —— 本仓库通过 git submodule 管理资源、Swift 依赖以及 `scripts/repos/` 下的工具链源码。克隆时请使用:
|
||||
```bash
|
||||
sudo nvram boot-args="amfi_get_out_of_my_way=1 -v" # 之后重启
|
||||
```
|
||||
|
||||
**方案 B——保持 SIP 开启(仅放宽 debug),然后用 amfidont 将二进制加入白名单**(AMFI 在系统范围内保持启用)。在恢复模式下:
|
||||
|
||||
```bash
|
||||
csrutil enable --without debug
|
||||
csrutil allow-research-guests enable
|
||||
```
|
||||
|
||||
然后重启进入 macOS,用 [`amfidont`](https://github.com/zqxwce/amfidont)(或 [`amfree`](https://github.com/retX0/amfree))将仓库加入白名单:
|
||||
|
||||
```bash
|
||||
sudo amfidont --path <repo>
|
||||
```
|
||||
|
||||
> `less`(无补丁)变体需要方案 A,或者搭配 `amfidont -S` 的方案 B(`sudo amfidont -S --path <repo>`)。
|
||||
|
||||
**依赖:**
|
||||
|
||||
```bash
|
||||
git clone --recurse-submodules https://github.com/Lakr233/vphone-cli.git
|
||||
brew install [email protected] aria2 wget gnu-tar openssl@3 ldid-procursus sshpass keystone libusb ipsw zstd
|
||||
```
|
||||
|
||||
(需要一个较新的 `python3`——3.11+;应用会基于它构建自己的 Python 环境,见 [Python 运行时](#python-运行时)。)
|
||||
|
||||
## 构建
|
||||
|
||||
两个一次性的引导脚本(编译后的二进制无法自行构建),之后一切都通过 `vphone-cli` 完成:
|
||||
|
||||
```bash
|
||||
./scripts/setup_tools.sh # 安装依赖、构建工具链子模块、创建 Python venv
|
||||
./scripts/build.sh # 构建并签名 vphone-cli、打包 .app、交叉编译 vphoned
|
||||
```
|
||||
|
||||
把二进制加入你的 `PATH`,这样下面的示例就能原样运行:
|
||||
|
||||
```bash
|
||||
cd .build/release
|
||||
vphone-cli --help
|
||||
```
|
||||
|
||||
## 快速开始
|
||||
|
||||
```bash
|
||||
make setup_machine # 完全自动化完成"首次启动"流程(包含 restore/CFW)
|
||||
# 选项:NON_INTERACTIVE=1 SUDO_PASSWORD=...
|
||||
# LESS=1 patchless 变体(- AMFI、SSV、Img4、TXM 绕过)
|
||||
# DEV=1 开发变体(+ TXM 权限/调试绕过)
|
||||
# JB=1 越狱变体(dev + 完整安全绕过)
|
||||
# EXP=1 实验变体(越狱 + 研究补丁:hv_vmm 重命名、DT 身份、还原后重写)
|
||||
# SPOOF_BUILD=<id> (仅 EXP)将 SystemVersion.plist 的 ProductBuildVersion 改写为 <id>,例如 23F77
|
||||
```
|
||||
|
||||
## 手动设置
|
||||
一条命令即可端到端创建一台虚拟机(下载 → 打补丁 → DFU 恢复 → CFW 安装 → 首次启动):
|
||||
|
||||
```bash
|
||||
make setup_tools # 安装 brew 依赖,构建 trustcache + insert_dylib,创建 Python 虚拟环境(含 pymobiledevice3/aria2c)
|
||||
make build # 构建并签名 vphone-cli
|
||||
make vm_new # 创建 VM 目录及清单文件(config.plist)
|
||||
# 选项:CPU=8 MEMORY=8192 DISK_SIZE=64
|
||||
make fw_prepare # 下载 IPSWs,提取、合并、生成 manifest
|
||||
make fw_patch # 修补启动链(常规变体)
|
||||
# 或:sudo make fw_patch_less # patchless 变体(- AMFI、SSV、Img4、TXM 绕过)
|
||||
# 或:make fw_patch_dev # 开发变体(+ TXM 权限/调试绕过)
|
||||
# 或:make fw_patch_jb # 越狱变体(dev + 完整安全绕过)
|
||||
# 或:make fw_patch_exp # 实验变体(越狱 + 研究补丁栈)
|
||||
vphone-cli vm create myphone -V jb # -V / --variant
|
||||
```
|
||||
|
||||
### 清理
|
||||
不带源标志时,它会下载一对默认的、经过测试的 iPhone + cloudOS 固件。要选择特定固件,请传入 **`-i`/`--iphone-source`** 和 **`-c`/`--cloudos-source`**——每个都接受 **URL** 或**本地 `.ipsw` 路径**(已验证可用的固件对见[测试环境](#测试环境)):
|
||||
|
||||
```bash
|
||||
make clean # 仅删除构建/工具链产物
|
||||
make clean CLEAN_VM=1 # 确认后同时删除 vm/
|
||||
make clean CLEAN_IPSW=1 # 确认后同时删除 ipsws/
|
||||
# 使用本地 IPSW
|
||||
vphone-cli vm create myphone -V jb \
|
||||
-i ~/ipsws/iPhone17,3_26.1_23B85_Restore.ipsw \
|
||||
-c ~/ipsws/cloudOS_26.1-23B85.ipsw
|
||||
|
||||
# 或使用 URL——下载后缓存到 ~/.vphone/ipsws
|
||||
vphone-cli vm create myphone -V jb \
|
||||
-i "https://updates.cdn-apple.com/.../iPhone17,3_26.1_23B85_Restore.ipsw" \
|
||||
-c "https://updates.cdn-apple.com/private-cloud-compute/<id>"
|
||||
```
|
||||
|
||||
默认清理不会删除 `vm/` 或 `ipsws/`。
|
||||
|
||||
### VM 配置
|
||||
|
||||
从 v1.0 开始,VM 配置存储在 `vm/config.plist` 中。在创建 VM 时设置 CPU、内存和磁盘大小:
|
||||
CFW 安装阶段需要 root 权限(挂载宿主机磁盘),并会提示输入 `sudo`;传入 `-s <pw>`(`--sudo-password`)可无人值守运行。加上 `-v` 可观看恢复过程(pmd3 日志,带颜色),`-vv` 显示 pmd3 调试细节,`-vvv` 显示 vphone-cli 的内部跟踪。然后启动它:
|
||||
|
||||
```bash
|
||||
# 使用自定义配置创建 VM
|
||||
make vm_new CPU=16 MEMORY=16384 DISK_SIZE=128
|
||||
|
||||
# 启动时自动从 config.plist 读取配置
|
||||
make boot
|
||||
vphone-cli vm launch myphone
|
||||
```
|
||||
|
||||
清单文件存储所有 VM 设置(CPU、内存、屏幕、ROM、存储),并与 [security-pcc 的 VMBundle.Config 格式](https://github.com/apple/security-pcc)兼容。
|
||||
虚拟机存放在位于 `~/.vphone/VMs/` 的**库**中(任何命令都可用 `--library-root <dir>` 覆盖)。运行任何虚拟机命令时不带名称(例如 `vphone-cli vm launch`),即可从你的虚拟机菜单中选择。
|
||||
|
||||
## 恢复过程
|
||||
## 命令
|
||||
|
||||
该过程需要 **两个终端**。保持终端 1 运行,同时在终端 2 操作。
|
||||
`vphone-cli vm create` 会运行整个流水线;下面的各个步骤让你可以手动驱动它,或重新运行某一个阶段。
|
||||
|
||||
### 管理
|
||||
|
||||
```bash
|
||||
# 终端 1
|
||||
make boot_dfu # 以 DFU 模式启动 VM(保持运行)
|
||||
vphone-cli vm list # 列出虚拟机(--json 用于脚本)
|
||||
vphone-cli vm info myphone # 显示某台虚拟机
|
||||
vphone-cli vm new myphone # 创建一个空 bundle(cpu/内存/磁盘选项)
|
||||
vphone-cli vm config myphone --cpu 8 --memory 8192
|
||||
vphone-cli vm clone myphone myphone-2 # 快速 APFS 克隆,全新设备标识
|
||||
vphone-cli vm export myphone --out myphone.tar.xz # xz -9;跳过 restore 目录 + 暂存文件
|
||||
vphone-cli vm import --in myphone.tar.xz --name restored
|
||||
vphone-cli vm rename myphone iphone16
|
||||
vphone-cli vm delete iphone16
|
||||
```
|
||||
|
||||
### 手动构建虚拟机(`vm create` 自动化的流程)
|
||||
|
||||
```bash
|
||||
# 终端 2
|
||||
make restore_get_shsh # 获取 SHSH blob
|
||||
make restore # 通过 pymobiledevice3 restore 后端刷写固件
|
||||
# 或:make restore_offline # 离线恢复(就地解密 AEA 镜像,并使用缓存的 .shsh blob)
|
||||
# 首次运行需要联网以完成 AEA 解密
|
||||
vphone-cli vm new myphone # 1. 空 bundle
|
||||
vphone-cli fw prepare myphone --iphone-version 26.1 # 2. 下载并合并 IPSW
|
||||
vphone-cli fw patch myphone --variant jb # 3. 给引导链打补丁
|
||||
|
||||
vphone-cli vm launch myphone --dfu & # 4. 启动进入 DFU(后台)
|
||||
vphone-cli restore myphone --get-shsh # 获取 SHSH
|
||||
vphone-cli restore myphone # DFU 恢复
|
||||
vphone-cli vm stop myphone # 停止 DFU 引导
|
||||
|
||||
vphone-cli cfw install myphone --variant jb # 5. 安装 CFW(宿主机挂载;会请求 sudo)
|
||||
vphone-cli vm launch myphone # 6. 首次启动
|
||||
```
|
||||
|
||||
## 安装自定义固件
|
||||
要升级到更新的 iOS,把 `fw prepare` 指向一个 IPSW:`--iphone-source /path/to.ipsw --cloudos-source /path/to.ipsw`。
|
||||
|
||||
恢复完成后,在终端 1 中停止 DFU 引导(Ctrl+C),使 VM 完全关机。安装程序会在主机上挂载 VM 的 `Disk.img`,放置所有 CFW 文件,并离线切换启动快照(无需 DFU / ramdisk / SSH),因此需要对磁盘的独占访问。
|
||||
## 运行与连接
|
||||
|
||||
```bash
|
||||
# 终端 2(会自动通过 sudo 重新执行)
|
||||
make cfw_install
|
||||
# 或:make cfw_install_dev # 开发变体
|
||||
# 或:make cfw_install_jb # 越狱变体
|
||||
# 或:make cfw_install_exp # 实验变体(越狱 + 研究补丁栈)
|
||||
# 或:SPOOF_BUILD=23F77 make cfw_install_exp # 同时改写 ProductBuildVersion
|
||||
# 或:FORCE_DSC_MAXSLIDE=1 make cfw_install # 在非 27 基础版本上强制 DSC maxSlide=0(所有变体;27 会自动执行)
|
||||
```
|
||||
`vphone-cli vm launch <name>` 会打开虚拟机窗口;`vphone-cli vm stop <name>` 会将其关闭。客户机在端口 `22222` 上运行 SSH 服务器(dropbear),在 `5901` 上运行 VNC,可通过虚拟机的 NAT IP 访问(在 `bridge100` 上用 `arp -a` 查找):
|
||||
|
||||
## 首次启动
|
||||
- **SSH(越狱):** `ssh -p 22222 mobile@<vm-ip>`(密码 `alpine`)
|
||||
- **SSH(regular/dev):** `ssh -p 22222 root@<vm-ip>`
|
||||
- **VNC:** `vnc://<vm-ip>:5901`
|
||||
|
||||
停止 DFU 引导并完成 CFW 安装后,正常启动 VM:
|
||||
对于 `jb`/`exp` 变体,Sileo 和 TrollStore 会在首次启动时自动安装(可监控 `/var/log/vphone_jb_setup.log`)。
|
||||
|
||||
```bash
|
||||
make boot
|
||||
```
|
||||
## Python 运行时
|
||||
|
||||
执行 `cfw_install_jb` 后,越狱变体在首次启动时将提供 **Sileo** 和 **TrollStore**。你可以使用 Sileo 安装 `openssh-server` 以获得 SSH 访问。
|
||||
有几个步骤(DFU 恢复、IPSW 处理)通过 Python 运行。首次使用时,vphone-cli 会基于宿主机上较新的 `python3`(3.11+)并使用捆绑的 `requirements.txt`,在 `~/.vphone/venv` 处配置一个自包含的 venv——因此签名后的 `.app` 是**可移植的**:把它复制到任何地方(例如 `/Applications`),无需仓库即可运行。配置是自动进行的;运行 `vphone-cli setup` 可提前完成配置。用 `VPHONE_PYTHON=/path/to/python3` 指定特定的解释器,或用 `VPHONE_VENV_DIR=/path` 迁移 venv。
|
||||
|
||||
对于常规版/开发版,VM 会提供**直接控制台**。当看到 `bash-4.4#` 时,按回车并运行以下命令以初始化 shell 环境并生成 SSH 主机密钥:
|
||||
## 常见问题
|
||||
|
||||
```bash
|
||||
export PATH='/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/bin/X11:/usr/games:/iosbinpack64/usr/local/sbin:/iosbinpack64/usr/local/bin:/iosbinpack64/usr/sbin:/iosbinpack64/usr/bin:/iosbinpack64/sbin:/iosbinpack64/bin'
|
||||
**`zsh: killed ./vphone-cli`** —— AMFI/debug 限制未被绕过;见[前置条件](#前置条件)(`amfi_get_out_of_my_way=1` 或 `amfidont`)。
|
||||
|
||||
mkdir -p /var/dropbear
|
||||
cp /iosbinpack64/etc/profile /var/profile
|
||||
cp /iosbinpack64/etc/motd /var/motd
|
||||
**`Virtualization is not available on this hardware`** —— 你的 Mac 本身就是一台虚拟机;PV=3 客户机启动无法嵌套。请使用非嵌套的 macOS 15+ 宿主机。
|
||||
|
||||
# 生成 SSH 主机密钥(SSH 能正常工作所必需)
|
||||
dropbearkey -t rsa -f /var/dropbear/dropbear_rsa_host_key
|
||||
dropbearkey -t ecdsa -f /var/dropbear/dropbear_ecdsa_host_key
|
||||
**卡在 “Press home to continue”** —— 通过 VNC 连接,然后右键点击(双指点击)来模拟 home 键。
|
||||
|
||||
shutdown -h now
|
||||
```
|
||||
**系统应用无法安装** —— 在 iOS 设置过程中,不要选择日本或欧盟作为你的地区(会有额外的监管检查,虚拟机无法满足);请选择例如美国。
|
||||
|
||||
> **注意:** 若不执行主机密钥生成步骤,dropbear(SSH 服务器)会接受连接但立刻关闭,因为它没有密钥进行握手。
|
||||
**应用启动时崩溃并报 `EXC_GUARD` / `GUARD_TYPE_MACH_PORT`** —— 用 `vphone-cli fw patch <name> --variant <v> --force-exc-guard` 重新打补丁,然后重新恢复/安装([#291](https://github.com/Lakr233/vphone-cli/issues/291))。对于 iOS 18 基础版本始终启用。
|
||||
|
||||
## 后续启动
|
||||
**安装 `.ipa`/`.tipa`** —— 使用运行中虚拟机的 Install 菜单(拖放或文件选择器)。
|
||||
|
||||
```bash
|
||||
make boot
|
||||
```
|
||||
## 自动化
|
||||
|
||||
在另一个终端中启动 usbmux 转发隧道:
|
||||
|
||||
```bash
|
||||
python3 -m pymobiledevice3 usbmux forward 2222 22222 # SSH(dropbear)
|
||||
python3 -m pymobiledevice3 usbmux forward 2222 22 # SSH(越狱版:在 Sileo 中安装 openssh-server 后)
|
||||
python3 -m pymobiledevice3 usbmux forward 5901 5901 # VNC
|
||||
python3 -m pymobiledevice3 usbmux forward 5910 5910 # RPC
|
||||
```
|
||||
|
||||
连接方式:
|
||||
|
||||
- **SSH(越狱版):** `ssh -p 2222 mobile@127.0.0.1`(密码:`alpine`)
|
||||
- **SSH(常规版/开发版):** `ssh -p 2222 root@127.0.0.1`(密码:`alpine`)
|
||||
- **VNC:** `vnc://127.0.0.1:5901`
|
||||
- [**RPC:**](http://github.com/doronz88/rpc-project) `rpcclient -p 5910 127.0.0.1`
|
||||
|
||||
## VM 备份与切换
|
||||
|
||||
保存并切换多个 VM 环境(例如不同的 iOS 构建版本或固件变体)。备份存储在 `vm.backups/` 下,使用 `rsync --sparse` 高效处理稀疏磁盘镜像。
|
||||
|
||||
```bash
|
||||
make vm_backup NAME=26.1-clean # 保存当前 VM
|
||||
rm -rf vm && make vm_new # 清空后从新构建开始
|
||||
# ... fw_prepare, fw_patch, restore, cfw_install, boot
|
||||
make vm_backup NAME=26.3-jb # 保存新的 VM
|
||||
make vm_list # 列出所有备份
|
||||
make vm_switch NAME=26.1-clean # 在不同备份之间切换
|
||||
```
|
||||
|
||||
> **注意:** 备份/切换/恢复前请先停止 VM。
|
||||
|
||||
## 常见问题(FAQ)
|
||||
|
||||
> **在做其他任何事情之前——先运行 `git pull` 确保你有最新版。**
|
||||
|
||||
**问:运行时出现 `zsh: killed ./vphone-cli`。**
|
||||
|
||||
AMFI/调试限制未正确绕过。选择以下任一方式:
|
||||
|
||||
- **方式 1(完全禁用 AMFI):**
|
||||
|
||||
```bash
|
||||
sudo nvram boot-args="amfi_get_out_of_my_way=1 -v"
|
||||
```
|
||||
|
||||
- **方式 2(仅禁用调试限制):**
|
||||
在恢复模式中使用 `csrutil enable --without debug`(不完全禁用 SIP),然后安装/加载 [`amfidont`](https://github.com/zqxwce/amfidont) 或 [`amfree`](https://github.com/retX0/amfree),保持 AMFI 其他功能不变。
|
||||
在本仓库中,也可通过 `make amfidont_allow_vphone` 自动写入 `amfidont` 所需的编码路径与 CDHash 允许配置。
|
||||
|
||||
**问:`make boot` / `make boot_dfu` 启动后报错 `VZErrorDomain Code=2 "Virtualization is not available on this hardware."`。**
|
||||
|
||||
这是因为宿主机本身运行在 Apple 虚拟机中,无法再进行嵌套 Virtualization.framework 来启动 guest。请在非嵌套的 macOS 15+ 主机上运行。可用 `make boot_host_preflight` 检查,若显示 `Model Name: Apple Virtual Machine 1` 和 `kern.hv_vmm_present=1` 即为该情况。当前版本会在此类宿主机上通过 `boot_binary_check` 在启动前快速失败。
|
||||
|
||||
**问:系统应用(App Store、信息等)无法下载或安装。**
|
||||
|
||||
在 iOS 初始设置过程中,请**不要**选择**日本**或**欧盟地区**作为你的国家/地区。这些地区要求额外的合规检查(如侧载披露、相机快门声等),虚拟机无法满足这些要求,因此系统应用无法正常下载安装。请选择其他地区(例如美国)以避免此问题。
|
||||
|
||||
**问:卡在"Press home to continue"屏幕。**
|
||||
|
||||
通过 VNC (`vnc://127.0.0.1:5901`) 连接,并在屏幕上右键单击任意位置(在 Mac 触控板上双指点击)。这会模拟 Home 按钮按下。
|
||||
|
||||
**问:如何获得 SSH 访问?**
|
||||
|
||||
从 Sileo 安装 `openssh-server`(越狱变体首次启动后可用)。
|
||||
|
||||
**问:安装 openssh-server 后 SSH 无法使用。**
|
||||
|
||||
重启虚拟机。SSH 服务器将在下次启动时自动启动。
|
||||
|
||||
**问:可以安装 `.tipa` 文件吗?**
|
||||
|
||||
可以。安装菜单同时支持 `.ipa` 和 `.tipa` 包。拖放或使用文件选择器即可。
|
||||
|
||||
**问:可以升级到更新的 iOS 版本吗?**
|
||||
|
||||
可以。使用你想要的版本的 IPSW URL 覆盖 `fw_prepare`:
|
||||
|
||||
```bash
|
||||
export IPHONE_SOURCE=/path/to/some_os.ipsw
|
||||
export CLOUDOS_SOURCE=/path/to/some_os.ipsw
|
||||
make fw_prepare
|
||||
make fw_patch
|
||||
```
|
||||
|
||||
我们的补丁是通过二进制分析(binary analysis)而非静态偏移(static offsets)应用的,因此更新的版本应该也能正常工作。如果出现问题,可以寻求 AI 的帮助。
|
||||
|
||||
**问:使用 `restore_offline` 后卡在设置界面。**
|
||||
|
||||
设备在设置过程中会尝试连接 Apple,如果你使用了 `restore_offline`,很可能当前没有联网。
|
||||
你可以将设备设为 supervised,以绕过大部分设置界面:
|
||||
|
||||
```bash
|
||||
python3 -m pymobiledevice3 profile supervise vphone
|
||||
```
|
||||
`vphone-cli` 暴露了一个宿主控制套接字(`<bundle>/vphone.sock`)用于程序化控制——截图、触控、滑动、硬件按键、剪贴板——每个动作都会返回一张内联截图,用于 AI 驱动的端到端测试。包装它的 MCP 服务器见 [vphone-mcp](https://github.com/pluginslab/vphone-mcp)。
|
||||
|
||||
## 致谢
|
||||
|
||||
|
||||
Reference in New Issue
Block a user