Source code for angr.analyses.decompiler.jumptable_entry_condition_rewriter

import claripy

from .structuring.structurer_nodes import ConditionNode, CodeNode
from .sequence_walker import SequenceWalker


[docs]class JumpTableEntryConditionRewriter(SequenceWalker): """ Remove artificial jump table entry conditions that ConditionProcessor introduced when dealing with jump tables. """
[docs] def __init__(self, jumptable_entry_conds): super().__init__() self._jumptable_entry_conds = jumptable_entry_conds
def _process_expr(self, expr): if expr in self._jumptable_entry_conds: return claripy.true new_args = [] replaced = False if expr.op in {"Or", "And", "Not"}: for arg in expr.args: new_arg = self._process_expr(arg) if new_arg is not None: replaced = True new_args.append(new_arg if new_arg is not None else arg) if replaced: return getattr(claripy, expr.op)(*new_args) return None def _handle_Code(self, node: CodeNode, **kwargs): new_node = super()._handle_Code(node, **kwargs) changed = False if new_node is not None: changed = True else: new_node = node new_cond = self._process_expr(new_node.reaching_condition) if new_node.reaching_condition is not None else None if new_cond is not None: changed = True else: new_cond = new_node.reaching_condition if changed: return CodeNode(new_node.node, new_cond) return None def _handle_Condition(self, node: ConditionNode, **kwargs): new_node = super()._handle_Condition(node, **kwargs) changed = False if new_node is None: new_node = node else: changed = True new_cond = self._process_expr(new_node.condition) if new_cond is not None: return ConditionNode( new_node.addr, node.reaching_condition, new_cond, new_node.true_node, false_node=new_node.false_node ) if changed: return new_node return None