
Guia para construir um iPhone virtual usando componentes VPHONE600AP do firmware PCC da Apple, com correção de firmware, modificação da cadeia de inicialização e depuração do kernel para pesquisa de segurança no iOS.
Por volta do final de 2024, a Apple começou a introduzir o Private Cloud Compute, alegando abrir um novo horizonte para a privacidade de IA baseada em nuvem. Então, por volta do final de 2025, surgiram algumas notícias interessantes: a Apple adicionou recentemente componentes relacionados ao vphone600ap ao firmware PCC, a partir do cloudOS 26.

Fonte: https://x.com/matteyeux/status/2006339694783848660/photo/1
"Máquina Virtual de Ambiente de Pesquisa do iPhone"?
Isso é um movimento planejado da Apple para construir e distribuir um ambiente de iPhone virtual para outros pesquisadores de segurança no futuro, ou foi simplesmente um erro? Dado que o kernel de compilação DEVELOPMENT/KASAN foi descoberto nas OTAs do iOS 15.0 beta ao 15.1 beta3 em 2021, a possibilidade de um deslize não pode ser descartada. Naquela época, o kernel permaneceu incluído por cerca de 4 meses, aproximadamente de junho a outubro de 2021.
Então, por volta de janeiro deste ano, um tweet foi postado mostrando um iPhone virtual sendo inicializado utilizando esses componentes relacionados ao vphone600ap.

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

Pelo que vi, quase tudo funcionou de forma verdadeiramente elegante. Comparado ao projeto QEMUAppleSilicon(Inferno) que eu tinha visto antes, ele roda muito mais rápido e suave. Além disso, parecia até suportar aceleração Metal. Por fim, completamente cativado por ele, mergulhei de cabeça e comecei a construir meu próprio iPhone virtual em 31 de janeiro.

O projeto referenciado é o security-pcc. Ele corresponde ao código-fonte do binário /System/Library/SecurityResearch/usr/bin/vrevm. Um ponto interessante é que ele usa métodos privados fornecidos pelo Virtualization.framework. Na máquina virtual usada para pesquisa PCC, você pode ver que ISA e PlatformVersion são explicitamente especificados durante o processo de inicialização do modelo de hardware.

Para o bootrom, AVPBooter.vresearch1.bin é usado (/System/Library/Frameworks/Virtualization.framework/Resources/AVPBooter.vresearch1.bin)

e para o SEPROM (avpsepbooter), AVPSEPBooter.vresearch1.bin é usado, que carrega separadamente um arquivo SEPStorage que funciona de forma semelhante ao AuxiliaryStorage. (/System/Library/Frameworks/Virtualization.framework/Versions/A/Resources/AVPSEPBooter.vresearch1.bin)
Outro ponto interessante é que, se você olhar o código para definir a resolução, ela é definida como 1290x2796, que corresponde aos dispositivos iPhone 14 Pro Max, 15 Plus, 15 Pro Max e 16 Plus.

Com apenas essa informação, deve ser mais que suficiente para modificar o super-tart para inicializar o iPhone virtual. Fiz as modificações conforme mostrado abaixo.
/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