def taintAnalysis(self, item): func = item.func if func.ircfg is None: func.ira = BinaryAnalysis.iraType(func.cfg.loc_db) func.ircfg = func.ira.new_ircfg_from_asmcfg(func.cfg) func.defUse = DiGraphDefUse(ReachingDefinitions(func.ircfg)) current_block = func.ircfg.get_block(item.block.loc_key) index = 0 dstArg = None for index, assignblk in enumerate(current_block): if assignblk.instr.offset == item.address: for dst, src in assignblk.items(): dstArg = dst break queue = [AssignblkNode(item.block.loc_key, index, dstArg)] currentPoint = 0 endPoint = 0 while currentPoint <= endPoint: node = queue[currentPoint] currentPoint += 1 assign = func.ircfg.blocks[node.label][node.index] self.focusAddress(assign.instr.offset, False) for node2 in func.defUse.successors(node): endPoint += 1 queue.append(node2)
def findDep(self, item): arg = item.args[self.lastClickIndex] address = item.address + item.instr.l func = item.func if func.ircfg is None: func.ira = BinaryAnalysis.iraType(func.cfg.loc_db) func.ircfg = func.ira.new_ircfg_from_asmcfg(func.cfg) func.defUse = DiGraphDefUse(ReachingDefinitions(func.ircfg)) indexReg = eval('BinaryAnalysis.machine.mn.regs.regs' + str(arg.size).zfill(2) + '_expr').index(arg) arg = eval('BinaryAnalysis.machine.mn.regs.regs' + str(BinaryAnalysis.disasmEngine.attrib).zfill(2) + '_expr')[ indexReg] elements = set() elements.add(arg) depgraph = DependencyGraph(func.ircfg, implicit=False, apply_simp=True, follow_call=False, follow_mem=True) currentLockey = next(iter(func.ircfg.getby_offset(address))) assignblkIndex = 0 currentBlock = func.ircfg.get_block(currentLockey) for assignblkIndex, assignblk in enumerate(currentBlock): if assignblk.instr.offset == address: break outputLog = '' for solNum, sol in enumerate(depgraph.get(currentBlock.loc_key, elements, assignblkIndex, set())): results = sol.emul(func.ira, ctx={}) outputLog += 'Solution %d:\n' % solNum for k, v in viewitems(results): outputLog += str(k) + ' = ' + str(v) + '\n' path = ' -> '.join(BinaryAnalysis.locDB.pretty_str(h) for h in sol.history[::-1]) outputLog += path + '\n\n' self.log.emit(outputLog)
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 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 __init__(self, address, cfg): self.rawIRA = BinaryAnalysis.iraType(cfg.loc_db) self.normalIRA = BinaryAnalysis.iraType(cfg.loc_db) self.ssaIRA = IRADelModCallStack(cfg.loc_db) self.maxIRA1 = IRADelModCallStack(cfg.loc_db) self.maxIRA2 = IRAOutRegs(cfg.loc_db) self.rawIRCFG = self.rawIRA.new_ircfg_from_asmcfg(cfg) self.normalIRCFG = None self.ssaIRCFG = None self.maxIRCFG = None self.rawDefUse = DiGraphDefUse(ReachingDefinitions(self.rawIRCFG)) self.normalDefUse = None self.ssaDefUse = None self.maxDefUse = None self.head = cfg.loc_db.get_offset_location(address) self.address = address self.cfg = cfg
def __init__(self, ircfg, asmcfg): self.defuse_edges = {} self.reaching_defs = ReachingDefinitions(ircfg) defuse = DiGraphDefUse(self.reaching_defs, deref_mem=False, apply_simp=True) heads = asmcfg.heads() self.dominators = asmcfg.compute_dominators(heads[0]) self.immediate_dominators = asmcfg.compute_immediate_dominators(heads[0]) self.back_edges = [] self.rev_back_edges = {} for node in asmcfg.walk_depth_first_forward(heads[0]): for successor in asmcfg.successors_iter(node): # check for a back edge to a dominator if successor in self.dominators[node]: edge = (node, successor) self.rev_back_edges.setdefault(successor, set()).add(node) self.back_edges.append(edge) for src, dst in defuse.edges(): self.defuse_edges.setdefault(src, []).append(dst)
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
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") ssa = SSADiGraph(ircfg_a) ssa.transform(head) open("ssa.dot", "w").write(ircfg_a.dot()) if args.propagexpr:
(G5_IRA, G5_EXP_IRA), (G6_IRA, G6_EXP_IRA), (G7_IRA, G7_EXP_IRA), (G8_IRA, G8_EXP_IRA), (G9_IRA, G9_EXP_IRA), (G10_IRA, G10_EXP_IRA), (G11_IRA, G11_EXP_IRA), (G12_IRA, G12_EXP_IRA), (G13_IRA, G13_EXP_IRA), (G14_IRA, G14_EXP_IRA), (G15_IRA, G15_EXP_IRA), (G16_IRA, G16_EXP_IRA), (G17_IRA, G17_EXP_IRA)]): # Extract test elements g_ira, g_exp_ira = test print("[+] Test", test_nb + 1) # Print initial graph, for debug open("graph_%02d.dot" % (test_nb + 1), "w").write(g_ira.dot()) reaching_defs = ReachingDefinitions(g_ira) defuse = DiGraphDefUse(reaching_defs, deref_mem=True) # # Simplify graph deadrm(g_ira) # # Print simplified graph, for debug open("simp_graph_%02d.dot" % (test_nb + 1), "w").write(g_ira.dot()) # Same number of blocks assert len(g_ira.blocks) == len(g_exp_ira.blocks) # Check that each expr in the blocks are the same for lbl, irb in viewitems(g_ira.blocks): exp_irb = g_exp_ira.blocks[lbl] assert exp_irb.assignblks == irb.assignblks
print(block) log.info("Gen Graph... %x" % ad) log.info("Print blocks (with analyse)") for label, block in viewitems(ircfg_model_call.blocks): print(block) if args.simplify > 0: log.info("Simplify...") ircfg_simplifier = IRCFGSimplifierCommon(lifter_model_call) 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: