
Apple के PCC फर्मवेयर से VPHONE600AP घटकों का उपयोग करके एक वर्चुअल iPhone बनाने की मार्गदर्शिका, जिसमें फर्मवेयर पैचिंग, बूटचेन संशोधन और iOS सुरक्षा अनुसंधान के लिए कर्नेल डिबगिंग शामिल है।
2024 के अंत के आसपास, Apple ने Private Cloud Compute पेश करना शुरू किया, जो क्लाउड-आधारित AI गोपनीयता के लिए नए क्षितिज खोलने का दावा करता था। फिर, 2025 के अंत के आसपास, कुछ दिलचस्प खबरें सामने आईं: Apple ने PCC फर्मवेयर में cloudOS 26 से शुरू होकर vphone600ap-संबंधित घटकों को नया जोड़ा था।

स्रोत: https://x.com/matteyeux/status/2006339694783848660/photo/1
“iPhone अनुसंधान पर्यावरण वर्चुअल मशीन”?
क्या यह Apple की ओर से भविष्य में अन्य सुरक्षा शोधकर्ताओं के लिए वर्चुअल iPhone पर्यावरण बनाने और वितरित करने की योजनाबद्ध चाल है, या यह केवल एक गलती थी? यह देखते हुए कि 2021 में iOS 15.0 बीटा से 15.1 बीटा3 OTA में DEVELOPMENT/KASAN बिल्ड कर्नेल की खोज की गई थी, चूक की संभावना से इनकार नहीं किया जा सकता। उस समय, कर्नेल लगभग 4 महीने तक शामिल रहा, मोटे तौर पर जून से अक्टूबर 2021 तक।
फिर, इस वर्ष जनवरी के आसपास, एक ट्वीट पोस्ट किया गया जिसमें इन vphone600ap-संबंधित घटकों का उपयोग करके एक वर्चुअल iPhone को बूट होते दिखाया गया।


मैंने जो देखा, उससे लगभग सब कुछ वास्तव में सुंदरता से काम करता था। QEMUAppleSilicon(Inferno) प्रोजेक्ट की तुलना में जो मैंने पहले देखा था, यह बहुत अधिक तेज़ और चिकना चलता है। इसके अलावा, यह Metal त्वरण का भी समर्थन करता प्रतीत होता है। अंततः, इससे पूरी तरह मोहित होकर, मैंने 31 जनवरी को अपना स्वयं का वर्चुअल iPhone बनाना शुरू कर दिया।

संदर्भित प्रोजेक्ट security-pcc है। यह /System/Library/SecurityResearch/usr/bin/vrevm बाइनरी के स्रोत कोड से मेल खाता है। एक दिलचस्प बात यह है कि यह Virtualization.framework द्वारा प्रदान की गई निजी विधियों का उपयोग करता है। PCC अनुसंधान के लिए उपयोग की जाने वाली वर्चुअल मशीन में, आप देख सकते हैं कि हार्डवेयर मॉडल आरंभीकरण प्रक्रिया के दौरान ISA और PlatformVersion स्पष्ट रूप से निर्दिष्ट किए गए हैं।

बूटरॉम के लिए, AVPBooter.vresearch1.bin का उपयोग किया जाता है (/System/Library/Frameworks/Virtualization.framework/Resources/AVPBooter.vresearch1.bin)

और SEPROM (avpsepbooter) के लिए, AVPSEPBooter.vresearch1.bin का उपयोग किया जाता है, जो अलग से एक SEPStorage फ़ाइल लोड करता है जो AuxiliaryStorage के समान कार्य करती है। (/System/Library/Frameworks/Virtualization.framework/Versions/A/Resources/AVPSEPBooter.vresearch1.bin)
एक और दिलचस्प बात यह है कि यदि आप रिज़ॉल्यूशन सेट करने के कोड को देखते हैं, तो यह 1290x2796 पर सेट है, जो iPhone 14 Pro Max, 15 Plus, 15 Pro Max, और 16 Plus उपकरणों के अनुरूप है।

इस जानकारी के साथ, वर्चुअल iPhone को बूट करने के लिए super-tart को संशोधित करना पर्याप्त से अधिक होना चाहिए। मैंने नीचे दिखाए अनुसार संशोधन किए।
/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
pconf._setProductionModeEnabled(true) var auxiliaryStoragePath = homeURL.appendingPathComponent(".tart/vms/vphone/nvram.bin").path let auxiliaryStorageURL = URL(fileURLWithPath: auxiliaryStoragePath) pconf.auxiliaryStorage = VZMacAuxiliaryStorage(url: auxiliaryStorageURL)
if #available(macOS 14, *) { let keyboard = VZUSBKeyboardConfiguration() configuration.keyboards = [keyboard] }
if #available(macOS 14, *) { let touch = _VZUSBTouchScreenConfiguration() configuration._setMultiTouchDevices([touch]) } ... configuration.platform = pconf
// Display let graphics_config = VZMacGraphicsDeviceConfiguration() let displays_config = VZMacGraphicsDisplayConfiguration( widthInPixels: 1179, heightInPixels: 2556, pixelsPerInch: 460 ) graphics_config.displays.append(displays_config) configuration.graphicsDevices = [graphics_config] ...
# फ़र्मवेयर को संशोधित करना
संदर्भित प्रोजेक्ट [vma2pwn](https://github.com/nick-botticelli/vma2pwn) है। विशेष रूप से संस्करण 12.0.1 के लिए, यह एक Mac वर्चुअल मशीन को लगभग पूरी तरह से संशोधित बूटचेन के साथ बूट करता है।
पहले [prepare.sh](https://github.com/nick-botticelli/vma2pwn/blob/main/prepare.sh) स्क्रिप्ट पर नज़र डालते हैं। यह फ़र्मवेयर घटकों, जैसे कि बूटलोडर और IM4P प्रारूप में संपीड़ित कर्नेल, को RAW प्रारूप में निकालता है और विशिष्ट हार्डकोडेड पतों पर निर्देशों/डेटा को पैच करता है। RestoreRamdisk वह रूट फ़ाइलसिस्टम है जिसका उपयोग फ़र्मवेयर को पुनर्स्थापित करते समय किया जाता है, और AVPBooter वर्चुअल मशीन में उपयोग किया जाने वाला BootROM है।
संक्षेप में, यह फ़र्मवेयर में शामिल अलग-अलग फ़ाइलों को निकालता है और कस्टम फ़र्मवेयर की पुनर्स्थापना की अनुमति देने के लिए अखंडता जाँचों को पैच करता है, या बूट-संबंधित लॉग को देखना आसान बनाने के लिए boot-args पैरामीटर को संशोधित करता है।
अंत में, [vma2pwn.sh](https://github.com/nick-botticelli/vma2pwn/blob/main/vma2pwn.sh) कस्टम फ़र्मवेयर को पुनर्स्थापित करने के लिए ज़िम्मेदार है। यह पहले DFU मोड में प्रवेश करके ऐसा करता है। यहाँ, वर्चुअल मशीन super-tart नामक किसी चीज़ का उपयोग करती है। यह मौजूदा tart वर्चुअल मशीन का एक संस्करण है जिसमें कस्टम बूटरॉम, सीरियल आउटपुट, DFU मोड और GDB डिबगिंग जैसी अतिरिक्त सुविधाएँ हैं। (ध्यान दें कि इसके लिए SIP/AMFI को अक्षम करना होगा।)
मैंने हाल ही में इसका उपयोग काफी उपयोगी रूप से किया है जब मैं [XNU कर्नेल 1-दिवसीय कमज़ोरियों (CVE-2021-30937, CVE-2021-30955) का अध्ययन कर रहा था](https://github.com/wh1te4ever/xnu_1day_practice)। यह शानदार है क्योंकि यह लाइव कर्नेल डिबगिंग का समर्थन करता है।
## कस्टम फ़र्मवेयर बनाना
मैंने cloudOS 26.1 (23B85) और iOS 26.1 (iPhone17,3; 23B85) के घटकों को मिलाया, उह,,, लेकिन... मुझे सटीक विवरण याद नहीं हैं। सटीक होने के लिए, मुझे कस्टम फ़र्मवेयर बनाने के लिए iPhone 16 और vphone-संबंधित घटकों को ठीक से मिलाना था, लेकिन मैं भूल गया हूँ कि मैंने वास्तव में किन घटकों को मिलाया था। जहाँ तक मुझे याद है:
- BuildManifest.plist:
मैंने Manifest कुंजी के अंतर्गत शब्दकोश तत्वों को संशोधित किया। मैंने इसे इस प्रकार कॉन्फ़िगर किया कि पुनर्स्थापना प्रक्रिया के दौरान, iPhone 16 (iOS 26.1) मॉडल से SystemVolume, SystemVolumeCanonicalMetadata, OS, StaticTrustCache, RestoreTrustCache और RestoreRamDisk का उपयोग किया जाएगा। बाकी को PCC फ़र्मवेयर से vphone-संबंधित फ़ाइलों का उपयोग करने के लिए सेट किया गया था।
- Restore.plist:
मेरा मानना है कि मैंने DeviceMap या SupportedProductTypes से संबंधित गुण जोड़े, या SystemRestoreImageFileSystems तत्व को बदल दिया।
नीचे दी गई फ़ाइलें मेरे मिश्रण का अंतिम परिणाम हैं।
[Restore.plist](https://github.com/wh1te4ever/super-tart-vphone-writeup/blob/main/contents/Restore.plist)
[BuildManifest.plist](https://github.com/wh1te4ever/super-tart-vphone-writeup/blob/main/contents/BuildManifest.plist)
- get_fw.py (आंशिक)```python
...
# 3. Import things from cloudOS
# kernelcache
os.system("cp 399b664dd623358c3de118ffc114e42dcd51c9309e751d43bc949b98f4e31349_extracted/kernelcache.* iPhone17,3_26.1_23B85_Restore")
# agx, all_flash, ane, dfu, pmp...
os.system("cp 399b664dd623358c3de118ffc114e42dcd51c9309e751d43bc949b98f4e31349_extracted/Firmware/agx/* iPhone17,3_26.1_23B85_Restore/Firmware/agx")
os.system("cp 399b664dd623358c3de118ffc114e42dcd51c9309e751d43bc949b98f4e31349_extracted/Firmware/all_flash/* iPhone17,3_26.1_23B85_Restore/Firmware/all_flash")
os.system("cp 399b664dd623358c3de118ffc114e42dcd51c9309e751d43bc949b98f4e31349_extracted/Firmware/ane/* iPhone17,3_26.1_23B85_Restore/Firmware/ane")
os.system("cp 399b664dd623358c3de118ffc114e42dcd51c9309e751d43bc949b98f4e31349_extracted/Firmware/dfu/* iPhone17,3_26.1_23B85_Restore/Firmware/dfu")
os.system("cp 399b664dd623358c3de118ffc114e42dcd51c9309e751d43bc949b98f4e31349_extracted/Firmware/pmp/* iPhone17,3_26.1_23B85_Restore/Firmware/pmp")
# sptm, txm, etc...
os.system("cp 399b664dd623358c3de118ffc114e42dcd51c9309e751d43bc949b98f4e31349_extracted/Firmware/*.im4p iPhone17,3_26.1_23B85_Restore/Firmware")
# 4. TODO: parse what things needed from BuildManifest.plist, Restore.plist in cloudOS 26.1
# It will be really complicated, so import things from already parse completed
os.system("sudo cp custom_26.1/BuildManifest.plist iPhone17,3_26.1_23B85_Restore")
os.system("sudo cp custom_26.1/Restore.plist iPhone17,3_26.1_23B85_Restore")
os.system("echo 'Done, grabbed all needed components for restoring'")
मैंने उस पोस्ट का संदर्भ लिया। कस्टम बूटलोडर को बाद में लोड करने के लिए, आपको image4_validate_property_callback को पैच करना होगा। बस IDA Pro में "Text-search (slow!)" सुविधा का उपयोग करके "0x4447" खोजें, और संबंधित फ़ंक्शन के एपिलॉग को हमेशा 0 लौटाने के लिए पैच करें।

फर्मवेयर को पुनर्स्थापित करने से पहले, vresearch101ap मॉडल का समर्थन करने के लिए कुछ संशोधन आवश्यक थे। एक बार बनने के बाद, idevicerestore टूल का उपयोग करके फर्मवेयर पुनर्स्थापना संभव हो जाती है।

AVPBooter के समान, पुनर्स्थापना के लिए उपयोग किए जाने वाले बूटलोडर, iBSS और iBEC, को हस्ताक्षर सत्यापन को बायपास करने के लिए पैच किया गया। मैंने सीरियल लॉग आउटपुट भी सक्षम किया ताकि यदि कोई बूटिंग समस्या हो, तो इसका कारण तुरंत पहचाना जा सके।
जैसा कि आप बाद में देखेंगे, एक मनमाना क्रिप्टेक्स लोड करने के लिए SSV (साइन्ड सिस्टम वॉल्यूम) सत्यापन को बायपास करना आवश्यक है। यह LLB में किया जाता है, जो DFU मोड के बजाय सामान्य मोड में बूट करने पर लोड होता है, और सत्यापन कभी-कभी कर्नेल में भी किया जाता है।
इसके अतिरिक्त, मैंने TXM को पैच किया ताकि भले ही कोई बाइनरी/लाइब्रेरी Trustcache में पंजीकृत न हो, फिर भी उसे ऐसे पहचाना जाए जैसे वह पंजीकृत हो।
patch(0x9D10, 0xd503201f) #nop patch(0x9D14, 0xd2800000) #mov x0, #0
patch(0x9D10, 0xd503201f) #nop patch(0x9D14, 0xd2800000) #mov x0, #0
patch(0x122d4, 0xd0000082) #adrp x2, #0x12000 patch(0x122d8, 0x9101c042) #add x2, x2, #0x70 patch(0x24070, "serial=3 -v debug=0x2014e %s")
patch(0xA0D8, 0xd503201f) #nop patch(0xA0DC, 0xd2800000) #mov x0, #0
patch(0x12888, 0xD0000082) #adrp x2, #0x12000 patch(0x1288C, 0x91264042) #add x2, x2, #0x990 patch(0x24990, "serial=3 -v debug=0x2014e %s")
patch(0x2BFE8, 0x1400000b) patch(0x2bca0, 0xd503201f) patch(0x2C03C, 0x17ffff6a) patch(0x2fcec, 0xd503201f) patch(0x2FEE8, 0x14000009)
patch(0x1AEE4, 0xd503201f) #nop
patch(0x2c1f8, 0xd2800000) #FFFFFFF0170301F8 patch(0x2bef4, 0xd2800000) #FFFFFFF01702FEF4 patch(0x2c060, 0xd2800000) #FFFFFFF017030060
patch(0x2476964, 0xd503201f) #FFFFFE000947A964
patch(0x23cfde4, 0xd503201f) #FFFFFE00093D3DE4
patch(0xf6d960, 0xd503201f) #FFFFFE0007F71960 ...
RAW प्रारूप में परिवर्तित करने और इसे पैच करने के बाद, आपको इसे वापस IM4P में परिवर्तित करना होगा।
कर्नेल या TXM के मामले में, एक PAYP संरचना मौजूद होती है, इसलिए उस संरचना को संरक्षित करना आवश्यक था।
नीचे वह कोड है जो [pyimg4](https://pypi.org/project/pyimg4/), [img4tool](https://github.com/tihmstar/img4tool), [img4](https://github.com/xerub/img4lib) टूल का उपयोग करके IM4P → RAW → IM4P में परिवर्तित करता है।
- patch_fw.py (आंशिक सामग्री, भाग 2)```python
...
# Patch iBSS
if not os.path.exists("iPhone17,3_26.1_23B85_Restore/Firmware/dfu/iBSS.vresearch101.RELEASE.im4p.bak"):
os.system("cp iPhone17,3_26.1_23B85_Restore/Firmware/dfu/iBSS.vresearch101.RELEASE.im4p iPhone17,3_26.1_23B85_Restore/Firmware/dfu/iBSS.vresearch101.RELEASE.im4p.bak")
os.system("tools/img4 -i iPhone17,3_26.1_23B85_Restore/Firmware/dfu/iBSS.vresearch101.RELEASE.im4p.bak -o iBSS.vresearch101.RELEASE")
... # patch things from raw
os.system("tools/img4tool -c iPhone17,3_26.1_23B85_Restore/Firmware/dfu/iBSS.vresearch101.RELEASE.im4p -t ibss iBSS.vresearch101.RELEASE")
# Patch iBEC
if not os.path.exists("iPhone17,3_26.1_23B85_Restore/Firmware/dfu/iBEC.vresearch101.RELEASE.im4p.bak"):
os.system("cp iPhone17,3_26.1_23B85_Restore/Firmware/dfu/iBEC.vresearch101.RELEASE.im4p iPhone17,3_26.1_23B85_Restore/Firmware/dfu/iBEC.vresearch101.RELEASE.im4p.bak")
os.system("tools/img4 -i iPhone17,3_26.1_23B85_Restore/Firmware/dfu/iBEC.vresearch101.RELEASE.im4p.bak -o iBEC.vresearch101.RELEASE")
... # patch things from raw
os.system("tools/img4tool -c iPhone17,3_26.1_23B85_Restore/Firmware/dfu/iBEC.vresearch101.RELEASE.im4p -t ibec iBEC.vresearch101.RELEASE")
# Patch LLB
if not os.path.exists("iPhone17,3_26.1_23B85_Restore/Firmware/all_flash/LLB.vresearch101.RESEARCH_RELEASE.im4p.bak"):
os.system("cp iPhone17,3_26.1_23B85_Restore/Firmware/all_flash/LLB.vresearch101.RESEARCH_RELEASE.im4p iPhone17,3_26.1_23B85_Restore/Firmware/all_flash/LLB.vresearch101.RESEARCH_RELEASE.im4p.bak")
os.system("tools/img4 -i iPhone17,3_26.1_23B85_Restore/Firmware/all_flash/LLB.vresearch101.RESEARCH_RELEASE.im4p.bak -o LLB.vresearch101.RESEARCH_RELEASE")
... # patch things from raw
os.system("tools/img4tool -c iPhone17,3_26.1_23B85_Restore/Firmware/all_flash/LLB.vresearch101.RESEARCH_RELEASE.im4p -t illb LLB.vresearch101.RESEARCH_RELEASE")
# 6. Grab & Patch TXM
if not os.path.exists("iPhone17,3_26.1_23B85_Restore/Firmware/txm.iphoneos.research.im4p.bak"):
os.system("cp iPhone17,3_26.1_23B85_Restore/Firmware/txm.iphoneos.research.im4p iPhone17,3_26.1_23B85_Restore/Firmware/txm.iphoneos.research.im4p.bak")
os.system("pyimg4 im4p extract -i iPhone17,3_26.1_23B85_Restore/Firmware/txm.iphoneos.research.im4p.bak -o txm.raw")
... # patch things from raw
#create im4p
os.system("pyimg4 im4p create -i txm.raw -o txm.im4p -f trxm --lzfse")
# preserve payp structure
txm_im4p_data = Path('iPhone17,3_26.1_23B85_Restore/Firmware/txm.iphoneos.research.im4p.bak').read_bytes()
payp_offset = txm_im4p_data.rfind(b'PAYP')
if payp_offset == -1:
print("Couldn't find payp structure !!!")
sys.exit()
with open('txm.im4p', 'ab') as f:
f.write(txm_im4p_data[(payp_offset-10):])
payp_sz = len(txm_im4p_data[(payp_offset-10):])
print(f"payp sz: {payp_sz}")
txm_im4p_data = bytearray(open('txm.im4p', 'rb').read())
txm_im4p_data[2:5] = (int.from_bytes(txm_im4p_data[2:5], 'big') + payp_sz).to_bytes(3, 'big')
open('txm.im4p', 'wb').write(txm_im4p_data)
os.system("mv txm.im4p iPhone17,3_26.1_23B85_Restore/Firmware/txm.iphoneos.research.im4p")
# 7. Grab & patch kernelcache
if not os.path.exists("iPhone17,3_26.1_23B85_Restore/kernelcache.research.vphone600.bak"):
os.system("cp iPhone17,3_26.1_23B85_Restore/kernelcache.research.vphone600 iPhone17,3_26.1_23B85_Restore/kernelcache.research.vphone600.bak")
os.system("pyimg4 im4p extract -i iPhone17,3_26.1_23B85_Restore/kernelcache.research.vphone600.bak -o kcache.raw")
... # patch things from raw
#create im4p
os.system("pyimg4 im4p create -i kcache.raw -o krnl.im4p -f krnl --lzfse")
# preserve payp structure
kernel_im4p_data = Path('iPhone17,3_26.1_23B85_Restore/kernelcache.research.vphone600.bak').read_bytes()
payp_offset = kernel_im4p_data.rfind(b'PAYP')
if payp_offset == -1:
print("Couldn't find payp structure !!!")
sys.exit()
with open('krnl.im4p', 'ab') as f:
f.write(kernel_im4p_data[(payp_offset-10):])
payp_sz = len(kernel_im4p_data[(payp_offset-10):])
print(f"payp sz: {payp_sz}")
kernel_im4p_data = bytearray(open('krnl.im4p', 'rb').read())
kernel_im4p_data[2:5] = (int.from_bytes(kernel_im4p_data[2:5], 'big') + payp_sz).to_bytes(3, 'big')
open('krnl.im4p', 'wb').write(kernel_im4p_data)
os.system("mv krnl.im4p iPhone17,3_26.1_23B85_Restore/kernelcache.research.vphone600")
...
एक बार सब कुछ तैयार हो जाने पर, चलिए वर्चुअल मशीन को DFU मोड में डालते हैं और इसे पुनर्स्थापित करने का प्रयास करते हैं।
नीचे उस पैनिक का स्क्रीनशॉट है जो SEP को सही ढंग से कॉन्फ़िगर न करने पर होता है। यदि आप इसे सही ढंग से सेट करते हैं, तो इसे बिना किसी समस्या के इस बिंदु से गुज़रना चाहिए।

पुनर्स्थापना पूरी होने के बाद, यह स्वचालित रूप से रीबूट होता है। हालांकि, launchd प्रक्रिया में एक पैनिक होता है क्योंकि /usr/lib/libSystem.B.dylib लाइब्रेरी गायब है। यह लाइब्रेरी Cryptex विभाजन पर dyld_shared_cache के अंदर स्थित है, और किसी कारणवश Cryptex विभाजन को पुनर्स्थापित नहीं किया जा सका। एक अस्थायी समाधान के रूप में, आपको रूट फ़ाइल सिस्टम को संशोधित करने और आवश्यक फ़ाइलों को इंजेक्ट करने के लिए एक SSH Ramdisk बनाना होगा। यही कारण है कि SSV सत्यापन से संबंधित पैच की आवश्यकता थी।


मैं https://github.com/verygenericname/SSHRD_Script में उपयोग किए गए रैमडिस्क का उपयोग करके बूट विफलता की समस्या को ठीक करने का प्रयास करने जा रहा हूँ।
DFU मोड में irecovery टूल का उपयोग करके बूटलोडर या कर्नेल जैसे घटकों को अपलोड और लोड करने के लिए, एक IMG4 इमेज की आवश्यकता होती है, जिसके लिए एक IM4M फ़ाइल की आवश्यकता है। इसलिए, मैंने पहले idevicerestore टूल का उपयोग करके shsh फ़ाइल प्राप्त की, और फिर इसे IM4M फ़ाइल में बदल दिया।```bash idevicerestore -e -y ./iPhone17,3_26.1_23B85_Restore -t
mv shsh/[ECID]-iPhone99,11-26.1.shsh shsh/[ECID]-iPhone99,11-26.1.shsh.gz
gunzip shsh/[ECID]-iPhone99,11-26.1.shsh.gz
...
pyimg4 im4m extract -i shsh/[ECID]-iPhone99,11-26.1.shsh -o vphone.im4m
फिर, उस IM4M फ़ाइल का उपयोग करके, मैंने उपयोग किए गए फर्मवेयर घटकों, जैसे iBSS, iBEC और डिवाइसट्री के लिए कई IMG4 फ़ाइलें उत्पन्न कीं।```python
# 1. Grab & Patch iBSS
if not os.path.exists("iPhone17\\,3_26.1_23B85_Restore/Firmware/dfu/iBSS.vresearch101.RELEASE.im4p.bak"):
os.system("cp iPhone17\\,3_26.1_23B85_Restore/Firmware/dfu/iBSS.vresearch101.RELEASE.im4p iPhone17\\,3_26.1_23B85_Restore/Firmware/dfu/iBSS.vresearch101.RELEASE.im4p.bak")
os.system("tools/img4 -i iPhone17\\,3_26.1_23B85_Restore/Firmware/dfu/iBSS.vresearch101.RELEASE.im4p.bak -o iBSS.vresearch101.RELEASE")
... # patch things from raw
os.system("tools/img4tool -c iBSS.vresearch101.RELEASE.im4p -t ibss iBSS.vresearch101.RELEASE")
os.system("tools/img4 -i iBSS.vresearch101.RELEASE.im4p -o ./Ramdisk/iBSS.vresearch101.RELEASE.img4 -M ./vphone.im4m")
# 2. Grab & Patch iBEC
if not os.path.exists("iPhone17\\,3_26.1_23B85_Restore/Firmware/dfu/iBEC.vresearch101.RELEASE.im4p.bak"):
os.system("cp iPhone17\\,3_26.1_23B85_Restore/Firmware/dfu/iBEC.vresearch101.RELEASE.im4p iPhone17\\,3_26.1_23B85_Restore/Firmware/dfu/iBEC.vresearch101.RELEASE.im4p.bak")
os.system("tools/img4 -i iPhone17\\,3_26.1_23B85_Restore/Firmware/dfu/iBEC.vresearch101.RELEASE.im4p -o iBEC.vresearch101.RELEASE")
... # patch things from raw
os.system("tools/img4tool -c iBEC.vresearch101.RELEASE.im4p -t ibec iBEC.vresearch101.RELEASE")
os.system("tools/img4 -i iBEC.vresearch101.RELEASE.im4p -o Ramdisk/iBEC.vresearch101.RELEASE.img4 -M vphone.im4m")
# 3. Grab SPTM
os.system("tools/img4 -i iPhone17\\,3_26.1_23B85_Restore/Firmware/sptm.vresearch1.release.im4p -o Ramdisk/sptm.vresearch1.release.img4 -M vphone.im4m -T sptm")
# 4. Grab devicetree
os.system("tools/img4 -i iPhone17\\,3_26.1_23B85_Restore/Firmware/all_flash/DeviceTree.vphone600ap.im4p -o Ramdisk/DeviceTree.vphone600ap.img4 -M vphone.im4m -T rdtr")
# 5. Grab sep
os.system("tools/img4 -i iPhone17\\,3_26.1_23B85_Restore/Firmware/all_flash/sep-firmware.vresearch101.RELEASE.im4p -o Ramdisk/sep-firmware.vresearch101.RELEASE.img4 -M vphone.im4m -T rsep")
# 6. Grab & Patch TXM
if not os.path.exists("iPhone17\\,3_26.1_23B85_Restore/Firmware/txm.iphoneos.release.im4p.bak"):
os.system("cp iPhone17\\,3_26.1_23B85_Restore/Firmware/txm.iphoneos.release.im4p iPhone17\\,3_26.1_23B85_Restore/Firmware/txm.iphoneos.release.im4p.bak")
os.system("pyimg4 im4p extract -i iPhone17\\,3_26.1_23B85_Restore/Firmware/txm.iphoneos.release.im4p.bak -o txm.raw")
... # patch things from raw
#create im4p
os.system("pyimg4 im4p create -i txm.raw -o txm.im4p -f trxm --lzfse")
# preserve payp structure
txm_im4p_data = Path('iPhone17,3_26.1_23B85_Restore/Firmware/txm.iphoneos.release.im4p.bak').read_bytes()
payp_offset = txm_im4p_data.rfind(b'PAYP')
if payp_offset == -1:
print("Couldn't find payp structure !!!")
sys.exit()
with open('txm.im4p', 'ab') as f:
f.write(txm_im4p_data[(payp_offset-10):])
payp_sz = len(txm_im4p_data[(payp_offset-10):])
print(f"payp sz: {payp_sz}")
txm_im4p_data = bytearray(open('txm.im4p', 'rb').read())
txm_im4p_data[2:5] = (int.from_bytes(txm_im4p_data[2:5], 'big') + payp_sz).to_bytes(3, 'big')
open('txm.im4p', 'wb').write(txm_im4p_data)
# sign
os.system("pyimg4 img4 create -p txm.im4p -o Ramdisk/txm.img4 -m vphone.im4m")
# 7. Grab & patch kernelcache
if not os.path.exists("iPhone17\\,3_26.1_23B85_Restore/kernelcache.research.vphone600.bak"):
os.system("cp iPhone17\\,3_26.1_23B85_Restore/kernelcache.research.vphone600 iPhone17\\,3_26.1_23B85_Restore/kernelcache.research.vphone600.bak")
os.system("pyimg4 im4p extract -i iPhone17\\,3_26.1_23B85_Restore/kernelcache.research.vphone600.bak -o kcache.raw")
... # patch things from raw
#create im4p
os.system("pyimg4 im4p create -i kcache.raw -o krnl.im4p -f rkrn --lzfse")
# preserve payp structure
kernel_im4p_data = Path('iPhone17,3_26.1_23B85_Restore/kernelcache.research.vphone600.bak').read_bytes()
payp_offset = kernel_im4p_data.rfind(b'PAYP')
if payp_offset == -1:
print("Couldn't find payp structure !!!")
sys.exit()
with open('krnl.im4p', 'ab') as f:
f.write(kernel_im4p_data[(payp_offset-10):])
payp_sz = len(kernel_im4p_data[(payp_offset-10):])
print(f"payp sz: {payp_sz}")
kernel_im4p_data = bytearray(open('krnl.im4p', 'rb').read())
kernel_im4p_data[2:5] = (int.from_bytes(kernel_im4p_data[2:5], 'big') + payp_sz).to_bytes(3, 'big')
open('krnl.im4p', 'wb').write(kernel_im4p_data)
# sign
os.system("pyimg4 img4 create -p krnl.im4p -o Ramdisk/krnl.img4 -m vphone.im4m")
# 8. Grab ramdisk & build custom ramdisk
os.system("pyimg4 im4p extract -i iPhone17,3_26.1_23B85_Restore/043-53775-129.dmg -o ramdisk.dmg")
os.system("mkdir SSHRD")
os.system("sudo hdiutil attach -mountpoint SSHRD ramdisk.dmg -owners off")
os.system("sudo hdiutil create -size 254m -imagekey diskimage-class=CRawDiskImage -format UDZO -fs APFS -layout NONE -srcfolder SSHRD -copyuid root ramdisk1.dmg")
os.system("sudo hdiutil detach -force SSHRD")
os.system("sudo hdiutil attach -mountpoint SSHRD ramdisk1.dmg -owners off")
... #remove unneccessary files for expand space
#resign all things preserving ents
target_path= [
"SSHRD/usr/local/bin/*", "SSHRD/usr/local/lib/*",
"SSHRD/usr/bin/*", "SSHRD/bin/*",
"SSHRD/usr/lib/*", "SSHRD/sbin/*", "SSHRD/usr/sbin/*", "SSHRD/usr/libexec/*"
]
for pattern in target_path:
for path in glob.glob(pattern):
if os.path.isfile(path) and not os.path.islink(path):
if "Mach-O" in subprocess.getoutput(f"file \"{path}\""):
os.system(f"tools/ldid_macosx_arm64 -S -M -Cadhoc \"{path}\"")
#8-2. Grab & build custom ramdisk's trustcache while building custom ramdisk
os.system("pyimg4 im4p extract -i iPhone17,3_26.1_23B85_Restore/Firmware/043-53775-129.dmg.trustcache -o trustcache.raw")
os.system("tools/trustcache_macos_arm64 create sshrd.tc SSHRD")
os.system("pyimg4 im4p create -i sshrd.tc -o trustcache.im4p -f rtsc")
# sign
os.system("pyimg4 img4 create -p trustcache.im4p -o Ramdisk/trustcache.img4 -m vphone.im4m")
#8-2. end
os.system("sudo hdiutil detach -force SSHRD")
os.system("sudo hdiutil resize -sectors min ramdisk1.dmg")
# sign
os.system("pyimg4 im4p create -i ramdisk1.dmg -o ramdisk1.dmg.im4p -f rdsk")
os.system("pyimg4 img4 create -p ramdisk1.dmg.im4p -o Ramdisk/ramdisk.img4 -m vphone.im4m")
जब सभी IMG4 इमेज बन जाएँ, तो उन्हें एक-एक करके लोड करें और Ramdisk के साथ बूट करें।
sleep 1; irecovery -f Ramdisk/sptm.vresearch1.release.img4 irecovery -c firmware
irecovery -f Ramdisk/txm.img4 irecovery -c firmware
irecovery -f Ramdisk/trustcache.img4 irecovery -c firmware irecovery -f Ramdisk/ramdisk.img4 irecovery -c ramdisk irecovery -f Ramdisk/DeviceTree.vphone600ap.img4 irecovery -c devicetree irecovery -f Ramdisk/sep-firmware.vresearch101.RELEASE.img4 irecovery -c firmware irecovery -f Ramdisk/krnl.img4 irecovery -c bootx
फिर, आपको बाईं ओर से तीसरी विंडो में Minecraft का Creeper चेहरा दिखाई देगा, जैसा कि नीचे दिखाया गया है।
यदि आप System Information ऐप में USB मेनू की जाँच करते हैं और "iPhone Research..." देखते हैं, तो अब आप [iproxy](https://github.com/libimobiledevice/libusbmuxd/blob/master/tools/iproxy.c) टूल का उपयोग करके वर्चुअल iPhone शेल तक पहुँच सकते हैं। (`iproxy 2222 22 &`)

रूट फ़ाइल सिस्टम को संशोधित करने के लिए, स्नैपशॉट का नाम बदलें।```python
ssh [email protected] -p2222
#pw: alpine
mount_apfs -o rw /dev/disk1s1 /mnt1
snaputil -l /mnt1
# (then will output will be printed with hash, result may be differ)
com.apple.os.update-8AAB8DBA5C8F1F756928411675F4A892087B04559CFB084B9E400E661ABAD119
snaputil -n <com.apple.os.update-hash> orig-fs /mnt1
umount /mnt1
exit
AEA फ़ाइल को ipsw टूल का उपयोग करके डिक्रिप्ट करें, एक dmg फ़ाइल बनाएं, इसे माउंट करें, और फिर Cryptex पार्टीशन से फ़ाइलों को वर्चुअल मशीन में स्थानांतरित करें। फ़ाइल स्थानांतरण के साथ-साथ, विशिष्ट पैच की आवश्यकता थी। सुविधा के लिए, मैंने बूट पर तीन विशिष्ट प्रक्रियाएँ शुरू करने के लिए जोड़ दीं: bash, dropbear, और trollvnc।
seputil में एक समस्या थी जहाँ यह gigalocker फ़ाइल को ठीक से नहीं ढूँढ पा रहा था, इसलिए मैंने इसे हमेशा AA.gl खोजने के लिए पैच किया। इसके अलावा, मैंने launchd_cache_loader को पैच किया ताकि यह सुनिश्चित हो सके कि संशोधित /System/Library/xpc/launchd.plist सही ढंग से लोड हो।```python ... ========= INSTALL CRYPTEX(SystemOS, AppOS) =========
key = subprocess.check_output("ipsw fw aea --key iPhone17,3_26.1_23B85_Restore/043-54303-126.dmg.aea", shell=True, text=True).strip() print(f"key: {key}") os.system(f"aea decrypt -i iPhone17,3_26.1_23B85_Restore/043-54303-126.dmg.aea -o CryptexSystemOS.dmg -key-value '{key}'")
os.system(f"cp iPhone17,3_26.1_23B85_Restore/043-54062-129.dmg CryptexAppOS.dmg")
os.system("mkdir CryptexSystemOS") os.system("sudo hdiutil attach -mountpoint CryptexSystemOS CryptexSystemOS.dmg -owners off")
os.system("mkdir CryptexAppOS") os.system("sudo hdiutil attach -mountpoint CryptexAppOS CryptexAppOS.dmg -owners off")
remote_cmd("/sbin/mount_apfs -o rw /dev/disk1s1 /mnt1")
remote_cmd("/bin/rm -rf /mnt1/System/Cryptexes/App") remote_cmd("/bin/rm -rf /mnt1/System/Cryptexes/OS")
remote_cmd("/bin/mkdir -p /mnt1/System/Cryptexes/App") remote_cmd("/bin/chmod 0755 /mnt1/System/Cryptexes/App") remote_cmd("/bin/mkdir -p /mnt1/System/Cryptexes/OS") remote_cmd("/bin/chmod 0755 /mnt1/System/Cryptexes/OS")
print("Copying cryptexs to vphone! Will take about 3 mintues...") os.system("tools/sshpass -p 'alpine' scp -q -r -ostricthostkeychecking=false -ouserknownhostsfile=/dev/null -o StrictHostKeyChecking=no -P 2222 CryptexSystemOS/. '[email protected]:/mnt1/System/Cryptexes/OS'") os.system("tools/sshpass -p 'alpine' scp -q -r -ostricthostkeychecking=false -ouserknownhostsfile=/dev/null -o StrictHostKeyChecking=no -P 2222 CryptexAppOS/. '[email protected]:/mnt1/System/Cryptexes/App'")
remote_cmd("/bin/ln -sf ../../../System/Cryptexes/OS/System/Library/Caches/com.apple.dyld /mnt1/System/Library/Caches/com.apple.dyld")
remote_cmd("/bin/ln -sf ../../../../System/Cryptexes/OS/System/DriverKit/System/Library/dyld /mnt1/System/DriverKit/System/Library/dyld")
os.system("rm custom_26.1/seputil 2>/dev/null") os.system("rm custom_26.1/seputil.bak 2>/dev/null")
file_path = "/mnt1/usr/libexec/seputil.bak" if not check_remote_file_exists(file_path): print(f"Created backup {file_path}") remote_cmd("/bin/cp /mnt1/usr/libexec/seputil /mnt1/usr/libexec/seputil.bak")
os.system("tools/sshpass -p 'alpine' scp -q -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -P 2222 [email protected]:/mnt1/usr/libexec/seputil.bak ./custom_26.1") os.system("mv custom_26.1/seputil.bak custom_26.1/seputil")
fp = open("custom_26.1/seputil", "r+b") patch(0x1B3F1, "AA") fp.close()
os.system("tools/ldid_macosx_arm64 -S -M -Ksigncert.p12 -Icom.apple.seputil custom_26.1/seputil")
os.system("tools/sshpass -p 'alpine' scp -q -r -ostricthostkeychecking=false -ouserknownhostsfile=/dev/null -o StrictHostKeyChecking=no -P 2222 custom_26.1/seputil '[email protected]:/mnt1/usr/libexec/seputil'") remote_cmd("/bin/chmod 0755 /mnt1/usr/libexec/seputil")
os.system("rm custom_26.1/seputil 2>/dev/null")
remote_cmd("/sbin/mount_apfs -o rw /dev/disk1s3 /mnt3") remote_cmd("/bin/mv /mnt3/*.gl /mnt3/AA.gl")
... # ========= INSTALL AppleParavirtGPUMetalIOGPUFamily =========
os.system("tools/sshpass -p 'alpine' scp -q -r -ostricthostkeychecking=false -ouserknownhostsfile=/dev/null -o StrictHostKeyChecking=no -P 2222 jb/iosbinpack64.tar '[email protected]:/mnt1'")
remote_cmd("/usr/bin/tar --preserve-permissions --no-overwrite-dir -xvf /mnt1/iosbinpack64.tar -C /mnt1") remote_cmd("/bin/rm /mnt1/iosbinpack64.tar")
''' /iosbinpack64/bin/mkdir -p /var/dropbear /iosbinpack64/bin/cp /iosbinpack64/etc/profile /var/profile /iosbinpack64/bin/cp /iosbinpack64/etc/motd /var/motd '''
os.system("rm custom_26.1/launchd_cache_loader 2>/dev/null") os.system("rm custom_26.1/launchd_cache_loader.bak 2>/dev/null")
file_path = "/mnt1/usr/libexec/launchd_cache_loader.bak" if not check_remote_file_exists(file_path): print(f"Created backup {file_path}") remote_cmd("/bin/cp /mnt1/usr/libexec/launchd_cache_loader /mnt1/usr/libexec/launchd_cache_loader.bak")
os.system("tools/sshpass -p 'alpine' scp -q -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -P 2222 [email protected]:/mnt1/usr/libexec/launchd_cache_loader.bak ./custom_26.1") os.system("mv custom_26.1/launchd_cache_loader.bak custom_26.1/launchd_cache_loader")
fp = open("custom_26.1/launchd_cache_loader", "r+b") patch(0xB58, 0xd503201f) fp.close()
os.system("tools/ldid_macosx_arm64 -S -M -Ksigncert.p12 -Icom.apple.launchd_cache_loader custom_26.1/launchd_cache_loader")
os.system("tools/sshpass -p 'alpine' scp -q -r -ostricthostkeychecking=false -ouserknownhostsfile=/dev/null -o StrictHostKeyChecking=no -P 2222 custom_26.1/launchd_cache_loader '[email protected]:/mnt1/usr/libexec/launchd_cache_loader'") remote_cmd("/bin/chmod 0755 /mnt1/usr/libexec/launchd_cache_loader")
os.system("rm custom_26.1/launchd_cache_loader 2>/dev/null")
os.system("tools/sshpass -p 'alpine' scp -q -r -ostricthostkeychecking=false -ouserknownhostsfile=/dev/null -o StrictHostKeyChecking=no -P 2222 jb/LaunchDaemons/bash.plist '[email protected]:/mnt1/System/Library/LaunchDaemons'") os.system("tools/sshpass -p 'alpine' scp -q -r -ostricthostkeychecking=false -ouserknownhostsfile=/dev/null -o StrictHostKeyChecking=no -P 2222 jb/LaunchDaemons/dropbear.plist '[email protected]:/mnt1/System/Library/LaunchDaemons'") os.system("tools/sshpass -p 'alpine' scp -q -r -ostricthostkeychecking=false -ouserknownhostsfile=/dev/null -o StrictHostKeyChecking=no -P 2222 jb/LaunchDaemons/trollvnc.plist '[email protected]:/mnt1/System/Library/LaunchDaemons'") remote_cmd("/bin/chmod 0644 /mnt1/System/Library/LaunchDaemons/bash.plist") remote_cmd("/bin/chmod 0644 /mnt1/System/Library/LaunchDaemons/dropbear.plist") remote_cmd("/bin/chmod 0644 /mnt1/System/Library/LaunchDaemons/trollvnc.plist")
os.system("rm custom_26.1/launchd.plist 2>/dev/null") os.system("rm custom_26.1/launchd.plist.bak 2>/dev/null")
file_path = "/mnt1/System/Library/xpc/launchd.plist.bak" if not check_remote_file_exists(file_path): print(f"Created backup {file_path}") remote_cmd("/bin/cp /mnt1/System/Library/xpc/launchd.plist /mnt1/System/Library/xpc/launchd.plist.bak")
os.system("tools/sshpass -p 'alpine' scp -q -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -P 2222 [email protected]:/mnt1/System/Library/xpc/launchd.plist.bak ./custom_26.1") os.system("mv custom_26.1/launchd.plist.bak custom_26.1/launchd.plist")
os.system("plutil -convert xml1 custom_26.1/launchd.plist")
target_file = 'custom_26.1/launchd.plist' source_file = 'jb/LaunchDaemons/bash.plist' insert_key = '/System/Library/LaunchDaemons/bash.plist'
with open(target_file, 'rb') as ft, open(source_file, 'rb') as fs: target_data = plistlib.load(ft) source_data = plistlib.load(fs)
target_data.setdefault('LaunchDaemons', {})[insert_key] = source_data
with open(target_file, 'wb') as f: plistlib.dump(target_data, f, sort_keys=False)
source_file = 'jb/LaunchDaemons/dropbear.plist' insert_key = '/System/Library/LaunchDaemons/dropbear.plist'
with open(target_file, 'rb') as ft, open(source_file, 'rb') as fs: target_data = plistlib.load(ft) source_data = plistlib.load(fs)
target_data.setdefault('LaunchDaemons', {})[insert_key] = source_data
with open(target_file, 'wb') as f: plistlib.dump(target_data, f, sort_keys=False)
source_file = 'jb/LaunchDaemons/trollvnc.plist' insert_key = '/System/Library/LaunchDaemons/trollvnc.plist'
with open(target_file, 'rb') as ft, open(source_file, 'rb') as fs: target_data = plistlib.load(ft) source_data = plistlib.load(fs)
target_data.setdefault('LaunchDaemons', {})[insert_key] = source_data
with open(target_file, 'wb') as f: plistlib.dump(target_data, f, sort_keys=False)
os.system("tools/sshpass -p 'alpine' scp -q -r -ostricthostkeychecking=false -ouserknownhostsfile=/dev/null -o StrictHostKeyChecking=no -P 2222 custom_26.1/launchd.plist '[email protected]:/mnt1/System/Library/xpc'") remote_cmd("/bin/chmod 0644 /mnt1/System/Library/xpc/launchd.plist")
os.system("rm custom_26.1/launchd.plist 2>/dev/null")
... remote_cmd("/sbin/halt") ...
# First Boot Attempt
बूट प्रक्रिया अब ठीक काम करनी चाहिए, लेकिन जब आप ब्लैक सेटअप स्क्रीन से आगे बढ़ने का प्रयास करते हैं, तो यह रीस्प्रिंग हो जाता है और आगे नहीं बढ़ता है।


# Implementing Metal
MetalTest नामक एक कस्टम प्रोग्राम के साथ जांच करने पर, यह दिखाता है कि मेटल समर्थित नहीं है।```python
#import <stdio.h>
#import <Metal/Metal.h>
#import <Foundation/Foundation.h>
int main(int argc, char *argv[], char *envp[]) {
id<MTLDevice> device = MTLCreateSystemDefaultDevice();
NSLog(@"device: %@", device);
if (device) {
NSLog(@"Metal Device Create Success: %@", [device name]);
} else {
NSLog(@"Metal Not Supported!");
}
return 0;
}
सामान्यतः, आउटपुट नीचे दिए गए परिणाम जैसा दिखना चाहिए था।```python
seo@seos-Virtual-Machine Desktop % sysctl kern.version
kern.version: Darwin Kernel Version 25.0.0: Mon Aug 25 21:17:21 PDT 2025; root:xnu-12377.1.9~3/RELEASE_ARM64_VMAPPLE
seo@seos-Virtual-Machine Desktop % ./MetalTest
2026-02-08 23:16:56.846 MetalTest[682:5810] device: <AppleParavirtDevice: 0x102c48fe0>
name = Apple Paravirtual device
2026-02-08 23:16:56.847 MetalTest[682:5810] Metal Device Create Success: Apple Paravirtual device
seo@seos-Virtual-Machine Desktop %
ioreg -l के साथ जाँच करने पर, जैसा कि आप देख सकते हैं, कर्नेल वास्तव में AppleParavirtGPU को पहचान रहा था।

जब iOS 16.6.1 चलाने वाले iPad 7th Gen पर जाँच की गई, तो MTLCreateSystemDefaultDevice फ़ंक्शन को कॉल करने पर आंतरिक रूप से AGXMetalA10 नामक एक विशिष्ट लाइब्रेरी के माध्यम से IOGPU ड्राइवर तक पहुंच होती है। यह AGXMetalA10 लाइब्रेरी /System/Library/Extensions में स्थित है।
यहाँ मेरे मन में अचानक एक विचार आया: क्या वर्चुअल iPhone के लिए भी GPU/Metal-संबंधित लाइब्रेरीज़ का उपयोग नहीं होगा?

PCC वर्चुअल मशीन में उसी पथ की जाँच करने पर पता चलता है कि वहाँ 7 फ़ाइलें मौजूद हैं।
मैंने PCC में उपयोग किए गए /System/Library/Extensions/AppleParavirtGPUMetalIOGPUFamily.bundle को लेकर सीधे वर्चुअल iPhone में रख दिया। (इसके लिए मैंने SSH Ramdisk का उपयोग किया।)

MetalTest की फिर से जाँच करने पर, MTLCreateSystemDefaultDevice फ़ंक्शन अब ठीक से काम करता है।

हालांकि, iPhone 16 मॉडल के dsc (dyld shared cache) में एक विशिष्ट dylib फ़ाइल मौजूद नहीं होने के कारण, मुझे PCC में dsc से इसे अलग से रिवर्स-इंजीनियर और कार्यान्वित करना पड़ा।


एक बार कार्यान्वित होने के बाद, अब आपको एक पृष्ठभूमि के साथ सेटअप स्क्रीन दिखाई देती है। चूंकि मैं होम बटन को ठीक से कार्यान्वित नहीं कर सका, इसलिए मैंने iproxy/VNC के माध्यम से इसे नियंत्रित करके एक अस्थायी समाधान का उपयोग किया।

यह केवल Apple Silicon Macs के साथ संगत है, और जिन डिवाइसों/संस्करणों के काम करने की पुष्टि हुई है वे इस प्रकार हैं:
मुझे उम्मीद है कि यह संभवतः किसी भी लक्ष्य पर काम करेगा जो pccvre का समर्थन करता है।

Tahoe संस्करण 26 के विपरीत, केवल VZVirtualMachineView ऑब्जेक्ट का उपयोग करके टच इंटरेक्शन संभव नहीं है, इसलिए माउस इवेंट फ़ंक्शनों को ओवरराइड करना आवश्यक था।