def simplify(self, ircfg, head): ssa = self.ircfg_to_ssa(ircfg, head) ssa = self.do_simplify_loop(ssa, head) ircfg = self.ssa_to_unssa(ssa, head) ircfg_simplifier = IRCFGSimplifierCommon(self.ir_arch) ircfg_simplifier.simplify(ircfg, head) return ircfg
def simplify(self, ircfg, head): ssa = self.ircfg_to_ssa(ircfg, head) ssa = self.do_simplify_loop(ssa, head) ircfg = self.ssa_to_unssa(ssa, head) ircfg_simplifier = IRCFGSimplifierCommon(self.ir_arch) ircfg_simplifier.deadremoval.add_expr_to_original_expr(ssa.ssa_variable_to_expr) ircfg_simplifier.simplify(ircfg, head) return ircfg
def getNormalIRCFG(self): if self.normalIRCFG is not None: return self.normalIRCFG else: self.normalIRCFG = self.normalIRA.new_ircfg_from_asmcfg(self.cfg) simplifier = IRCFGSimplifierCommon(self.normalIRA) simplifier.simplify(self.normalIRCFG, self.head) self.normalDefUse = DiGraphDefUse( ReachingDefinitions(self.normalIRCFG)) return self.normalIRCFG
def simplify(self, ircfg, head): ssa = self.ircfg_to_ssa(ircfg, head) ssa = self.do_simplify_loop(ssa, head) ircfg = self.ssa_to_unssa(ssa, head) if args.stack2var: replace_stack_vars(self.ir_arch, ircfg) ircfg_simplifier = IRCFGSimplifierCommon(self.ir_arch) ircfg_simplifier.simplify(ircfg, head) return ircfg
def simplify(self, ircfg, head): ssa = self.ircfg_to_ssa(ircfg, head) ssa = self.do_simplify_loop(ssa, head) ircfg = self.ssa_to_unssa(ssa, head) if args.stack2var: replace_stack_vars(self.ir_arch, ircfg) ircfg_simplifier = IRCFGSimplifierCommon(self.ir_arch) ircfg_simplifier.simplify(ircfg, head) return ircfg
def getSSAIRCFG(self): if self.ssaIRCFG is not None: return self.ssaIRCFG else: self.ssaIRCFG = self.ssaIRA.new_ircfg_from_asmcfg(self.cfg) simplifier = IRCFGSimplifierCommon(self.ssaIRA) simplifier.simplify(self.ssaIRCFG, self.head) ssa = SSADiGraph(self.ssaIRCFG) ssa.transform(self.head) self.ssaDefUse = DiGraphDefUse(ReachingDefinitions(self.ssaIRCFG)) return self.ssaIRCFG
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
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
def __init__(self, raw, address): self.cont = Container.fallback_container(raw + b'\xC3', vm=None, addr=address) self.address = address self.machine = Machine('x86_64') self.mdis = self.machine.dis_engine(self.cont.bin_stream, loc_db=self.cont.loc_db) self.asmcfg = self.mdis.dis_multiblock(self.address) self.head = self.asmcfg.getby_offset(self.address).loc_key self.orignal_ira = self.machine.ira(self.mdis.loc_db) self.orginal_ircfg = self.orignal_ira.new_ircfg_from_asmcfg( self.asmcfg) self.common_simplifier = IRCFGSimplifierCommon(self.orignal_ira) self.common_simplifier.simplify(self.orginal_ircfg, self.head) self.custom_ira1 = IRADelModCallStack(self.mdis.loc_db) self.custom_ira2 = IRAOutRegs(self.mdis.loc_db) self.ircfg = self.custom_ira1.new_ircfg_from_asmcfg(self.asmcfg) self.simplify()
class Block: def __init__(self, raw, address): self.cont = Container.fallback_container(raw + b'\xC3', vm=None, addr=address) self.address = address self.machine = Machine('x86_64') self.mdis = self.machine.dis_engine(self.cont.bin_stream, loc_db=self.cont.loc_db) self.asmcfg = self.mdis.dis_multiblock(self.address) self.head = self.asmcfg.getby_offset(self.address).loc_key self.orignal_ira = self.machine.ira(self.mdis.loc_db) self.orginal_ircfg = self.orignal_ira.new_ircfg_from_asmcfg( self.asmcfg) self.common_simplifier = IRCFGSimplifierCommon(self.orignal_ira) self.common_simplifier.simplify(self.orginal_ircfg, self.head) self.custom_ira1 = IRADelModCallStack(self.mdis.loc_db) self.custom_ira2 = IRAOutRegs(self.mdis.loc_db) self.ircfg = self.custom_ira1.new_ircfg_from_asmcfg(self.asmcfg) self.simplify() def simplify(self): simplifier = IRCFGSimplifierCommon(self.custom_ira1) simplifier.simplify(self.ircfg, self.head) for loc in self.ircfg.leaves(): irblock = self.ircfg.blocks.get(loc) if irblock is None: continue regs = {} for reg in self.custom_ira1.get_out_regs(irblock): regs[reg] = reg assignblks = list(irblock) newAssignBlk = AssignBlock(regs, assignblks[-1].instr) assignblks.append(newAssignBlk) newIrBlock = IRBlock(irblock.loc_key, assignblks) self.ircfg.blocks[loc] = newIrBlock simplifier = CustomIRCFGSimplifierSSA(self.custom_ira2) simplifier.simplify(self.ircfg, self.head)
def simplify(self): simplifier = IRCFGSimplifierCommon(self.custom_ira1) simplifier.simplify(self.ircfg, self.head) for loc in self.ircfg.leaves(): irblock = self.ircfg.blocks.get(loc) if irblock is None: continue regs = {} for reg in self.custom_ira1.get_out_regs(irblock): regs[reg] = reg assignblks = list(irblock) newAssignBlk = AssignBlock(regs, assignblks[-1].instr) assignblks.append(newAssignBlk) newIrBlock = IRBlock(irblock.loc_key, assignblks) self.ircfg.blocks[loc] = newIrBlock simplifier = CustomIRCFGSimplifierSSA(self.custom_ira2) simplifier.simplify(self.ircfg, self.head)
def getMaxIRCFG(self): if self.maxIRCFG is not None: return self.maxIRCFG else: self.maxIRCFG = self.maxIRA1.new_ircfg_from_asmcfg(self.cfg) simplifier = IRCFGSimplifierCommon(self.maxIRA1) simplifier.simplify(self.maxIRCFG, self.head) for loc in self.maxIRCFG.leaves(): irblock = self.maxIRCFG.blocks.get(loc) if irblock is None: continue regs = {} for reg in self.maxIRA1.get_out_regs(irblock): regs[reg] = reg assignblks = list(irblock) newAssignBlk = AssignBlock(regs, assignblks[-1].instr) assignblks.append(newAssignBlk) newIrBlock = IRBlock(irblock.loc_key, assignblks) self.maxIRCFG.blocks[loc] = newIrBlock simplifier = CustomIRCFGSimplifierSSA(self.maxIRA2) simplifier.simplify(self.maxIRCFG, self.head) self.maxDefUse = DiGraphDefUse(ReachingDefinitions(self.maxIRCFG)) return self.maxIRCFG
ir_arch.add_asmblock_to_ircfg(block, ircfg) ir_arch_a.add_asmblock_to_ircfg(block, ircfg_a) log.info("Print blocks (without analyse)") for label, block in viewitems(ir_arch.blocks): print(block) log.info("Gen Graph... %x" % ad) log.info("Print blocks (with analyse)") for label, block in viewitems(ir_arch_a.blocks): print(block) if args.simplify > 0: log.info("Simplify...") ircfg_simplifier = IRCFGSimplifierCommon(ir_arch_a) ircfg_simplifier.simplify(ircfg_a, head) log.info("ok...") if args.defuse: reachings = ReachingDefinitions(ircfg_a) open('graph_defuse.dot', 'w').write(DiGraphDefUse(reachings).dot()) out = ircfg.dot() open('graph_irflow_raw.dot', 'w').write(out) out = ircfg_a.dot() open('graph_irflow.dot', 'w').write(out) if args.ssa and not args.propagexpr: if len(entry_points) != 1: raise RuntimeError("Your graph should have only one head")
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() mdis = dis_engine(bs) ir_arch = IRADelModCallStack(mdis.loc_db) # populate symbols with ida names for addr, name in idautils.Names(): if name is None: continue if (mdis.loc_db.get_offset_location(addr) or mdis.loc_db.get_name_location(name)): # Symbol alias continue mdis.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([mdis.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(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_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()
lifter.add_asmblock_to_ircfg(block, ircfg) lifter_model_call.add_asmblock_to_ircfg(block, ircfg_a) log.info("Print blocks (without analyse)") for label, block in viewitems(ircfg.blocks): print(block) log.info("Gen Graph... %x" % ad) log.info("Print blocks (with analyse)") for label, block in viewitems(ircfg_a.blocks): print(block) if args.simplify > 0: log.info("Simplify...") ircfg_simplifier = IRCFGSimplifierCommon(lifter_model_call) ircfg_simplifier.simplify(ircfg_a, head) log.info("ok...") if args.defuse: reachings = ReachingDefinitions(ircfg_a) open('graph_defuse.dot', 'w').write(DiGraphDefUse(reachings).dot()) out = ircfg.dot() open('graph_irflow_raw.dot', 'w').write(out) out = ircfg_a.dot() open('graph_irflow.dot', 'w').write(out) if args.ssa and not args.propagexpr: if len(entry_points) != 1: raise RuntimeError("Your graph should have only one head")
ir_arch.add_asmblock_to_ircfg(block, ircfg) ir_arch_a.add_asmblock_to_ircfg(block, ircfg_a) log.info("Print blocks (without analyse)") for label, block in viewitems(ir_arch.blocks): print(block) log.info("Gen Graph... %x" % ad) log.info("Print blocks (with analyse)") for label, block in viewitems(ir_arch_a.blocks): print(block) if args.simplify > 0: log.info("Simplify...") ircfg_simplifier = IRCFGSimplifierCommon(ir_arch_a) ircfg_simplifier.simplify(ircfg_a, head) log.info("ok...") if args.defuse: reachings = ReachingDefinitions(ircfg_a) open('graph_defuse.dot', 'w').write(DiGraphDefUse(reachings).dot()) out = ircfg.dot() open('graph_irflow_raw.dot', 'w').write(out) out = ircfg_a.dot() open('graph_irflow.dot', 'w').write(out) if args.ssa and not args.propagexpr: if len(entry_points) != 1: raise RuntimeError("Your graph should have only one head")
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.GetInputFile() if verbose: print(fname) bs = bin_stream_ida() mdis = dis_engine(bs) ir_arch = IRADelModCallStack(mdis.loc_db) # populate symbols with ida names for addr, name in idautils.Names(): if name is None: continue if (mdis.loc_db.get_offset_location(addr) or mdis.loc_db.get_name_location(name)): # Symbol alias continue mdis.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([mdis.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(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_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()
def get_graph(self): simplify = self.simplify dontmodstack = self.dontmodstack loadmemint = self.loadmemint type_graph = self.type_graph bin_str = "" for s in self.data.segments: bin_str += self.data.read(s.start, len(s)) # add padding between each segment if s.end != self.data.end: bin_str += '\x00' * (((s.end | 0xfff) + 1) - s.end) bs = bin_stream_str(input_str=bin_str, base_address=self.data.start) machine = Machine(archs[self.data.arch.name]) mdis = machine.dis_engine(bs) asmcfg = mdis.dis_multiblock(self.function.start) entry_points = set( [mdis.loc_db.get_offset_location(self.function.start)]) class IRADelModCallStack(machine.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 ir_arch = IRADelModCallStack(mdis.loc_db) ircfg = ir_arch.new_ircfg_from_asmcfg(asmcfg) 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(irb.loc_key, irs) head = list(entry_points)[0] if simplify: ircfg_simplifier = IRCFGSimplifierCommon(ir_arch) ircfg_simplifier.simplify(ircfg, head) if type_graph == TYPE_GRAPH_IR: return MiasmIRGraph(self.add_names(ircfg)) class IRAOutRegs(machine.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_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 loadmemint: 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 # dirty patch to synchronize nodes and blocks lists in ircfg nodes_to_del = [ node for node in ircfg.nodes() if not node in ircfg.blocks ] for node in nodes_to_del: ircfg.del_node(node) head = list(entry_points)[0] simplifier = CustomIRCFGSimplifierSSA(ir_arch) ircfg = simplifier.simplify(ircfg, head) return MiasmIRGraph(self.add_names(ircfg))