Virtualiser iOS sur Apple Silicon
(nickb.website)- Une expérimentation visant à démarrer une build iPhone XR d’iOS 15.0.2 jusqu’à
PreBoard.appen utilisant Virtualization.framework sur Mac Apple silicon et l’environnement vma2 - Le cœur de l’approche consiste à réutiliser la chaîne de démarrage de macOS 12.0.1 et à ne remplacer que l’image système iOS,
mtree,root_hashettrustcache, afin de réduire la charge liée à la modification de la chaîne de démarrage initiale - En appelant l’API privée
_setProductionModeEnabled(false)pour abaisser la VM à l’état CPFM01, TSS signe des firmwares arbitraires pour les appareils vma2 publics, ce qui réduit le besoin de l’ancienne approche vma2pwn - Le démarrage réel nécessite des patches noyau et système touchant les vérifications de plateforme XNU, le system keybag, les contrôles de taille IOMFB, le ramdisk,
launchd,mount, le DYLD shared cache,lockdowndetmobileactivationd - Le principal problème non résolu reste la compatibilité du system keybag ; il n’est pas encore confirmé non plus que la saisie tactile soit possible via les API privées de Virtualization.framework
Objectif de l’expérimentation et point de départ
- Après la transition vers Apple silicon et Mac Catalyst, iOS et macOS se sont rapprochés ; avec la possibilité de virtualiser macOS, la question centrale est devenue de savoir si iOS pouvait lui aussi être virtualisé en modifiant une chaîne de démarrage de la même famille
- Le travail précédent, vma2pwn, était un projet visant à créer une chaîne de démarrage macOS vma2 modifiable pour les VM invitées macOS, et sert de base à cette expérimentation
- Parmi les exemples publics aboutis de virtualisation/émulation d’iOS figure le produit virtual iPhone cloud de Corellium
- qemu-t8030, des travaux basés sur QEMU et les articles de Zhuowei Zhang ont aussi servi de référence ; en particulier, la relation entre
IOSurfaceRootsur macOS etIOCoreSurfaceRootsur iOS a aidé ensuite à explorer les patches noyau - L’article de Zhuowei Zhang considérait que les apps macOS à interface graphique ne peuvent pas s’exécuter sur iOS, mais que les apps iOS graphiques peuvent s’exécuter sur macOS ; cette propriété s’applique aussi à une grande partie du système graphique d’iOS
Fonctionnalités privées de Virtualization.framework
- Le Virtualization.framework d’Apple contient une fonction privée non documentée,
_setProductionModeEnabled(false) - Cet appel, ainsi que la fonctionnalité correspondante dans la configuration de la VM, abaissent la VM au Chip Fuse Mode CPFM
01, configurant l’appareil virtuel dans un état à la fois « secure » et « non-production » - Sur un appareil physique, TSS refuse de signer les blobs SHSH nécessaires aux appareils non-production/non-secure tels que CPFM
00ou01 - Pour les appareils vma2 publics, TSS signe le firmware arbitraire fourni, ce qui réduit fortement la nécessité de l’approche vma2pwn, qui consistait à construire une chaîne de firmware modifiée
Méthode de configuration de la VM iOS
- L’approche qui a le mieux fonctionné consiste à conserver telle quelle la chaîne de démarrage de macOS 12.0.1 et à remplacer l’image de l’OS système par l’image et les fichiers associés de la build iPhone XR d’iOS 15.0.2
- Les éléments remplacés sont l’image système,
mtree,root_hashettrustcache - Cette méthode contourne en grande partie la nécessité de modifier la chaîne de démarrage et le ramdisk de récupération avant l’initialisation d’iOS
- Les éléments remplacés sont l’image système,
- La build iPhone XR a été choisie en raison de sa prise en charge arm64e et de la possibilité d’une résolution plus faible
- D’autres configurations d’appareils arm64e pourraient aussi réussir, mais le noyau vma2 est codé en dur pour renvoyer
"iPad8,6"pour certaines clés sysctl - Les builds arm64 ont rencontré des problèmes supplémentaires et des incompatibilités binaires, et ont donc été jugées peu intéressantes à tenter
- Pour exécuter la VM, l’auteur utilise super-tart, un fork de tart, une app tierce de gestion de VM Apple silicon
- super-tart permet d’utiliser les fonctionnalités privées nécessaires de Virtualization.framework
- Certaines modifications, comme le changement de réglage
_setProductionModeEnabled(false), n’ont pas encore toutes été poussées - Les outils Virtualization.framework utilisant des API privées nécessitent de désactiver SIP, et il peut aussi être nécessaire de désactiver AMFI
- Un fork d’idevicerestore est utilisé comme outil de restauration
Patches noyau
- Le patch de vérification de signature utilisé dans vma2pwn peut être nécessaire, mais il n’est pas certain qu’il le soit absolument avec l’approche CPFM
01 - Les patches liés aux signatures consistent à faire en sorte que les fonctions suivantes du noyau vma2 renvoient 0
_apfs_extract_root_hash_arm_authenticate_root_hash__img4_firmware_property_callback_is_root_hash_authentication_required_img4_firmware_evaluate
lookup_in_static_trust_cachedoit être patché pour renvoyer 1- Comme les binaires iOS ne sont pas des binaires de plateforme simulateur, ils se terminent initialement avec
EXEC, [0xe] Binary with wrong platform- Le problème se résout en patchant XNU pour sauter la ligne de vérification
PLATFORM_IOS - Dans le noyau vma2, cela s’applique en remplaçant
B.NEparB
- Le problème se résout en patchant XNU pour sauter la ligne de vérification
- En raison de l’incompatibilité du system keybag,
PreBoard.appaffiche « Swipe up to upgrade. » au lieu deSetup.app- En appliquant deux patches à
ipc_make_system_keybagpour forcer la fonction à ne pas renvoyer d’erreur, il est possible d’atteindrePreBoard.app - Cette limite n’est pas encore totalement résolue
- En appliquant deux patches à
- L’inadéquation de taille de la structure IOMFB entre les frameworks système iOS et le noyau macOS provoque une panique noyau avec la chaîne
CLCDTransaction size mismatch. Returning error 0x%X.- Supprimer le contrôle de taille dans
IOMobileFramebufferUserClient::swap_submitarrête la panique
- Supprimer le contrôle de taille dans
Préparer les patches de fichiers système
- Le ramdisk de récupération et les fichiers système iOS étant signés, ils se terminent à l’exécution s’ils ne sont pas resignés après patch
- Dans l’environnement modifié, l’utilisation de
ldidde Procursus est suggérée- Exemple d’installation :
brew install ldid-procursus - Exemple de resignature :
ldid_macosx_arm64 -S -M <binary> -Spseudo-signe le binaire et-Mconserve les entitlements existants
- Exemple d’installation :
- De nombreux binaires effectuent des vérifications d’identité ; avant resignature, il faut donc les renommer avec leur identity, puis les remettre à leur nom d’origine
keybagdconfirmeIdentifier=com.apple.keybagdaveccodesign -d -v keybagdmv keybagd com.apple.keybagdldid_macosx_arm64 -S -M com.apple.keybagdmv com.apple.keybagd keybagd
- Les fonctions qui ne reçoivent pas automatiquement de symboles peuvent être trouvées en recherchant des XRef de chaînes, puis en suivant les fonctions appelantes via les références aux appels de journalisation
- Pour obtenir un shell interactif sur le terminal série, il est possible de porter Bash et un LaunchDaemon
- La méthode utilisée consiste à copier les fichiers associés depuis un payload de jailbreak iOS compatible en version, comme Procursus
Modification des DMG et du ramdisk
- Pour patcher le système ou le ramdisk de récupération, il faut modifier directement le volume DMG
- Dans l’exemple iOS 15.0.2, le volume iOS System inclus dans l’IPSW est converti en format lisible/inscriptible
hdiutil convert -format UDRW -o 018-66258-074-rw.dmg 018-66258-074.dmg- Après montage :
sudo mount -uw /Volumes/Sky19A404.N104N841OS - Après modification :
hdiutil convert -format ULFO -o 018-66258-074.dmg 018-66258-074-rw.dmg - Puis
asr imagescan --source 018-66258-074.dmg
- Avant le démarrage d’iOS, il faut modifier
/usr/local/bin/restored_externaldans le ramdisk de récupération- La version iOS de
restored_externaltente de créer le system keybag avecMKBKeyBagCreateSystem, mais ce n’est pas compatible avec le noyau macOS - Le contournement consiste à supprimer la vérification d’erreur
- En patchant la condition d’appel de
ramrod_set_NVRAM_variable,allow-root-hash-mismatchest réglé à true, c’est-à-dire1, et l’authentification du root hash est ignorée
- La version iOS de
- Il faut aussi modifier
/usr/sbin/asrdans le ramdisk de récupération- asr64_patcher d’iSuns9 peut être utilisé
- Il faut trouver la fonction qui affiche la chaîne
"Image failed signature verification.", puis, dans la fonction qui la référence, remplacer l’appel ARMv8-ABLpar un sautBvers le chemin"Image passed signature verification" - Dans le binaire
asrd’iOS 15.0.2,b #0x7cest appliqué à l’offset fichier0x27A18
Modification du volume système iOS
- Pour adapter iOS lui-même au noyau macOS, la plupart des fichiers installés à la racine du système de fichiers doivent être déplacés dans
/System/Library/Templates/Datasur le volume système - Une fois le système démarré, ces fichiers se trouvent dans
/ - Les dossiers vides de la racine ordinaire peuvent devoir rester sur le volume système même s’ils sont effectivement vides
- Par exemple
/Applications - Cette partie n’a pas été suffisamment testée
- Par exemple
Patches de launchd et keybagd
- Au début du démarrage d’iOS,
/sbin/launchds’exécute, et des patches sont nécessaires pour lancer le processus de démarrage initial sans échec - Le premier patch s’applique à la plist de configuration intégrée dans le binaire
- Il faut chercher la chaîne
<key>SIGTERMTimeout</key>et regarder environ 172 octets avant pour trouver le paramètre concerné - Ajouter
<key>PerformAfterUserspaceReboot</key><true/>aux sectionsmount-phase-2,fips,tzinit,finish-demo-restore,fud,xpcroleaccountd,prng_seedctletMSUEarlyBootTask - Changer
RequireSuccessde la sectiondata-protectionen<false/>
- Il faut chercher la chaîne
- La modification de
data-protectionest nécessaire parce que/usr/libexec/init_data_protectionéchoue lorsqu’il est exécuté dans la VM- Ce fichier est un lien symbolique vers
/usr/libexec/seputil
- Ce fichier est un lien symbolique vers
- Comme les modifications de la plist intégrée peuvent dépasser l’espace de chaînes existant, il est possible de coller un XML compressé avec un minimizer XML, puis de remplir la zone restante avec des espaces compatibles XML
launchdinitialise aussi/usr/libexec/keybagd, mais ce binaire échoue en raison des différences de noyau précédentes- Un contournement consiste à compiler un exécutable qui se termine simplement avec le code de sortie 0 et à remplacer
keybagdpar celui-ci - Le projet fixkeybag a aussi été examiné, mais son code de création de system keybag appelle lui aussi
MKBKeyBagCreateSystem, et échoue donc même dans l’état iOS démarré
- Un contournement consiste à compiler un exécutable qui se termine simplement avec le code de sortie 0 et à remplacer
launchdnécessite un patch supplémentaire qui remplace parNOPla branche conditionnelleTBZdéclenchant la chaîne de paniqueUserspace reboot changed system version: previous %s != current %s
Modification de mount, du DYLD shared cache et de la couche graphique
- Comme la chaîne de démarrage macOS et le ramdisk macOS gèrent le processus de restauration, le
/sbin/mountd’iOS ne traite pas correctement les volumes APFS créés - La solution consiste à prendre le binaire
mountdu volume système macOS, à modifier ses métadonnées Mach-O pour qu’il puisse s’exécuter sur iOS, puis à le remplacer- Cela peut se faire manuellement, ou avec
vtool, inclus dans macOS
- Cela peut se faire manuellement, ou avec
- La modification plus difficile concerne le DYLD shared cache
IOSurfaceRootsur macOS etIOCoreSurfaceRootsur iOS sont fondamentalement le même pilote, mais ils sont incompatibles à cause de la différence de nom- Le DYLD shared cache d’iOS contient la chaîne plus longue
"IOCoreSurfaceRoot"; il faut donc la remplacer par"IOSurfaceRoot"et remplir les octets restants avec0x00
- L’outil ipsw de blacktop est utilisé pour analyser et extraire le DYLD shared cache
ipsw dyld split <dsc file>sépare les dylib intégrées- Dans le binaire
/System/Library/Frameworks/IOSurface.framework/IOSurface, il faut trouver la référence à"IOCoreSurfaceRoot"dans la fonction__iosConnectInitalize ipsw dyld a2oconvertit l’adresse virtuelle en offset fichier- Dans l’exemple, l’offset
0x28fde373dedyld_shared_cache_arm64eest patché
- Après modification du DYLD shared cache, une exception se produit parce que le cdhash d’un autre emplacement ne correspond plus
- Le GDB stub fourni par le frontend Virtualization.framework permet de placer un breakpoint sur la fonction noyau
cs_validate_hashafin de vérifier le cdhash complet - Dans l’exemple iOS 15.0.2, les anciens octets à l’offset fichier
0x5a9cffc0sont patchés avec le nouveau cdhash
- Le GDB stub fourni par le frontend Virtualization.framework permet de placer un breakpoint sur la fonction noyau
Patches des démons système et de l’activation
watchdogdvérifie s’il s’exécute dans une VM et provoque une boucle de crash, car il n’existe pas de chemin de code macOS permettant une sortie normale, mais ce crash est considéré comme inoffensif- Dans
backboardd, des patches d’appels liés à la migration des données susceptibles de déclencherPreBoard.appont été expérimentés, mais aucune différence n’a été observée en dehors d’un blocage sur le logo Apple - Dans la fonction
get_device_type_internal_block_invokedelockdownd, l’appelgetMGIntpour"ShouldHactivate"est patché enmov x0, #1afin de forcer la hactivation, qui contourne les restrictions d’activation iOS normales en environnement de développement mobileactivationdpeut aussi être patché pour autoriser la hactivation- La fonction
shouldHactivateest remplacée par les instructions ARMv8-Amov x0, #0etret
- La fonction
- Les modifications supplémentaires nécessaires au device tree vma2 sont laissées au lecteur
- Certaines opérations peuvent nécessiter des mesures non conventionnelles comme
chmod -R 777 /
Limites restantes et saisie tactile
- Pour dépasser le problème du system keybag, il faut mieux comprendre la structure correspondante dans le système iOS et le noyau, puis créer des patches supplémentaires
- Le projet a déjà demandé au moins plusieurs centaines d’heures, et l’état d’avancement public actuel se limite à un démarrage jusqu’à
PreBoard.app - Il n’est pas encore confirmé que la fonction tactile fonctionne via le noyau et le firmware publics vma2 Mac
- Virtualization.framework contient des API privées liées au tactile
_VZAppleTouchScreenConfiguration_VZUSBTouchScreenConfiguration_VZTouch_VZMultiTouchEvent
- Ces API peuvent envoyer des événements tactiles, mais l’usage exact des paramètres n’est pas entièrement compris
- L’enum
TouchPhaseest une enum simple implémentant les valeurs du même nom queNSTouch.Phase - Le code d’exemple peut parfois générer des exceptions
- Il n’est pas non plus confirmé que les coordonnées soient mappées comme la VM l’attend, ni que la VM puisse les traiter
- L’enum
- La démo montre la séquence de démarrage, avec une attente d’environ 30 secondes au milieu qui a été coupée
1 commentaires
Avis sur Hacker News
Corellium a gagné son litige, ce qui lui permet de louer des VM iOS dans le cloud pour la recherche en sécurité https://hn.algolia.com/?query=corellium
Si l’on peut virtualiser iOS sur un MacBook Apple Silicon, la demande pour des services commerciaux de virtualisation iOS pourrait diminuer
Les particuliers paient environ 400 $ par mois, et les entreprises 60 000 $ par an https://support.corellium.com/subscriptions/pricing
Bonne nouvelle. La prochaine étape, ce serait de trouver comment installer macOS sur un iPad, pour qu’on puisse enfin utiliser cet ordinateur qu’on espérait voir Apple fabriquer
https://www.theverge.com/2024/7/22/24200536/windows-xp-ipad-...
Mac Catalyst semble aussi fonctionner dans un seul sens, comme prévu
En termes de taille, l’iPad Mini serait idéal, mais iPadOS est inutile ; en ce moment je regarde du côté de la Surface Go. Elle est toutefois un peu grande
Je sais qu’il n’existe pas de produit avec macOS, mais si quelqu’un a une recommandation de petite tablette compatible Win11, je suis preneur. Je suis même prêt à commander en Chine si nécessaire
À voir le profil GitHub de l’auteur, il semble tout juste diplômé en informatique ; c’est un travail vraiment impressionnant
J’ai l’impression qu’Apple n’a pas fait du Simulator un Emulator parce qu’ils ne veulent pas que les gens fouillent dans les couches internes d’iOS
Une fois le bootloader passé, surtout quand Apple contrôle aussi le matériel, je me demande s’il y a vraiment une raison de maintenir autant de différences entre les deux systèmes d’exploitation
La personne qui a créé qemu-t8030 a réussi à lancer SpringBoard https://mastodon.social/@ntrung03/109712247237110967, mais n’a pas publié le code
Ce serait formidable si cette avancée pouvait être combinée avec le présent travail
https://www.xia0.sh/2024/03/09/Boot-Newer-iOS-with-QEMU-Step...
Ancien commentaire : https://news.ycombinator.com/item?id=40219423
Article lié : https://worthdoingbadly.com/hv/
Il traite des machines virtuelles accélérées matériellement sur un iPhone 12 jailbreaké / iOS 14.1
C’est un peu hors sujet, mais je me demande si quelqu’un a déjà virtualisé macOS ARM sur x86-64
On ne peut donc virtualiser que des systèmes d’exploitation compilés pour la même architecture CPU que le système hôte
Dans les autres cas, par exemple exécuter du logiciel ARM sur x86 ou l’inverse, il faut passer par l’émulation, qui interprète le code ou le recompile dynamiquement
Par définition, n’importe quoi peut être émulé sur n’importe quoi d’autre. Récemment, on a même vu Linux pour MIPS démarrer sur le tout premier microprocesseur, l’Intel 4004, mais les performances peuvent poser problème
Virtualiser des CPU Mn serait encore moins utile, à mon avis
Apple fournit déjà un iOS Simulator dans Xcode ; je me demande en quoi ce projet est meilleur que les outils fournis par Apple
Par exemple, on ne peut pas prendre un binaire iOS depuis l’App Store et l’exécuter tel quel dans l’iOS Simulator, encore moins sur un Mac Intel
Comme le Simulator n’exécute pas un iOS complet, il ne permet pas non plus d’étudier et de comprendre le fonctionnement interne réel d’iOS. Si l’on creuse suffisamment profondément dans les frameworks du Simulator, on finit par retomber sur macOS
Un émulateur, en revanche, exécute un build complet d’iOS identique à celui d’un vrai appareil. En théorie, il peut exécuter n’importe quel binaire iOS sans modification et permettre d’étudier le fonctionnement du véritable système d’exploitation
C’est comparable à la différence entre exécuter une app avec Wine et l’exécuter dans une VM Windows. Sauf que, dans le cas du Simulator, c’est plutôt comme s’il fallait recompiler et lier séparément l’app pour l’environnement Wine avant d’exécuter une app Windows
Si vous voulez étudier les entrailles de Windows, vous n’apprendrez pas grand-chose en lançant simplement Wine, alors qu’en examinant une VM Windows, vous en apprendrez beaucoup plus
Ce sera un cadeau de Noël en avance pour les fermes à clics