def set_empty_dst_to_next(self, block, ir_blocks): for index, irblock in enumerate(ir_blocks): if irblock.dst is not None: continue next_loc_key = block.get_next() if next_loc_key is None: loc_key = None if block.lines: line = block.lines[-1] if line.offset is not None: loc_key = self.loc_db.get_or_create_offset_location( line.offset + line.l) if loc_key is None: loc_key = self.loc_db.add_location() block.add_cst(loc_key, AsmConstraint.c_next) else: loc_key = next_loc_key dst = m2_expr.ExprLoc(loc_key, self.pc.size) if irblock.assignblks: instr = irblock.assignblks[-1].instr else: instr = None assignblk = AssignBlock({self.IRDst: dst}, instr) ir_blocks[index] = IRBlock(irblock.loc_key, list(irblock.assignblks) + [assignblk])
def gen_loc_key_and_expr(self, size): """ Return a loc_key and it's corresponding ExprLoc @size: size of expression """ loc_key = self.loc_db.add_location() return loc_key, m2_expr.ExprLoc(loc_key, size)
def gen_loc_key_and_expr(self, size): """ Return a loc_key and it's corresponding ExprLoc @size: size of expression """ loc_key = self.symbol_pool.gen_loc_key() return loc_key, m2_expr.ExprLoc(loc_key, size)
def block2assignblks(self, block): irblocks_list = super(mipsCGen, self).block2assignblks(block) for irblocks in irblocks_list: for blk_idx, irblock in enumerate(irblocks): has_breakflow = any(assignblock.instr.breakflow() for assignblock in irblock) if not has_breakflow: continue irs = [] for assignblock in irblock: if self.ir_arch.pc not in assignblock: irs.append(AssignBlock(assignments, assignblock.instr)) continue assignments = dict(assignblock) # Add internal branch destination assignments[self.delay_slot_dst] = assignblock[ self.ir_arch.pc] assignments[self.delay_slot_set] = m2_expr.ExprInt(1, 32) # Replace IRDst with next instruction dst_loc_key = self.ir_arch.get_next_instr(assignblock.instr) assignments[self.ir_arch.IRDst] = m2_expr.ExprLoc(dst_loc_key, 32) irs.append(AssignBlock(assignments, assignblock.instr)) irblocks[blk_idx] = IRBlock(irblock.loc_key, irs) return irblocks_list
def tbnz(arg1, arg2, arg3): bitmask = m2_expr.ExprInt(1, arg1.size) << arg2 dst = arg3 if arg1 & bitmask else m2_expr.ExprLoc( ir.get_next_loc_key(instr), 64 ) PC = dst ir.IRDst = dst
def _gen_graph(self): """ Gen irbloc digraph """ self._graph = DiGraphIR(self.blocks, self.loc_db) for lbl, block in self.blocks.iteritems(): assert isinstance(lbl, m2_expr.LocKey) self._graph.add_node(lbl) for dst in self.dst_trackback(block): if dst.is_int(): dst_lbl = self.loc_db.get_or_create_offset_location(int(dst)) dst = m2_expr.ExprLoc(dst_lbl.loc_key, self.pc.size) if dst.is_loc(): self._graph.add_edge(lbl, dst.loc_key)
def add_irblock(self, irblock): """ Add the @irblock to the current IRCFG @irblock: IRBlock instance """ self.blocks[irblock.loc_key] = irblock self.add_node(irblock.loc_key) for dst in self.dst_trackback(irblock): if dst.is_int(): dst_loc_key = self.loc_db.get_or_create_offset_location(int(dst)) dst = m2_expr.ExprLoc(dst_loc_key, irblock.dst.size) if dst.is_loc(): self.add_uniq_edge(irblock.loc_key, dst.loc_key)
def teq(ir, instr, arg1, arg2): e = [] loc_except, loc_except_expr = ir.gen_loc_key_and_expr(ir.IRDst.size) loc_next = ir.get_next_loc_key(instr) loc_next_expr = m2_expr.ExprLoc(loc_next, ir.IRDst.size) do_except = [] do_except.append( m2_expr.ExprAssign( exception_flags, m2_expr.ExprInt(EXCEPT_DIV_BY_ZERO, exception_flags.size))) do_except.append(m2_expr.ExprAssign(ir.IRDst, loc_next_expr)) blk_except = IRBlock(loc_except.index, [AssignBlock(do_except, instr)]) cond = arg1 - arg2 e = [] e.append( m2_expr.ExprAssign( ir.IRDst, m2_expr.ExprCond(cond, loc_next_expr, loc_except_expr))) return e, [blk_except]
def remove_jmp_blocks(self): """ Remove irblock with only IRDst set, by linking it's parent destination to the block destination. """ # Find candidates jmp_blocks = set() for block in self.blocks.itervalues(): if len(block) != 1: continue assignblk = block[0] if len(assignblk) > 1: continue assert set(assignblk.keys()) == set([self.IRDst]) if len(self.graph.successors(block.loc_key)) != 1: continue if not assignblk[self.IRDst].is_loc(): continue dst = assignblk[self.IRDst].loc_key if dst == block.loc_key: # Infinite loop block continue jmp_blocks.add(block.loc_key) # Remove them, relink graph modified = False for loc_key in jmp_blocks: block = self.blocks[loc_key] dst_loc_key = block.dst parents = self.graph.predecessors(block.loc_key) for lbl in parents: parent = self.blocks.get(lbl, None) if parent is None: continue dst = parent.dst if dst.is_id(block.loc_key): dst = m2_expr.ExprLoc(dst_loc_key, dst.size) self.graph.discard_edge(lbl, block.loc_key) self.graph.discard_edge(block.loc_key, dst_loc_key) self.graph.add_uniq_edge(lbl, dst_loc_key) modified = True elif dst.is_cond(): src1, src2 = dst.src1, dst.src2 if src1.is_id(block.loc_key): dst = m2_expr.ExprCond(dst.cond, m2_expr.ExprLoc(dst_loc_key, dst.size), dst.src2) self.graph.discard_edge(lbl, block.loc_key) self.graph.discard_edge(block.loc_key, dst_loc_key) self.graph.add_uniq_edge(lbl, dst_loc_key) modified = True if src2.is_id(block.loc_key): dst = m2_expr.ExprCond(dst.cond, dst.src1, m2_expr.ExprLoc(dst_loc_key, dst.size)) self.graph.discard_edge(lbl, block.loc_key) self.graph.discard_edge(block.loc_key, dst_loc_key) self.graph.add_uniq_edge(lbl, dst_loc_key) modified = True if dst.src1 == dst.src2: dst = dst.src1 else: continue new_parent = parent.set_dst(dst) self.blocks[parent.loc_key] = new_parent # Remove unlinked useless nodes for loc_key in jmp_blocks: if (len(self.graph.predecessors(loc_key)) == 0 and len(self.graph.successors(loc_key)) == 0): self.graph.del_node(loc_key) del self.blocks[loc_key] return modified
def blr(arg1): PC = arg1 ir.IRDst = arg1 LR = m2_expr.ExprLoc(ir.get_next_loc_key(instr), 64)
def b_lt(arg1): cond = cond2expr['LT'] dst = arg1 if cond else m2_expr.ExprLoc(ir.get_next_loc_key(instr), 64) PC = dst ir.IRDst = dst
def b_eq(arg1): dst = arg1 if zf else m2_expr.ExprLoc(ir.get_next_loc_key(instr), 64) PC = dst ir.IRDst = dst
def b_ne(arg1): dst = m2_expr.ExprLoc(ir.get_next_loc_key(instr), 64) if zf else arg1 PC = dst ir.IRDst = dst
def cbnz(arg1, arg2): dst = arg2 if arg1 else m2_expr.ExprLoc(ir.get_next_loc_key(instr), 64) PC = dst ir.IRDst = dst
def cbz(arg1, arg2): dst = m2_expr.ExprLoc(ir.get_next_loc_key(instr), 64) if arg1 else arg2 PC = dst ir.IRDst = dst