diff options
| author | serpilliere <devnull@localhost> | 2012-02-27 14:28:30 +0100 |
|---|---|---|
| committer | serpilliere <devnull@localhost> | 2012-02-27 14:28:30 +0100 |
| commit | 68e955c4a81b6dcedec53c815744fa24568ec640 (patch) | |
| tree | 14ffea36d3b850ea0b72061136eac6e1448920f6 /example/expression | |
| parent | abbf20e77b276e4df3d43dbb2d62061178a1914e (diff) | |
| download | miasm-68e955c4a81b6dcedec53c815744fa24568ec640.tar.gz miasm-68e955c4a81b6dcedec53c815744fa24568ec640.zip | |
example: add a code analyser
find condition to satisfy to explore the complete exec graph of a function (a *very* simple/weak fuzzgrind clone)
Diffstat (limited to 'example/expression')
| -rw-r--r-- | example/expression/find_conditions.py | 123 | ||||
| -rw-r--r-- | example/expression/simple_tests | bin | 0 -> 160 bytes |
2 files changed, 123 insertions, 0 deletions
diff --git a/example/expression/find_conditions.py b/example/expression/find_conditions.py new file mode 100644 index 00000000..9fa5def8 --- /dev/null +++ b/example/expression/find_conditions.py @@ -0,0 +1,123 @@ +import sys +from miasm.arch.ia32_arch import * +from miasm.tools.emul_helper import * +from miasm.core.bin_stream import bin_stream +from miasm.tools.to_c_helper import * +from optparse import OptionParser + + + +""" +Symbolic execute a function, and generate conditions list used to +explore whole binary control flow + +python find_conditions.py -a 0 simple_tests +""" + +parser = OptionParser(usage = "usage: %prog [options] file") +parser.add_option('-a', "--address", dest="address", metavar="ADDRESS", + help="address to disasemble", default="0") + + +(options, args) = parser.parse_args(sys.argv[1:]) +if not args: + parser.print_help() + sys.exit(0) +fname = args[0] +ad_to_dis = options.address + +data = (open(fname).read()) +in_str = bin_stream(data) +symbol_pool = asmbloc.asm_symbol_pool() + +def add_bloc_to_disasm(ad, all_blocs, job_done): + b = asmbloc.dis_bloc_all(x86_mn, in_str, ad, set(), + symbol_pool, bloc_wd = 1)[0] + all_blocs[ad] = b + + +def get_bloc(ad, all_blocs, job_done): + if not ad in all_blocs: + add_bloc_to_disasm(ad, all_blocs, job_done) + return all_blocs[ad] + +init_state = x86_machine().pool +def print_state(state): + to_out= [] + for r in [eax, ebx, ecx, edx, esi, edi, esp, ebp]: + if state[r] == init_state[r]: + continue + to_out.append((r, state[r])) + for k, v in state.items(): + if isinstance(k, ExprMem): + to_out.append((k, v)) + for k, v in to_out: + print k, '=', v + +def emul_mn(states_todo, states_done, all_blocs, job_done): + while states_todo: + ad, pool = states_todo.pop() + if (ad, pool) in states_done: + print 'skip', ad + continue + states_done.add((ad, pool)) + machine = x86_machine() + machine.pool = pool.copy() + ad = int(ad.arg) + b = get_bloc(ad, all_blocs, job_done) + ad = emul_bloc(machine, b) + print_state(machine.pool) + if isinstance(ad, ExprCond): + # Create 2 states, each including complementary conditions + p1 = machine.pool.copy() + p2 = machine.pool.copy() + c1 = {ad.cond: ExprInt(uint32(0))} + c2 = {ad.cond: ExprInt(uint32(1))} + p1[ad.cond] = ExprInt(uint32(0)) + p2[ad.cond] = ExprInt(uint32(1)) + ad1 = machine.eval_expr(ad.reload_expr(c1), {}) + ad2 = machine.eval_expr(ad.reload_expr(c2), {}) + if not (isinstance(ad1, ExprInt) and isinstance(ad2, ExprInt)): + print str(ad1), str(ad2) + raise ValueError("zarb condition") + states_todo.add((ad1, p1)) + states_todo.add((ad2, p2)) + elif isinstance(ad, ExprInt): + pass + elif ad == ret_addr: + continue + else: + raise ValueError("zarb eip") + +all_blocs = {} +job_done = set() +machine = x86_machine() + +argc = ExprId('argc') +argv = ExprId('argv') +ret_addr = ExprId('ret_addr') + +machine.eval_instr(push(('u32', 'u32'), argv)) +machine.eval_instr(push(('u32', 'u32'), argc)) +machine.eval_instr(push(('u32', 'u32'), ret_addr)) + +ad = int(ad_to_dis, 16) +print 'disasm', hex(ad) + +states_todo = set() +states_todo.add((ExprInt(uint32(ad)), machine.pool)) +states_done = set() +emul_mn(states_todo, states_done, all_blocs, job_done) + +all_info = set() +print '*'*40, 'conditions to match', '*'*40 +for ad, pool in states_done: + for k, v in pool.items(): + t = (k, v) + # filter conditions which are argc aware + if argc in k: + all_info.add(t) + +machine = x86_machine() +for k, v in list(all_info): + print machine.eval_expr(k.reload_expr({}), {}), "=", v diff --git a/example/expression/simple_tests b/example/expression/simple_tests new file mode 100644 index 00000000..96fbdc25 --- /dev/null +++ b/example/expression/simple_tests Binary files differ |