StikDebug/scripts/prepare_cryptex_ddi.py
2026-09-20 22:56:31 -07:00

53 lines
2.1 KiB
Python

#!/usr/bin/env python3
"""Bundle the verified generic DDI used in the iPhone19,2 mounting test."""
import argparse
import hashlib
import plistlib
import shutil
import tempfile
import urllib.request
from pathlib import Path
REVISION = "59a90f1e3f1e7190b9a429c768568b83c321582e"
BASE = f"https://raw.githubusercontent.com/doronz88/DeveloperDiskImage/{REVISION}/PersonalizedImages/Xcode_iOS_DDI_Cryptex"
PAYLOADS = {
"Cryptex1,GenericDmg": "Image.dmg",
"Cryptex1,GenericTrustCache": "Image.dmg.trustcache",
"Cryptex1,CryptexInfoPlist": "Image.dmg.cryptex_info",
"Cryptex1,GenericVolume": "Image.dmg.root_hash",
}
def prepare(output: Path):
if output.exists():
raise ValueError(f"Output already exists: {output}")
output.parent.mkdir(parents=True, exist_ok=True)
staging = Path(tempfile.mkdtemp(prefix="cryptex-", dir=output.parent))
try:
def download(name):
with urllib.request.urlopen(f"{BASE}/{name}", timeout=120) as response:
data = response.read()
(staging / name).write_bytes(data)
return data
manifest = plistlib.loads(download("BuildManifest.plist"))
identity = next(i for i in manifest["BuildIdentities"]
if i.get("Info", {}).get("Variant", "").endswith("Developer Disk Image Cryptex"))
for key, name in PAYLOADS.items():
entry = identity["Manifest"][key]
if entry["Info"]["Path"] != name:
raise ValueError(f"Unexpected Cryptex path for {key}")
data = download(name)
if not data or hashlib.sha384(data).digest() != entry["Digest"]:
raise ValueError(f"Cryptex payload failed verification: {name}")
staging.rename(output)
print(f"Verified Cryptex DDI {manifest['ProductBuildVersion']} from {REVISION}")
finally:
if staging.exists():
shutil.rmtree(staging)
if __name__ == "__main__":
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("--output", type=Path, required=True)
prepare(parser.parse_args().output)