Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
regs = { }
guard = self.state.se.true
for stmt in self.irsb.statements():
if type(stmt) == pyvex.IRStmt.IMark:
self.last_imark = stmt
elif type(stmt) == pyvex.IRStmt.Exit:
l.debug("%s adding conditional exit", self)
e = SimExit(expr=self.state.BVV(stmt.offsIP, self.state.arch.bits), guard=guard, state=self.state, source=self.state.BVV(self.last_imark.addr, self.state.arch.bits), jumpkind=self.irsb.jumpkind, simplify=False)
self.conditional_exits.append(e)
self.add_exits(e)
if self.irsb.jumpkind == 'Ijk_Call' and o.DO_RET_EMULATION in self.state.options:
self.postcall_exit = SimExit(expr=self.state.BVV(self.last_imark.addr+self.last_imark.len, self.state.arch.bits), guard=guard, state=self.state, source=self.state.BVV(self.last_imark.addr, self.state.arch.bits), jumpkind='Ijk_Ret', simplify=False)
self.add_exits(self.postcall_exit)
elif type(stmt) == pyvex.IRStmt.WrTmp:
temps[stmt.tmp] = self._fastpath_irexpr(stmt.data, temps, regs)
elif type(stmt) == pyvex.IRStmt.Put:
regs[stmt.offset] = self._fastpath_irexpr(stmt.data, temps, regs)
else:
continue
next_expr = self._fastpath_irexpr(self.irsb.next, temps, regs)
if next_expr is not None:
self.has_default_exit = True
self.default_exit = SimExit(expr=next_expr, guard=guard, state=self.state, jumpkind=self.irsb.jumpkind, simplify=False, source=self.state.BVV(self.last_imark.addr, self.state.arch.bits))
self.add_exits(self.default_exit)
if self.irsb.jumpkind == 'Ijk_Call' and o.DO_RET_EMULATION in self.state.options:
self.postcall_exit = SimExit(expr=self.state.BVV(self.last_imark.addr+self.last_imark.len, self.state.arch.bits), guard=guard, state=self.state, source=self.state.BVV(self.last_imark.addr, self.state.arch.bits), jumpkind='Ijk_Ret', simplify=False)
self.add_exits(self.postcall_exit)
def resolve_stmt(stmt):
if type(stmt) is pyvex.IRStmt.WrTmp:
tmps[stmt.tmp] = resolve_expr(stmt.data)
elif type(stmt) is pyvex.IRStmt.Store:
state.store(resolve_expr(stmt.addr), resolve_expr(stmt.data))
elif type(stmt) is pyvex.IRStmt.Put:
state.put(stmt.offset, resolve_expr(stmt.data))
else:
raise CouldNotResolveException
def resolve_stmt(stmt):
if type(stmt) is pyvex.IRStmt.WrTmp:
tmps[stmt.tmp] = resolve_expr(stmt.data)
elif self.track_mem and type(stmt) is pyvex.IRStmt.Store:
state.store(resolve_expr(stmt.addr), resolve_expr(stmt.data))
elif type(stmt) is pyvex.IRStmt.Put:
state.put(stmt.offset, resolve_expr(stmt.data))
else:
raise CouldNotResolveException
stmts = block.statements
tmp_exit = None
exit_stmt_idx = None
dst = None
for i, stmt in reversed(list(enumerate(stmts))):
if tmp_exit is None:
# Looking for the Exit statement
if isinstance(stmt, pyvex.IRStmt.Exit) and \
isinstance(stmt.guard, pyvex.IRExpr.RdTmp):
tmp_exit = stmt.guard.tmp
dst = stmt.dst
exit_stmt_idx = i
else:
# Looking for the WrTmp statement
if isinstance(stmt, pyvex.IRStmt.WrTmp) and \
stmt.tmp == tmp_exit:
if isinstance(stmt.data, pyvex.IRExpr.Binop) and \
stmt.data.op == 'Iop_CmpEQ32' and \
isinstance(stmt.data.child_expressions[0], pyvex.IRExpr.Const) and \
isinstance(stmt.data.child_expressions[1], pyvex.IRExpr.Const) and \
stmt.data.child_expressions[0].con.value == stmt.data.child_expressions[1].con.value:
# Create a new IRConst
irconst = pyvex.IRExpr.Const() # XXX: THIS IS BROKEN FIX THIS VERY SOON
irconst.con = dst
irconst.is_atomic = True
irconst.result_type = dst.type
irconst.tag = 'Iex_Const'
block.statements = block.statements[ : exit_stmt_idx] + block.statements[exit_stmt_idx + 1 : ]
# Replace the default exit!
temps = set()
regs = set()
# Retrieve the target: are we slicing from a register(IRStmt.Put), or a temp(IRStmt.WrTmp)?
try:
stmts = self._get_irsb(self._dst_run).statements
except SimTranslationError:
return
if self._dst_stmt_idx != -1:
dst_stmt = stmts[self._dst_stmt_idx]
if type(dst_stmt) is pyvex.IRStmt.Put:
regs.add(dst_stmt.offset)
elif type(dst_stmt) is pyvex.IRStmt.WrTmp:
temps.add(dst_stmt.tmp)
else:
raise AngrBladeError('Incorrect type of the specified target statement. We only support Put and WrTmp.')
prev = (self._get_addr(self._dst_run), self._dst_stmt_idx)
else:
next_expr = self._get_irsb(self._dst_run).next
if type(next_expr) is pyvex.IRExpr.RdTmp:
temps.add(next_expr.tmp)
elif type(next_expr) is pyvex.IRExpr.Const:
# A const doesn't rely on anything else!
pass
else:
raise AngrBladeError('Unsupported type for irsb.next: %s' % type(next_expr))
# make sure opt_level is 0
irsb = self.project.factory.block(addr=irsb_addr, max_size=irsb.size, opt_level=0).vex
# second pass. get all instruction addresses
instr_addrs = [ (i.addr + i.delta) for i in irsb.statements if isinstance(i, pyvex.IRStmt.IMark) ]
# third pass. for each statement, collect all constants that are referenced or used.
instr_addr = None
next_instr_addr = None
for stmt_idx, stmt in enumerate(irsb.statements):
if type(stmt) is pyvex.IRStmt.IMark: # pylint: disable=unidiomatic-typecheck
instr_addr = instr_addrs[0]
instr_addrs = instr_addrs[1 : ]
next_instr_addr = instr_addrs[0] if instr_addrs else None
elif type(stmt) is pyvex.IRStmt.WrTmp: # pylint: disable=unidiomatic-typecheck
if type(stmt.data) is pyvex.IRExpr.Load: # pylint: disable=unidiomatic-typecheck
# load
# e.g. t7 = LDle:I64(0x0000000000600ff8)
_process(irsb, stmt, stmt_idx, stmt.data.addr, instr_addr, next_instr_addr)
elif type(stmt.data) in (pyvex.IRExpr.Binop, ): # pylint: disable=unidiomatic-typecheck
# binary operation
for arg in stmt.data.args:
_process(irsb, stmt, stmt_idx, arg, instr_addr, next_instr_addr)
elif type(stmt.data) is pyvex.IRExpr.Const: # pylint: disable=unidiomatic-typecheck
_process(irsb, stmt, stmt_idx, stmt.data, instr_addr, next_instr_addr)
elif type(stmt) is pyvex.IRStmt.Put: # pylint: disable=unidiomatic-typecheck
# put
# e.g. PUT(rdi) = 0x0000000000400714
if 'lr_saved_on_stack' not in function.info or not function.info['lr_saved_on_stack']:
return
sp_offset = self.project.arch.sp_offset
initial_sp = 0x7fff0000
last_sp = None
tmps = {}
last_imark = next((stmt for stmt in reversed(irsb.statements)
if isinstance(stmt, pyvex.IRStmt.IMark)
), 0
)
tmp_irsb = self.project.factory.block(last_imark.addr + last_imark.delta).vex
# pylint:disable=too-many-nested-blocks
for stmt in tmp_irsb.statements:
if isinstance(stmt, pyvex.IRStmt.WrTmp):
data = stmt.data
if isinstance(data, pyvex.IRExpr.Get) and data.offset == sp_offset:
# t0 = GET:I32(sp)
tmps[stmt.tmp] = initial_sp
elif isinstance(data, pyvex.IRExpr.Binop):
# only support Add
if data.op == 'Iop_Add32':
arg0, arg1 = data.args
if isinstance(arg0, pyvex.IRExpr.RdTmp) and isinstance(arg1, pyvex.IRExpr.Const):
if arg0.tmp in tmps:
tmps[stmt.tmp] = tmps[arg0.tmp] + arg1.con.value
elif isinstance(data, pyvex.IRExpr.Load):
if isinstance(data.addr, pyvex.IRExpr.RdTmp):
if data.addr.tmp in tmps:
tmps[stmt.tmp] = ('load', tmps[data.addr.tmp])
elif isinstance(stmt, pyvex.IRStmt.Put):
:return:
'''
temps = set()
src_stmt_ids = set()
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