调整文件目录
This commit is contained in:
@@ -10,16 +10,35 @@ import struct
|
||||
import zlib
|
||||
from pathlib import Path
|
||||
|
||||
AAD = b"Q05-Lidar init_boot resource v1"
|
||||
DEFAULT_AAD = "Q05-Lidar init_boot resource v1"
|
||||
FORMAT_MAGIC = {
|
||||
"q05": (b"Q05R2\x00", "q05-lidar-resource-v2", DEFAULT_AAD),
|
||||
"ez60": (b"EZ60R2\x00", "ez60-resource-v2", "Mazda-EZ60 init_boot resource v1"),
|
||||
}
|
||||
|
||||
|
||||
def b64u(data):
|
||||
return base64.urlsafe_b64encode(data).decode("ascii").rstrip("=")
|
||||
|
||||
|
||||
def decode_key_material(key_text):
|
||||
text = str(key_text).strip()
|
||||
if text.startswith("raw:"):
|
||||
key = text.split(":", 1)[1].encode("utf-8")
|
||||
elif len(text) == 64 and all(c in "0123456789abcdefABCDEF" for c in text):
|
||||
key = bytes.fromhex(text)
|
||||
elif len(text.encode("utf-8")) == 32:
|
||||
key = text.encode("utf-8")
|
||||
else:
|
||||
key = base64.urlsafe_b64decode(text + "=" * (-len(text) % 4))
|
||||
if len(key) != 32:
|
||||
raise ValueError(f"key must decode to 32 bytes, got {len(key)} bytes")
|
||||
return key
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Encrypt a Q05-Lidar init_boot image into resource.dat"
|
||||
description="Encrypt a vehicle init_boot image into a resource dat file"
|
||||
)
|
||||
parser.add_argument("input_img", help="Magisk-patched init_boot image")
|
||||
parser.add_argument(
|
||||
@@ -27,9 +46,19 @@ def main():
|
||||
default="resource.dat",
|
||||
help="Output encrypted resource file, default: resource.dat",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--vehicle",
|
||||
choices=sorted(FORMAT_MAGIC.keys()),
|
||||
default="q05",
|
||||
help="Resource header/profile to write. Default: q05.",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--aad",
|
||||
help="Optional AES-GCM AAD text. Defaults to the selected vehicle profile.",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--key",
|
||||
help="Optional AES-256 key as base64url or 64-char hex. Omit to generate a random key.",
|
||||
help="Optional AES-256 key as base64url, 64-char hex, raw:TEXT, or 32-byte UTF-8 text. Omit to generate a random key.",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--no-compress",
|
||||
@@ -49,29 +78,28 @@ def main():
|
||||
input_path = Path(args.input_img)
|
||||
plain = input_path.read_bytes()
|
||||
sha256 = hashlib.sha256(plain).hexdigest()
|
||||
magic, resource_format, default_aad = FORMAT_MAGIC[args.vehicle]
|
||||
aad = (args.aad or default_aad).encode("utf-8")
|
||||
|
||||
if args.key:
|
||||
text = args.key.strip()
|
||||
if len(text) == 64 and all(c in "0123456789abcdefABCDEF" for c in text):
|
||||
key = bytes.fromhex(text)
|
||||
else:
|
||||
key = base64.urlsafe_b64decode(text + "=" * (-len(text) % 4))
|
||||
if len(key) != 32:
|
||||
raise SystemExit("key must decode to 32 bytes")
|
||||
try:
|
||||
key = decode_key_material(args.key)
|
||||
except Exception as e:
|
||||
raise SystemExit(str(e))
|
||||
else:
|
||||
key = os.urandom(32)
|
||||
|
||||
compression = "none" if args.no_compress else "zlib"
|
||||
body = plain if args.no_compress else zlib.compress(plain, level=9)
|
||||
nonce = os.urandom(12)
|
||||
ciphertext = AESGCM(key).encrypt(nonce, body, AAD)
|
||||
ciphertext = AESGCM(key).encrypt(nonce, body, aad)
|
||||
|
||||
header = {
|
||||
"format": "q05-lidar-resource-v2",
|
||||
"format": resource_format,
|
||||
"cipher": "AES-256-GCM",
|
||||
"kdf": "none",
|
||||
"compression": compression,
|
||||
"aad": AAD.decode("utf-8"),
|
||||
"aad": aad.decode("utf-8"),
|
||||
"nonce": b64u(nonce),
|
||||
"sha256": sha256,
|
||||
"plainSize": len(plain),
|
||||
@@ -80,7 +108,7 @@ def main():
|
||||
|
||||
output_path = Path(args.output)
|
||||
header_bytes = json.dumps(header, ensure_ascii=False, separators=(",", ":")).encode("utf-8")
|
||||
output_path.write_bytes(b"Q05R2\x00" + struct.pack(">I", len(header_bytes)) + header_bytes + ciphertext)
|
||||
output_path.write_bytes(magic + struct.pack(">I", len(header_bytes)) + header_bytes + ciphertext)
|
||||
|
||||
print("resource.dat created")
|
||||
print(f"input: {input_path}")
|
||||
|
||||
Reference in New Issue
Block a user