Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
def check_bp_save_fauxware(arch):
p = angr.Project(os.path.join(test_location, arch, 'fauxware'), auto_load_libs=False)
p.analyses.CFGFast()
main = p.kb.functions['main']
dra = p.analyses.Decompiler(main)
first_block_stmts = dra.codegen._sequence.nodes[0].nodes[0].statements
for stmt in first_block_stmts:
if isinstance(stmt, ailment.Stmt.Store):
nose.tools.assert_false(
(isinstance(stmt.data, ailment.Expr.Register)
and stmt.data.reg_offset == p.arch.bp_offset)
or (isinstance(stmt.data, ailment.Expr.StackBaseOffset)
and stmt.data.offset == 0))
self.text = None
self.posmap = None
self.nodemap = None
self._indent = indent
self._handlers = {
SequenceNode: self._handle_Sequence,
CodeNode: self._handle_Code,
LoopNode: self._handle_Loop,
ConditionNode: self._handle_Condition,
ConditionalBreakNode: self._handle_ConditionalBreak,
MultiNode: self._handle_MultiNode,
Block: self._handle_AILBlock,
# AIL statements
Stmt.Store: self._handle_Stmt_Store,
Stmt.Assignment: self._handle_Stmt_Assignment,
Stmt.Call: self._handle_Stmt_Call,
# AIL expressions
Expr.Register: self._handle_Expr_Register,
Expr.Load: self._handle_Expr_Load,
Expr.Tmp: self._handle_Expr_Tmp,
Expr.Const: self._handle_Expr_Const,
Expr.UnaryOp: self._handle_Expr_UnaryOp,
Expr.BinaryOp: self._handle_Expr_BinaryOp,
Expr.Convert: self._handle_Expr_Convert,
Expr.StackBaseOffset: self._handle_Expr_StackBaseOffset,
Expr.DirtyExpression: self._handle_Expr_Dirty,
# SimVariables
SimStackVariable: self._handle_Variable_SimStackVariable,
SimRegisterVariable: self._handle_Variable_SimRegisterVariable,
}
def _ail_handle_Store(self, stmt):
addr = self._expr(stmt.addr)
data = self._expr(stmt.data)
# replace
if(addr, data) != (stmt.addr, stmt.data):
return Stmt.Store(stmt.idx, addr, data, stmt.size,
stmt.endness, variable=stmt.variable, **stmt.tags)
return stmt
from .condjump import SimIRStmt_ConditionalJump
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
def _find_retaddr_save_stmt(self):
first_block = self._get_block(self._func.addr)
for idx, stmt in enumerate(first_block.statements):
if isinstance(stmt, ailment.Stmt.Store) \
and isinstance(stmt.addr, ailment.Expr.StackBaseOffset) \
and isinstance(stmt.data, ailment.Expr.Register) \
and stmt.data.reg_offset == self.project.arch.bp_offset \
and stmt.addr.offset < 0:
return first_block, idx
if isinstance(stmt, ailment.Stmt.Store) \
and isinstance(stmt.addr, ailment.Expr.StackBaseOffset) \
and isinstance(stmt.data, ailment.Expr.StackBaseOffset) \
and stmt.data.offset == 0 \
and stmt.addr.offset < 0:
return first_block, idx
def _link_variables_on_block(self, block, kb):
"""
Link atoms (AIL expressions) in the given block to corresponding variables identified previously.
:param ailment.Block block: The AIL block to work on.
:return: None
"""
variable_manager = kb.variables[self.function.addr]
for stmt_idx, stmt in enumerate(block.statements):
# I wish I could do functional programming in this method...
stmt_type = type(stmt)
if stmt_type is ailment.Stmt.Store:
# find a memory variable
mem_vars = variable_manager.find_variables_by_atom(block.addr, stmt_idx, stmt)
if len(mem_vars) == 1:
stmt.variable, stmt.offset = next(iter(mem_vars))
self._link_variables_on_expr(variable_manager, block, stmt_idx, stmt, stmt.data)
elif stmt_type is ailment.Stmt.Assignment:
self._link_variables_on_expr(variable_manager, block, stmt_idx, stmt, stmt.dst)
self._link_variables_on_expr(variable_manager, block, stmt_idx, stmt, stmt.src)
elif stmt_type is ailment.Stmt.ConditionalJump:
self._link_variables_on_expr(variable_manager, block, stmt_idx, stmt, stmt.condition)
elif stmt_type is ailment.Stmt.Call:
if stmt.ret_expr:
self._link_variables_on_expr(variable_manager, block, stmt_idx, stmt, stmt.ret_expr)
def _find_canary_init_stmt(self):
first_block = self._get_block(self._func.addr)
for idx, stmt in enumerate(first_block.statements):
if isinstance(stmt, ailment.Stmt.Store) \
and isinstance(stmt.addr, ailment.Expr.StackBaseOffset) \
and isinstance(stmt.data, ailment.Expr.Load) \
and self._is_add(stmt.data.addr):
# Check addr: must be fs+0x28
op0, op1 = stmt.data.addr.operands
if isinstance(op1, ailment.Expr.Register):
op0, op1 = op1, op0
if isinstance(op0, ailment.Expr.Register) and isinstance(op1, ailment.Expr.Const):
if op0.reg_offset == self.project.arch.get_register_offset('fs') and op1.value == 0x28:
return first_block, idx
return None