mirror of
https://github.com/StikDebug/StikDebug.git
synced 2026-10-15 12:02:14 +00:00
ci(ios): bundle the verified generic developer image
This commit is contained in:
parent
a4722251f2
commit
e145bbe932
2 changed files with 63 additions and 0 deletions
10
.github/workflows/build_ipa.yml
vendored
10
.github/workflows/build_ipa.yml
vendored
|
|
@ -29,6 +29,15 @@ jobs:
|
|||
with:
|
||||
xcode-version: '26.6'
|
||||
|
||||
- name: Test Cryptex image validation
|
||||
run: swift test
|
||||
|
||||
- name: Prepare checksum-pinned idevice with Cryptex support
|
||||
run: python3 scripts/prepare_idevice.py
|
||||
|
||||
- name: Prepare verified generic developer image
|
||||
run: python3 scripts/prepare_cryptex_ddi.py --output build/BundledCryptexDDI
|
||||
|
||||
- name: 3. Compile Project Archive
|
||||
run: |
|
||||
xcodebuild clean archive \
|
||||
|
|
@ -48,6 +57,7 @@ jobs:
|
|||
- name: 4. Package .app into .ipa
|
||||
run: |
|
||||
cp -R build/StikDebug.xcarchive/Products/Applications/StikDebug.app .
|
||||
cp -R build/BundledCryptexDDI StikDebug.app/BundledCryptexDDI
|
||||
mkdir -p Payload
|
||||
cp -R StikDebug.app Payload/
|
||||
zip -r StikDebug.ipa Payload
|
||||
|
|
|
|||
53
scripts/prepare_cryptex_ddi.py
Normal file
53
scripts/prepare_cryptex_ddi.py
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
#!/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)
|
||||
Loading…
Add table
Add a link
Reference in a new issue