diff options
| author | serpilliere <devnull@localhost> | 2011-07-27 17:54:05 +0200 |
|---|---|---|
| committer | serpilliere <devnull@localhost> | 2011-07-27 17:54:05 +0200 |
| commit | 1c0a33b9e672ef82da5daea808db0c5fa76b951f (patch) | |
| tree | 050b15a9ba03fa1360d4b88b8a982d70d9bfbf80 /example/find_rop.py | |
| parent | af4e01c25740d5cd3e42035b4764cafa2817c364 (diff) | |
| download | focaccia-miasm-1c0a33b9e672ef82da5daea808db0c5fa76b951f.tar.gz focaccia-miasm-1c0a33b9e672ef82da5daea808db0c5fa76b951f.zip | |
add find rop example using symbolic exec
Diffstat (limited to 'example/find_rop.py')
| -rw-r--r-- | example/find_rop.py | 166 |
1 files changed, 166 insertions, 0 deletions
diff --git a/example/find_rop.py b/example/find_rop.py new file mode 100644 index 00000000..91806225 --- /dev/null +++ b/example/find_rop.py @@ -0,0 +1,166 @@ +import os, sys +from elfesteem import * +from miasm.tools.pe_helper import * +import inspect +from miasm.core import asmbloc +from miasm.core import parse_asm +from elfesteem import pe +from miasm.tools.to_c_helper import * + + +if len(sys.argv) < 2: + print "%s dllfile"%sys.argv[0] + sys.exit(0) +fname = sys.argv[1] +e = pe_init.PE(open(fname, 'rb').read()) +in_str = bin_stream(e.virt) + +# find gadget only in first section +section_code_name = e.SHList.shlist[0].name.strip("\x00") +s_code = e.getsectionbyname(section_code_name) + + +code_start = e.rva2virt(s_code.addr) +code_stop = e.rva2virt(s_code.addr+s_code.size) + + +print "run on", hex(code_start), hex(code_stop) + + +filename = os.environ.get('PYTHONSTARTUP') +if filename and os.path.isfile(filename): + execfile(filename) + + +def whoami(): + return inspect.stack()[1][3] + + + +def mem_read_wrap(evaluator, e): + return e + + +def mem_write_wrap(evaluator, dst, s, src, pool_out): + return ExprTop() + + + +min_addr = code_start +max_addr = code_stop + +print hex(min_addr), hex(max_addr) +arg1 = ExprId('ARG1', 32, True) +arg2 = ExprId('ARG2', 32, True) +ret1 = ExprId('RET1', 32, True) + +data1 = ExprId('DATA1', 32, True) +data2 = ExprId('DATA2', 32, True) +data3 = ExprId('DATA3', 32, True) +data4 = ExprId('DATA4', 32, True) +data5 = ExprId('DATA5', 32, True) +data6 = ExprId('DATA6', 32, True) +data7 = ExprId('DATA7', 32, True) +data8 = ExprId('DATA8', 32, True) +data9 = ExprId('DATA9', 32, True) +data10 = ExprId('DATA10', 32, True) + +machine = eval_abs({esp:init_esp, ebp:init_ebp, eax:init_eax, ebx:init_ebx, ecx:init_ecx, edx:init_edx, esi:init_esi, edi:init_edi, + cs:ExprInt(uint32(9)), + zf : ExprInt(uint32(0)), nf : ExprInt(uint32(0)), pf : ExprInt(uint32(0)), + of : ExprInt(uint32(0)), cf : ExprInt(uint32(0)), tf : ExprInt(uint32(0)), + i_f: ExprInt(uint32(1)), df : ExprInt(uint32(0)), af : ExprInt(uint32(0)), + iopl: ExprInt(uint32(0)), nt : ExprInt(uint32(0)), rf : ExprInt(uint32(0)), + vm : ExprInt(uint32(0)), ac : ExprInt(uint32(0)), vif: ExprInt(uint32(0)), + vip: ExprInt(uint32(0)), i_d: ExprInt(uint32(0)),tsc1: ExprInt(uint32(0)), + tsc2: ExprInt(uint32(0)), + dr7:ExprInt(uint32(0)), + cr0:init_cr0, + + }, + mem_read_wrap, + mem_write_wrap, + ) + + +# add some info for example +machine.eval_instr(push(arg2)) +machine.eval_instr(push(arg1)) +machine.eval_instr(push(ret1)) +machine.eval_instr(push(ebp)) +machine.eval_instr(mov(ebp, esp)) +machine.eval_instr(sub(esp, ExprInt(uint32(0x14)))) +machine.eval_instr(mov(eax, ExprMem(ebp + ExprInt(uint32(8))))) +machine.eval_instr(mov(edx, ExprMem(eax + ExprInt(uint32(12))))) +machine.eval_instr(mov(eax, ExprMem(ebp + ExprInt(uint32(12))))) +machine.eval_instr(mov(ExprMem(esp), eax)) +machine.eval_instr(push(ExprInt(uint32(0x1337beef)))) + +for k in machine.pool: + machine.pool[k] = expr_simp(machine.pool[k]) + +print dump_reg(machine.pool) +init_mem = dict(machine.pool) + + +for f_ad in xrange(min_addr, max_addr): + if f_ad %0x100 == 0: + print hex(f_ad) + machine.pool = dict(init_mem) + start_ad = f_ad + my_eip = ExprInt(uint32(f_ad)) + cycles = 0 + + while True: + cycles += 1 + # max 5 instructions chain + if cycles> 5: + break + + #final check + if isinstance(my_eip, ExprCond): + my_eip = my_eip.src1 + elif not isinstance(my_eip, ExprInt): + break + ad = int(my_eip.arg) + #if not e.is_in_virt_address(ad): + if not (min_addr < ad< max_addr): + break + in_str.offset = ad + + l = x86_mn.dis(in_str) + # print hex(my_eip.arg), l + if not l: + break + + args = [] + my_eip.arg+=uint32(l.l) + try: + ex = get_instr_expr(l, my_eip, args) + except: + break + try: + my_eip, mem_dst = emul_full_expr(ex, l, my_eip, None, machine) + except: + break + + for k in machine.pool: + machine.pool[k] = expr_simp(machine.pool[k]) + + if isinstance(my_eip, ExprCond): + continue + # we want eip controled by ARG* id or DATA + # here, crappy test on str (not clean expression filtering) + if not ("ARG" in str(my_eip) or "DATA" in str(my_eip)): + continue + + # we want esp controled by ARG* id or DATA + my_esp = machine.pool[esp] + if not ("ARG" in str(my_esp) or "DATA" in str(my_esp)): + continue + + # this should give stack pivot + print "#"*0x80 + print 'constraint solved ad ', hex(start_ad) + print "eip", my_eip + print "esp", my_esp |