def emul_symb(ir_arch, mdis, states_todo, states_done): while states_todo: addr, symbols, conds = states_todo.pop() print '*' * 40, "addr", addr, '*' * 40 if (addr, symbols, conds) in states_done: print 'Known state, skipping', addr continue states_done.add((addr, symbols, conds)) symbexec = SymbolicExecutionEngine(ir_arch, {}) symbexec.symbols = symbols.copy() if ir_arch.pc in symbexec.symbols: del symbexec.symbols[ir_arch.pc] irblock = get_block(ir_arch, mdis, addr) print 'Run block:' print irblock addr = symbexec.eval_updt_irblock(irblock) print 'Final state:' symbexec.dump(mems=False) assert addr is not None if isinstance(addr, ExprCond): # Create 2 states, each including complementary conditions cond_group_a = {addr.cond: ExprInt(0, addr.cond.size)} cond_group_b = {addr.cond: ExprInt(1, addr.cond.size)} addr_a = expr_simp( symbexec.eval_expr(addr.replace_expr(cond_group_a), {})) addr_b = expr_simp( symbexec.eval_expr(addr.replace_expr(cond_group_b), {})) if not (addr_a.is_int() or asmblock.expr_is_label(addr_a) and addr_b.is_int() or asmblock.expr_is_label(addr_b)): print str(addr_a), str(addr_b) raise ValueError("Unsupported condition") if isinstance(addr_a, ExprInt): addr_a = int(addr_a.arg) if isinstance(addr_b, ExprInt): addr_b = int(addr_b.arg) states_todo.add((addr_a, symbexec.symbols.copy(), tuple(list(conds) + cond_group_a.items()))) states_todo.add((addr_b, symbexec.symbols.copy(), tuple(list(conds) + cond_group_b.items()))) elif isinstance(addr, ExprInt): addr = int(addr.arg) states_todo.add((addr, symbexec.symbols.copy(), tuple(conds))) elif asmblock.expr_is_label(addr): addr = addr.name states_todo.add((addr, symbexec.symbols.copy(), tuple(conds))) elif addr == ret_addr: print 'Return address reached' continue else: raise ValueError("Unsupported destination")
def emul_symb(ir_arch, ircfg, mdis, states_todo, states_done): while states_todo: addr, symbols, conds = states_todo.pop() print '*' * 40, "addr", addr, '*' * 40 if (addr, symbols, conds) in states_done: print 'Known state, skipping', addr continue states_done.add((addr, symbols, conds)) symbexec = SymbolicExecutionEngine(ir_arch) symbexec.symbols = symbols.copy() if ir_arch.pc in symbexec.symbols: del symbexec.symbols[ir_arch.pc] irblock = get_block(ir_arch, ircfg, mdis, addr) print 'Run block:' print irblock addr = symbexec.eval_updt_irblock(irblock) print 'Final state:' symbexec.dump(mems=False) assert addr is not None if isinstance(addr, ExprCond): # Create 2 states, each including complementary conditions cond_group_a = {addr.cond: ExprInt(0, addr.cond.size)} cond_group_b = {addr.cond: ExprInt(1, addr.cond.size)} addr_a = expr_simp(symbexec.eval_expr(addr.replace_expr(cond_group_a), {})) addr_b = expr_simp(symbexec.eval_expr(addr.replace_expr(cond_group_b), {})) if not (addr_a.is_int() or addr_a.is_loc() and addr_b.is_int() or addr_b.is_loc()): print str(addr_a), str(addr_b) raise ValueError("Unsupported condition") if isinstance(addr_a, ExprInt): addr_a = int(addr_a.arg) if isinstance(addr_b, ExprInt): addr_b = int(addr_b.arg) states_todo.add((addr_a, symbexec.symbols.copy(), tuple(list(conds) + cond_group_a.items()))) states_todo.add((addr_b, symbexec.symbols.copy(), tuple(list(conds) + cond_group_b.items()))) elif addr == ret_addr: print 'Return address reached' continue elif addr.is_int(): addr = int(addr.arg) states_todo.add((addr, symbexec.symbols.copy(), tuple(conds))) elif addr.is_loc(): states_todo.add((addr, symbexec.symbols.copy(), tuple(conds))) else: raise ValueError("Unsupported destination")
symbexec = SymbolicExecutionEngine(ir_arch, symbols_init) blocks, symbol_pool = parse_asm.parse_txt(machine.mn, 32, ''' PUSH argv PUSH argc PUSH ret_addr ''') b = list(blocks)[0] print b # add fake address and len to parsed instructions for i, line in enumerate(b.lines): line.offset, line.l = i, 1 ir_arch.add_block(b) irb = get_block(ir_arch, mdis, 0) symbexec.emulbloc(irb) symbexec.dump_mem() # reset ir_arch blocks ir_arch.blocks = {} states_todo = set() states_done = set() states_todo.add((addr, symbexec.symbols, ())) # emul blocks, propagate states emul_symb(ir_arch, mdis, states_todo, states_done) all_info = []
def emul_symb(ir_arch, mdis, states_todo, states_done): while states_todo: ad, symbols, conds = states_todo.pop() print '*' * 40, "addr", ad, '*' * 40 if (ad, symbols, conds) in states_done: print 'skip', ad continue states_done.add((ad, symbols, conds)) sb = SymbolicExecutionEngine(ir_arch, {}) sb.symbols = symbols.copy() if ir_arch.pc in sb.symbols: del(sb.symbols[ir_arch.pc]) b = get_block(ir_arch, mdis, ad) print 'run block' print b # print blocks[ad] ad = sb.emulbloc(b) print 'final state' sb.dump_id() print 'dataflow' # data_flow_graph_from_expr(sb) assert(ad is not None) print "DST", ad if isinstance(ad, ExprCond): # Create 2 states, each including complementary conditions p1 = sb.symbols.copy() p2 = sb.symbols.copy() c1 = {ad.cond: ExprInt(0, ad.cond.size)} c2 = {ad.cond: ExprInt(1, ad.cond.size)} print ad.cond p1[ad.cond] = ExprInt(0, ad.cond.size) p2[ad.cond] = ExprInt(1, ad.cond.size) ad1 = expr_simp(sb.eval_expr(ad.replace_expr(c1), {})) ad2 = expr_simp(sb.eval_expr(ad.replace_expr(c2), {})) if not (isinstance(ad1, ExprInt) or (isinstance(ad1, ExprId) and isinstance(ad1.name, asmblock.AsmLabel)) and isinstance(ad2, ExprInt) or (isinstance(ad2, ExprId) and isinstance(ad2.name, asmblock.AsmLabel))): print str(ad1), str(ad2) raise ValueError("zarb condition") conds1 = list(conds) + c1.items() conds2 = list(conds) + c2.items() if isinstance(ad1, ExprId): ad1 = ad1.name if isinstance(ad2, ExprId): ad2 = ad2.name if isinstance(ad1, ExprInt): ad1 = ad1.arg if isinstance(ad2, ExprInt): ad2 = ad2.arg states_todo.add((ad1, p1, tuple(conds1))) states_todo.add((ad2, p2, tuple(conds2))) elif isinstance(ad, ExprInt): ad = int(ad.arg) states_todo.add((ad, sb.symbols.copy(), tuple(conds))) elif isinstance(ad, ExprId) and isinstance(ad.name, asmblock.AsmLabel): if isinstance(ad, ExprId): ad = ad.name states_todo.add((ad, sb.symbols.copy(), tuple(conds))) elif ad == ret_addr: print 'ret reached' continue else: raise ValueError("zarb eip")