Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
def _ail_handle_Assignment(self, stmt):
dst_type = type(stmt.dst)
if dst_type is ailment.Expr.Register:
offset = stmt.dst.reg_offset
data = self._expr(stmt.src)
size = stmt.src.bits // 8
self._assign_to_register(offset, data, size, src=stmt.src, dst=stmt.dst)
elif dst_type is ailment.Expr.Tmp:
# simply write to self.tmps
data = self._expr(stmt.src)
if data is None:
return
self.tmps[stmt.dst.tmp_idx] = data
else:
l.warning('Unsupported dst type %s.', dst_type)
def _ail_handle_Assignment(self, stmt):
dst_type = type(stmt.dst)
if dst_type is ailment.Expr.Register:
offset = stmt.dst.reg_offset
data = self._expr(stmt.src)
size = stmt.src.bits // 8
self._assign_to_register(offset, data, size, src=stmt.src, dst=stmt.dst)
elif dst_type is ailment.Expr.Tmp:
# simply write to self.tmps
data = self._expr(stmt.src)
if data is None:
return
self.tmps[stmt.dst.tmp_idx] = data
else:
l.warning('Unsupported dst type %s.', dst_type)
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))
:return:
"""
src = self._expr(stmt.src)
dst = stmt.dst
if type(dst) is Expr.Tmp:
new_src = self.state.get_variable(src)
if new_src is not None:
l.debug("%s = %s, replace %s with %s.", dst, src, src, new_src)
self.state.store_variable(dst, new_src)
else:
l.debug("Replacing %s with %s.", dst, src)
self.state.store_variable(dst, src)
elif type(dst) is Expr.Register:
if type(src) is Expr.Tmp:
l.debug("%s = %s, replace %s with %s.", dst, src, src, dst)
l.debug("New replacement: %s with %s", src, dst)
self.state.filter_variables(src)
self.state.store_variable(src, dst)
elif type(src) is Expr.Const:
l.debug("%s = %s, replace %s with %s.", dst, src, dst, src)
l.debug("New replacement: %s with %s", dst, src)
self.state.filter_variables(dst)
self.state.store_variable(dst, src)
else:
l.debug("%s = %s", dst, src)
else:
l.warning('Unsupported type of Assignment dst %s.', type(dst).__name__)
if posmap: posmap.tick_pos(len(s0))
s_v = self.variable.c_repr(posmap=posmap)
s1 = ":"
if posmap: posmap.tick_pos(len(s1))
s2 = self._get_offset_string(posmap=posmap)
s3 = ")"
if posmap: posmap.tick_pos(len(s3))
return s0 + s_v + s1 + s2 + s3
else:
s0 = "*("
if posmap: posmap.tick_pos(len(s0))
s = self.variable.c_repr(posmap=posmap)
s1 = ")"
if posmap: posmap.tick_pos(len(s1))
return s0 + s + s1
elif isinstance(self.variable, Expr.Register):
s0 = self.variable.reg_name if hasattr(self.variable, 'reg_name') else str(self.variable)
if posmap:
posmap.add_mapping(posmap.pos, len(s0), self)
posmap.tick_pos(len(s0))
s1 = ":"
if posmap: posmap.tick_pos(len(s1))
s2 = self._get_offset_string(in_hex=True, posmap=posmap)
return s0 + s1 + s2
else:
s0 = "*("
if posmap: posmap.tick_pos(len(s0))
s = str(self.variable)
if posmap:
posmap.add_mapping(posmap.pos, len(s), self)
posmap.tick_pos(len(s))
s1 = ":"
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,
}
self._analyze()
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
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
Y = int(math.log2(operand_0.operands[0].operands[1].value))
Z = operand_1.value
divisor = self._check_divisor(pow(2, Y+Z+V), C, ndigits)
else:
X = operand_0.operands[0]
Y = operand_1.value
C = operand_0.operands[1].value
divisor = self._check_divisor(pow(2, Y), C)
if divisor and X:
new_const = Expr.Const(expr.idx, None, divisor, 64)
return Expr.BinaryOp(expr.idx, 'DivMod', [X, new_const], **expr.tags)
if isinstance(operand_1, Expr.Const):
if isinstance(operand_0, Expr.Register):
new_operand = Expr.Const(operand_1.idx, None, 2**operand_1.value, operand_1.bits)
return Expr.BinaryOp(expr.idx, 'DivMod', [operand_0, new_operand])
elif isinstance(operand_0, Expr.BinaryOp) \
and operand_0.op == 'Shr' \
and isinstance(operand_0.operands[1], Expr.Const):
new_const = Expr.Const(operand_1.idx, None,
operand_0.operands[1].value+operand_1.value, operand_1.bits)
return Expr.BinaryOp(expr.idx, 'Shr', [operand_0.operands[0], new_const], **expr.tags)
if (operand_0, operand_1) != (expr.operands[0], expr.operands[1]):
return Expr.BinaryOp(expr.idx, 'Shr', [operand_0, operand_1])
return expr
def _link_variables_on_expr(self, variable_manager, block, stmt_idx, stmt, expr):
"""
Link atoms (AIL expressions) in the given expression to corresponding variables identified previously.
:param variable_manager: Variable manager of the function.
:param ailment.Block block: AIL block.
:param int stmt_idx: ID of the statement.
:param stmt: The AIL statement that `expr` belongs to.
:param expr: The AIl expression to work on.
:return: None
"""
if type(expr) is ailment.Expr.Register:
# find a register variable
reg_vars = variable_manager.find_variables_by_atom(block.addr, stmt_idx, expr)
# TODO: make sure it is the correct register we are looking for
if len(reg_vars) == 1:
reg_var, offset = next(iter(reg_vars))
expr.variable = reg_var
expr.offset = offset
elif type(expr) is ailment.Expr.Load:
# import ipdb; ipdb.set_trace()
variables = variable_manager.find_variables_by_atom(block.addr, stmt_idx, expr)
if len(variables) == 0:
self._link_variables_on_expr(variable_manager, block, stmt_idx, stmt, expr.addr)
else:
if len(variables) > 1:
l.error("More than one variable are available for atom %s. Consider fixing it using phi nodes.",