Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
if not isinstance(pred.statements[-1], ailment.Stmt.ConditionalJump):
_l.debug("The predecessor does not end with a conditional jump.")
return
# Find the statement that computes real canary value xor stored canary value
canary_check_stmt_idx = self._find_canary_xor_stmt(pred, store_offset)
if canary_check_stmt_idx is None:
_l.debug("Cannot find the canary check statement in the predecessor.")
return
# Awesome. Now patch this function.
# Patch the pred so that it jumps to the one that is not stack_chk_fail_caller
other_node = next(iter([ end_node for end_node in end_nodes if end_node is not stack_chk_fail_caller ]))
pred_copy = pred.copy()
pred_copy.statements[-1] = ailment.Stmt.Jump(len(pred_copy.statements) - 1,
ailment.Expr.Const(None, None, other_node.addr,
self.project.arch.bits)
)
self._update_block(pred, pred_copy)
# Remove the block that calls stack_chk_fail_caller
self._remove_block(stack_chk_fail_caller)
# Remove the statement that loads the stack canary from fs
first_block_copy = first_block.copy()
first_block_copy.statements.pop(stmt_idx)
self._update_block(first_block, first_block_copy)
# what's this node?
l.error("Found a node that belongs to neither loop body nor loop successors. Something is wrong.")
raise Exception()
if dst is not loop_head:
loop_region_graph.add_edge(node, replaced_nodes.get(dst, dst))
if dst in traversed:
continue
queue.append(dst)
# Create a graph region and structure it
region = GraphRegion(loop_head, loop_region_graph)
structurer = self.project.analyses.Structurer(region)
seq = structurer.result
last_stmt = self._get_last_statement(seq)
if type(last_stmt) is ailment.Stmt.Jump:
target = last_stmt.target
if target.value != loop_head.addr:
l.error('The last Goto in the loop body does not jump to the loop head. Why?')
raise Exception()
# we want to remove this Jump as it is not necessary anymore
self._remove_last_statement(seq)
seq.remove_empty_node()
return seq
def _ail_handle_Jump(self, stmt):
target = self._expr(stmt.target)
return Stmt.Jump(stmt.idx, target, **stmt.tags)
def _extract_jump_targets(stmt):
"""
Extract goto targets from a Jump or a ConditionalJump statement.
:param stmt: The statement to analyze.
:return: A list of known concrete jump targets.
:rtype: list
"""
targets = [ ]
# FIXME: We are assuming all jump targets are concrete targets. They may not be.
if isinstance(stmt, ailment.Stmt.Jump):
targets.append(stmt.target.value)
elif isinstance(stmt, ailment.Stmt.ConditionalJump):
targets.append(stmt.true_target.value)
targets.append(stmt.false_target.value)
return targets
def _goto_handle_block(self, block, successor): # pylint:disable=no-self-use
"""
:param ailment.Block block:
:return:
"""
if block.statements and isinstance(block.statements[-1], ailment.Stmt.Jump):
goto_stmt = block.statements[-1] # ailment.Stmt.Jump
if successor and isinstance(goto_stmt.target, ailment.Expr.Const) \
and goto_stmt.target.value == successor.addr:
# we can remove this statement
block.statements = block.statements[:-1]
from .call import SimIRStmt_Call
import ailment
# STMT_CLASSES = [None]*ailment.Stmt.tag_count
# for name, cls in vars(ailment.Stmt).items():
# if isinstance(cls, type) and issubclass(cls, ailment.Stmt.Statement) and cls is not ailment.Stmt.IRStmt:
# STMT_CLASSES[cls.tag_int] = globals()['SimIRStmt_' + name]
# if any(x is None for x in STMT_CLASSES):
# raise ImportError("Something is messed up loading angr: not all ailment stmts accounted for")
STMT_CLASSES = {
ailment.Stmt.Assignment: SimIRStmt_Assignment,
ailment.Stmt.Store: SimIRStmt_Store,
ailment.Stmt.Jump: SimIRStmt_Jump,
ailment.Stmt.ConditionalJump: SimIRStmt_ConditionalJump,
ailment.Stmt.Call: SimIRStmt_Call,
# ailment.Stmt.DirtyStatement: SimIRStmt_DirtyStatement