From 4be2c8dc7656aec5143fbda716de203205523f42 Mon Sep 17 00:00:00 2001 From: sasheg Date: Sun, 13 Sep 2026 17:32:57 +0000 Subject: [PATCH] tools: add sled (zero-drift) detector + capstone disassembly history in trap handler --- tools/sbl_uni.py | 38 +++++++++++++++++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/tools/sbl_uni.py b/tools/sbl_uni.py index 2a3fc00..d509864 100644 --- a/tools/sbl_uni.py +++ b/tools/sbl_uni.py @@ -101,6 +101,12 @@ def main(): last = [0] from collections import deque hist = deque(maxlen=20000) + # sled detector: sequential runs (pc == prev+2/4) longer than THRESH + # are zero-drifts; log run start (the jump/fall that entered it). + _sled_start = [0] + _sled_n = [0] + _sled_log = [] + _SLED_TH = 100 calls = [] if "--calltrace" in sys.argv else None rets = [] if "--retrace" in sys.argv else None qlog = [] if "--querylog" in sys.argv else None @@ -134,6 +140,16 @@ def main(): def hook_code(mu, addr, size, data): count[0] += 1 last[0] = addr + _pp = _prev[0] + _prev[0] = addr + if addr == _pp + 2 or addr == _pp + 4: + if _sled_n[0] == 0: + _sled_start[0] = _pp + _sled_n[0] += 1 + else: + if _sled_n[0] >= _SLED_TH and len(_sled_log) < 20: + _sled_log.append((count[0], _sled_start[0], _pp, _sled_n[0])) + _sled_n[0] = 0 if 0x08006B8C <= addr < 0x08006B9E: try: _lr = mu.reg_read(_LR) @@ -187,6 +203,21 @@ def main(): print(f" [73A100]={bytes(mu.mem_read(0x073A100, 4)).hex()}") except Exception as e: print(f" [73A100] unreadable: {e}") + try: + from capstone import Cs, CS_ARCH_ARM, CS_MODE_THUMB, CS_MODE_ARM + md_t = Cs(CS_ARCH_ARM, CS_MODE_THUMB) + md_a = Cs(CS_ARCH_ARM, CS_MODE_ARM) + for _pc, _th in list(hist)[-60:]: + try: + _b = _pc & ~1 + _c = mu.mem_read(_b, 8 if _th else 12) + for _ins in (md_t if _th else md_a).disasm(_c, _b): + print(f" hist {_b:#x}{'t' if _th else 'a'}: {_ins.mnemonic} {_ins.op_str}") + break + except Exception: + print(f" hist {_pc:#x}: ") + except ImportError: + pass _trap_n[0] -= 1 if _trap_n[0] <= 0 and "--trapn" in sys.argv: mu.emu_stop() @@ -216,7 +247,6 @@ def main(): if len(elog) < 20000: elog.append((count[0], _prev[0], -addr, 2)) _inrng[_i] = inside - _prev[0] = addr if calls is not None and size in (2, 4): try: if size == 2: @@ -585,6 +615,12 @@ def main(): print(f" {pc:#x}: ") except ImportError: print("hist:", [hex(pc) for pc, _ in list(hist)[-12:]]) + if _sled_log or _sled_n[0] >= _SLED_TH: + if _sled_n[0] >= _SLED_TH: + _sled_log.append((count[0], _sled_start[0], last[0], _sled_n[0])) + print(f"sleds: {len(_sled_log)}") + for n, s, e, c in _sled_log: + print(f" insn#{n} [{s:#x}..{e:#x}] len={c}") if elog is not None: print(f"entries: {len(elog)}") for n, prev, cur, th in elog[:10]: