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 ircfg_to_ssa(self, ircfg, head): """ Apply the SSA transformation to @ircfg using it's @head @ircfg: IRCFG instance to simplify @head: Location instance of the ircfg head """ ssa = SSADiGraph(ircfg) ssa.immutable_ids.update(self.ssa_forbidden_regs) ssa.ssa_variable_to_expr.update(self.all_ssa_vars) ssa.transform(head) self.all_ssa_vars.update(ssa.ssa_variable_to_expr) self.ir_arch.ssa_var.update(ssa.ssa_variable_to_expr) return ssa
def Analyze(self, addr, deep=False): todo_list = [] if addr in self.ssa_cache: return self.ssa_cache[addr] asmcfg = self.mdis.dis_multiblock(addr) ira = self.machine.ira(asmcfg.loc_db) try: ircfg = ira.new_ircfg_from_asmcfg(asmcfg) except: # Failed on converting self.ssa_cache[addr] = None return None modified = True while modified: modified = ircfg.simplify(expr_simp) ssa = SSADiGraph(ircfg) ssa.transform(asmcfg.loc_db.get_offset_location(addr)) # for lbl, irblock in ircfg.blocks.items(): # print(irblock.to_string(ircfg.loc_db)) if deep: for lbl, irblock in ircfg.blocks.items(): for blk in irblock.assignblks: for val in blk.values(): if (isinstance(val, ExprOp) and val.op == "call_func_ret" and isinstance(val.args[0], ExprLoc)): callee_addr = asmcfg.loc_db.get_location_offset( val.args[0].loc_key) if callee_addr not in todo_list: todo_list.append(callee_addr) self.ssa_cache[addr] = ircfg if deep: # Recursively analyze functions which are called by initial target function for callee_addr in todo_list: self.Analyze(callee_addr, deep) return ircfg
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") ssa = SSADiGraph(ircfg_a) ssa.transform(head) open("ssa.dot", "w").write(ircfg_a.dot()) if args.propagexpr: def is_addr_ro_variable(bs, addr, size): """ Return True if address at @addr is a read-only variable. WARNING: Quick & Dirty @addr: integer representing the address of the variable @size: size in bits """ try:
ircfg_simplifier.simplify(ircfg_model_call, head) log.info("ok...") if args.defuse: reachings = ReachingDefinitions(ircfg_model_call) open('graph_defuse.dot', 'w').write(DiGraphDefUse(reachings).dot()) out = ircfg.dot() open('graph_irflow_raw.dot', 'w').write(out) out = ircfg_model_call.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") ssa = SSADiGraph(ircfg_model_call) ssa.transform(head) open("ssa.dot", "w").write(ircfg_model_call.dot()) if args.propagexpr: def is_addr_ro_variable(bs, addr, size): """ Return True if address at @addr is a read-only variable. WARNING: Quick & Dirty @addr: integer representing the address of the variable @size: size in bits """ try:
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") ssa = SSADiGraph(ircfg_a) ssa.transform(head) open("ssa.dot", "wb").write(ircfg_a.dot()) if args.propagexpr: class IRAOutRegs(ira): def get_out_regs(self, block): regs_todo = super(self.__class__, 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: