for miasm_int, res in [(five, 1), (four, 0), (seven, 0), (one0seven, 0)]: e6 = ExprOp('parity', miasm_int) ez3 = translator1.from_expr(e6) z3_e6 = z3.BitVecVal(res, 1) assert equiv(ez3, z3_e6) # -------------------------------------------------------------------------- # '-' for miasm_int, res in [(five, -5), (four, -4)]: e6 = ExprOp('-', miasm_int) ez3 = translator1.from_expr(e6) z3_e6 = z3.BitVecVal(res, 32) assert equiv(ez3, z3_e6) # -------------------------------------------------------------------------- label_histoire = loc_db.add_location("label_histoire", 0xdeadbeef) e7 = ExprLoc(label_histoire, 32) ez3 = translator1.from_expr(e7) z3_e7 = z3.BitVecVal(0xdeadbeef, 32) assert equiv(ez3, z3_e7) # Should just not throw anything to pass lbl_e8 = loc_db.add_location("label_jambe") e8 = ExprLoc(lbl_e8, 32) ez3 = translator1.from_expr(e8) assert not equiv(ez3, z3_e7) # -------------------------------------------------------------------------- # cntleadzeros, cnttrailzeros
r = ExprId("r", 32) a_init = ExprId("a_init", 32) b_init = ExprId("b_init", 32) c_init = ExprId("c_init", 32) d_init = ExprId("d_init", 32) r_init = ExprId("r_init", 32) # Return register pc = ExprId("pc", 32) sp = ExprId("sp", 32) CST1 = ExprInt(0x11, 32) CST2 = ExprInt(0x12, 32) CST3 = ExprInt(0x13, 32) LBL0 = loc_db.add_location("lbl0", 0) LBL1 = loc_db.add_location("lbl1", 1) LBL2 = loc_db.add_location("lbl2", 2) LBL3 = loc_db.add_location("lbl3", 3) LBL4 = loc_db.add_location("lbl4", 4) LBL5 = loc_db.add_location("lbl5", 5) LBL6 = loc_db.add_location("lbl6", 6) IRDst = ExprId('IRDst', 32) dummy = ExprId('dummy', 32) def gen_irblock(label, exprs_list): irs = [] for exprs in exprs_list: if isinstance(exprs, AssignBlock):
for miasm_int, res in [(five, 1), (four, 0), (seven, 0), (one0seven, 0)]: e6 = ExprOp('parity', miasm_int) ez3 = translator1.from_expr(e6) z3_e6 = z3.BitVecVal(res, 1) assert equiv(ez3, z3_e6) # -------------------------------------------------------------------------- # '-' for miasm_int, res in [(five, -5), (four, -4)]: e6 = ExprOp('-', miasm_int) ez3 = translator1.from_expr(e6) z3_e6 = z3.BitVecVal(res, 32) assert equiv(ez3, z3_e6) # -------------------------------------------------------------------------- label_histoire = loc_db.add_location("label_histoire", 0xdeadbeef) e7 = ExprLoc(label_histoire, 32) ez3 = translator1.from_expr(e7) z3_e7 = z3.BitVecVal(0xdeadbeef, 32) assert equiv(ez3, z3_e7) # Should just not throw anything to pass lbl_e8 = loc_db.add_location("label_jambe") e8 = ExprLoc(lbl_e8, 32) ez3 = translator1.from_expr(e8) assert not equiv(ez3, z3_e7) # -------------------------------------------------------------------------- # cntleadzeros, cnttrailzeros
def build_graph(start_addr, type_graph, simplify=False, dontmodstack=True, loadint=False, verbose=False): machine = guess_machine(addr=start_addr) dis_engine, ira = machine.dis_engine, machine.ira class IRADelModCallStack(ira): def call_effects(self, addr, instr): assignblks, extra = super(IRADelModCallStack, self).call_effects(addr, instr) if not dontmodstack: return assignblks, extra out = [] for assignblk in assignblks: dct = dict(assignblk) dct = { dst:src for (dst, src) in viewitems(dct) if dst != self.sp } out.append(AssignBlock(dct, assignblk.instr)) return out, extra if verbose: print("Arch", dis_engine) fname = idc.get_root_filename() if verbose: print(fname) bs = bin_stream_ida() loc_db = LocationDB() mdis = dis_engine(bs, loc_db=loc_db) ir_arch = IRADelModCallStack(loc_db) # populate symbols with ida names for addr, name in idautils.Names(): if name is None: continue if (loc_db.get_offset_location(addr) or loc_db.get_name_location(name)): # Symbol alias continue loc_db.add_location(name, addr) if verbose: print("start disasm") if verbose: print(hex(start_addr)) asmcfg = mdis.dis_multiblock(start_addr) entry_points = set([loc_db.get_offset_location(start_addr)]) if verbose: print("generating graph") open('asm_flow.dot', 'w').write(asmcfg.dot()) print("generating IR... %x" % start_addr) ircfg = ir_arch.new_ircfg_from_asmcfg(asmcfg) if verbose: print("IR ok... %x" % start_addr) for irb in list(viewvalues(ircfg.blocks)): irs = [] for assignblk in irb: new_assignblk = { expr_simp(dst): expr_simp(src) for dst, src in viewitems(assignblk) } irs.append(AssignBlock(new_assignblk, instr=assignblk.instr)) ircfg.blocks[irb.loc_key] = IRBlock(loc_db, irb.loc_key, irs) if verbose: out = ircfg.dot() open(os.path.join(tempfile.gettempdir(), 'graph.dot'), 'wb').write(out) title = "Miasm IR graph" head = list(entry_points)[0] if simplify: ircfg_simplifier = IRCFGSimplifierCommon(ir_arch) ircfg_simplifier.simplify(ircfg, head) title += " (simplified)" if type_graph == TYPE_GRAPH_IR: graph = GraphMiasmIR(ircfg, title, None) graph.Show() return class IRAOutRegs(ira): def get_out_regs(self, block): regs_todo = super(IRAOutRegs, self).get_out_regs(block) out = {} for assignblk in block: for dst in assignblk: reg = self.ssa_var.get(dst, None) if reg is None: continue if reg in regs_todo: out[reg] = dst return set(viewvalues(out)) # Add dummy dependency to uncover out regs affectation for loc in ircfg.leaves(): irblock = ircfg.blocks.get(loc) if irblock is None: continue regs = {} for reg in ir_arch.get_out_regs(irblock): regs[reg] = reg assignblks = list(irblock) new_assiblk = AssignBlock(regs, assignblks[-1].instr) assignblks.append(new_assiblk) new_irblock = IRBlock(irblock.loc_db, irblock.loc_key, assignblks) ircfg.blocks[loc] = new_irblock class CustomIRCFGSimplifierSSA(IRCFGSimplifierSSA): def do_simplify(self, ssa, head): modified = super(CustomIRCFGSimplifierSSA, self).do_simplify(ssa, head) if loadint: modified |= load_from_int(ssa.graph, bs, is_addr_ro_variable) return modified def simplify(self, ircfg, head): ssa = self.ircfg_to_ssa(ircfg, head) ssa = self.do_simplify_loop(ssa, head) if type_graph == TYPE_GRAPH_IRSSA: ret = ssa.graph elif type_graph == TYPE_GRAPH_IRSSAUNSSA: ircfg = self.ssa_to_unssa(ssa, head) ircfg_simplifier = IRCFGSimplifierCommon(self.ir_arch) ircfg_simplifier.simplify(ircfg, head) ret = ircfg else: raise ValueError("Unknown option") return ret head = list(entry_points)[0] simplifier = CustomIRCFGSimplifierSSA(ir_arch) ircfg = simplifier.simplify(ircfg, head) open('final.dot', 'w').write(ircfg.dot()) graph = GraphMiasmIR(ircfg, title, None) graph.Show()
class FlatteningLoops(object): def __init__(self): self._loc_key_to_loop = {} self.loc_db = LocationDB() self.loops = [] # for blocks outside of any loop self._outside_of_scope = FlatteningLoop([], set(), {}, {}, self.loc_db.add_location()) self._outside_of_scope.is_default = True self._address = None def get_block(self, block_loc_key, symb_exec, source_flat_block=None): flat_loop = self[block_loc_key] flat_hash = source_hash_value = source_loop_loc_key = None if flat_loop.is_default: if source_flat_block: source_loop_loc_key = source_flat_block.source_loop_loc_key or source_flat_block.block_loc_key source_flat_loop = self[source_loop_loc_key] source_hash_value = source_flat_block.source_hash_value or source_flat_block.control_hash_value if block_loc_key in source_flat_loop.affected_lines: flat_hash, no_affected_expr = \ flat_loop.get_affected_hash(symb_exec, block_loc_key, source_flat_loop, None) source_hash_value = None else: flat_hash, _ = flat_loop.get_affected_hash(symb_exec, block_loc_key, flat_loop, None) # TODO check init block too to prevent initial duplicity in case of loops(eliminated by the decompiler) flat_block = FlatteningBlock(flat_loop.loc_key, source_loop_loc_key, block_loc_key, flat_hash, source_hash_value) return flat_block def create(self, head_vars, affected_lines, primary_loc_keys, ircfg, address): self._address = hex(address) if address else "None" affected_exprs = {} dp = depgraph.DependencyGraph(ircfg, True) for block_loc_key in affected_lines: block = ircfg.blocks[block_loc_key] cur_affected_exprs = SortedSet(key=lambda x: str(x)) for line_nb in affected_lines[block_loc_key]: affected_assignments = block.assignblks[line_nb] for ind, (dst, src) in enumerate(affected_assignments.items()): if type(src) not in [ExprInt, ExprMem]: res = next(dp.get(block_loc_key, {dst}, ind, {block_loc_key})) cur_affected_exprs.update(filter(lambda x: not is_bad_expr(x), res.pending.keys())) affected_exprs[block_loc_key] = cur_affected_exprs loop = FlatteningLoop(list(head_vars), primary_loc_keys, affected_lines, affected_exprs, self.loc_db.add_location()) upd = {} for i in loop.primary_loc_keys: if i in self._loc_key_to_loop: raise RuntimeError("Overlap of primary blocks of the flattening loops") upd[i] = loop self._loc_key_to_loop.update(upd) self.loops.append(loop) return loop def __getitem__(self, loc_key): """ Retrieves particular flattening loop by ID of the block :param loc_key: :return: """ return self._loc_key_to_loop.get(loc_key, self._outside_of_scope) def __contains__(self, loc_key): return loc_key in self._loc_key_to_loop def __len__(self): return len(self.loops)
PC = ExprId("pc", 32) SP = ExprId("sp", 32) CST0 = ExprInt(0x0, 32) CST1 = ExprInt(0x1, 32) CST2 = ExprInt(0x2, 32) CST3 = ExprInt(0x3, 32) CST22 = ExprInt(0x22, 32) CST23 = ExprInt(0x23, 32) CST24 = ExprInt(0x24, 32) CST33 = ExprInt(0x33, 32) CST35 = ExprInt(0x35, 32) CST37 = ExprInt(0x37, 32) LBL0 = loc_db.add_location("lbl0", 0) LBL1 = loc_db.add_location("lbl1", 1) LBL2 = loc_db.add_location("lbl2", 2) LBL3 = loc_db.add_location("lbl3", 3) LBL4 = loc_db.add_location("lbl4", 4) LBL5 = loc_db.add_location("lbl5", 5) LBL6 = loc_db.add_location("lbl6", 6) def gen_irblock(label, exprs_list): """ Returns an IRBlock. Used only for tests purpose """ irs = [] for exprs in exprs_list: if isinstance(exprs, AssignBlock): irs.append(exprs)
from builtins import str from miasm.core.locationdb import LocationDB # Basic tests (LocationDB description) loc_db = LocationDB() loc_key1 = loc_db.add_location() loc_key2 = loc_db.add_location(offset=0x1234) loc_key3 = loc_db.add_location(name="first_name") loc_db.add_location_name(loc_key3, "second_name") loc_db.set_location_offset(loc_key3, 0x5678) loc_db.remove_location_name(loc_key3, "second_name") assert loc_db.get_location_offset(loc_key1) is None assert loc_db.get_location_offset(loc_key2) == 0x1234 assert loc_db.pretty_str(loc_key1) == str(loc_key1) assert loc_db.pretty_str(loc_key2) == "loc_1234" assert loc_db.pretty_str(loc_key3) == "first_name" loc_db.consistency_check() # Offset manipulation loc_key4 = loc_db.add_location() assert loc_db.get_location_offset(loc_key4) is None loc_db.set_location_offset(loc_key4, 0x1122) assert loc_db.get_location_offset(loc_key4) == 0x1122 loc_db.unset_location_offset(loc_key4) assert loc_db.get_location_offset(loc_key4) is None try: loc_db.set_location_offset(loc_key4, 0x1234) has_raised = False except KeyError:
from builtins import str from miasm.core.locationdb import LocationDB # Basic tests (LocationDB description) loc_db = LocationDB() loc_key1 = loc_db.add_location() loc_key2 = loc_db.add_location(offset=0x1234) loc_key3 = loc_db.add_location(name="first_name") loc_db.add_location_name(loc_key3, "second_name") loc_db.set_location_offset(loc_key3, 0x5678) loc_db.remove_location_name(loc_key3, "second_name") assert loc_db.get_location_offset(loc_key1) is None assert loc_db.get_location_offset(loc_key2) == 0x1234 assert loc_db.pretty_str(loc_key1) == str(loc_key1) assert loc_db.pretty_str(loc_key2) == "loc_1234" assert loc_db.pretty_str(loc_key3) == "first_name" loc_db.consistency_check() # Offset manipulation loc_key4 = loc_db.add_location() assert loc_db.get_location_offset(loc_key4) is None loc_db.set_location_offset(loc_key4, 0x1122) assert loc_db.get_location_offset(loc_key4) == 0x1122 loc_db.unset_location_offset(loc_key4) assert loc_db.get_location_offset(loc_key4) is None try: loc_db.set_location_offset(loc_key4, 0x1234) has_raised = False
def launch_depgraph(): global graphs, comments, sol_nb, settings, addr, ir_arch, ircfg # Get the current function addr = idc.get_screen_ea() func = ida_funcs.get_func(addr) # Init machine = guess_machine(addr=func.start_ea) mn, dis_engine, ira = machine.mn, machine.dis_engine, machine.ira bs = bin_stream_ida() loc_db = LocationDB() mdis = dis_engine(bs, loc_db=loc_db, dont_dis_nulstart_bloc=True) ir_arch = ira(loc_db) # Populate symbols with ida names for ad, name in idautils.Names(): if name is None: continue loc_db.add_location(name, ad) asmcfg = mdis.dis_multiblock(func.start_ea) # Generate IR ircfg = ir_arch.new_ircfg_from_asmcfg(asmcfg) # Get settings settings = depGraphSettingsForm(ir_arch, ircfg, mn) settings.Execute() loc_key, elements, line_nb = settings.loc_key, settings.elements, settings.line_nb # Simplify assignments for irb in list(viewvalues(ircfg.blocks)): irs = [] offset = loc_db.get_location_offset(irb.loc_key) fix_stack = offset is not None and settings.unalias_stack for assignblk in irb: if fix_stack: stk_high = m2_expr.ExprInt(idc.get_spd(assignblk.instr.offset), ir_arch.sp.size) fix_dct = { ir_arch.sp: mn.regs.regs_init[ir_arch.sp] + stk_high } new_assignblk = {} for dst, src in viewitems(assignblk): if fix_stack: src = src.replace_expr(fix_dct) if dst != ir_arch.sp: dst = dst.replace_expr(fix_dct) dst, src = expr_simp(dst), expr_simp(src) new_assignblk[dst] = src irs.append(AssignBlock(new_assignblk, instr=assignblk.instr)) ircfg.blocks[irb.loc_key] = IRBlock(irb.loc_db, irb.loc_key, irs) # Get dependency graphs dg = settings.depgraph graphs = dg.get(loc_key, elements, line_nb, set([loc_db.get_offset_location(func.start_ea)])) # Display the result comments = {} sol_nb = 0 # Register and launch ida_kernwin.add_hotkey("Shift-N", next_element) treat_element()