Guide pour construire un iPhone virtuel à l'aide des composants VPHONE600AP du firmware PCC d'Apple, avec patching du firmware, modification de la chaîne de boot et débogage du noyau pour la recherche en sécurité iOS.
Vers fin 2024, Apple a commencé à introduire Private Cloud Compute, affirmant ouvrir un nouvel horizon pour la confidentialité de l'IA basée sur le cloud. Puis, vers fin 2025, des nouvelles intéressantes sont apparues : Apple avait récemment ajouté des composants liés à vphone600ap au firmware PCC, à partir de cloudOS 26.

Source: https://x.com/matteyeux/status/2006339694783848660/photo/1
« iPhone Research Environment Virtual Machine » ?
Est-ce une initiative planifiée par Apple pour construire et distribuer un environnement d'iPhone virtuel à d'autres chercheurs en sécurité à l'avenir, ou était-ce simplement une erreur ? Étant donné qu'un noyau de construction DEVELOPMENT/KASAN a été découvert dans les OTA des bêta iOS 15.0 à 15.1 bêta3 en 2021, la possibilité d'un faux pas ne peut être exclue. À l'époque, le noyau est resté inclus pendant environ 4 mois, de juin à octobre 2021.
Puis, vers janvier de cette année, un tweet a été posté montrant un iPhone virtuel démarrant en utilisant ces composants liés à vphone600ap.

Source: https://x.com/_inside/status/2008951845725548783

D'après ce que j'ai vu, presque tout fonctionnait vraiment avec élégance. Comparé au projet QEMUAppleSilicon(Inferno) que j'avais vu auparavant, cela tournait beaucoup plus vite et plus fluidement. De plus, cela semblait même prendre en charge l'accélération Metal. Finalement, complètement captivé par cela, je me suis lancé et j'ai commencé à construire mon propre iPhone virtuel le 31 janvier.

Le projet référencé est security-pcc. Il correspond au code source du binaire /System/Library/SecurityResearch/usr/bin/vrevm. Un point intéressant est qu'il utilise des méthodes privées fournies par Virtualization.framework. Dans la machine virtuelle utilisée pour la recherche PCC, on peut voir que l'ISA et PlatformVersion sont explicitement spécifiés lors du processus d'initialisation du modèle matériel.

Pour le bootrom, AVPBooter.vresearch1.bin est utilisé (/System/Library/Frameworks/Virtualization.framework/Resources/AVPBooter.vresearch1.bin)

et pour le SEPROM (avpsepbooter), AVPSEPBooter.vresearch1.bin est utilisé, qui charge séparément un fichier SEPStorage fonctionnant de manière similaire à AuxiliaryStorage. (/System/Library/Frameworks/Virtualization.framework/Versions/A/Resources/AVPSEPBooter.vresearch1.bin)
Un autre point intéressant est que si l'on regarde le code pour définir la résolution, elle est réglée sur 1290x2796, ce qui correspond aux appareils iPhone 14 Pro Max, 15 Plus, 15 Pro Max et 16 Plus.

Avec seulement ces informations, cela devrait être largement suffisant pour modifier super-tart afin de démarrer l'iPhone virtuel. J'ai apporté les modifications comme indiqué ci-dessous.
/Sources/tart/VM.swift```swift ... class VM: NSObject, VZVirtualMachineDelegate, ObservableObject { ... // vzHardwareModel derives the VZMacHardwareModel config specific to the "platform type" // of the VM (currently only vresearch101 supported) static private func vzHardwareModel_VRESEARCH101() throws -> VZMacHardwareModel { var hw_model: VZMacHardwareModel
guard let hw_descriptor = _VZMacHardwareModelDescriptor() else { fatalError("Failed to create hardware descriptor") } hw_descriptor.setPlatformVersion(3) // .appleInternal4 = 3 hw_descriptor.setBoardID(0x90) hw_descriptor.setISA(2) hw_model = VZMacHardwareModel._hardwareModel(withDescriptor: hw_descriptor)
guard hw_model.isSupported else { fatalError("VM hardware config not supported (model.isSupported = false)") }
return hw_model }
static func craftConfiguration( diskURL: URL, nvramURL: URL, romURL: URL, sepromURL: URL? = nil, vmConfig: VMConfig, network: Network = NetworkShared(), additionalStorageDevices: [VZStorageDeviceConfiguration], directorySharingDevices: [VZDirectorySharingDeviceConfiguration], serialPorts: [VZSerialPortConfiguration], suspendable: Bool = false, nested: Bool = false, audio: Bool = true, clipboard: Bool = true, sync: VZDiskImageSynchronizationMode = .full, caching: VZDiskImageCachingMode? = nil ) throws -> VZVirtualMachineConfiguration { let configuration: VZVirtualMachineConfiguration = .init()
// Boot loader let bootloader = try vmConfig.platform.bootLoader(nvramURL: nvramURL) Dynamic(bootloader)._setROMURL(romURL) configuration.bootLoader = bootloader
// SEP ROM let homeURL = FileManager.default.homeDirectoryForCurrentUser var sepstoragePath = homeURL.appendingPathComponent(".tart/vms/vphone/SEPStorage").path let sepstorageURL = URL(fileURLWithPath: sepstoragePath) let sep_config = Dynamic._VZSEPCoprocessorConfiguration(storageURL: sepstorageURL) if let sepromURL { // default AVPSEPBooter.vresearch1.bin from VZ framework sep_config.romBinaryURL = sepromURL } sep_config.debugStub = Dynamic._VZGDBDebugStubConfiguration(port: 8001) configuration._setCoprocessors([sep_config.asObject])
// Some vresearch101 config let pconf = VZMacPlatformConfiguration() pconf.hardwareModel = try vzHardwareModel_VRESEARCH101()
let serial = Dynamic._VZMacSerialNumber.initWithString("AAAAAA1337") let identifier = Dynamic.VZMacMachineIdentifier._machineIdentifierWithECID(0x1111111111111111, serialNumber: serial.asObject) pconf.machineIdentifier = identifier.asObject as! VZMacMachineIdentifier