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