angr.engines.vex.heavy.resilience 源代码

from __future__ import annotations
import pyvex

from angr import sim_options as o

from .concretizers import concretizers
from angr.engines.vex.light.resilience import VEXResilienceMixin, raiseme
from angr.engines.vex.claripy.datalayer import ClaripyDataMixin, symbol, value


[文档] class HeavyResilienceMixin(VEXResilienceMixin, ClaripyDataMixin): @staticmethod def __make_default(ty, symbolic, name): if symbolic: return symbol(ty, name) return value(ty, 0) def _check_unsupported_ccall(self, func_name, retty, args, **kwargs): if o.BYPASS_UNSUPPORTED_IRCCALL not in self.state.options: return super()._check_unsupported_ccall(func_name, retty, args, **kwargs) self.state.history.add_event( "resilience", resilience_type="ccall", callee=func_name, message="unsupported ccall" ) return self.__make_default( retty, o.UNSUPPORTED_BYPASS_ZERO_DEFAULT not in self.state.options, "unsupported_" + func_name ) def _check_errored_ccall(self, func_name, ty, args, **kwargs): if o.BYPASS_ERRORED_IRCCALL not in self.state.options: return super()._check_errored_ccall(func_name, ty, args, **kwargs) self.state.history.add_event( "resilience", resilience_type="ccall", callee=func_name, message="ccall raised SimCCallError" ) return self.__make_default(ty, True, "errored_" + func_name) def _check_unsupported_dirty(self, func_name, ty, args, **kwargs): if o.BYPASS_UNSUPPORTED_IRDIRTY not in self.state.options: return super()._check_unsupported_dirty(func_name, ty, args, **kwargs) if ty is None: return None return self.__make_default( ty, o.UNSUPPORTED_BYPASS_ZERO_DEFAULT not in self.state.options, "unsupported_" + func_name ) def _check_unsupported_op(self, op, args): ty = pyvex.get_op_retty(op) if o.BYPASS_UNSUPPORTED_IROP not in self.state.options: return super()._check_unsupported_op(op, args) self.state.history.add_event("resilience", resilience_type="irop", op=op, message="unsupported IROp") if o.UNSUPPORTED_FORCE_CONCRETIZE in self.state.options: try: concretizer = concretizers[op] return concretizer(self.state, args) except KeyError: pass return self.__make_default(ty, o.UNSUPPORTED_BYPASS_ZERO_DEFAULT not in self.state.options, "unsupported_" + op) def _check_errored_op(self, op, args): ty = pyvex.get_op_retty(op) if o.BYPASS_ERRORED_IROP not in self.state.options: return super()._check_errored_op(op, args) self.state.history.add_event("resilience", resilience_type="irop", op=op, message="unsupported IROp") return self.__make_default(ty, True, "errored_" + op) def _check_zero_division(self, op, args): if getattr(self.state, "mode", None) == "static" and len(args) == 2 and (args[1] == 0).is_true(): # Monkeypatch the dividend to another value instead of 0 args = list(args) ty = pyvex.expr.op_arg_types(op)[1][1] args[1] = value(ty, 1) return self._perform_vex_expr_Op(op, args) res = super()._check_zero_division(op, args) if res is not raiseme: return res return self._check_errored_op(op, args) def _check_errored_stmt(self, stmt): if o.BYPASS_ERRORED_IRSTMT not in self.state.options: return super()._check_errored_stmt(stmt) self.state.history.add_event( "resilience", resilience_type="irstmt", stmt=type(stmt).__name__, message="errored IRStmt" ) return None