Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
def test_loadg_no_constraint_creation():
state = SimState(arch='armel', mode='symbolic')
engine = SimEngineVEX()
from angr.engines.vex.statements.loadg import SimIRStmt_LoadG
stmt = pyvex.IRStmt.LoadG('Iend_LE', 'ILGop_16Uto32',
0, # dst
pyvex.IRExpr.Const(pyvex.const.U32(0x2000)), # addr (src)
pyvex.IRExpr.Const(pyvex.const.U32(0x1337)), # alt
pyvex.IRExpr.RdTmp(1) # guard
)
tyenv = pyvex.IRTypeEnv(state.arch)
tyenv.types = [ 'Ity_I32', 'Ity_I32' ]
state.scratch.set_tyenv(tyenv)
state.scratch.temps[1] = state.solver.BVS('tmp_1', 32)
SimIRStmt_LoadG(engine, state, stmt)
# LOADG should not create new constraints - it is a simple conditional memory read. The conditions should only be
# used inside the value AST to guard the memory read.
assert not state.solver.constraints
assert state.scratch.temps[0] is not None
assert state.scratch.temps[0].variables.issuperset(state.scratch.temps[1].variables)
assert state.scratch.temps[0].op == 'If'
def _fastpath_irexpr(self, expr, temps, regs):
if type(expr) == pyvex.IRExpr.Const:
return translate_irconst(self.state, expr.con)
elif type(expr) == pyvex.IRExpr.RdTmp:
return temps[expr.tmp]
elif type(expr) == pyvex.IRExpr.Get and expr.offset in regs:
return regs[expr.offset]
else:
return None
if not isinstance(statements[put_stmt_id], pyvex.IRStmt.Put):
return None
if not isinstance(statements[put_stmt_id].data, pyvex.IRExpr.RdTmp):
return None
temps.add(statements[put_stmt_id].data.tmp)
for i in xrange(put_stmt_id, -1, -1):
stmt = statements[i]
if isinstance(stmt, pyvex.IRStmt.WrTmp):
data = None
if stmt.tmp in temps:
data = stmt.data
if isinstance(data, pyvex.IRExpr.RdTmp):
temps.add(data.tmp)
elif isinstance(data, pyvex.IRExpr.Get):
src_stmt_ids.add(i)
temps.remove(stmt.tmp)
return src_stmt_ids
def _backward_handler_expr_Unop(self, expr, state):
arg = expr.args[0]
if type(arg) is pyvex.IRExpr.RdTmp:
self._backward_handler_expr(arg, state)
def _resolve_expr(expr):
if type(expr) is pyvex.IRExpr.Binop:
arg0, arg1 = expr.args
if expr.op.startswith('Iop_Add'):
return _resolve_expr(arg0) + _resolve_expr(arg1)
elif expr.op.startswith('Iop_Sub'):
return _resolve_expr(arg0) - _resolve_expr(arg1)
elif type(expr) is pyvex.IRExpr.RdTmp and expr.tmp in tmps and tmps[expr.tmp] is not None:
return tmps[expr.tmp]
elif type(expr) is pyvex.IRExpr.Const:
return Constant(expr.con.value)
elif type(expr) is pyvex.IRExpr.Get:
return state.get(expr.offset)
elif self.track_mem and type(expr) is pyvex.IRExpr.Load:
return state.load(_resolve_expr(expr.addr))
raise CouldNotResolveException
def _resolve_expr(expr):
if type(expr) is pyvex.IRExpr.Binop:
arg0, arg1 = expr.args
if expr.op.startswith('Iop_Add'):
return _resolve_expr(arg0) + _resolve_expr(arg1)
elif expr.op.startswith('Iop_Sub'):
return _resolve_expr(arg0) - _resolve_expr(arg1)
elif type(expr) is pyvex.IRExpr.RdTmp and expr.tmp in tmps and tmps[expr.tmp] is not None:
return tmps[expr.tmp]
elif type(expr) is pyvex.IRExpr.Const:
return Constant(expr.con.value)
elif type(expr) is pyvex.IRExpr.Get:
return state.get(expr.offset)
elif type(expr) is pyvex.IRExpr.Load:
return state.load(_resolve_expr(expr.addr))
else:
raise CouldNotResolveException
# + 10 | t12 = Add64(0x0000000000400a50,t11)
# + 11 | t16 = LDbe:I64(t12)
# 12 | PUT(r2) = t16
# 13 | ------ IMark(0x4007e6, 4, 0) ------
# + 14 | t17 = Add64(0x0000000000400a50,t16)
# + Next: t17
#
# Special case: a base address is added to the loaded offset before jumping to it.
if isinstance(stmt.data.args[0], pyvex.IRExpr.Const) and \
isinstance(stmt.data.args[1], pyvex.IRExpr.RdTmp):
stmts_adding_base_addr.append(JumpTargetBaseAddr(stmt_loc, stmt,
stmt.data.args[1].tmp,
base_addr=stmt.data.args[0].con.value)
)
stmts_to_remove.append(stmt_loc)
elif isinstance(stmt.data.args[0], pyvex.IRExpr.RdTmp) and \
isinstance(stmt.data.args[1], pyvex.IRExpr.Const):
stmts_adding_base_addr.append(JumpTargetBaseAddr(stmt_loc, stmt,
stmt.data.args[0].tmp,
base_addr=stmt.data.args[1].con.value)
)
stmts_to_remove.append(stmt_loc)
elif isinstance(stmt.data.args[0], pyvex.IRExpr.RdTmp) and \
isinstance(stmt.data.args[1], pyvex.IRExpr.RdTmp):
# one of the tmps must be holding a concrete value at this point
stmts_adding_base_addr.append(JumpTargetBaseAddr(stmt_loc, stmt,
stmt.data.args[0].tmp,
tmp_1=stmt.data.args[1].tmp)
)
stmts_to_remove.append(stmt_loc)
else:
# not supported
def _handle_expression_Load(self, expr):
# loading from memory!
addr = expr.addr
if isinstance(addr, pyvex.IRExpr.RdTmp):
tmp_addr = addr.tmp
if tmp_addr in self.tmps:
self.last_instr = DerefInstruction(self.ins_addr, 'load',
self._ast_to_addr_regs(self.tmps[tmp_addr])
)
self.instrs.append(self.last_instr)
if exit_stmt_idx is None or exit_stmt_idx == DEFAULT_STATEMENT:
# Initialize the temps set with whatever in the `next` attribute of this irsb
next_expr = self._get_irsb(run).next
if type(next_expr) is pyvex.IRExpr.RdTmp:
temps.add(next_expr.tmp)
# if there are conditional exits, we *always* add them into the slice (so if they should not be taken, we do not
# lose the condition)
for stmt_idx_, s_ in enumerate(self._get_irsb(run).statements):
if not type(s_) is pyvex.IRStmt.Exit:
continue
if s_.jumpkind != 'Ijk_Boring':
continue
if type(s_.guard) is pyvex.IRExpr.RdTmp:
temps.add(s_.guard.tmp)
# Put it in our slice
irsb_addr = self._get_addr(run)
self._inslice_callback(stmt_idx_, s_, {'irsb_addr': irsb_addr, 'prev': prev})
prev = (irsb_addr, stmt_idx_)
infodict = {'irsb_addr' : self._get_addr(run),
'prev' : prev,
'has_statement': False
}
slicer = SimSlicer(self.project.arch, stmts,
target_tmps=temps,
target_regs=regs,
target_stack_offsets=stack_offsets,
# its use site.
# TODO: handle this case
l.debug('Failed to determine value of register gp for function %#x.', func.addr)
return False, [ ]
else:
state.regs.gp = func.info['gp']
def overwrite_tmp_value(state):
state.inspect.tmp_write_expr = state.solver.BVV(func.info['gp'], state.arch.bits)
# Special handling for cases where `gp` is stored on the stack
got_gp_stack_store = False
for block_addr_in_slice in set(slice_node[0] for slice_node in b.slice.nodes()):
for stmt in project.factory.block(block_addr_in_slice).vex.statements:
if isinstance(stmt, pyvex.IRStmt.Put) and stmt.offset == gp_offset and \
isinstance(stmt.data, pyvex.IRExpr.RdTmp):
tmp_offset = stmt.data.tmp # pylint:disable=cell-var-from-loop
# we must make sure value of that temporary variable equals to the correct gp value
state.inspect.make_breakpoint('tmp_write', when=BP_BEFORE,
condition=lambda s, bbl_addr_=block_addr_in_slice,
tmp_offset_=tmp_offset:
s.scratch.bbl_addr == bbl_addr_ and s.inspect.tmp_write_num == tmp_offset_,
action=overwrite_tmp_value
)
got_gp_stack_store = True
break
if got_gp_stack_store:
break
simgr = self.project.factory.simulation_manager(state)
simgr.use_technique(Slicecutor(annotated_cfg))
simgr.run()