diff options
Diffstat (limited to 'miasm2/ir/ir.py')
| -rw-r--r-- | miasm2/ir/ir.py | 173 |
1 files changed, 33 insertions, 140 deletions
diff --git a/miasm2/ir/ir.py b/miasm2/ir/ir.py index bf9b4e9a..721101e2 100644 --- a/miasm2/ir/ir.py +++ b/miasm2/ir/ir.py @@ -302,6 +302,20 @@ class IRBlock(object): self._dst = None self._dst_linenb = None + def __eq__(self, other): + if self.__class__ is not other.__class__: + return False + if self.loc_key != other.loc_key: + return False + if len(self.assignblks) != len(other.assignblks): + return False + for assignblk1, assignblk2 in zip(self.assignblks, other.assignblks): + if assignblk1 != assignblk2: + return False + return True + + def __ne__(self, other): + return not self.__eq__(other) def get_label(self): warnings.warn('DEPRECATION WARNING: use ".loc_key" instead of ".label"') @@ -421,7 +435,7 @@ class IRBlock(object): node_name = "".join("%s:\n" % name for name in names) out.append(node_name) - for i, assignblk in enumerate(self): + for assignblk in self: out.append(assignblk.to_string(loc_db)) return '\n'.join(out) @@ -437,12 +451,12 @@ class irbloc(IRBlock): super(irbloc, self).__init__(loc_key, irs) -class DiGraphIR(DiGraph): +class IRCFG(DiGraph): """DiGraph for IR instances""" def __init__(self, irdst, loc_db, blocks=None, *args, **kwargs): - """Instanciate a DiGraphIR + """Instanciate a IRCFG @loc_db: LocationDB instance @blocks: IR blocks """ @@ -451,7 +465,7 @@ class DiGraphIR(DiGraph): blocks = {} self._blocks = blocks self._irdst = irdst - super(DiGraphIR, self).__init__(*args, **kwargs) + super(IRCFG, self).__init__(*args, **kwargs) @property def IRDst(self): @@ -463,7 +477,7 @@ class DiGraphIR(DiGraph): def add_irblock(self, irblock): """ - Add the @irblock to the current DiGraphIR + Add the @irblock to the current IRCFG @irblock: IRBlock instance """ self.blocks[irblock.loc_key] = irblock @@ -533,7 +547,7 @@ class DiGraphIR(DiGraph): node """ self._dot_offset = offset - return super(DiGraphIR, self).dot() + return super(IRCFG, self).dot() def get_loc_key(self, addr): """Transforms an ExprId/ExprInt/loc_key/int into a loc_key @@ -661,137 +675,16 @@ class DiGraphIR(DiGraph): return done - def remove_empty_assignblks(self): - modified = False - for loc_key, block in self.blocks.iteritems(): - irs = [] - for assignblk in block: - if len(assignblk): - irs.append(assignblk) - else: - modified = True - self.blocks[loc_key] = IRBlock(loc_key, irs) - return modified - - 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.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.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.discard_edge(lbl, block.loc_key) - self.discard_edge(block.loc_key, dst_loc_key) - self.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.discard_edge(lbl, block.loc_key) - self.discard_edge(block.loc_key, dst_loc_key) - self.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.discard_edge(lbl, block.loc_key) - self.discard_edge(block.loc_key, dst_loc_key) - self.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.predecessors(loc_key)) == 0 and - len(self.successors(loc_key)) == 0): - self.del_node(loc_key) - del self.blocks[loc_key] - return modified +class DiGraphIR(IRCFG): + """ + DEPRECATED object + Use IRCFG instead of DiGraphIR + """ - def merge_blocks(self): - """ - Group irblock with one and only one son if this son has one and only one - parent - """ - modified = False - todo = set(self.nodes()) - while todo: - block = todo.pop() - sons = self.successors(block) - if len(sons) != 1: - continue - son = list(sons)[0] - if self.predecessors(son) != [block]: - continue - if block not in self.blocks: - continue - if son not in self.blocks: - continue - # Block has one son, son has one parent => merge - assignblks = [] - for assignblk in self.blocks[block]: - if self.IRDst not in assignblk: - assignblks.append(assignblk) - continue - affs = {} - for dst, src in assignblk.iteritems(): - if dst != self.IRDst: - affs[dst] = src - assignblks.append(AssignBlock(affs, assignblk.instr)) - - assignblks += self.blocks[son].assignblks - new_block = IRBlock(block, assignblks) - - self.discard_edge(block, son) - - for lson in self.successors(son): - self.add_uniq_edge(block, lson) - self.discard_edge(son, lson) - del self.blocks[son] - self.del_node(son) - - self.blocks[block] = new_block - todo.add(block) - modified = True - return modified + def __init__(self, irdst, loc_db, blocks=None, *args, **kwargs): + warnings.warn('DEPRECATION WARNING: use "IRCFG" instead of "DiGraphIR"') + super(IRCFG, self).__init__(irdst, loc_db, blocks=None, *args, **kwargs) class IntermediateRepresentation(object): @@ -814,17 +707,17 @@ class IntermediateRepresentation(object): def new_ircfg(self, *args, **kwargs): """ - Return a new instance of DiGraphIR + Return a new instance of IRCFG """ - return DiGraphIR(self.IRDst, self.loc_db, *args, **kwargs) + return IRCFG(self.IRDst, self.loc_db, *args, **kwargs) def new_ircfg_from_asmcfg(self, asmcfg, *args, **kwargs): """ - Return a new instance of DiGraphIR from an @asmcfg + Return a new instance of IRCFG from an @asmcfg @asmcfg: AsmCFG instance """ - ircfg = DiGraphIR(self.IRDst, self.loc_db, *args, **kwargs) + ircfg = IRCFG(self.IRDst, self.loc_db, *args, **kwargs) for block in asmcfg.blocks: self.add_asmblock_to_ircfg(block, ircfg) return ircfg @@ -888,7 +781,7 @@ class IntermediateRepresentation(object): """ Add a native block to the current IR @block: native assembly block - @ircfg: DiGraphIR instance + @ircfg: IRCFG instance @gen_pc_updt: insert PC update effects between instructions """ |