Пример #1
0
 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)
Пример #2
0
 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]
Пример #3
0
 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)
Пример #4
0
 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]
Пример #5
0
 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
Пример #6
0
 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
Пример #7
0
 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)
Пример #8
0
 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
Пример #9
0
 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
Пример #10
0
 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
Пример #11
0
 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)
Пример #12
0
 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
Пример #13
0
 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
Пример #14
0
 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
Пример #15
0
 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
Пример #16
0
 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
Пример #17
0
 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)