vphone-cli Setup and Usage Guide
Project: https://github.com/Lakr233/vphone-cli
I. Pre-Setup Checks
1. Hardware Requirements
Use the following:
- A physical Mac with Apple silicon.
- macOS 15 or later.
- The full version of Xcode.
- A stable network connection.
- At least 100 GB of available disk space.
- An administrator account and its password.
Do not run this project in VMware, Parallels, UTM, or an Apple Virtual Machine. The project cannot start another Virtualization.framework virtual machine from inside a nested virtual machine.
2. Check the Current Environment
Open Terminal and run the following commands one by one:
uname -m
sw_vers -productVersion
system_profiler SPHardwareDataType | grep "Model Name"
sysctl -n kern.hv_vmm_present
df -h /
Expected results:
uname -mshould displayarm64.- The macOS version must be 15 or later.
- The model must not be
Apple Virtual Machine 1. - If
kern.hv_vmm_presentdisplays1, the current macOS system may itself be running inside a virtual machine, and you should not continue. - There should be sufficient available disk space.
3. Install the Full Version of Xcode
Install Xcode from the App Store. After installation, launch Xcode once and accept the license agreement. Then run the following commands in Terminal:
sudo xcode-select -s /Applications/Xcode.app/Contents/Developer
sudo xcodebuild -license accept
xcrun -sdk iphoneos --show-sdk-path
The last command should output a path to iPhoneOS.sdk.
4. Install Homebrew
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
Verify the installation:
brew --version
II. Modify Mac Security Settings: Completely Disable SIP and Configure the AMFI Boot Arguments
1. Record the Existing Boot Arguments
In a normal macOS Terminal session, run:
nvram -p | grep '^boot-args'
If the command produces output, take a photo of it or copy and save it. Setting new boot-args later will overwrite the existing value.
Then shut down the Mac.
2. Enter macOS Recovery Mode
- After the Mac has completely shut down, press and hold the power button. Do not release it immediately.
- Continue holding the power button after the screen turns on.
- Release the power button when you see “Loading startup options” or the gear-shaped “Options” icon.
- Select Options.
- Click Continue.
- If prompted to select a system volume, select Macintosh HD.
- If prompted to select an administrator user, select the current administrator account and enter its login password.
3. Open Terminal in Recovery Mode
After entering the Recovery utilities screen, select Utilities → Terminal from the menu bar at the top of the screen.
4. Run Commands in the Recovery Terminal
Confirm that the current Terminal window is running in Recovery Mode, then execute the following commands one by one:
csrutil disable
csrutil allow-research-guests enable
Select the system volume used for daily operation, usually Macintosh HD.
After the commands complete, you can verify the settings:
csrutil status
csrutil allow-research-guests status
Then select Apple menu → Restart in the upper-left corner.
5. Configure the AMFI Boot Arguments
After restarting into normal macOS, open Terminal and run:
sudo nvram boot-args="amfi_get_out_of_my_way=1 -v"
This command overwrites the existing boot-args. Therefore, you must save the original value beforehand.
Then restart the Mac.
6. Verify the Configuration After Restarting
After entering macOS again, run:
csrutil status
csrutil allow-research-guests status
sysctl -n kern.bootargs
Expected results:
- SIP shows
disabled. - Research Guests shows
enabled. kern.bootargscontains:
amfi_get_out_of_my_way=1 -v
III. Build and Verify
1. Build the Program
Clone the project and initialize its submodules.
Run the following command from the project root directory:
make build
A successful build should display output similar to:
=== Building vphone-cli ===
=== Signing with entitlements ===
signed OK
2. Run the Preflight Check
make boot_host_preflight
Pay particular attention to the following items in the output:
SIP:allow-research-guests:current kern.bootargs:Signed Release BinaryResult
If the Mac security settings have been configured correctly, the following conditions should be met:
- SIP is
disabled. - Research Guests is
enabled. - The boot arguments contain
amfi_get_out_of_my_way=1. - The
Signed Release Binarytest exits with code0. - The output should not contain
exit 137,signal 9, ornested VM.
IV. Run the Complete Automated Deployment
1. Run the Setup Command from the Project Root Directory
make setup_machine EXP=1
This installs the experimental firmware variant, including jailbreak-related functionality.
The command performs the following steps in sequence:
- Installs Homebrew dependencies.
- Creates a Python virtual environment.
- Builds the required tools and
vphone-cli. - Creates a default 64 GB virtual disk.
- Downloads the iPhone IPSW and cloudOS firmware.
- Merges and patches the boot chain.
- Starts the virtual machine in DFU mode.
- Obtains SHSH data.
- Restores the virtual iPhone.
- Mounts the virtual disk offline and installs the CFW.
- Performs first-boot initialization.
The default firmware combination is the project-provided and tested iPhone17,3 / iOS 26.1 / 23B85, together with the corresponding cloudOS source.
2. Important Notes During Deployment
- Do not allow the Mac to enter sleep mode.
- Do not close the MacBook display.
- Do not close the Terminal window running the setup process.
- Do not manually terminate
vphone-cli, the restore process, or the virtual machine window. - When prompted for a
sudopassword, enter the password of the current Mac administrator account. - Firmware downloads and restoration may take a long time. As long as the Terminal continues to show progress, keep waiting.
3. First-Boot Procedure
If the script displays output similar to:
press Enter to start VM
Press Enter once to start the virtual machine.
The script will later display:
Press Enter once the VM is fully booted
Wait until one of the following conditions is met:
- The virtual iPhone has reached a stable system interface; or
- The Regular variant console displays the
bash-4.4#prompt.
After confirming that the system is no longer continuously scrolling boot logs, press Enter. The script will send the first-boot initialization commands and wait for the virtual machine to shut down.
The final output should include:
=== Done ===
Setup completed.
V. Routine Startup
After deployment is complete, use the following commands each time you want to start the virtual iPhone:
cd path_to_project/vphone-cli
make boot
Under normal conditions, this opens the virtual iPhone window.
When exiting, prefer the project window's normal exit method or shut down the virtual device normally. Do not force-terminate the process while the virtual disk is being written.
VI. Create an ECDSA Key for vphone
Dropbear currently supports ECDSA. Create a dedicated ECDSA P-521 key for vphone so that future SSH logins do not require a password.
Run the following command on mac-black:
ssh-keygen \
-t ecdsa \
-b 521 \
-f ~/.ssh/vphone_ecdsa \
-C "miao@vphone"
Check the virtual machine's IP address.
Obtain the IP address from the top of the iOS simulator interface. For example:
192.168.64.7
[Image]
Then install the public key. Replace the IP address in the command with the correct address:
ssh \
-p 22222 \
-o PreferredAuthentications=password \
-o PubkeyAuthentication=no \
'PATH=/var/jb/usr/bin:/var/jb/bin:/iosbinpack64/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin; export PATH; umask 077; mkdir -p /var/root/.ssh; cat >> /var/root/.ssh/authorized_keys; chmod 700 /var/root/.ssh; chmod 600 /var/root/.ssh/authorized_keys' \
< ~/.ssh/vphone_ecdsa.pub
According to the vphone-cli project configuration, the default password for root is:
alpine
Verify passwordless login:
ssh \
-i ~/.ssh/vphone_ecdsa \
-p 22222 \
-o IdentitiesOnly=yes \
-o BatchMode=yes \
'echo "public key login OK"'
Expected output:
public key login OK
If the key is needed by Benchmark Bridge, set the private-key path to:
~/.ssh/vphone_ecdsa
VII. Basic iOS Virtual Device Control
1. Operations over SSH
Log in to the iPhone over SSH:
The EXP Procursus environment includes uiopen.
Open Settings:
uiopen -a Settings
Open an application by Bundle ID:
uiopen -b com.apple.Health
uiopen -b com.apple.Maps
Open a URL:
uiopen -u https://www.apple.com.cn
List registered applications and their Bundle IDs:
uicache -l
Search for a specific application:
uicache -l | grep -i safari
If /var/jb has not yet been created, the EXP first-boot initialization has not completed. Check it with:
ls -ld /var/jb
tail -100 /var/log/vphone_jb_setup.log
2. Operations Without SSH
Run the following commands from the root directory of the vphone-cli repository:
cd path_to_project/vphone-cli
Inject a Home button event:
printf '%s\n' \
'{"t":"key","name":"home","screen":false}' |
nc -U vm/vphone.sock
A successful request returns:
{"ok":true}
This injects an actual Home HID event through vphoned.
You can use the same method for other hardware buttons, including Power, Volume Up, and Volume Down:
printf '%s\n' '{"t":"key","name":"power","screen":false}' |
nc -U vm/vphone.sock
printf '%s\n' '{"t":"key","name":"volup","screen":false}' |
nc -U vm/vphone.sock
printf '%s\n' '{"t":"key","name":"voldown","screen":false}' |
nc -U vm/vphone.sock
Take a Screenshot
cd /path_to_project/vphone-cli
mkdir -p screenshot
shot_file="$PWD/screenshot/iphone-$(date '+%Y%m%d-%H%M%S').png"
printf '{"t":"screenshot","path":"%s"}\n' "$shot_file" |
nc -U vm/vphone.sock >/dev/null
The generated file path will look similar to:
/path_to_project/vphone-cli/screenshot/iphone-20260721-143052.png
Tap and Swipe
Tap a screen coordinate:
printf '%s\n' \
'{"t":"tap","x":645,"y":1398,"screen":false}' |
nc -U vm/vphone.sock
Swipe upward:
printf '%s\n' \
'{"t":"swipe","x1":645,"y1":2400,"x2":645,"y2":900,"ms":300,"screen":false}' |
nc -U vm/vphone.sock
The default screen coordinate dimensions are 1290 × 2796.