LakrandClaude Opus 5 b7a7498a14 Let libmisfix say which MobileGestalt queries it actually sees
On test-26.4 the UDID override reaches misagent — a paid-team profile
whose ProvisionedDevices lists the override installs, and one that does
not is refused with 0xE8008012, exactly as it should be. installd then
refuses the same app with 0xE8008015, "A valid provisioning profile for
this executable was not found", and a hand-restarted installd does it
again, so it is not staleness.

Two explanations fit that equally well from outside: installd asks and
gets the wrong answer, or installd never asks through this symbol at
all. They are not distinguishable without instrumenting, and the second
is quite likely — `MICodeSigningVerifier` lives in MobileInstallation,
not in installd, and it calls libmis, so the query that matters is made
cache-to-cache between two shared-cache images rather than from the main
executable the way misagent's is. installd's own imports are only
_MGCopyAnswer and _MGGetBoolAnswer, the same as misagent's, so the
import table cannot tell them apart either. The one MobileGestalt line
the guest logged during a failing install was from installd and said
"elided platform fast path for key: re6Zb+zwFKJNlkQTUeT+/w".

So the hook now logs each query and whether it answered, behind a new
`LogQueries` flag that is off by default — these daemons are asked a
lot, and the log is how a person watches an install. If an install
produces no line from installd, the call is not coming through
MGCopyAnswer and the hook needs a different point to stand on.

The config cache now holds the whole dictionary rather than just the
UDID, so a second setting costs no second read and every value stays
consistent with the file it came from. MISFixCopyConfiguredDeviceIdentifier
returns the dictionary's own string instead of a copy; it was already
documented as borrowed.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-30 18:41:23 +09:00
…
…

Docs · English · 中文 · 日本語 · 한국어

vphone-cli

Run a virtual iPhone on an Apple Silicon Mac.

Virtual iPhone running on macOS

vphone-cli runs iOS with Apple's Virtualization.framework and PCC research virtual machines, for security research, reverse engineering, and debugging.

  • Graphical Window: Use the virtual iPhone's screen on your Mac, browse apps and files, and take screenshots and screen recordings.
  • Custom Firmware: The system comes pre-patched, and you can install a package environment.
  • Backup and Cloning: You can export, import, and clone VMs.
  • Automation API: An optional local HTTP and WebSocket interface.
  • No Extra Dependencies: Needs no Xcode, Python, or Homebrew at runtime.

For 1.x, see the 1.0.14 release. Version 2.x cannot start VMs created by 1.x. You need to create them again.

Requirements

  • A physical Apple Silicon Mac running macOS 15 or newer. It does not work in a macOS VM.

  • Enough disk space. Each VM uses a 64 GB virtual disk by default, and firmware and temporary files take additional space.

  • A network connection. Restoring the system fetches signing tickets online.

  • Adjusted security settings. Boot into macOS Recovery, run these commands in Terminal, then restart:

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

    SIP stays enabled, with only the debugging restrictions relaxed. For the reasons and other ways to set this up, see Host Setup.

Get Started

  1. Download the latest vphone-launchpad (vphone-launchpad-<version>.zip), unzip it, and open it.
  2. In Host Setup, grant Developer Tools access and install the helper.
  3. In Core Bundle, click Download and Install. Launchpad downloads and verifies VPhone.bundle, then allows the VM program inside it to run on your Mac.
  4. In Machines, click New Machine, choose a firmware pairing, and click Create.

Launchpad downloads the firmware, patches it, restores the system, and boots it for the first time. When it finishes, the VM keeps running.

You can also use your own iPhone and cloudOS IPSWs. For verified pairings, see Compatibility.

Install the Package Environment

The VM has no package manager by default. To install one:

  1. In the menu bar, choose Apps > Install Bootstrap… and select the roothide layout (rootless is deprecated). This installs Irisin in the VM.

  2. For the first installation, select all of the following packages in Irisin at once, press and hold the install button, and choose Bootstrap Install:

    • apt
    • bash
    • uikittools
    • launchctl
    • openssh-server

    Installing them together in one bootstrap pass is recommended. Several of these packages depend on one another (for example, bash and debianutils), and openssh-server in particular declares some dependencies circularly or imprecisely, so installing them one by one with a normal install can fail partway.

  3. After the first installation, install further packages normally.

If the first installation fails or leaves the environment in an inconsistent state, do not attempt to repair it in place. Remove the environment with Apps > Uninstall Bootstrap… and install it again from step 1.

To remove the environment, choose Apps > Uninstall Bootstrap…. The VM restarts after removal.

Hold Option while opening the Apps menu to see two more options:

  • Install Bootstrap from File…: Installs from a local Irisin .deb.
  • Uninstall Bootstrap Without Restarting…: Removes the environment without restarting the VM.

Command Line

Launchpad manages VMs through the vphone-cli inside VPhone.bundle. You can also use it directly in Terminal:

Task Command
List VMs vphone-cli vm list
Show VM information vphone-cli vm info myphone
Start a VM vphone-cli vm launch myphone
Stop a VM vphone-cli vm stop myphone
Clone a VM vphone-cli vm clone myphone copy
Export a VM vphone-cli vm export myphone --out myphone.tzst
Import a VM vphone-cli vm import myphone.tzst --name restored

VMs are stored in ~/.vphone/ by default. Run vphone-cli <group> --help to see all commands. To create a VM without Launchpad, see Create and Run.

Automation API

Add --api-listen at launch to turn it on:

vphone-cli vm launch myphone --api-listen 127.0.0.1:8765
# The output shows [api] token: …
curl -H "Authorization: Bearer $TOKEN" http://127.0.0.1:8765/v1/health

Each launch generates a new token. To use a fixed token, set the VPHONE_API_TOKEN environment variable. Requests without the token and requests from web pages are refused. For the interface reference, see the API documentation.

Troubleshooting

Start with Troubleshooting, which covers cases such as the system refusing the VM program, restore failures, and getting stuck on "Press home to continue". If that does not solve it, open an issue.

Documentation

Document Contents
Host Setup SIP and AMFI settings, building from source, environment checks
Create and Run Firmware sources, the creation process, storage and backups
Compatibility Verified firmware pairings
Troubleshooting Common errors and how to fix them
Launchpad Command Line Install and test a local build with vphone-launchpad-cli
Research Notes Patch and implementation details

Project Structure

  • vphone-launchpad: A Mac app that downloads and installs VPhone.bundle and sets up the host. Released separately.
  • vphone-cli: Prepares firmware, patches it, restores the system, and manages VMs.
  • vphone-vm: Runs the VM and shows its window.
  • vphoned: The control service inside the VM. The window's features and the API work through it.
Path Contents
VPhoneExecutable/ vphone-cli, vphone-vm, firmware patching and restore
VPhoneKit/ Shared host libraries and API client
VPhoneDaemon/ vphoned
VPhoneGuestComponents/ Hooks and helper programs inside the VM
VPhoneLaunchpad/ The Launchpad app and its helper

To build from source, run xcodebuild -workspace VPhone.xcworkspace -scheme VPhone build. The output is VPhone.bundle.

Acknowledgements

S
Description
GitHub Trending: Lakr233/vphone-cli
Readme MIT
100 MiB
Languages
Swift 77.9%
C 16.7%
Objective-C 4.8%
Shell 0.3%
Objective-C++ 0.2%
Other 0.1%