Files
UniXNU/scripts/trust-append-module.py

25 lines
1.2 KiB
Python

#!/usr/bin/env python3
"""trust-append-module.py IN OUT CDHASH [CDHASH ...]: copy a trust bundle (bundle-ipsw-trust.py layout) and append one version-2
module with the given CDHashes (hash type 2). The IPSW modules stay byte for byte; the kernel loads the new one as an engineering module."""
import struct
import sys
import uuid
from pathlib import Path
if len(sys.argv) < 4:
sys.exit(__doc__)
data = Path(sys.argv[1]).read_bytes()
count = struct.unpack_from('<I', data)[0]
starts = list(struct.unpack_from(f'<{count}I', data, 4)) + [len(data)]
modules = [data[starts[i]:starts[i + 1]] for i in range(count)]
hashes = sorted({bytes.fromhex(h) for h in sys.argv[3:]})
assert all(len(h) == 20 for h in hashes), 'CDHashes are 20 bytes'
ident = uuid.uuid5(uuid.NAMESPACE_URL, 'org.unixnu.owner:' + ''.join(h.hex() for h in hashes)).bytes
modules.append(struct.pack('<I16sI', 2, ident, len(hashes)) + b''.join(h + bytes([2, 0, 0, 0]) for h in hashes))
cursor, offsets = 4 + 4 * len(modules), []
for m in modules:
offsets.append(cursor)
cursor += len(m)
Path(sys.argv[2]).write_bytes(struct.pack(f'<{len(modules) + 1}I', len(modules), *offsets) + b''.join(modules))
print(f'{sys.argv[2]}: {count} -> {len(modules)} modules, last has {len(hashes)} hashes')