Files
MAG160C/analysis/reverse_tools/parse_ddt.py
T

86 lines
3.3 KiB
Python

import struct, sys, os
path = r"C:\Project\MAG160C\analysis\ida\Core160043865.ddt"
b = open(path, "rb").read()
print(f"size: {len(b)}")
def u32(o): return struct.unpack_from("<I", b, o)[0]
def i32(o): return struct.unpack_from("<i", b, o)[0]
def u16(o): return struct.unpack_from("<H", b, o)[0]
def i16(o): return struct.unpack_from("<h", b, o)[0]
magic = u32(0)
w, h = u32(4), u32(8)
count = u32(12) # 0x41558 endpoint count
nsegs = u32(16) # 0x41554 segments
loc238 = u32(20) # v3: shift-related
loc230 = u32(24) # v3
c5c = u32(28) # 0x4155c
c60 = u32(32) # 0x41560
print(f"magic={magic:#x} w={w} h={h} endpoints={count} nsegs={nsegs} loc238={loc238} loc230={loc230:#x}({i32(24)}) 0x4155c={c5c} 0x41560={c60}")
o = 36
T = [u32(o + i*4) for i in range(count)]
print("T (0x41564):", T)
o += count*4
B = [u32(o + i*4) for i in range(count)]
print("B (0x415b4):", B)
o += count*4
C = [u32(o + i*4) for i in range(count)]
print("C (0x41604):", C)
o += count*4
D = [u32(o + i*4) for i in range(count-1)]
print("D (0x41654):", D)
o += (count-1)*4
print(f"table blocks start: 0x{o:x}")
npix = w * h
u26 = c60 + (3*nsegs - 1)*npix*2 + c5c
print(f"per-endpoint block: {u26} bytes")
blind_total = sum(d*40 for d in D)
trailer = count*0x10 + 0x24
total = count*u26 + blind_total + (count-1)*4 + 36 + 4*4 + trailer
print(f"blind_total={blind_total} trailer={trailer} computed_total={total} file={len(b)}")
# dump endpoint table structure: per endpoint:
# thr rows: (nsegs-1)*npix u16 (2 rows x 19200)
# gain/off rows: nsegs*npix*2 u16 (6 rows x 19200) [seg][pix] gain/off pairs
ep = o
for e in range(count):
thr_off = ep
g_off = thr_off + (nsegs-1)*npix*2 + (c5c>>1)*2 if False else thr_off + (nsegs-1)*npix*2 + (c5c//2)*2
print(f"EP{e}: thr@{thr_off:#x} gain@{g_off:#x} T={T[e]}")
t0 = i16(thr_off), i16(thr_off+2), i16(thr_off+4), i16(thr_off+19200*2)
g0 = u16(g_off), u16(g_off+2), u16(g_off+4), u16(g_off+19200*2), u16(g_off+2*19200*2)
print(f" thr[0..3]={t0} thr[1st pix row start]={t0[3]}")
print(f" gain seg0[0..3]={g0[0:4]} gain seg1[0]={g0[4]}")
ep += u26
# blind records: after all endpoint blocks
blind_off = ep
print(f"blind records at 0x{blind_off:x}, total {blind_total} bytes")
for e in range(count-1):
n = D[e]
print(f"EP{e} blind count={n}")
for i in range(min(n, 8)):
r = blind_off + e*0 + i*40
target, typ = u32(r), u32(r+4)
neigh = [u32(r + 8 + j*4) for j in range(8)]
print(f" rec[{i}]: target={target} type={typ} neigh={neigh[:typ-2 if typ>=3 else 8]}")
blind_off += n*40
# check: what's after blind records (trailer)
print(f"trailer at 0x{blind_off:x}:")
for i in range(8):
print(f" +{i*4}: {u32(blind_off+i*4):#010x}")
# compare with the captured working tables
gain = open(r"C:\Project\MAG160C\build-artifacts\mag160c_official_nuc_gain.bin", "rb").read()
thr = open(r"C:\Project\MAG160C\build-artifacts\mag160c_official_nuc_thr.bin", "rb").read()
print(f"\ncaptured working tables: gain={len(gain)} thr={len(thr)}")
print(f"thr[0:4]={[i16(i*2) for i in range(4)]} (from thr.bin)")
print(f"gain[0:4]={[u16(i*2) for i in range(4)]}")
print(f"gain[19200*2:19200*2+4]={[u16(19200*2+i*2) for i in range(4)]} (seg1)")
# find which endpoint the working table corresponds to: interpolate check later in C