
Démarrez et gérez des iPhones virtuels sur Apple Silicon avec le patchage du firmware, des variantes de jailbreak et des fonctionnalités de recherche en sécurité pour les tests et l'analyse iOS.
Démarrez un iPhone virtuel via le framework Virtualization d'Apple en utilisant l'infrastructure de VM de recherche PCC.

Hôte :
Dépendances :
brew install [email protected] aria2 wget gnu-tar openssl@3 ldid-procursus sshpass keystone cmake libusb ipsw zstd
brew install zqxwce/tap/vphone-cli
git clone --recurse-submodules https://github.com/Lakr233/vphone-cli.git
./scripts/setup_tools.sh # installe les dépendances, compile les sous-modules de la toolchain, crée le venv Python
./scripts/build.sh # compile + signe vphone-cli, regroupe le .app, compile vphoned en croisé
cd .build/vphone-cli.app/Contents/MacOS/
vphone-cli --help
Une seule commande crée une VM de bout en bout (téléchargement → patch → restauration DFU → installation CFW → premier démarrage) :
vphone-cli vm create myphone -V jb # -V / --variant
vphone-cli vm launch myphone
vphone-cli vm create exécute tout le pipeline ; les étapes individuelles ci-dessous vous permettent de piloter manuellement ou de relancer une étape.
vphone-cli vm list # liste les VM (--json pour le scripting)
vphone-cli vm info myphone # affiche une VM
vphone-cli vm new myphone # crée un bundle vide (options cpu/mem/disk)
vphone-cli vm config myphone --cpu 8 --memory 8192
vphone-cli vm clone myphone myphone-2 # clone APFS rapide, nouvelle identité d'appareil
vphone-cli vm export myphone --out myphone.tzst # zstd rapide par défaut (--max = xz -9) ; --out peut être un répertoire (nom automatique <vm>.tzst/.txz) ; ignore le dossier restore + les fichiers de staging
vphone-cli vm import myphone.tzst --name restored
vphone-cli vm rename myphone iphone16
vphone-cli vm delete iphone16
vm create automatise)vphone-cli vm new myphone # 1. bundle vide
vphone-cli fw prepare myphone --iphone-version 26.1 # 2. téléchargement + fusion des IPSW
vphone-cli fw patch myphone --variant jb # 3. patch de la chaîne de démarrage
vphone-cli vm launch myphone --dfu & # 4. démarrage en DFU (arrière-plan)
vphone-cli restore myphone --get-shsh # récupération du SHSH
vphone-cli restore myphone # restauration DFU
vphone-cli vm stop myphone # arrêt du démarrage DFU
vphone-cli cfw install myphone --variant jb # 5. installation du CFW (montage hôte ; demande sudo)
vphone-cli vm launch myphone # 6. premier démarrage
Mettez à jour vers un iOS plus récent en pointant fw prepare vers un IPSW : --iphone-source /path/to.ipsw --cloudos-source /path/to.ipsw.
Cinq variantes de patch avec un contournement de sécurité croissant — passez-en une à --variant :
| Variante | Chaîne de démarrage | CFW | Notes |
|---|---|---|---|
less | 4 patches | 2 phases | Sans patch — conserve les mitigations iOS activées |
regular | 42 patches | 10 phases | Contournement AMFI/SSV/Img4/TXM |
dev | 53 patches | 12 phases | + contournement entitlement/debug TXM |
jb | 113 patches | 14 phases | + jailbreak complet (Sileo, TrollStore auto-installé au premier démarrage) |
exp | 141 patches | 18 phases | Sur-ensemble JB + patches de recherche anti-détection de VM |
Voir research/0_binary_patch_comparison.md pour le détail par composant.
ssh -p 22222 mobile@<vm-ip> (mot de passe alpine)ssh -p 22222 root@<vm-ip>vnc://<vm-ip>:5901Tout ce que vphone-cli crée se trouve sous ~/.vphone/ — conservé hors du dépôt et du .app pour que le bundle signé reste portable. Redirigez tout l'arborescence avec $VPHONE_ROOT :
| Chemin | Contenu |
|---|---|
~/.vphone/ | Racine de données par utilisateur — remplacez tout l'emplacement avec $VPHONE_ROOT. |
~/.vphone/VMs/ | Bundles de VM — un répertoire par VM. C'est la bibliothèque ; remplacez avec $VPHONE_LIBRARY_ROOT. |
~/.vphone/ipsws/ | IPSW iPhone + cloudOS téléchargés, mis en cache et réutilisés entre les VM. |
~/.vphone/tools/ | Artefacts APFS seal-volume mis en cache (apfs_sealvolume_<version>) récupérés lors de fw prepare. |
~/.vphone/debs/ | Paquets .deb mis en cache que l'installation CFW jb/exp dépose dans l'invité (Sileo, apt, …). |
~/.vphone/venv/ | Environnement Python auto-provisionné (voir Runtime Python ; remplacez avec $VPHONE_VENV_DIR). |
Priorité : les remplacements par élément ($VPHONE_LIBRARY_ROOT, $VPHONE_VENV_DIR) priment sur $VPHONE_ROOT, qui prime sur la valeur par défaut ~/.vphone. Les caches ipsws/, tools/ et debs/ se trouvent toujours directement sous la racine active.
Option A — désactivez complètement SIP, puis désactivez AMFI via boot-arg (le plus permissif).
En mode Recovery (appui long sur le bouton d'alimentation → Terminal) :
csrutil disable
csrutil allow-research-guests enable
Redémarrez ensuite sous macOS et définissez le boot-arg AMFI (nécessite SIP complètement désactivé pour prendre effet) :
sudo nvram boot-args="amfi_get_out_of_my_way=1 -v" # redémarrez après
Option B — gardez SIP activé (assoupli debug uniquement), puis autorisez le binaire avec amfidont (laisse AMFI activé à l'échelle du système).
En mode Recovery :
csrutil enable --without debug
csrutil allow-research-guests enable
Redémarrez ensuite sous macOS et :
vphone-amfidont # .build/vphone-cli.app/Contents/Resources/vphone-amfidont pour les builds locaux
| Hôte | iPhone | CloudOS |
|---|---|---|
| Mac16,11 27.0b2 | 17,3_18.6.2_22G100 | 26.1-23B85 |
| Mac16,8 26.5.1 | 17,3_26.0_23A341 | 26.1-23B85 |
| Mac16,8 26.5.1 | 17,3_26.0.1_23A355 | 26.1-23B85 |
| Mac16,12 26.3 | 17,3_26.1_23B85 | 26.1-23B85 |
| Mac16,12 26.3 | 17,3_26.3_23D127 | 26.1-23B85 |
| Mac16,12 26.3 | 17,3_26.3_23D127 | 26.3-23D128 |
| Mac16,12 26.3 | 17,3_26.3.1_23D8133 | 26.3-23D128 |
| Mac16,11 26.2 | 17,3_26.4_23E246 | 26.4-23E5207q |
| Mac16,11 26.2 | 17,3_26.5_23F77 | 26.4-23E5207q |
| Mac16,11 27.0b2 | 17,3_26.5.2_23F84 | 26.4-23E5207q |
| Mac16,6 26.4.1 | 17,3_26.6_23G71 | 26.4-23E5207q |
| Mac16,11 27.0b2 | 17,3_26.6.1_23G83 | 26.4-23E5207q |
| Mac16,11 27.0b2 | 17,3_27.0_24A5380h | 26.4-23E5207q |
| Mac16,6 26.4.1 | 17,3_27.0_24A5390f | 26.4-23E5207q |
| Mac16,6 26.6.1 | 17,3_27.0_24A5408d | 26.4-23E5207q |
| Mac16,11 27.0b2 | 17,3_27.0_24A5418b | 26.4-23E5207q |
| Mac16,11 27.0b2 | 17,3_27.0_24A5424a | 26.4-23E5207q |
zsh: killed ./vphone-cli — les restrictions AMFI/debug ne sont pas contournées ; voir Prérequis (amfi_get_out_of_my_way=1 ou amfidont).
Virtualization is not available on this hardware — votre Mac est lui-même une VM ; le démarrage d'un invité PV=3 ne peut pas être imbriqué. Utilisez un hôte macOS 15+ non imbriqué.
Bloqué sur « Press home to continue » — connectez-vous via VNC et faites un clic droit (clic à deux doigts) pour simuler le bouton d'accueil.
Les applications système ne s'installent pas — lors de la configuration iOS, ne choisissez pas le Japon ou l'UE comme région (contrôles réglementaires supplémentaires que la VM ne peut pas satisfaire) ; choisissez par exemple les États-Unis.
L'application plante au lancement avec EXC_GUARD / GUARD_TYPE_MACH_PORT — re-patchez avec vphone-cli fw patch <name> --variant <v> --force-exc-guard, puis restaurez/réinstallez (#291). Toujours activé pour les bases iOS 18.
Installer un .ipa/.tipa — utilisez le menu Install de la VM en cours d'exécution (glisser-déposer ou sélecteur de fichiers).
cfw install se bloque en re-signant un binaire système (ex. Campo), la mémoire augmente sans limite — bug connu dans ldid-procursus jusqu'à 2.1.5-procursus7 (le stable Homebrew actuel) : bytes(uint64_t) appelle __builtin_clzll(0) sans garde de zéro, ce qui est un comportement indéfini, et sur cette build se résout en une longueur 0 qui provoque un underflow d'un compteur de boucle non signé — ldid tourne en écrivant un octet à la fois dans un buffer croissant au lieu de se terminer. Déclenché par tout plist d'entitlements contenant une valeur entière exactement 0 (certains vrais binaires système Apple en ont). Corrigé en amont mais pas encore dans une release taguée ; recompilez depuis la source : brew install --HEAD ldid-procursus && brew link --overwrite ldid-procursus. Tuez d'abord le processus ldid bloqué (sudo kill -9 <pid>) si vous l'avez déjà atteint.
vphone-cli expose un socket de contrôle hôte (<bundle>/vphone.sock) pour un contrôle programmatique — captures d'écran, toucher, balayages, touches matérielles, presse-papiers — chaque action renvoyant une capture d'écran intégrée pour les tests E2E pilotés par IA. Voir vphone-mcp pour un serveur MCP qui l'enveloppe.