tools: add sled (zero-drift) detector + capstone disassembly history in trap handler
This commit is contained in:
+37
-1
@@ -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}: <unreadable>")
|
||||
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}: <unreadable>")
|
||||
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]:
|
||||
|
||||
Reference in New Issue
Block a user