Source code for angr.engines.syscall
import angr
import logging
l = logging.getLogger(name=__name__)
from .engine import SuccessorsMixin
from .procedure import ProcedureMixin
# pylint:disable=abstract-method,arguments-differ
[docs]class SimEngineSyscall(SuccessorsMixin, ProcedureMixin):
"""
A SimEngine mixin which adds a successors handling step that checks if a syscall was just requested and if so
handles it as a step.
"""
[docs] def process_successors(self, successors, **kwargs):
state = self.state
# we have at this point entered the next step so we need to check the previous jumpkind
if (
not state.history
or not state.history.parent
or not state.history.parent.jumpkind
or not state.history.parent.jumpkind.startswith("Ijk_Sys")
):
return super().process_successors(successors, **kwargs)
l.debug("Invoking system call handler")
sys_procedure = self.project.simos.syscall(state)
if sys_procedure is None:
if angr.sim_options.BYPASS_UNSUPPORTED_SYSCALL not in state.options:
raise AngrUnsupportedSyscallError(
"Trying to perform a syscall on an emulated system which is not currently cofigured to support "
"syscalls. To resolve this, make sure that your SimOS is a subclass of SimUserspace, or set the "
"BYPASS_UNSUPPORTED_SYSCALL state option."
)
else:
try:
cc = angr.SYSCALL_CC[state.arch.name][state.os_name](state.arch)
except KeyError:
try:
l.warning("No syscall calling convention available for %s/%s", state.arch.name, state.os_name)
cc = angr.SYSCALL_CC[state.arch.name]["default"](state.arch)
except KeyError:
cc = None # some default will get picked down the line...
sys_procedure = angr.SIM_PROCEDURES["stubs"]["syscall"](cc=cc)
return self.process_procedure(state, successors, sys_procedure, **kwargs)
from ..errors import AngrUnsupportedSyscallError