fix: ios 16
This commit is contained in:
@@ -0,0 +1,62 @@
|
||||
"""Encrypt/decrypt Coruna secondary type-0x01 .min.js packs."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import lzma
|
||||
import struct
|
||||
|
||||
from Crypto.Cipher import ChaCha20
|
||||
|
||||
WRAP_MAGIC = b"\x0d\xf0\xed\x0b" # 0x0BEDF00D LE
|
||||
F00D_MAGIC = 0xF00DBEEF
|
||||
|
||||
|
||||
def build_f00dbeef_type01(dylib: bytes) -> bytes:
|
||||
"""Single-entry F00DBEEF used by this campaign's secondary packs."""
|
||||
header = struct.pack(
|
||||
"<6I",
|
||||
F00D_MAGIC,
|
||||
1, # version / entry-count field as in sample
|
||||
0x00010000, # type 0x01
|
||||
3,
|
||||
0x18, # payload offset
|
||||
len(dylib),
|
||||
)
|
||||
return header + dylib
|
||||
|
||||
|
||||
def wrap_xz(plaintext: bytes) -> bytes:
|
||||
compressed = lzma.compress(plaintext, format=lzma.FORMAT_XZ)
|
||||
return WRAP_MAGIC + struct.pack("<I", len(plaintext)) + compressed
|
||||
|
||||
|
||||
def unwrap_xz(blob: bytes) -> bytes:
|
||||
if blob[:4] != WRAP_MAGIC:
|
||||
raise ValueError(f"bad wrap magic: {blob[:4]!r}")
|
||||
expected = struct.unpack_from("<I", blob, 4)[0]
|
||||
plain = lzma.decompress(blob[8:])
|
||||
if len(plain) != expected:
|
||||
raise ValueError(f"xz size mismatch: {len(plain)} != {expected}")
|
||||
return plain
|
||||
|
||||
|
||||
def chacha_crypt(data: bytes, key: bytes) -> bytes:
|
||||
if len(key) != 32:
|
||||
raise ValueError("ChaCha20 key must be 32 bytes")
|
||||
return ChaCha20.new(key=key, nonce=b"\x00" * 8).encrypt(data)
|
||||
|
||||
|
||||
def encrypt_secondary_minjs(dylib: bytes, key: bytes) -> bytes:
|
||||
return chacha_crypt(wrap_xz(build_f00dbeef_type01(dylib)), key)
|
||||
|
||||
|
||||
def decrypt_secondary_minjs(blob: bytes, key: bytes) -> bytes:
|
||||
plain = unwrap_xz(chacha_crypt(blob, key))
|
||||
if struct.unpack_from("<I", plain, 0)[0] != F00D_MAGIC:
|
||||
raise ValueError("not F00DBEEF after decrypt")
|
||||
offset = struct.unpack_from("<I", plain, 16)[0]
|
||||
size = struct.unpack_from("<I", plain, 20)[0]
|
||||
dylib = plain[offset : offset + size]
|
||||
if len(dylib) != size:
|
||||
raise ValueError("truncated dylib in F00DBEEF")
|
||||
return dylib
|
||||
Reference in New Issue
Block a user