Add r2sptrace.py in scripts from #12070

This commit is contained in:
pancake 2024-08-05 17:23:54 +02:00
parent c4fa97b7bd
commit 7c928d72d2

54
scripts/r2sptrace.py Normal file
View File

@ -0,0 +1,54 @@
# https://gist.github.com/thestr4ng3r/403fecffc081a899618b1500ba6d1156
# https://github.com/radareorg/radare2/issues/12070
import r2pipe
r = r2pipe.open()
ptr_size = int(r.cmd("e asm.bits").strip()) // 8
addr_stackptr = {}
blocks = r.cmdj("afbj")
def sp_delta_for_fcn_call(fcn):
cc = fcn["calltype"]
if cc == "stdcall":
nargs = fcn["nargs"]
return -nargs * ptr_size
return 0
def sp_delta_for_instr(instr):
if instr["type"] == "call" or instr["type"] == "ucall":
if "jump" in instr:
call_fcn = r.cmdj("afij@{}".format(instr["jump"]))
if len(call_fcn) > 0:
return sp_delta_for_fcn_call(call_fcn[0])
else:
print("WARNING: Target not known for jump at {:#x}!".format(instr["addr"]))
return 0 if "stackptr" not in instr else instr["stackptr"]
def block_at(addr):
for block in blocks:
if block["addr"] == addr:
return block
return None
def trace_block(block, stackptr):
instrs = r.cmdj("aoj {}@{}".format(block["ninstr"], block["addr"]))
for instr in instrs:
addr = instr["addr"]
if addr in addr_stackptr:
if addr_stackptr[addr] != stackptr:
print("WARNING: mismatch at {:#x}: {} != {}".format(addr, stackptr, addr_stackptr[addr]))
return
addr_stackptr[addr] = stackptr
stackptr -= sp_delta_for_instr(instr)
if "jump" in block:
trace_block(block_at(block["jump"]), stackptr)
if "fail" in block:
trace_block(block_at(block["fail"]), stackptr)
trace_block(blocks[0], 0)
for addr, stackptr in addr_stackptr.items():
r.cmd("CC sp: {}@{}".format(stackptr, addr))