diff options
Diffstat (limited to 'sploit/rev')
| -rw-r--r-- | sploit/rev/__init__.py | 3 | ||||
| -rw-r--r-- | sploit/rev/r2.py | 92 | 
2 files changed, 94 insertions, 1 deletions
| diff --git a/sploit/rev/__init__.py b/sploit/rev/__init__.py index c489b98..b6a73a2 100644 --- a/sploit/rev/__init__.py +++ b/sploit/rev/__init__.py @@ -1,4 +1,5 @@  from . import ( -        ldd +        ldd, +        r2,  ) diff --git a/sploit/rev/r2.py b/sploit/rev/r2.py new file mode 100644 index 0000000..cd4684f --- /dev/null +++ b/sploit/rev/r2.py @@ -0,0 +1,92 @@ +from sploit.mem import Symtbl +from sploit.arch import arch + +import re +from subprocess import run +from collections import namedtuple as nt + +def run_cmd(binary,cmd): +    return run(['r2','-q','-c',cmd,'-e','scr.color=false',binary],capture_output=True).stdout.decode('utf-8').split('\n')[:-1] + +def get_elf_symbols(elf): +    out = {} + +    cmd_syms = 'is~ FUNC ' +    out_syms = r2.run_cmd(elf,cmd_syms) +    out_syms = [re.split(r'\s+',sym) for sym in out_syms] +    out_syms = {sym[6]:int(sym[2],0) for sym in out_syms if sym[6].find('.')<0} +    out.update(out_syms) + +    cmd_syms = 'is~ LOOS ' +    out_syms = r2.run_cmd(elf,cmd_syms) +    out_syms = [re.split(r'\s+',sym) for sym in out_syms] +    out_syms = {sym[6]:int(sym[2],0) for sym in out_syms if sym[6].find('.')<0} +    out.update(out_syms) + +    cmd_syms = 'is~ TLS ' +    out_syms = r2.run_cmd(elf,cmd_syms) +    out_syms = [re.split(r'\s+',sym) for sym in out_syms] +    out_syms = {sym[6]:int(sym[2],0) for sym in out_syms if sym[6].find('.')<0} +    out.update(out_syms) + +    cmd_syms = 'ii~ FUNC ' +    out_syms = r2.run_cmd(elf,cmd_syms) +    out_syms = [re.split(r'\s+',sym) for sym in out_syms] +    out_syms = {"_PLT_"+sym[4]:int(sym[1],0) for sym in out_syms} +    out.update(out_syms) + +    cmd_syms = 'fs relocs;f' +    out_syms = r2.run_cmd(elf,cmd_syms) +    out_syms = [re.split(r'\s+',sym) for sym in out_syms] +    out_syms = {"_GOT_"+sym[2][sym[2].rfind('.')+1:]:int(sym[0],0) for sym in out_syms} +    out.update(out_syms) + +    cmd_strs = 'fs strings;f' +    out_strs = r2.run_cmd(elf,cmd_strs) +    out_strs = [re.split(r'\s+',sym) for sym in out_strs] +    out_strs = {sym[2][sym[2].rfind('.')+1:]:int(sym[0],0) for sym in out_strs} +    out.update(out_strs) + +    return Symtbl(**out) + +def get_locals(binary,func): +    addr = hex(func) +    cmd_locals = f's {func};af;aafr;aaft;afvf' +    out = r2.run_cmd(binary,cmd_locals) +    out = [re.split(r':?\s+',var) for var in out] +    out = {var[1]:int(var[0],0)-arch.wordsize for var in out} +    return Symtbl(**out) + +def ret_gadget(binary): +    cmd_ret = '/R/ ret~ret' +    out = r2.run_cmd(binary,cmd_ret) +    out = out[0] +    out = re.split(r'\s+',out) +    out = out[1] +    return int(out,0) + +def rop_gadget(binary,gad): +    cmd_gad = f'"/R/q {gad}"' +    out = r2.run_cmd(binary,cmd_gad) +    Gad = nt("Gad", "addr asm") +    out = [Gad(int(gad[:gad.find(':')],0),gad[gad.find(':')+2:]) for gad in out] +    return out + +def rop_gadget_exact(binary,gad): +    gads = r2.rop_gadget(gad,elf) +    for g in gads: +        if g.asm[:-1].replace('; ',';') == gad: +            return g + +def get_call_returns(binary,xref_from,xref_to): +    cmd_xrefs = f's {hex(xref_from)};af;axq' +    xrefs = r2.run_cmd(binary,cmd_xrefs) +    xrefs = [re.split(r'\s+',x) for x in xrefs] +    xrefs = [x for x in xrefs if int(x[2],0)==xref_to] +    rets = [] +    CallRet = nt("CallRet", "xref_from xref_to call_addr ret_addr") +    for x in xrefs: +        cmd_ret = f's {x[0]};so;s' +        ret = r2.run_cmd(binary,cmd_ret) +        rets.append(CallRet(xref_from,xref_to,int(x[0],0),int(ret[0],0))) +    return rets | 
