angr.sim_procedure

class angr.sim_procedure.SimProcedure

Bases: object

A SimProcedure is a wonderful object which describes a procedure to run on a state.

You may subclass SimProcedure and override run(), replacing it with mutating self.state however you like, and then either returning a value or jumping away somehow.

A detailed discussion of programming SimProcedures may be found at https://docs.angr.io/extending-angr/simprocedures

Parameters:
  • arch – The architecture to use for this procedure

  • symbolic_return – Whether the procedure’s return value should be stubbed into a single symbolic variable constratined to the real return value

  • returns – Whether the procedure should return to its caller afterwards

  • is_syscall – Whether this procedure is a syscall

  • num_args – The number of arguments this procedure should extract

  • display_name – The name to use when displaying this procedure

  • library_name – The name of the library from which the function we’re emulating comes

  • cc (SimCC | None) – The SimCC to use for this procedure

  • sim_kwargs – Additional keyword arguments to be passed to run()

  • is_function – Whether this procedure emulates a function

The following class variables should be set if necessary when implementing a new SimProcedure:

Variables:
  • NO_RET – Set this to true if control flow will never return from this function

  • DYNAMIC_RET – Set this to true if whether the control flow returns from this function or not depends on the context (e.g., libc’s error() call). Must implement dynamic_returns() method.

  • ADDS_EXITS – Set this to true if you do any control flow other than returning

  • IS_FUNCTION – Does this procedure simulate a function? True by default

  • ARGS_MISMATCH – Does this procedure have a different list of arguments than what is provided in the function specification? This may happen when we manually extract arguments in the run() method of a SimProcedure. False by default.

  • local_vars – If you use self.call(), set this to a list of all the local variable names in your class. They will be restored on return.

The following instance variables are available when working with simprocedures from the inside or the outside:

Variables:
  • project – The associated angr project

  • arch – The associated architecture

  • addr – The linear address at which the procedure is executing

  • cc – The calling convention in use for engaging with the ABI

  • canonical – The canonical version of this SimProcedure. Procedures are deepcopied for many reasons, including to be able to store state related to a specific run and to be able to hook continuations.

  • kwargs – Any extra keyword arguments used to construct the procedure; will be passed to run

  • display_name – See the eponymous parameter

  • library_name – See the eponymous parameter

  • abi – If this is a syscall simprocedure, which ABI are we using to map the syscall numbers?

  • symbolic_return – See the eponymous parameter

  • syscall_number – If this procedure is a syscall, the number will be populated here.

  • returns – See eponymous parameter and NO_RET cvar

  • is_syscall – See eponymous parameter

  • is_function – See eponymous parameter and cvar

  • is_stub – See eponymous parameter

  • is_continuation – Whether this procedure is the original or a continuation resulting from self.call()

  • continuations – A mapping from name to each known continuation

  • run_func – The name of the function implementing the procedure. “run” by default, but different in continuations.

  • num_args – The number of arguments to the procedure. If not provided in the parameter, extracted from the definition of self.run

The following instance variables are only used in a copy of the procedure that is actually executing on a state:

Variables:
  • state – The SimState we should be mutating to perform the procedure

  • successors – The SimSuccessors associated with the current step

  • arguments – The function arguments, deserialized from the state

  • arg_session (None | ArgSession | int) – The ArgSession that was used to parse arguments out of the state, in case you need it for varargs

  • use_state_arguments – Whether we’re using arguments extracted from the state or manually provided

  • ret_to – The current return address

  • ret_expr – The computed return value

  • call_ret_expr – The return value from having used self.call()

  • inhibit_autoret – Whether we should avoid automatically adding an exit for returning once the run function ends

  • arg_session – The ArgSession object that was used to extract the runtime argument values. Useful for if you want to extract variadic args.

__init__(project=None, cc=None, prototype=None, symbolic_return=None, returns=None, is_syscall=False, is_stub=False, num_args=None, display_name=None, library_name=None, is_function=None, **kwargs)
Parameters:
state: SimState
arg_session: None | ArgSession | int
execute(state, successors=None, arguments=None, ret_to=None)

Call this method with a SimState and a SimSuccessors to execute the procedure.

Alternately, successors may be none if this is an inline call. In that case, you should provide arguments to the function.

make_continuation(name)
NO_RET = False
DYNAMIC_RET = False
ADDS_EXITS = False
IS_FUNCTION = True
ARGS_MISMATCH = False
ALT_NAMES = None
local_vars: tuple[str, ...] = ()
run(*args, **kwargs)

Implement the actual procedure here!

Return type:

Any

static_exits(blocks, **kwargs)

Get new exits by performing static analysis and heuristics. This is a fast and best-effort approach to get new exits for scenarios where states are not available (e.g. when building a fast CFG).

Parameters:

blocks (list) – Blocks that are executed before reaching this SimProcedure.

Returns:

A list of dicts. Each dict should contain the following entries: ‘address’, ‘jumpkind’, and ‘namehint’.

Return type:

list

dynamic_returns(blocks, **kwargs)

Determines if a call to this function returns or not by performing static analysis and heuristics.

Parameters:

blocks – Blocks that are executed before reaching this SimProcedure.

Return type:

bool

Returns:

True if the call returns, False otherwise.

property should_add_successors
set_args(args)
va_arg(ty, index=None)
inline_call(procedure, *arguments, **kwargs)

Call another SimProcedure in-line to retrieve its return value. Returns an instance of the procedure with the ret_expr property set.

Parameters:
  • procedure – The class of the procedure to execute

  • arguments – Any additional positional args will be used as arguments to the procedure call

  • sim_kwargs – Any additional keyword args will be passed as sim_kwargs to the procedure constructor

fix_prototype_returnty(ret_size)
ret(expr=None)

Add an exit representing a return from this function. If this is not an inline call, grab a return address from the state and jump to it. If this is not an inline call, set a return expression with the calling convention.

call(addr, args, continue_at, cc=None, prototype=None, jumpkind='Ijk_Call')

Add an exit representing calling another function via pointer.

Parameters:
  • addr – The address of the function to call

  • args – The list of arguments to call the function with

  • continue_at – Later, when the called function returns, execution of the current procedure will continue in the named method.

  • cc – Optional: use this calling convention for calling the new function. Default is to use the current convention.

  • prototype – Optional: The prototype to use for the call. Will default to all-ints.

jump(addr, jumpkind='Ijk_Boring')

Add an exit representing jumping to an address.

exit(exit_code)

Add an exit representing terminating the program.

property is_java
property argument_types
property return_type