Files
vt1200/dwt/rom_dump.py
T

67 lines
2.0 KiB
Python

#!/usr/bin/env python3
"""Full ROM dump over rdebug `peek`, compared with the known v2.2 image.
The ROM is mapped at bit `0x3F200000` for 0x1C0000 bytes (1.75 MiB). A
sequential `peek` of 1 KiB chunks returns the image; the md5 is compared with
the file the project has been using.
python3 dwt/rom_dump.py --host 100.103.100.103
"""
from __future__ import annotations
import argparse
import hashlib
import sys
import exploit
ROM_BASE_BITS = 0x3F200000
ROM_LEN = 0x1C0000
KNOWN_MD5 = "b46a3e442ccb86134d2356bd70d22fd2"
def main(argv):
ap = argparse.ArgumentParser(
description=__doc__,
formatter_class=argparse.RawDescriptionHelpFormatter)
ap.add_argument("--host", default="100.103.100.103")
ap.add_argument("--port", type=int, default=771)
ap.add_argument("--timeout", type=float, default=10.0)
ap.add_argument("--out", default="dwt/evidence/real-unit-rom.bin")
ap.add_argument("--known", default=KNOWN_MD5)
a = ap.parse_args(argv[1:])
rd = exploit.RDebug(a.host, a.port, a.timeout, False)
rd.connect()
data = bytearray()
nchunks = (ROM_LEN + exploit.MAX_XFER - 1) // exploit.MAX_XFER
done = 0
try:
for off in range(0, ROM_LEN, exploit.MAX_XFER):
n = min(exploit.MAX_XFER, ROM_LEN - off)
data += rd.peek(ROM_BASE_BITS + off * 8, n)
done += 1
if done % 32 == 0 or done == nchunks:
print(f"\r[.] {done}/{nchunks} chunks", end="", file=sys.stderr,
flush=True)
finally:
rd.close()
print(file=sys.stderr)
with open(a.out, "wb") as fh:
fh.write(data)
md5 = hashlib.md5(data).hexdigest()
print(f"[+] {len(data)} bytes -> {a.out}")
print(f"[+] md5 {md5}")
print(f"[+] known {a.known}")
print("[+] MATCH" if md5 == a.known else "[-] MISMATCH")
return 0 if md5 == a.known else 1
if __name__ == "__main__":
try:
sys.exit(main(sys.argv))
except (exploit.ProtocolError, OSError) as exc:
print(f"error: {exc}", file=sys.stderr)
sys.exit(2)