def adjusted_location(self, ea): eas = [ stmt.ea for stmt in statement_iterator_t(self.function) if stmt.ea is not None and stmt.ea >= ea ] if len(eas) == 0: return ea return min(eas)
def display_labels(self): locations = [] for stmt in statement_iterator_t(self.function): if type(stmt) == goto_t and stmt.is_known(): locations.append(stmt.expr.value) elif type(stmt) == branch_t: locations.append(stmt.true.value) locations.append(stmt.false.value) return [self.adjusted_location(ea) for ea in locations]
def assert_live_ranges(self, step, input, expected): dec = self.decompile_until(input, step) lr = ssa.live_range_t(dec.function) allstmts = list(iterators.statement_iterator_t(dec.function)) actual = {} for expr, stmts in lr.expr_to_stmt.iteritems(): t = self.deep_tokenize(dec.function, expr) actual[t] = list(set([idx for idx in range(len(allstmts)) for stmt in stmts if allstmts[idx] is stmt])) self.assertEqual(expected, actual)
def prune(self): while True: pruned = False for stmt in iterators.statement_iterator_t(self.function): if not self.is_prunable(stmt): continue pruned = True self.remove(stmt) if not pruned: break return
def assert_live_ranges(self, step, input, expected): dec = self.decompile_until(input, step) lri = ssa.live_range_iterator_t(dec.function) allstmts = [id(stmt) for stmt in iterators.statement_iterator_t(dec.function)] actual = {} for lr in lri.live_ranges(): stmts = lr.statements t = self.deep_tokenize(dec.function, lr.definition) if t not in actual: actual[t] = [] actual[t].append([allstmts.index(id(stmt)) for stmt in stmts]) self.assertEqual(expected, actual)
def propagate(self): for stmt in iterators.statement_iterator_t(self.function): if type(stmt.expr) != assign_t: continue if isinstance(stmt.expr.op2, phi_t) and len(stmt.expr.op1.uses) == 1 and \ isinstance(stmt.expr.op1.uses[0].parent, phi_t): use = stmt.expr.op1.uses[0] self.propagate_to(stmt.expr.op2, use.parent) use.unlink() use.parent.remove(use) stmt.expr.unlink() stmt.remove() return True
def propagate(self): for stmt in iterators.statement_iterator_t(self.function): if type(stmt.expr) != assign_t: continue if isinstance(stmt.expr.op2, phi_t) and len(stmt.expr.op2) == 2: if stmt.expr.op1 == stmt.expr.op2[0]: self.propagate_to(stmt.expr.op1, stmt.expr.op2[1]) elif stmt.expr.op1 == stmt.expr.op2[1]: self.propagate_to(stmt.expr.op1, stmt.expr.op2[0]) else: continue stmt.expr.unlink() stmt.remove() return True
def assert_live_ranges(self, step, input, expected): dec = self.decompile_until(input, step) lri = ssa.live_range_iterator_t(dec.function) allstmts = [ id(stmt) for stmt in iterators.statement_iterator_t(dec.function) ] actual = {} for lr in lri.live_ranges(): stmts = lr.statements t = self.deep_tokenize(dec.function, lr.definition) if t not in actual: actual[t] = [] actual[t].append([allstmts.index(id(stmt)) for stmt in stmts]) self.assertEqual(expected, actual)
def expand_branches(self, blocks=None): for stmt in iterators.statement_iterator_t(self.function): if type(stmt) != branch_t: continue if blocks and stmt.container.block not in blocks: continue condition = stmt.expr.copy() goto_true = goto_t(stmt.ea, stmt.true.copy()) goto_false = goto_t(stmt.ea, stmt.false.copy()) _if = if_t(stmt.ea, condition, container_t(stmt.container.block, [goto_true])) simplify_expressions.run(_if.expr, deep=True) stmt.container.insert(stmt.index(), _if) stmt.container.insert(stmt.index(), goto_false) stmt.remove() return
def rename(self): for op in iterators.operand_iterator_t(self.function, filter=self.should_rename): new = self.rename_with(op) op.replace(new) op.unlink() # clear out phi statements with operands that do not have indexes anymore. for phi in iterators.operand_iterator_t(self.function, klass=phi_t): for op in list(phi.operands): if op.index is None: phi.remove(op) op.unlink() for stmt in iterators.statement_iterator_t(self.function): if isinstance(stmt.expr, assign_t) and isinstance(stmt.expr.op2, phi_t) and len(stmt.expr.op2) == 0: stmt.expr.unlink() stmt.remove() return
def rename(self): for op in iterators.operand_iterator_t(self.function, filter=self.should_rename): new = self.rename_with(op) op.replace(new) op.unlink() # clear out phi statements with operands that do not have indexes anymore. for phi in iterators.operand_iterator_t(self.function, klass=phi_t): for op in list(phi.operands): if op.index is None: phi.remove(op) op.unlink() for stmt in iterators.statement_iterator_t(self.function): if isinstance(stmt.expr, assign_t) and isinstance( stmt.expr.op2, phi_t) and len(stmt.expr.op2) == 0: stmt.expr.unlink() stmt.remove() return
def adjusted_location(self, ea): eas = [stmt.ea for stmt in statement_iterator_t(self.function) if stmt.ea is not None and stmt.ea >= ea] if len(eas) == 0: return ea return min(eas)