API Reference

class angr.BP(when='before', enabled=None, condition=None, action=None, **kwargs)

Bases: object

A breakpoint.

__init__(when='before', enabled=None, condition=None, action=None, **kwargs)
check(state, when)

Checks state state to see if the breakpoint should fire.

Parameters:
  • state – The state.

  • when – Whether the check is happening before or after the event.

Returns:

A boolean representing whether the checkpoint should fire.

fire(state)

Trigger the breakpoint.

Parameters:

state – The state.

class angr.Analysis

Bases: object

This class represents an analysis on the program.

Variables:
  • project – The project for this analysis.

  • kb (KnowledgeBase) – The knowledgebase object.

  • _progress_callback – A callback function for receiving the progress of this analysis. It only takes one argument, which is a float number from 0.0 to 100.0 indicating the current progress.

  • _show_progressbar (bool) – If a progressbar should be shown during the analysis. It’s independent from _progress_callback.

  • _progressbar (progress.Progress) – The progress bar object.

project: Project
kb: KnowledgeBase
errors: list[AnalysisLogEntry] = []
named_errors: defaultdict[str, list[AnalysisLogEntry]] = {}
exception angr.AngrAnalysisError

Bases: AngrError

exception angr.AngrAnnotatedCFGError

Bases: AngrError

exception angr.AngrAssemblyError

Bases: AngrError

exception angr.AngrBackwardSlicingError

Bases: AngrError

exception angr.AngrBladeError

Bases: AngrError

exception angr.AngrBladeSimProcError

Bases: AngrBladeError

exception angr.AngrCFGError

Bases: AngrError

exception angr.AngrCallableError

Bases: AngrSurveyorError

exception angr.AngrCallableMultistateError

Bases: AngrCallableError

exception angr.AngrCorruptDBError

Bases: AngrDBError

exception angr.AngrDBError

Bases: AngrError

exception angr.AngrDDGError

Bases: AngrAnalysisError

exception angr.AngrDataGraphError

Bases: AngrAnalysisError

exception angr.AngrDecompilationError

Bases: AngrError

exception angr.AngrDelayJobNotice

Bases: AngrForwardAnalysisError

exception angr.AngrDirectorError

Bases: AngrExplorationTechniqueError

exception angr.AngrError

Bases: Exception

exception angr.AngrExitError

Bases: AngrError

exception angr.AngrExplorationTechniqueError

Bases: AngrError

exception angr.AngrExplorerError

Bases: AngrExplorationTechniqueError

exception angr.AngrForwardAnalysisError

Bases: AngrError

exception angr.AngrIncompatibleDBError

Bases: AngrDBError

exception angr.AngrIncongruencyError

Bases: AngrAnalysisError

exception angr.AngrInvalidArgumentError

Bases: AngrError

exception angr.AngrJobMergingFailureNotice

Bases: AngrForwardAnalysisError

exception angr.AngrJobWideningFailureNotice

Bases: AngrForwardAnalysisError

exception angr.AngrLifterError

Bases: AngrError

exception angr.AngrLoopAnalysisError

Bases: AngrAnalysisError

exception angr.AngrMissingTypeError

Bases: AngrTypeError

exception angr.AngrNoPluginError

Bases: AngrError

exception angr.AngrPathError

Bases: AngrError

exception angr.AngrRuntimeError

Bases: RuntimeError

exception angr.AngrSimOSError

Bases: AngrError

exception angr.AngrSkipJobNotice

Bases: AngrForwardAnalysisError

exception angr.AngrSurveyorError

Bases: AngrError

exception angr.AngrSyscallError

Bases: AngrError

exception angr.AngrTracerError

Bases: AngrExplorationTechniqueError

exception angr.AngrTypeError

Bases: AngrError, TypeError

exception angr.AngrUnsupportedSyscallError

Bases: AngrSyscallError, SimProcedureError, SimUnsupportedError

exception angr.AngrVFGError

Bases: AngrError

exception angr.AngrVFGRestartAnalysisNotice

Bases: AngrVFGError

exception angr.AngrValueError

Bases: AngrError, ValueError

exception angr.AngrVaultError

Bases: AngrError

class angr.Blade(graph, dst_run, dst_stmt_idx, direction='backward', project=None, cfg=None, ignore_sp=False, ignore_bp=False, ignored_regs=None, max_level=3, base_state=None, stop_at_calls=False, cross_insn_opt=False, max_predecessors=10, include_imarks=True)

Bases: object

Blade is a light-weight program slicer that works with networkx DiGraph containing CFGNodes. It is meant to be used in angr for small or on-the-fly analyses.

Parameters:
  • graph (networkx.DiGraph)

  • dst_run (int)

  • dst_stmt_idx (int)

  • direction (str)

  • ignore_sp (bool)

  • ignore_bp (bool)

  • max_level (int)

  • stop_at_calls (bool)

  • max_predecessors (int)

  • include_imarks (bool)

__init__(graph, dst_run, dst_stmt_idx, direction='backward', project=None, cfg=None, ignore_sp=False, ignore_bp=False, ignored_regs=None, max_level=3, base_state=None, stop_at_calls=False, cross_insn_opt=False, max_predecessors=10, include_imarks=True)
Parameters:
  • graph (DiGraph) – A graph representing the control flow graph. Note that it does not take angr.analyses.CFGEmulated or angr.analyses.CFGFast.

  • dst_run (int) – An address specifying the target SimRun.

  • dst_stmt_idx (int) – The target statement index. -1 means executing until the last statement.

  • direction (str) – ‘backward’ or ‘forward’ slicing. Forward slicing is not yet supported.

  • project (angr.Project) – The project instance.

  • cfg (angr.analyses.CFGBase) – the CFG instance. It will be made mandatory later.

  • ignore_sp (bool) – Whether the stack pointer should be ignored in dependency tracking. Any dependency from/to stack pointers will be ignored if this options is True.

  • ignore_bp (bool) – Whether the base pointer should be ignored or not.

  • max_level (int) – The maximum number of blocks that we trace back for.

  • stop_at_calls (bool) – Limit slicing within a single function. Do not proceed when encounters a call edge.

  • include_imarks (bool) – Should IMarks (instruction boundaries) be included in the slice.

  • max_predecessors (int)

Returns:

None

property slice
dbg_repr(arch=None)
class angr.Block(addr, project=None, arch=None, size=None, max_size=None, byte_string=None, thumb=False, backup_state=None, extra_stop_points=None, opt_level=None, num_inst=None, traceflags=0, strict_block_end=None, collect_data_refs=False, cross_insn_opt=True, load_from_ro_regions=False, const_prop=False, initial_regs=None, skip_stmts=False)

Bases: Serializable

Represents a basic block in a binary or a program.

Parameters:

arch (Arch | None)

BLOCK_MAX_SIZE = 4096
__init__(addr, project=None, arch=None, size=None, max_size=None, byte_string=None, thumb=False, backup_state=None, extra_stop_points=None, opt_level=None, num_inst=None, traceflags=0, strict_block_end=None, collect_data_refs=False, cross_insn_opt=True, load_from_ro_regions=False, const_prop=False, initial_regs=None, skip_stmts=False)
Parameters:

arch (Arch | None)

arch
addr
thumb
size
pp(**kwargs)
set_initial_regs()
static reset_initial_regs()
property vex: IRSB | IRSB
property vex_nostmt
property disassembly: DisassemblerBlock

Provide a disassembly object using whatever disassembler is available

property capstone: CapstoneBlock
property codenode
property bytes: bytes | None
property instructions: int
property instruction_addrs
serialize_to_cmessage()

Serialize the class object and returns a protobuf cmessage object.

Returns:

A protobuf cmessage object.

Return type:

protobuf.cmessage

classmethod parse_from_cmessage(cmsg)

Parse a protobuf cmessage and create a class object.

Parameters:

cmsg – The probobuf cmessage object.

Returns:

A unserialized class object.

Return type:

cls

class angr.ExplorationTechnique

Bases: object

An ExplorationTechnique is a set of hooks for a simulation manager that assists in the implementation of new techniques in symbolic exploration.

Any number of these methods may be overridden by a subclass. To use an exploration technique, call simgr.use_technique with an instance of the technique.

__init__()
setup(simgr)

Perform any initialization on this manager you might need to do.

Parameters:

simgr (angr.SimulationManager) – The simulation manager to which you have just been added

step(simgr, stash='active', **kwargs)

Hook the process of stepping a stash forward. Should call simgr.step(stash, **kwargs) in order to do the actual processing.

Parameters:
filter(simgr, state, **kwargs)

Perform filtering on which stash a state should be inserted into.

If the state should be filtered, return the name of the stash to move the state to. If you want to modify the state before filtering it, return a tuple of the stash to move the state to and the modified state. To defer to the original categorization procedure, return the result of simgr.filter(state, **kwargs)

If the user provided a filter_func in their step or run command, it will appear here.

Parameters:
selector(simgr, state, **kwargs)

Determine if a state should participate in the current round of stepping. Return True if the state should be stepped, and False if the state should not be stepped. To defer to the original selection procedure, return the result of simgr.selector(state, **kwargs).

If the user provided a selector_func in their step or run command, it will appear here.

Parameters:
step_state(simgr, state, **kwargs)

Determine the categorization of state successors into stashes. The result should be a dict mapping stash names to the list of successor states that fall into that stash, or None as a stash name to use the original stash name.

If you would like to directly work with a SimSuccessors object, you can obtain it with simgr.successors(state, **kwargs). This is not recommended, as it denies other hooks the opportunity to look at the successors. Therefore, the usual technique is to call simgr.step_state(state, **kwargs) and then mutate the returned dict before returning it yourself.

..note:: This takes precedence over the filter hook - filter is only applied to states returned from here in the None stash.

Parameters:
successors(simgr, state, **kwargs)

Perform the process of stepping a state forward, returning a SimSuccessors object.

To defer to the original succession procedure, return the result of simgr.successors(state, **kwargs). Be careful about not calling this method (e.g. calling project.factory.successors manually) as it denies other hooks the opportunity to instrument the step. Instead, you can mutate the kwargs for the step before calling the original, and mutate the result before returning it yourself.

If the user provided a successor_func in their step or run command, it will appear here.

Parameters:
complete(simgr)

Return whether or not this manager has reached a “completed” state, i.e. SimulationManager.run() should halt.

This is the one hook which is not subject to the nesting rules of hooks. You should not call simgr.complete, you should make your own decision and return True or False. Each of the techniques’ completion checkers will be called and the final result will be compted with simgr.completion_mode.

Parameters:

simgr (angr.SimulationManager)

class angr.KnowledgeBase(project, obj=None, name=None)

Bases: object

Represents a “model” of knowledge about an artifact.

Contains things like a CFG, data references, etc.

functions: FunctionManager
variables: VariableManager
defs: KeyDefinitionManager
cfgs: CFGManager
types: TypesStore
propagations: PropagationManager
xrefs: XRefManager
decompilations: StructuredCodeManager
__init__(project, obj=None, name=None)
property callgraph
property unresolved_indirect_jumps
property resolved_indirect_jumps
has_plugin(name)
get_plugin(name)
register_plugin(name, plugin)
release_plugin(name)
K = ~K
get_knowledge(requested_plugin_cls)

Type inference safe method to request a knowledge base plugin Explicitly passing the type of the requested plugin achieves two things: 1. Every location using this plugin can be easily found with an IDE by searching explicit references to the type 2. Basic type inference can deduce the result type and properly type check usages of it

If there isn’t already an instance of this class None will be returned to make it clear to the caller that there is no existing knowledge of this type yet. The code that initially creates this knowledge should use the register_plugin method to register the initial knowledge state :type requested_plugin_cls: type[K] :param requested_plugin_cls: :rtype: K | None :return: Instance of the requested plugin class or null if it is not a known plugin

Parameters:

requested_plugin_cls (type[K])

Return type:

K | None

request_knowledge(requested_plugin_cls)
Return type:

K

Parameters:

requested_plugin_cls (type[K])

class angr.PTChunk(base, sim_state, heap=None)

Bases: Chunk

A chunk, inspired by the implementation of chunks in ptmalloc. Provides a representation of a chunk via a view into the memory plugin. For the chunk definitions and docs that this was loosely based off of, see glibc malloc/malloc.c, line 1033, as of commit 5a580643111ef6081be7b4c7bd1997a5447c903f. Alternatively, take the following link. https://sourceware.org/git/?p=glibc.git;a=blob;f=malloc/malloc.c;h=67cdfd0ad2f003964cd0f7dfe3bcd85ca98528a7;hb=5a580643111ef6081be7b4c7bd1997a5447c903f#l1033

Variables:
  • base – the location of the base of the chunk in memory

  • state – the program state that the chunk is resident in

  • heap – the heap plugin that the chunk is managed by

__init__(base, sim_state, heap=None)
get_size()

Returns the actual size of a chunk (as opposed to the entire size field, which may include some flags).

get_data_size()

Returns the size of the data portion of a chunk.

set_size(size, is_free=None)

Use this to set the size on a chunk. When the chunk is new (such as when a free chunk is shrunk to form an allocated chunk and a remainder free chunk) it is recommended that the is_free hint be used since setting the size depends on the chunk’s freeness, and vice versa.

Parameters:
  • size – size of the chunk

  • is_free – boolean indicating the chunk’s freeness

set_prev_freeness(is_free)

Sets (or unsets) the flag controlling whether the previous chunk is free.

Parameters:

is_free – if True, sets the previous chunk to be free; if False, sets it to be allocated

is_prev_free()

Returns a concrete state of the flag indicating whether the previous chunk is free or not. Issues a warning if that flag is symbolic and has multiple solutions, and then assumes that the previous chunk is free.

Returns:

True if the previous chunk is free; False otherwise

prev_size()

Returns the size of the previous chunk, masking off what would be the flag bits if it were in the actual size field. Performs NO CHECKING to determine whether the previous chunk size is valid (for example, when the previous chunk is not free, its size cannot be determined).

is_free()

Returns a concrete determination as to whether the chunk is free.

data_ptr()

Returns the address of the payload of the chunk.

next_chunk()

Returns the chunk immediately following (and adjacent to) this one, if it exists.

Returns:

The following chunk, or None if applicable

prev_chunk()

Returns the chunk immediately prior (and adjacent) to this one, if that chunk is free. If the prior chunk is not free, then its base cannot be located and this method raises an error.

Returns:

If possible, the previous chunk; otherwise, raises an error

fwd_chunk()

Returns the chunk following this chunk in the list of free chunks. If this chunk is not free, then it resides in no such list and this method raises an error.

Returns:

If possible, the forward chunk; otherwise, raises an error

set_fwd_chunk(fwd)

Sets the chunk following this chunk in the list of free chunks.

Parameters:

fwd – the chunk to follow this chunk in the list of free chunks

bck_chunk()

Returns the chunk backward from this chunk in the list of free chunks. If this chunk is not free, then it resides in no such list and this method raises an error.

Returns:

If possible, the backward chunk; otherwise, raises an error

set_bck_chunk(bck)

Sets the chunk backward from this chunk in the list of free chunks.

Parameters:

bck – the chunk to precede this chunk in the list of free chunks

exception angr.PathUnreachableError

Bases: AngrPathError

class angr.PointerWrapper(value, buffer=False)

Bases: object

__init__(value, buffer=False)
class angr.Project(thing, default_analysis_mode=None, ignore_functions=None, use_sim_procedures=True, exclude_sim_procedures_func=None, exclude_sim_procedures_list=(), arch=None, simos=None, engine=None, load_options=None, translation_cache=True, selfmodifying_code=False, support_selfmodifying_code=None, store_function=None, load_function=None, analyses_preset=None, concrete_target=None, eager_ifunc_resolution=None, **kwargs)

Bases: object

This is the main class of the angr module. It is meant to contain a set of binaries and the relationships between them, and perform analyses on them.

Parameters:
  • thing – The path to the main executable object to analyze, or a CLE Loader object.

  • arch (Arch)

  • load_options (dict[str, Any] | None)

  • selfmodifying_code (bool)

  • support_selfmodifying_code (bool | None)

The following parameters are optional.

Parameters:
  • default_analysis_mode – The mode of analysis to use by default. Defaults to ‘symbolic’.

  • ignore_functions – A list of function names that, when imported from shared libraries, should never be stepped into in analysis (calls will return an unconstrained value).

  • use_sim_procedures – Whether to replace resolved dependencies for which simprocedures are available with said simprocedures.

  • exclude_sim_procedures_func – A function that, when passed a function name, returns whether or not to wrap it with a simprocedure.

  • exclude_sim_procedures_list – A list of functions to not wrap with simprocedures.

  • arch – The target architecture (auto-detected otherwise).

  • simos – a SimOS class to use for this project.

  • engine – The SimEngine class to use for this project.

  • translation_cache (bool) – If True, cache translated basic blocks rather than re-translating them.

  • selfmodifying_code (bool) – Whether we aggressively support self-modifying code. When enabled, emulation will try to read code from the current state instead of the original memory, regardless of the current memory protections.

  • store_function – A function that defines how the Project should be stored. Default to pickling.

  • load_function – A function that defines how the Project should be loaded. Default to unpickling.

  • analyses_preset (angr.misc.PluginPreset) – The plugin preset for the analyses provider (i.e. Analyses instance).

  • load_options (dict[str, Any] | None)

  • support_selfmodifying_code (bool | None)

Any additional keyword arguments passed will be passed onto cle.Loader.

Variables:
  • analyses – The available analyses.

  • entry – The program entrypoint.

  • factory – Provides access to important analysis elements such as path groups and symbolic execution results.

  • filename – The filename of the executable.

  • loader – The program loader.

  • storage – Dictionary of things that should be loaded/stored with the Project.

Parameters:
  • arch (Arch)

  • load_options (dict[str, Any] | None)

  • selfmodifying_code (bool)

  • support_selfmodifying_code (bool | None)

__init__(thing, default_analysis_mode=None, ignore_functions=None, use_sim_procedures=True, exclude_sim_procedures_func=None, exclude_sim_procedures_list=(), arch=None, simos=None, engine=None, load_options=None, translation_cache=True, selfmodifying_code=False, support_selfmodifying_code=None, store_function=None, load_function=None, analyses_preset=None, concrete_target=None, eager_ifunc_resolution=None, **kwargs)
Parameters:
  • load_options (dict[str, Any] | None)

  • selfmodifying_code (bool)

  • support_selfmodifying_code (bool | None)

arch: Arch
property kb
get_kb(name)
property analyses: AnalysesHubWithDefault
hook(addr, hook=None, length=0, kwargs=None, replace=False)

Hook a section of code with a custom function. This is used internally to provide symbolic summaries of library functions, and can be used to instrument execution or to modify control flow.

When hook is not specified, it returns a function decorator that allows easy hooking. Usage:

# Assuming proj is an instance of angr.Project, we will add a custom hook at the entry
# point of the project.
@proj.hook(proj.entry)
def my_hook(state):
    print("Welcome to execution!")
Parameters:
  • addr – The address to hook.

  • hook – A angr.project.Hook describing a procedure to run at the given address. You may also pass in a SimProcedure class or a function directly and it will be wrapped in a Hook object for you.

  • length – If you provide a function for the hook, this is the number of bytes that will be skipped by executing the hook by default.

  • kwargs – If you provide a SimProcedure for the hook, these are the keyword arguments that will be passed to the procedure’s run method eventually.

  • replace (bool | None) – Control the behavior on finding that the address is already hooked. If true, silently replace the hook. If false (default), warn and do not replace the hook. If none, warn and replace the hook.

is_hooked(addr)

Returns True if addr is hooked.

Parameters:

addr – An address.

Return type:

bool

Returns:

True if addr is hooked, False otherwise.

hooked_by(addr)

Returns the current hook for addr.

Parameters:

addr – An address.

Return type:

SimProcedure | None

Returns:

None if the address is not hooked.

unhook(addr)

Remove a hook.

Parameters:

addr – The address of the hook.

hook_symbol(symbol_name, simproc, kwargs=None, replace=None)

Resolve a dependency in a binary. Looks up the address of the given symbol, and then hooks that address. If the symbol was not available in the loaded libraries, this address may be provided by the CLE externs object.

Additionally, if instead of a symbol name you provide an address, some secret functionality will kick in and you will probably just hook that address, UNLESS you’re on powerpc64 ABIv1 or some yet-unknown scary ABI that has its function pointers point to something other than the actual functions, in which case it’ll do the right thing.

Parameters:
  • symbol_name – The name of the dependency to resolve.

  • simproc – The SimProcedure instance (or function) with which to hook the symbol

  • kwargs – If you provide a SimProcedure for the hook, these are the keyword arguments that will be passed to the procedure’s run method eventually.

  • replace (Optional[bool]) – Control the behavior on finding that the address is already hooked. If true, silently replace the hook. If false, warn and do not replace the hook. If none (default), warn and replace the hook.

Returns:

The address of the new symbol.

Return type:

int

symbol_hooked_by(symbol_name)

Return the SimProcedure, if it exists, for the given symbol name.

Parameters:

symbol_name (str) – Name of the symbol.

Return type:

SimProcedure | None

Returns:

None if the address is not hooked.

is_symbol_hooked(symbol_name)

Check if a symbol is already hooked.

Parameters:

symbol_name (str) – Name of the symbol.

Returns:

True if the symbol can be resolved and is hooked, False otherwise.

Return type:

bool

unhook_symbol(symbol_name)

Remove the hook on a symbol. This function will fail if the symbol is provided by the extern object, as that would result in a state where analysis would be unable to cope with a call to this symbol.

rehook_symbol(new_address, symbol_name, stubs_on_sync)

Move the hook for a symbol to a specific address :type new_address: :param new_address: the new address that will trigger the SimProc execution :type symbol_name: :param symbol_name: the name of the symbol (f.i. strcmp ) :return: None

execute(*args, **kwargs)

This function is a symbolic execution helper in the simple style supported by triton and manticore. It designed to be run after setting up hooks (see Project.hook), in which the symbolic state can be checked.

This function can be run in three different ways:

  • When run with no parameters, this function begins symbolic execution from the entrypoint.

  • It can also be run with a “state” parameter specifying a SimState to begin symbolic execution from.

  • Finally, it can accept any arbitrary keyword arguments, which are all passed to project.factory.full_init_state.

If symbolic execution finishes, this function returns the resulting simulation manager.

terminate_execution()

Terminates a symbolic execution that was started with Project.execute().

class angr.Server(project, spill_yard=None, db=None, max_workers=None, max_states=10, staging_max=10, bucketizer=True, recursion_limit=1000, worker_exit_callback=None, techniques=None, add_options=None, remove_options=None)

Bases: object

Server implements the analysis server with a series of control interfaces exposed.

Variables:
  • project – An instance of angr.Project.

  • spill_yard (str) – A directory to store spilled states.

  • db (str) – Path of the database that stores information about spilled states.

  • max_workers (int) – Maximum number of workers. Each worker starts a new process.

  • max_states (int) – Maximum number of active states for each worker.

  • staging_max (int) – Maximum number of inactive states that are kept into memory before spilled onto the disk and potentially be picked up by another worker.

  • bucketizer (bool) – Use the Bucketizer exploration strategy.

  • _worker_exit_callback – A method that will be called upon the exit of each worker.

__init__(project, spill_yard=None, db=None, max_workers=None, max_states=10, staging_max=10, bucketizer=True, recursion_limit=1000, worker_exit_callback=None, techniques=None, add_options=None, remove_options=None)
inc_active_workers()
dec_active_workers()
stop()
property active_workers
property stopped
on_worker_exit(worker_id, stashes)
run()
exception angr.SimAbstractMemoryError

Bases: SimMemoryError

exception angr.SimActionError

Bases: SimError

class angr.SimCC(arch)

Bases: object

A calling convention allows you to extract from a state the data passed from function to function by calls and returns. Most of the methods provided by SimCC that operate on a state assume that the program is just after a call but just before stack frame allocation, though this may be overridden with the stack_base parameter to each individual method.

This is the base class for all calling conventions.

Parameters:

arch (archinfo.Arch)

__init__(arch)
Parameters:

arch (Arch) – The Archinfo arch for this CC

ARG_REGS: list[str] = []
FP_ARG_REGS: list[str] = []
STACKARG_SP_BUFF = 0
STACKARG_SP_DIFF = 0
CALLER_SAVED_REGS: list[str] = []
RETURN_ADDR: SimFunctionArgument | None = None
RETURN_VAL: SimFunctionArgument | None = None
OVERFLOW_RETURN_VAL: SimFunctionArgument | None = None
FP_RETURN_VAL: SimFunctionArgument | None = None
ARCH: type[Arch] | None = None
EXTRA_ARCHES: tuple[type[Arch], ...] = ()
CALLEE_CLEANUP = False
STACK_ALIGNMENT = 1
property int_args

Iterate through all the possible arg positions that can only be used to store integer or pointer values.

Returns an iterator of SimFunctionArguments

property memory_args

Iterate through all the possible arg positions that can be used to store any kind of argument.

Returns an iterator of SimFunctionArguments

property fp_args

Iterate through all the possible arg positions that can only be used to store floating point values.

Returns an iterator of SimFunctionArguments

is_fp_arg(arg)

This should take a SimFunctionArgument instance and return whether or not that argument is a floating-point argument.

Returns True for MUST be a floating point arg,

False for MUST NOT be a floating point arg, None for when it can be either.

class ArgSession(cc)

Bases: object

A class to keep track of the state accumulated in laying parameters out into memory

both_iter
cc
fp_iter
int_iter
__init__(cc)
getstate()
setstate(state)
arg_session(ret_ty)

Return an arg session.

A session provides the control interface necessary to describe how integral and floating-point arguments are laid out into memory. The default behavior is that there are a finite list of int-only and fp-only argument slots, and an infinite number of generic slots, and when an argument of a given type is requested, the most slot available is used. If you need different behavior, subclass ArgSession.

You need to provide the return type of the function in order to kick off an arg layout session.

Parameters:

ret_ty (SimType | None)

return_in_implicit_outparam(ty)
stack_space(args)
Parameters:

args – A list of SimFunctionArguments

Returns:

The number of bytes that should be allocated on the stack to store all these args, NOT INCLUDING the return address.

return_val(ty, perspective_returned=False)

The location the return value is stored, based on its type.

property return_addr

The location the return address is stored.

next_arg(session, arg_type)
Parameters:
static is_fp_value(val)
static guess_prototype(args, prototype=None)

Come up with a plausible SimTypeFunction for the given args (as would be passed to e.g. setup_callsite).

You can pass a variadic function prototype in the base_type parameter and all its arguments will be used, only guessing types for the variadic arguments.

arg_locs(prototype)
Return type:

list[SimFunctionArgument]

get_args(state, prototype, stack_base=None)
set_return_val(state, val, ty, stack_base=None, perspective_returned=False)
setup_callsite(state, ret_addr, args, prototype, stack_base=None, alloc_base=None, grow_like_stack=True)

This function performs the actions of the caller getting ready to jump into a function.

Parameters:
  • state – The SimState to operate on

  • ret_addr – The address to return to when the called function finishes

  • args – The list of arguments that that the called function will see

  • prototype – The signature of the call you’re making. Should include variadic args concretely.

  • stack_base – An optional pointer to use as the top of the stack, circa the function entry point

  • alloc_base – An optional pointer to use as the place to put excess argument data

  • grow_like_stack – When allocating data at alloc_base, whether to allocate at decreasing addresses

The idea here is that you can provide almost any kind of python type in args and it’ll be translated to a binary format to be placed into simulated memory. Lists (representing arrays) must be entirely elements of the same type and size, while tuples (representing structs) can be elements of any type and size. If you’d like there to be a pointer to a given value, wrap the value in a PointerWrapper.

If stack_base is not provided, the current stack pointer will be used, and it will be updated. If alloc_base is not provided, the stack base will be used and grow_like_stack will implicitly be True.

grow_like_stack controls the behavior of allocating data at alloc_base. When data from args needs to be wrapped in a pointer, the pointer needs to point somewhere, so that data is dumped into memory at alloc_base. If you set alloc_base to point to somewhere other than the stack, set grow_like_stack to False so that sequential allocations happen at increasing addresses.

teardown_callsite(state, return_val=None, prototype=None, force_callee_cleanup=False)

This function performs the actions of the callee as it’s getting ready to return. It returns the address to return to.

Parameters:
  • state – The state to mutate

  • return_val – The value to return

  • prototype – The prototype of the given function

  • force_callee_cleanup – If we should clean up the stack allocation for the arguments even if it’s not the callee’s job to do so

TODO: support the stack_base parameter from setup_callsite…? Does that make sense in this context? Maybe it could make sense by saying that you pass it in as something like the “saved base pointer” value?

static find_cc(arch, args, sp_delta, platform='Linux')

Pinpoint the best-fit calling convention and return the corresponding SimCC instance, or None if no fit is found.

Parameters:
  • arch (Arch) – An ArchX instance. Can be obtained from archinfo.

  • args (list[SimRegArg | SimStackArg]) – A list of arguments. It may be updated by the first matched calling convention to remove non-argument arguments.

  • sp_delta (int) – The change of stack pointer before and after the call is made.

  • platform (str | None)

Return type:

SimCC | None

Returns:

A calling convention instance, or None if none of the SimCC subclasses seems to fit the arguments provided.

classmethod arches()
Return type:

tuple[type[Arch], ...]

get_arg_info(state, prototype)

This is just a simple wrapper that collects the information from various locations prototype is as passed to self.arg_locs and self.get_args :param angr.SimState state: The state to evaluate and extract the values from :return: A list of tuples, where the nth tuple is (type, name, location, value) of the nth argument

exception angr.SimCCError

Bases: SimError

exception angr.SimCCallError

Bases: SimExpressionError

exception angr.SimConcreteBreakpointError

Bases: AngrError

exception angr.SimConcreteMemoryError

Bases: AngrError

exception angr.SimConcreteRegisterError

Bases: AngrError

exception angr.SimEmptyCallStackError

Bases: SimError

exception angr.SimEngineError

Bases: SimError

exception angr.SimError

Bases: Exception

bbl_addr = None
stmt_idx = None
ins_addr = None
executed_instruction_count = None
guard = None
record_state(state)
exception angr.SimEventError

Bases: SimStateError

exception angr.SimException

Bases: SimError

exception angr.SimExpressionError

Bases: SimError

exception angr.SimFastMemoryError

Bases: SimMemoryError

exception angr.SimFastPathError

Bases: SimEngineError

class angr.SimFile(name=None, content=None, size=None, has_end=None, seekable=True, writable=True, ident=None, concrete=None, **kwargs)

Bases: SimFileBase, DefaultMemory

The normal SimFile is meant to model files on disk. It subclasses SimSymbolicMemory so loads and stores to/from it are very simple.

Parameters:
  • name – The name of the file

  • content – Optional initial content for the file as a string or bitvector

  • size – Optional size of the file. If content is not specified, it defaults to zero

  • has_end – Whether the size boundary is treated as the end of the file or a frontier at which new content will be generated. If unspecified, will pick its value based on options.FILES_HAVE_EOF. Another caveat is that if the size is also unspecified this value will default to False.

  • seekable – Optional bool indicating whether seek operations on this file should succeed, default True.

  • writable – Whether writing to this file is allowed

  • concrete – Whether or not this file contains mostly concrete data. Will be used by some SimProcedures to choose how to handle variable-length operations like fgets.

Variables:

has_end – Whether this file has an EOF

__init__(name=None, content=None, size=None, has_end=None, seekable=True, writable=True, ident=None, concrete=None, **kwargs)
property category

reg, mem, or file.

Type:

Return the category of this SimMemory instance. It can be one of the three following categories

set_state(state)

Sets a new state (for example, if the state has been branched)

property size

The number of data bytes stored by the file at present. May be a symbolic value.

concretize(**kwargs)

Return a concretization of the contents of the file, as a flat bytestring.

read(pos, size, **kwargs)

Read some data from the file.

Parameters:
  • pos – The offset in the file to read from.

  • size – The size to read. May be symbolic.

Returns:

A tuple of the data read (a bitvector of the length that is the maximum length of the read), the actual size of the read, and the new file position pointer.

write(pos, data, size=None, events=True, **kwargs)

Write some data to the file.

Parameters:
  • pos – The offset in the file to write to. May be ignored if the file is a stream or device.

  • data – The data to write as a bitvector

  • size – The optional size of the data to write. If not provided will default to the length of the data. Must be constrained to less than or equal to the size of the data.

Returns:

The new file position pointer.

copy(memo: dict[int, Any] | None = None, **kwargs: Any) S_co

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:
  • memo (Optional[dict[int, Any]]) – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

  • kwargs (Any)

Return type:

TypeVar(S_co, covariant=True)

merge(others, merge_conditions, common_ancestor=None)

Should merge the state plugin with the provided others. This will be called by state.merge() after copying the target state, so this should mutate the current instance to merge with the others.

Note that when multiple instances of a single plugin object (for example, a file) are referenced in the state, it is important that merge only ever be called once. This should be solved by designating one of the plugin’s referees as the “real owner”, who should be the one to actually merge it. This technique doesn’t work to resolve the similar issue that arises during copying because merging doesn’t produce a new reference to insert.

There will be n others and n+1 merge conditions, since the first condition corresponds to self. To match elements up to conditions, say zip([self] + others, merge_conditions)

When implementing this, make sure that you “deepen” both others and common_ancestor before calling sub-elements’ merge methods, e.g.

self.foo.merge(
    [o.foo for o in others],
    merge_conditions,
    common_ancestor=common_ancestor.foo if common_ancestor is not None else None
)

During static analysis, merge_conditions can be None, in which case you should use state.solver.union(values). TODO: fish please make this less bullshit

There is a utility claripy.ite_cases which will help with constructing arbitrarily large merged ASTs. Use it like self.bar = claripy.ite_cases(zip(conditions[1:], [o.bar for o in others]), self.bar)

Parameters:
  • others – the other state plugins to merge with

  • merge_conditions – a symbolic condition for each of the plugins

  • common_ancestor – a common ancestor of this plugin and the others being merged

Returns:

True if the state plugins are actually merged.

Return type:

bool

widen(_)

The widening operation for plugins. Widening is a special kind of merging that produces a more general state from several more specific states. It is used only during intensive static analysis. The same behavior regarding copying and mutation from merge should be followed.

Parameters:

others – the other state plugin

Returns:

True if the state plugin is actually widened.

Return type:

bool

class angr.SimFileBase(name=None, writable=True, ident=None, concrete=False, file_exists=True, **kwargs)

Bases: SimStatePlugin

SimFiles are the storage mechanisms used by SimFileDescriptors.

Different types of SimFiles can have drastically different interfaces, and as a result there’s not much that can be specified on this base class. All the read and write methods take a pos argument, which may have different semantics per-class. 0 will always be a valid position to use, though, and the next position you should use is part of the return tuple.

Some simfiles are “streams”, meaning that the position that reads come from is determined not by the position you pass in (it will in fact be ignored), but by an internal variable. This is stored as .pos if you care to read it. Don’t write to it. The same lack-of-semantics applies to this field as well.

Variables:
  • name – The name of the file. Purely for cosmetic purposes

  • ident – The identifier of the file, typically autogenerated from the name and a nonce. Purely for cosmetic purposes, but does appear in symbolic values autogenerated in the file.

  • seekable – Bool indicating whether seek operations on this file should succeed. If this is True, then pos must be a number of bytes from the start of the file.

  • writable – Bool indicating whether writing to this file is allowed.

  • pos – If the file is a stream, this will be the current position. Otherwise, None.

  • concrete – Whether or not this file contains mostly concrete data. Will be used by some SimProcedures to choose how to handle variable-length operations like fgets.

  • file_exists – Set to False, if file does not exists, set to a claripy Bool if unknown, default True.

seekable = False
pos = None
__init__(name=None, writable=True, ident=None, concrete=False, file_exists=True, **kwargs)
static make_ident(name)
concretize(**kwargs)

Return a concretization of the contents of the file. The type of the return value of this method will vary depending on which kind of SimFile you’re using.

read(pos, size, **kwargs)

Read some data from the file.

Parameters:
  • pos – The offset in the file to read from.

  • size – The size to read. May be symbolic.

Returns:

A tuple of the data read (a bitvector of the length that is the maximum length of the read), the actual size of the read, and the new file position pointer.

write(pos, data, size=None, **kwargs)

Write some data to the file.

Parameters:
  • pos – The offset in the file to write to. May be ignored if the file is a stream or device.

  • data – The data to write as a bitvector

  • size – The optional size of the data to write. If not provided will default to the length of the data. Must be constrained to less than or equal to the size of the data.

Returns:

The new file position pointer.

property size

The number of data bytes stored by the file at present. May be a symbolic value.

copy(memo: dict[int, Any] | None = None, **kwargs: Any) S_co

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:
  • memo (Optional[dict[int, Any]]) – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

  • kwargs (Any)

Return type:

TypeVar(S_co, covariant=True)

class angr.SimFileDescriptor(simfile, flags=0)

Bases: SimFileDescriptorBase

A simple file descriptor forwarding reads and writes to a SimFile. Contains information about the current opened state of the file, such as the flags or (if relevant) the current position.

Variables:
  • file – The SimFile described to by this descriptor

  • flags – The mode that the file descriptor was opened with, a bitfield of flags

__init__(simfile, flags=0)
read_data(size, **kwargs)

Reads some data from the file, returning the data.

Parameters:

size – The requested length of the read

Returns:

A tuple of the data read and the real length of the read

write_data(data, size=None, **kwargs)

Write some data, provided as an argument into the file.

Parameters:
  • data – A bitvector to write into the file

  • size – The requested size of the write (may be symbolic)

Returns:

The real length of the write

seek(offset, whence='start')

Seek the file descriptor to a different position in the file.

Parameters:
  • offset – The offset to seek to, interpreted according to whence

  • whence – What the offset is relative to; one of the strings “start”, “current”, or “end”

Returns:

A symbolic boolean describing whether the seek succeeded or not

eof()

Return the EOF status. May be a symbolic boolean.

tell()

Return the current position, or None if the concept doesn’t make sense for the given file.

size()

Return the size of the data stored in the file in bytes, or None if the concept doesn’t make sense for the given file.

concretize(**kwargs)

Return a concretization of the underlying file. Returns whatever format is preferred by the file.

property file_exists

This should be True in most cases. Only if we opened an fd of unknown existence, ALL_FILES_EXIST is False and ANY_FILE_MIGHT_EXIST is True, this is a symbolic boolean.

property read_storage

Return the SimFile backing reads from this fd

property write_storage

Return the SimFile backing writes to this fd

property read_pos

Return the current position of the read file pointer.

If the underlying read file is a stream, this will return the position of the stream. Otherwise, will return the position of the file descriptor in the file.

property write_pos

Return the current position of the read file pointer.

If the underlying read file is a stream, this will return the position of the stream. Otherwise, will return the position of the file descriptor in the file.

set_state(state)

Sets a new state (for example, if the state has been branched)

copy(memo: dict[int, Any] | None = None, **kwargs: Any) S_co

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:
  • memo (Optional[dict[int, Any]]) – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

  • kwargs (Any)

Return type:

TypeVar(S_co, covariant=True)

merge(others, merge_conditions, common_ancestor=None)

Should merge the state plugin with the provided others. This will be called by state.merge() after copying the target state, so this should mutate the current instance to merge with the others.

Note that when multiple instances of a single plugin object (for example, a file) are referenced in the state, it is important that merge only ever be called once. This should be solved by designating one of the plugin’s referees as the “real owner”, who should be the one to actually merge it. This technique doesn’t work to resolve the similar issue that arises during copying because merging doesn’t produce a new reference to insert.

There will be n others and n+1 merge conditions, since the first condition corresponds to self. To match elements up to conditions, say zip([self] + others, merge_conditions)

When implementing this, make sure that you “deepen” both others and common_ancestor before calling sub-elements’ merge methods, e.g.

self.foo.merge(
    [o.foo for o in others],
    merge_conditions,
    common_ancestor=common_ancestor.foo if common_ancestor is not None else None
)

During static analysis, merge_conditions can be None, in which case you should use state.solver.union(values). TODO: fish please make this less bullshit

There is a utility claripy.ite_cases which will help with constructing arbitrarily large merged ASTs. Use it like self.bar = claripy.ite_cases(zip(conditions[1:], [o.bar for o in others]), self.bar)

Parameters:
  • others – the other state plugins to merge with

  • merge_conditions – a symbolic condition for each of the plugins

  • common_ancestor – a common ancestor of this plugin and the others being merged

Returns:

True if the state plugins are actually merged.

Return type:

bool

widen(_)

The widening operation for plugins. Widening is a special kind of merging that produces a more general state from several more specific states. It is used only during intensive static analysis. The same behavior regarding copying and mutation from merge should be followed.

Parameters:

others – the other state plugin

Returns:

True if the state plugin is actually widened.

Return type:

bool

class angr.SimFileDescriptorDuplex(read_file, write_file)

Bases: SimFileDescriptorBase

A file descriptor that refers to two file storage mechanisms, one to read from and one to write to. As a result, operations like seek, eof, etc no longer make sense.

Parameters:
  • read_file – The SimFile to read from

  • write_file – The SimFile to write to

__init__(read_file, write_file)
read_data(size, **kwargs)

Reads some data from the file, returning the data.

Parameters:

size – The requested length of the read

Returns:

A tuple of the data read and the real length of the read

write_data(data, size=None, **kwargs)

Write some data, provided as an argument into the file.

Parameters:
  • data – A bitvector to write into the file

  • size – The requested size of the write (may be symbolic)

Returns:

The real length of the write

set_state(state)

Sets a new state (for example, if the state has been branched)

eof()

Return the EOF status. May be a symbolic boolean.

tell()

Return the current position, or None if the concept doesn’t make sense for the given file.

seek(offset, whence='start')

Seek the file descriptor to a different position in the file.

Parameters:
  • offset – The offset to seek to, interpreted according to whence

  • whence – What the offset is relative to; one of the strings “start”, “current”, or “end”

Returns:

A symbolic boolean describing whether the seek succeeded or not

size()

Return the size of the data stored in the file in bytes, or None if the concept doesn’t make sense for the given file.

concretize(**kwargs)

Return a concretization of the underlying files, as a tuple of (read file, write file).

property read_storage

Return the SimFile backing reads from this fd

property write_storage

Return the SimFile backing writes to this fd

property read_pos

Return the current position of the read file pointer.

If the underlying read file is a stream, this will return the position of the stream. Otherwise, will return the position of the file descriptor in the file.

property write_pos

Return the current position of the read file pointer.

If the underlying read file is a stream, this will return the position of the stream. Otherwise, will return the position of the file descriptor in the file.

copy(memo: dict[int, Any] | None = None, **kwargs: Any) S_co

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:
  • memo (Optional[dict[int, Any]]) – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

  • kwargs (Any)

Return type:

TypeVar(S_co, covariant=True)

merge(others, merge_conditions, common_ancestor=None)

Should merge the state plugin with the provided others. This will be called by state.merge() after copying the target state, so this should mutate the current instance to merge with the others.

Note that when multiple instances of a single plugin object (for example, a file) are referenced in the state, it is important that merge only ever be called once. This should be solved by designating one of the plugin’s referees as the “real owner”, who should be the one to actually merge it. This technique doesn’t work to resolve the similar issue that arises during copying because merging doesn’t produce a new reference to insert.

There will be n others and n+1 merge conditions, since the first condition corresponds to self. To match elements up to conditions, say zip([self] + others, merge_conditions)

When implementing this, make sure that you “deepen” both others and common_ancestor before calling sub-elements’ merge methods, e.g.

self.foo.merge(
    [o.foo for o in others],
    merge_conditions,
    common_ancestor=common_ancestor.foo if common_ancestor is not None else None
)

During static analysis, merge_conditions can be None, in which case you should use state.solver.union(values). TODO: fish please make this less bullshit

There is a utility claripy.ite_cases which will help with constructing arbitrarily large merged ASTs. Use it like self.bar = claripy.ite_cases(zip(conditions[1:], [o.bar for o in others]), self.bar)

Parameters:
  • others – the other state plugins to merge with

  • merge_conditions – a symbolic condition for each of the plugins

  • common_ancestor – a common ancestor of this plugin and the others being merged

Returns:

True if the state plugins are actually merged.

Return type:

bool

widen(_)

The widening operation for plugins. Widening is a special kind of merging that produces a more general state from several more specific states. It is used only during intensive static analysis. The same behavior regarding copying and mutation from merge should be followed.

Parameters:

others – the other state plugin

Returns:

True if the state plugin is actually widened.

Return type:

bool

exception angr.SimFileError

Bases: SimMemoryError, SimFilesystemError

class angr.SimFileStream(name=None, content=None, pos=0, **kwargs)

Bases: SimFile

A specialized SimFile that uses a flat memory backing, but functions as a stream, tracking its position internally.

The pos argument to the read and write methods will be ignored, and will return None. Instead, there is an attribute pos on the file itself, which will give you what you want.

Parameters:
  • name – The name of the file, for cosmetic purposes

  • pos – The initial position of the file, default zero

  • kwargs – Any other keyword arguments will go on to the SimFile constructor.

Variables:

pos – The current position in the file.

__init__(name=None, content=None, pos=0, **kwargs)
set_state(state)

Sets a new state (for example, if the state has been branched)

read(pos, size, **kwargs)

Read some data from the file.

Parameters:
  • pos – The offset in the file to read from.

  • size – The size to read. May be symbolic.

Returns:

A tuple of the data read (a bitvector of the length that is the maximum length of the read), the actual size of the read, and the new file position pointer.

write(_, data, size=None, **kwargs)

Write some data to the file.

Parameters:
  • pos – The offset in the file to write to. May be ignored if the file is a stream or device.

  • data – The data to write as a bitvector

  • size – The optional size of the data to write. If not provided will default to the length of the data. Must be constrained to less than or equal to the size of the data.

Returns:

The new file position pointer.

copy(memo: dict[int, Any] | None = None, **kwargs: Any) S_co

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:
  • memo (Optional[dict[int, Any]]) – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

  • kwargs (Any)

Return type:

TypeVar(S_co, covariant=True)

merge(others, merge_conditions, common_ancestor=None)

Should merge the state plugin with the provided others. This will be called by state.merge() after copying the target state, so this should mutate the current instance to merge with the others.

Note that when multiple instances of a single plugin object (for example, a file) are referenced in the state, it is important that merge only ever be called once. This should be solved by designating one of the plugin’s referees as the “real owner”, who should be the one to actually merge it. This technique doesn’t work to resolve the similar issue that arises during copying because merging doesn’t produce a new reference to insert.

There will be n others and n+1 merge conditions, since the first condition corresponds to self. To match elements up to conditions, say zip([self] + others, merge_conditions)

When implementing this, make sure that you “deepen” both others and common_ancestor before calling sub-elements’ merge methods, e.g.

self.foo.merge(
    [o.foo for o in others],
    merge_conditions,
    common_ancestor=common_ancestor.foo if common_ancestor is not None else None
)

During static analysis, merge_conditions can be None, in which case you should use state.solver.union(values). TODO: fish please make this less bullshit

There is a utility claripy.ite_cases which will help with constructing arbitrarily large merged ASTs. Use it like self.bar = claripy.ite_cases(zip(conditions[1:], [o.bar for o in others]), self.bar)

Parameters:
  • others – the other state plugins to merge with

  • merge_conditions – a symbolic condition for each of the plugins

  • common_ancestor – a common ancestor of this plugin and the others being merged

Returns:

True if the state plugins are actually merged.

Return type:

bool

exception angr.SimFilesystemError

Bases: SimError

class angr.SimHeapBrk(heap_base=None, heap_size=None)

Bases: SimHeapBase

SimHeapBrk represents a trivial heap implementation based on the Unix brk system call. This type of heap stores virtually no metadata, so it is up to the user to determine when it is safe to release memory. This also means that it does not properly support standard heap operations like realloc.

This heap implementation is a holdover from before any more proper implementations were modelled. At the time, various libc (or win32) SimProcedures handled the heap in the same way that this plugin does now. To make future heap implementations plug-and-playable, they should implement the necessary logic themselves, and dependent SimProcedures should invoke a method by the same name as theirs (prepended with an underscore) upon the heap plugin. Depending on the heap implementation, if the method is not supported, an error should be raised.

Out of consideration for the original way the heap was handled, this plugin implements functionality for all relevant SimProcedures (even those that would not normally be supported together in a single heap implementation).

Variables:

heap_location – the address of the top of the heap, bounding the allocations made starting from heap_base

__init__(heap_base=None, heap_size=None)
copy(memo: dict[int, Any] | None = None, **kwargs: Any) S_co

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:
  • memo (Optional[dict[int, Any]]) – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

  • kwargs (Any)

Return type:

TypeVar(S_co, covariant=True)

allocate(sim_size)

The actual allocation primitive for this heap implementation. Increases the position of the break to allocate space. Has no guards against the heap growing too large.

Parameters:

sim_size – a size specifying how much to increase the break pointer by

Returns:

a pointer to the previous break position, above which there is now allocated space

release(sim_size)

The memory release primitive for this heap implementation. Decreases the position of the break to deallocate space. Guards against releasing beyond the initial heap base.

Parameters:

sim_size – a size specifying how much to decrease the break pointer by (may be symbolic or not)

merge(others, merge_conditions, common_ancestor=None)

Should merge the state plugin with the provided others. This will be called by state.merge() after copying the target state, so this should mutate the current instance to merge with the others.

Note that when multiple instances of a single plugin object (for example, a file) are referenced in the state, it is important that merge only ever be called once. This should be solved by designating one of the plugin’s referees as the “real owner”, who should be the one to actually merge it. This technique doesn’t work to resolve the similar issue that arises during copying because merging doesn’t produce a new reference to insert.

There will be n others and n+1 merge conditions, since the first condition corresponds to self. To match elements up to conditions, say zip([self] + others, merge_conditions)

When implementing this, make sure that you “deepen” both others and common_ancestor before calling sub-elements’ merge methods, e.g.

self.foo.merge(
    [o.foo for o in others],
    merge_conditions,
    common_ancestor=common_ancestor.foo if common_ancestor is not None else None
)

During static analysis, merge_conditions can be None, in which case you should use state.solver.union(values). TODO: fish please make this less bullshit

There is a utility claripy.ite_cases which will help with constructing arbitrarily large merged ASTs. Use it like self.bar = claripy.ite_cases(zip(conditions[1:], [o.bar for o in others]), self.bar)

Parameters:
  • others – the other state plugins to merge with

  • merge_conditions – a symbolic condition for each of the plugins

  • common_ancestor – a common ancestor of this plugin and the others being merged

Returns:

True if the state plugins are actually merged.

Return type:

bool

widen(others)

The widening operation for plugins. Widening is a special kind of merging that produces a more general state from several more specific states. It is used only during intensive static analysis. The same behavior regarding copying and mutation from merge should be followed.

Parameters:

others – the other state plugin

Returns:

True if the state plugin is actually widened.

Return type:

bool

exception angr.SimHeapError

Bases: SimStateError

class angr.SimHeapPTMalloc(heap_base=None, heap_size=None)

Bases: SimHeapFreelist

A freelist-style heap implementation inspired by ptmalloc. The chunks used by this heap contain heap metadata in addition to user data. While the real-world ptmalloc is implemented using multiple lists of free chunks (corresponding to their different sizes), this more basic model uses a single list of chunks and searches for free chunks using a first-fit algorithm.

NOTE: The plugin must be registered using register_plugin with name heap in order to function properly.

Variables:
  • heap_base – the address of the base of the heap in memory

  • heap_size – the total size of the main memory region managed by the heap in memory

  • mmap_base – the address of the region from which large mmap allocations will be made

  • free_head_chunk – the head of the linked list of free chunks in the heap

__init__(heap_base=None, heap_size=None)
copy(memo: dict[int, Any] | None = None, **kwargs: Any) S_co

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:
  • memo (Optional[dict[int, Any]]) – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

  • kwargs (Any)

Return type:

TypeVar(S_co, covariant=True)

chunks()

Returns an iterator over all the chunks in the heap.

allocated_chunks()

Returns an iterator over all the allocated chunks in the heap.

free_chunks()

Returns an iterator over all the free chunks in the heap.

chunk_from_mem(ptr)

Given a pointer to a user payload, return the base of the chunk associated with that payload (i.e. the chunk pointer). Returns None if ptr is null.

Parameters:

ptr – a pointer to the base of a user payload in the heap

Returns:

a pointer to the base of the associated heap chunk, or None if ptr is null

malloc(sim_size)

A somewhat faithful implementation of libc malloc.

Parameters:

sim_size – the amount of memory (in bytes) to be allocated

Returns:

the address of the allocation, or a NULL pointer if the allocation failed

free(ptr)

A somewhat faithful implementation of libc free.

Parameters:

ptr – the location in memory to be freed

calloc(sim_nmemb, sim_size)

A somewhat faithful implementation of libc calloc.

Parameters:
  • sim_nmemb – the number of elements to allocated

  • sim_size – the size of each element (in bytes)

Returns:

the address of the allocation, or a NULL pointer if the allocation failed

realloc(ptr, size)

A somewhat faithful implementation of libc realloc.

Parameters:
  • ptr – the location in memory to be reallocated

  • size – the new size desired for the allocation

Returns:

the address of the allocation, or a NULL pointer if the allocation was freed or if no new allocation was made

merge(others, merge_conditions, common_ancestor=None)

Should merge the state plugin with the provided others. This will be called by state.merge() after copying the target state, so this should mutate the current instance to merge with the others.

Note that when multiple instances of a single plugin object (for example, a file) are referenced in the state, it is important that merge only ever be called once. This should be solved by designating one of the plugin’s referees as the “real owner”, who should be the one to actually merge it. This technique doesn’t work to resolve the similar issue that arises during copying because merging doesn’t produce a new reference to insert.

There will be n others and n+1 merge conditions, since the first condition corresponds to self. To match elements up to conditions, say zip([self] + others, merge_conditions)

When implementing this, make sure that you “deepen” both others and common_ancestor before calling sub-elements’ merge methods, e.g.

self.foo.merge(
    [o.foo for o in others],
    merge_conditions,
    common_ancestor=common_ancestor.foo if common_ancestor is not None else None
)

During static analysis, merge_conditions can be None, in which case you should use state.solver.union(values). TODO: fish please make this less bullshit

There is a utility claripy.ite_cases which will help with constructing arbitrarily large merged ASTs. Use it like self.bar = claripy.ite_cases(zip(conditions[1:], [o.bar for o in others]), self.bar)

Parameters:
  • others – the other state plugins to merge with

  • merge_conditions – a symbolic condition for each of the plugins

  • common_ancestor – a common ancestor of this plugin and the others being merged

Returns:

True if the state plugins are actually merged.

Return type:

bool

widen(others)

The widening operation for plugins. Widening is a special kind of merging that produces a more general state from several more specific states. It is used only during intensive static analysis. The same behavior regarding copying and mutation from merge should be followed.

Parameters:

others – the other state plugin

Returns:

True if the state plugin is actually widened.

Return type:

bool

init_state()

Use this function to perform any initialization on the state at plugin-add time

class angr.SimHostFilesystem(host_path=None, **kwargs)

Bases: SimConcreteFilesystem

Simulated mount that makes some piece from the host filesystem available to the guest.

Parameters:
  • host_path (str) – The path on the host to mount

  • pathsep (str) – The host path separator character, default os.path.sep

__init__(host_path=None, **kwargs)
copy(memo: dict[int, Any] | None = None, **kwargs: Any) S_co

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:
  • memo (Optional[dict[int, Any]]) – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

  • kwargs (Any)

Return type:

TypeVar(S_co, covariant=True)

exception angr.SimIRSBError

Bases: SimEngineError

exception angr.SimIRSBNoDecodeError

Bases: SimIRSBError

exception angr.SimMemoryAddressError

Bases: SimMemoryError

exception angr.SimMemoryError

Bases: SimStateError

exception angr.SimMemoryLimitError

Bases: SimMemoryError

exception angr.SimMemoryMissingError(missing_addr, missing_size, *args)

Bases: SimMemoryError

__init__(missing_addr, missing_size, *args)
exception angr.SimMergeError

Bases: SimStateError

exception angr.SimMissingTempError

Bases: SimValueError, IndexError

class angr.SimMount

Bases: SimStatePlugin

This is the base class for “mount points” in angr’s simulated filesystem. Subclass this class and give it to the filesystem to intercept all file creations and opens below the mountpoint. Since this a SimStatePlugin you may also want to implement set_state, copy, merge, etc.

get(path_elements)

Implement this function to instrument file lookups.

Parameters:

path_elements – A list of path elements traversing from the mountpoint to the file

Returns:

A SimFile, or None

insert(path_elements, simfile)

Implement this function to instrument file creation.

Parameters:
  • path_elements – A list of path elements traversing from the mountpoint to the file

  • simfile – The file to insert

Returns:

A bool indicating whether the insert occurred

delete(path_elements)

Implement this function to instrument file deletion.

Parameters:

path_elements – A list of path elements traversing from the mountpoint to the file

Returns:

A bool indicating whether the delete occurred

lookup(sim_file)

Look up the path of a SimFile in the mountpoint

Parameters:

sim_file – A SimFile object needs to be looked up

Returns:

A string representing the path of the file in the mountpoint Or None if the SimFile does not exist in the mountpoint

class angr.SimOS(project, name=None)

Bases: object

A class describing OS/arch-level configuration.

Parameters:
__init__(project, name=None)
Parameters:
name: str | None
configure_project()

Configure the project to set up global settings (like SimProcedures).

state_blank(addr=None, initial_prefix=None, brk=None, stack_end=None, stack_size=8388608, stdin=None, thread_idx=None, permissions_backer=None, **kwargs)

Initialize a blank state.

All parameters are optional.

Parameters:
  • addr – The execution start address.

  • initial_prefix

  • stack_end – The end of the stack (i.e., the byte after the last valid stack address).

  • stack_size – The number of bytes to allocate for stack space

  • brk – The address of the process’ break.

Returns:

The initialized SimState.

Any additional arguments will be passed to the SimState constructor

state_entry(**kwargs)
state_full_init(**kwargs)
state_call(addr, *args, **kwargs)
prepare_call_state(calling_state, initial_state=None, preserve_registers=(), preserve_memory=())

This function prepares a state that is executing a call instruction. If given an initial_state, it copies over all of the critical registers to it from the calling_state. Otherwise, it prepares the calling_state for action.

This is mostly used to create minimalistic for CFG generation. Some ABIs, such as MIPS PIE and x86 PIE, require certain information to be maintained in certain registers. For example, for PIE MIPS, this function transfer t9, gp, and ra to the new state.

prepare_function_symbol(symbol_name, basic_addr=None)

Prepare the address space with the data necessary to perform relocations pointing to the given symbol

Returns a 2-tuple. The first item is the address of the function code, the second is the address of the relocation target.

handle_exception(successors, engine, exception)

Perform exception handling. This method will be called when, during execution, a SimException is thrown. Currently, this can only indicate a segfault, but in the future it could indicate any unexpected exceptional behavior that can’t be handled by ordinary control flow.

The method may mutate the provided SimSuccessors object in any way it likes, or re-raise the exception.

Parameters:
  • successors – The SimSuccessors object currently being executed on

  • engine – The engine that was processing this step

  • exception – The actual exception object

syscall(state, allow_unsupported=True)
Return type:

SimProcedure | None

Parameters:
syscall_abi(state)
Return type:

str | None

Parameters:

state (SimState)

syscall_cc(state)
Return type:

SimCCSyscall | None

Parameters:

state (SimState)

is_syscall_addr(addr)
Return type:

bool

syscall_from_addr(addr, allow_unsupported=True)
Return type:

SimProcedure | None

syscall_from_number(number, allow_unsupported=True, abi=None)
Return type:

SimProcedure | None

setup_gdt(state, gdt)

Write the GlobalDescriptorTable object in the current state memory

Parameters:
  • state – state in which to write the GDT

  • gdt – GlobalDescriptorTable object

Returns:

generate_gdt(fs, gs, fs_size=4294967295, gs_size=4294967295)

Generate a GlobalDescriptorTable object and populate it using the value of the gs and fs register

Parameters:
  • fs – value of the fs segment register

  • gs – value of the gs segment register

  • fs_size – size of the fs segment register

  • gs_size – size of the gs segment register

Returns:

gdt a GlobalDescriptorTable object

exception angr.SimOperationError

Bases: SimError

class angr.SimPackets(name, write_mode=None, content=None, writable=True, ident=None, **kwargs)

Bases: SimFileBase

The SimPackets is meant to model inputs whose content is delivered a series of asynchronous chunks. The data is stored as a list of read or write results. For symbolic sizes, state.libc.max_packet_size will be respected. If the SHORT_READS option is enabled, reads will return a symbolic size constrained to be less than or equal to the requested size.

A SimPackets cannot be used for both reading and writing - for socket objects that can be both read and written to you should use a file descriptor to multiplex the read and write operations into two separate file storage mechanisms.

Parameters:
  • name – The name of the file, for cosmetic purposes

  • write_mode – Whether this file is opened in read or write mode. If this is unspecified it will be autodetected.

  • content – Some initial content to use for the file. Can be a list of bytestrings or a list of tuples of content ASTs and size ASTs.

Variables:
  • write_mode – See the eponymous parameter

  • content – A list of packets, as tuples of content ASTs and size ASTs.

__init__(name, write_mode=None, content=None, writable=True, ident=None, **kwargs)
set_state(state)

Sets a new state (for example, if the state has been branched)

property size

The number of data bytes stored by the file at present. May be a symbolic value.

concretize(**kwargs)

Returns a list of the packets read or written as bytestrings.

read(pos, size, **kwargs)

Read a packet from the stream.

Parameters:
  • pos (int) – The packet number to read from the sequence of the stream. May be None to append to the stream.

  • size – The size to read. May be symbolic.

  • short_reads – Whether to replace the size with a symbolic value constrained to less than or equal to the original size. If unspecified, will be chosen based on the state option.

Returns:

A tuple of the data read (a bitvector of the length that is the maximum length of the read) and the actual size of the read.

write(pos, data, size=None, events=True, **kwargs)

Write a packet to the stream.

Parameters:
  • pos (int) – The packet number to write in the sequence of the stream. May be None to append to the stream.

  • data – The data to write, as a string or bitvector.

  • size – The optional size to write. May be symbolic; must be constrained to at most the size of data.

Returns:

The next packet to use after this

copy(memo: dict[int, Any] | None = None, **kwargs: Any) S_co

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:
  • memo (Optional[dict[int, Any]]) – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

  • kwargs (Any)

Return type:

TypeVar(S_co, covariant=True)

merge(others, merge_conditions, common_ancestor=None)

Should merge the state plugin with the provided others. This will be called by state.merge() after copying the target state, so this should mutate the current instance to merge with the others.

Note that when multiple instances of a single plugin object (for example, a file) are referenced in the state, it is important that merge only ever be called once. This should be solved by designating one of the plugin’s referees as the “real owner”, who should be the one to actually merge it. This technique doesn’t work to resolve the similar issue that arises during copying because merging doesn’t produce a new reference to insert.

There will be n others and n+1 merge conditions, since the first condition corresponds to self. To match elements up to conditions, say zip([self] + others, merge_conditions)

When implementing this, make sure that you “deepen” both others and common_ancestor before calling sub-elements’ merge methods, e.g.

self.foo.merge(
    [o.foo for o in others],
    merge_conditions,
    common_ancestor=common_ancestor.foo if common_ancestor is not None else None
)

During static analysis, merge_conditions can be None, in which case you should use state.solver.union(values). TODO: fish please make this less bullshit

There is a utility claripy.ite_cases which will help with constructing arbitrarily large merged ASTs. Use it like self.bar = claripy.ite_cases(zip(conditions[1:], [o.bar for o in others]), self.bar)

Parameters:
  • others – the other state plugins to merge with

  • merge_conditions – a symbolic condition for each of the plugins

  • common_ancestor – a common ancestor of this plugin and the others being merged

Returns:

True if the state plugins are actually merged.

Return type:

bool

widen(_)

The widening operation for plugins. Widening is a special kind of merging that produces a more general state from several more specific states. It is used only during intensive static analysis. The same behavior regarding copying and mutation from merge should be followed.

Parameters:

others – the other state plugin

Returns:

True if the state plugin is actually widened.

Return type:

bool

class angr.SimPacketsStream(name, pos=0, **kwargs)

Bases: SimPackets

A specialized SimPackets that tracks its position internally.

The pos argument to the read and write methods will be ignored, and will return None. Instead, there is an attribute pos on the file itself, which will give you what you want.

Parameters:
  • name – The name of the file, for cosmetic purposes

  • pos – The initial position of the file, default zero

  • kwargs – Any other keyword arguments will go on to the SimPackets constructor.

Variables:

pos – The current position in the file.

__init__(name, pos=0, **kwargs)
read(pos, size, **kwargs)

Read a packet from the stream.

Parameters:
  • pos (int) – The packet number to read from the sequence of the stream. May be None to append to the stream.

  • size – The size to read. May be symbolic.

  • short_reads – Whether to replace the size with a symbolic value constrained to less than or equal to the original size. If unspecified, will be chosen based on the state option.

Returns:

A tuple of the data read (a bitvector of the length that is the maximum length of the read) and the actual size of the read.

write(_, data, size=None, **kwargs)

Write a packet to the stream.

Parameters:
  • pos (int) – The packet number to write in the sequence of the stream. May be None to append to the stream.

  • data – The data to write, as a string or bitvector.

  • size – The optional size to write. May be symbolic; must be constrained to at most the size of data.

Returns:

The next packet to use after this

copy(memo: dict[int, Any] | None = None, **kwargs: Any) S_co

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:
  • memo (Optional[dict[int, Any]]) – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

  • kwargs (Any)

Return type:

TypeVar(S_co, covariant=True)

merge(others, merge_conditions, common_ancestor=None)

Should merge the state plugin with the provided others. This will be called by state.merge() after copying the target state, so this should mutate the current instance to merge with the others.

Note that when multiple instances of a single plugin object (for example, a file) are referenced in the state, it is important that merge only ever be called once. This should be solved by designating one of the plugin’s referees as the “real owner”, who should be the one to actually merge it. This technique doesn’t work to resolve the similar issue that arises during copying because merging doesn’t produce a new reference to insert.

There will be n others and n+1 merge conditions, since the first condition corresponds to self. To match elements up to conditions, say zip([self] + others, merge_conditions)

When implementing this, make sure that you “deepen” both others and common_ancestor before calling sub-elements’ merge methods, e.g.

self.foo.merge(
    [o.foo for o in others],
    merge_conditions,
    common_ancestor=common_ancestor.foo if common_ancestor is not None else None
)

During static analysis, merge_conditions can be None, in which case you should use state.solver.union(values). TODO: fish please make this less bullshit

There is a utility claripy.ite_cases which will help with constructing arbitrarily large merged ASTs. Use it like self.bar = claripy.ite_cases(zip(conditions[1:], [o.bar for o in others]), self.bar)

Parameters:
  • others – the other state plugins to merge with

  • merge_conditions – a symbolic condition for each of the plugins

  • common_ancestor – a common ancestor of this plugin and the others being merged

Returns:

True if the state plugins are actually merged.

Return type:

bool

exception angr.SimPosixError

Bases: SimStateError

class angr.SimProcedure(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)

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

The following parameters are optional:

Parameters:
  • 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 – 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 – 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)
state: SimState
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.

ty_ptr(ty)
property is_java
property argument_types
property return_type
exception angr.SimProcedureArgumentError

Bases: SimProcedureError

exception angr.SimProcedureError

Bases: SimEngineError

exception angr.SimRegionMapError

Bases: SimMemoryError

exception angr.SimReliftException(state)

Bases: SimEngineError

__init__(state)
angr.SimSegfaultError

alias of SimSegfaultException

exception angr.SimSegfaultException(addr, reason, original_addr=None)

Bases: SimException, SimMemoryError

__init__(addr, reason, original_addr=None)
exception angr.SimShadowStackError

Bases: SimProcedureError

exception angr.SimSlicerError

Bases: SimError

exception angr.SimSolverError

Bases: SimError

exception angr.SimSolverModeError

Bases: SimSolverError

exception angr.SimSolverOptionError

Bases: SimSolverError

class angr.SimState(project=None, arch=None, plugins=None, mode=None, options=None, add_options=None, remove_options=None, special_memory_filler=None, os_name=None, plugin_preset='default', cle_memory_backer=None, dict_memory_backer=None, permissions_map=None, default_permissions=3, stack_perms=None, stack_end=None, stack_size=None, regioned_memory_cls=None, **kwargs)

Bases: Generic[IPTypeConc, IPTypeSym], PluginHub[SimStatePlugin]

The SimState represents the state of a program, including its memory, registers, and so forth.

Parameters:
Variables:
  • regs – A convenient view of the state’s registers, where each register is a property

  • mem – A convenient view of the state’s memory, a angr.state_plugins.view.SimMemView

  • registers – The state’s register file as a flat memory region

  • memory – The state’s memory as a flat memory region

  • solver – The symbolic solver and variable manager for this state

  • inspect – The breakpoint manager, a angr.state_plugins.inspect.SimInspector

  • log – Information about the state’s history

  • scratch – Information about the current execution step

  • posix – MISNOMER: information about the operating system or environment model

  • fs – The current state of the simulated filesystem

  • libc – Information about the standard library we are emulating

  • cgc – Information about the cgc environment

  • uc_manager – Control of under-constrained symbolic execution

  • unicorn – Control of the Unicorn Engine

solver: SimSolver
posix: SimSystemPosix
registers: DefaultMemory
regs: SimRegNameView
memory: DefaultMemory
callstack: CallStack
mem: SimMemView
history: SimStateHistory
inspect: SimInspector
jni_references: SimStateJNIReferences
scratch: SimStateScratch
__init__(project=None, arch=None, plugins=None, mode=None, options=None, add_options=None, remove_options=None, special_memory_filler=None, os_name=None, plugin_preset='default', cle_memory_backer=None, dict_memory_backer=None, permissions_map=None, default_permissions=3, stack_perms=None, stack_end=None, stack_size=None, regioned_memory_cls=None, **kwargs)
Parameters:
property plugins
property ip

Get the instruction pointer expression, trigger SimInspect breakpoints, and generate SimActions. Use _ip to not trigger breakpoints or generate actions.

Returns:

an expression

property addr: IPTypeConc

Get the concrete address of the instruction pointer, without triggering SimInspect breakpoints or generating SimActions. An integer is returned, or an exception is raised if the instruction pointer is symbolic.

Returns:

an int

property arch: Arch
T = ~T
get_plugin(name)

Get the plugin named name. If no such plugin is currently active, try to activate a new one using the current preset.

has_plugin(name)

Return whether or not a plugin with the name name is currently active.

register_plugin(name, plugin, inhibit_init=False)

Add a new plugin plugin with name name to the active plugins.

property javavm_memory

In case of an JavaVM with JNI support, a state can store the memory plugin twice; one for the native and one for the java view of the state.

Returns:

The JavaVM view of the memory plugin.

property javavm_registers

In case of an JavaVM with JNI support, a state can store the registers plugin twice; one for the native and one for the java view of the state.

Returns:

The JavaVM view of the registers plugin.

simplify(*args)

Simplify this state’s constraints.

add_constraints(*constraints)

Add some constraints to the state.

You may pass in any number of symbolic booleans as variadic positional arguments.

satisfiable(**kwargs)

Whether the state’s constraints are satisfiable

downsize()

Clean up after the solver engine. Calling this when a state no longer needs to be solved on will reduce memory usage.

step(**kwargs)

Perform a step of symbolic execution using this state. Any arguments to AngrObjectFactory.successors can be passed to this.

Returns:

A SimSuccessors object categorizing the results of the step.

block(*args, **kwargs)

Represent the basic block at this state’s instruction pointer. Any arguments to AngrObjectFactory.block can ba passed to this.

Returns:

A Block object describing the basic block of code at this point.

copy()

Returns a copy of the state.

merge(*others, **kwargs)

Merges this state with the other states. Returns the merging result, merged state, and the merge flag.

Parameters:
  • states – the states to merge

  • merge_conditions – a tuple of the conditions under which each state holds

  • common_ancestor – a state that represents the common history between the states being merged. Usually it is only available when EFFICIENT_STATE_MERGING is enabled, otherwise weak-refed states might be dropped from state history instances.

  • plugin_whitelist – a list of plugin names that will be merged. If this option is given and is not None, any plugin that is not inside this list will not be merged, and will be created as a fresh instance in the new state.

  • common_ancestor_history – a SimStateHistory instance that represents the common history between the states being merged. This is to allow optimal state merging when EFFICIENT_STATE_MERGING is disabled.

Returns:

(merged state, merge flag, a bool indicating if any merging occurred)

widen(*others)

Perform a widening between self and other states :type others: :param others: :return:

reg_concrete(*args, **kwargs)

Returns the contents of a register but, if that register is symbolic, raises a SimValueError.

mem_concrete(*args, **kwargs)

Returns the contents of a memory but, if the contents are symbolic, raises a SimValueError.

stack_push(thing)

Push ‘thing’ to the stack, writing the thing to memory and adjusting the stack pointer.

stack_pop()

Pops from the stack and returns the popped thing. The length will be the architecture word size.

stack_read(offset, length, bp=False)

Reads length bytes, at an offset into the stack.

Parameters:
  • offset – The offset from the stack pointer.

  • length – The number of bytes to read.

  • bp – If True, offset from the BP instead of the SP. Default: False.

make_concrete_int(expr)
prepare_callsite(retval, args, cc='wtf')
dbg_print_stack(depth=None, sp=None)

Only used for debugging purposes. Return the current stack info in formatted string. If depth is None, the current stack frame (from sp to bp) will be printed out.

set_mode(mode)
property thumb
property with_condition
exception angr.SimStateError

Bases: SimError

exception angr.SimStateOptionsError

Bases: SimError

class angr.SimStatePlugin

Bases: object

This is a base class for SimState plugins. A SimState plugin will be copied along with the state when the state is branched. They are intended to be used for things such as tracking open files, tracking heap details, and providing storage and persistence for SimProcedures.

STRONGREF_STATE = False
__init__()
set_state(state)

Sets a new state (for example, if the state has been branched)

set_strongref_state(state)
copy(_memo)

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:

memo – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

static memo(f)

A decorator function you should apply to copy

Return type:

_CopyFunc[TypeVar(S_co, covariant=True)]

Parameters:

f (Callable[[T, dict[int, Any]], S_co])

merge(others, merge_conditions, common_ancestor=None)

Should merge the state plugin with the provided others. This will be called by state.merge() after copying the target state, so this should mutate the current instance to merge with the others.

Note that when multiple instances of a single plugin object (for example, a file) are referenced in the state, it is important that merge only ever be called once. This should be solved by designating one of the plugin’s referees as the “real owner”, who should be the one to actually merge it. This technique doesn’t work to resolve the similar issue that arises during copying because merging doesn’t produce a new reference to insert.

There will be n others and n+1 merge conditions, since the first condition corresponds to self. To match elements up to conditions, say zip([self] + others, merge_conditions)

When implementing this, make sure that you “deepen” both others and common_ancestor before calling sub-elements’ merge methods, e.g.

self.foo.merge(
    [o.foo for o in others],
    merge_conditions,
    common_ancestor=common_ancestor.foo if common_ancestor is not None else None
)

During static analysis, merge_conditions can be None, in which case you should use state.solver.union(values). TODO: fish please make this less bullshit

There is a utility claripy.ite_cases which will help with constructing arbitrarily large merged ASTs. Use it like self.bar = claripy.ite_cases(zip(conditions[1:], [o.bar for o in others]), self.bar)

Parameters:
  • others – the other state plugins to merge with

  • merge_conditions – a symbolic condition for each of the plugins

  • common_ancestor – a common ancestor of this plugin and the others being merged

Returns:

True if the state plugins are actually merged.

Return type:

bool

widen(others)

The widening operation for plugins. Widening is a special kind of merging that produces a more general state from several more specific states. It is used only during intensive static analysis. The same behavior regarding copying and mutation from merge should be followed.

Parameters:

others – the other state plugin

Returns:

True if the state plugin is actually widened.

Return type:

bool

classmethod register_default(name, xtr=None)
init_state()

Use this function to perform any initialization on the state at plugin-add time

exception angr.SimStatementError

Bases: SimError

exception angr.SimSymbolicFilesystemError

Bases: SimFilesystemError

exception angr.SimTranslationError

Bases: SimEngineError

exception angr.SimUCManagerAllocationError

Bases: SimUCManagerError

exception angr.SimUCManagerError

Bases: SimError

exception angr.SimUnicornError

Bases: SimError

exception angr.SimUnicornSymbolic

Bases: SimError

exception angr.SimUnicornUnsupport

Bases: SimError

exception angr.SimUninitializedAccessError(expr_type, expr)

Bases: SimExpressionError

__init__(expr_type, expr)
exception angr.SimUnsatError

Bases: SimValueError

exception angr.SimUnsupportedError

Bases: SimError

exception angr.SimValueError

Bases: SimSolverError

exception angr.SimZeroDivisionException

Bases: SimException, SimOperationError

class angr.SimulationManager(project, active_states=None, stashes=None, hierarchy=None, resilience=None, save_unsat=False, auto_drop=None, errored=None, completion_mode=<built-in function any>, techniques=None, suggestions=True, **kwargs)

Bases: object

The Simulation Manager is the future future.

Simulation managers allow you to wrangle multiple states in a slick way. States are organized into “stashes”, which you can step forward, filter, merge, and move around as you wish. This allows you to, for example, step two different stashes of states at different rates, then merge them together.

Stashes can be accessed as attributes (i.e. .active). A mulpyplexed stash can be retrieved by prepending the name with mp_, e.g. .mp_active. A single state from the stash can be retrieved by prepending the name with one_, e.g. .one_active.

Note that you shouldn’t usually be constructing SimulationManagers directly - there is a convenient shortcut for creating them in Project.factory: see angr.factory.AngrObjectFactory.

The most important methods you should look at are step, explore, and use_technique.

Parameters:
  • project (angr.project.Project) – A Project instance.

  • stashes – A dictionary to use as the stash store.

  • active_states – Active states to seed the “active” stash with.

  • hierarchy – A StateHierarchy object to use to track the relationships between states.

  • resilience – A set of errors to catch during stepping to put a state in the errore list. You may also provide the values False, None (default), or True to catch, respectively, no errors, all angr-specific errors, and a set of many common errors.

  • save_unsat – Set to True in order to introduce unsatisfiable states into the unsat stash instead of discarding them immediately.

  • auto_drop – A set of stash names which should be treated as garbage chutes.

  • completion_mode – A function describing how multiple exploration techniques with the complete hook set will interact. By default, the builtin function any.

  • techniques – A list of techniques that should be pre-set to use with this manager.

  • suggestions – Whether to automatically install the Suggestions exploration technique. Default True.

Variables:
  • errored – Not a stash, but a list of ErrorRecords. Whenever a step raises an exception that we catch, the state and some information about the error are placed in this list. You can adjust the list of caught exceptions with the resilience parameter.

  • stashes – All the stashes on this instance, as a dictionary.

  • completion_mode – A function describing how multiple exploration techniques with the complete hook set will interact. By default, the builtin function any.

ALL = '_ALL'
DROP = '_DROP'
__init__(project, active_states=None, stashes=None, hierarchy=None, resilience=None, save_unsat=False, auto_drop=None, errored=None, completion_mode=<built-in function any>, techniques=None, suggestions=True, **kwargs)
active: list[SimState]
stashed: list[SimState]
pruned: list[SimState]
unsat: list[SimState]
deadended: list[SimState]
unconstrained: list[SimState]
found: list[SimState]
one_active: SimState
one_stashed: SimState
one_pruned: SimState
one_unsat: SimState
one_deadended: SimState
one_unconstrained: SimState
one_found: SimState
property errored: list[ErrorRecord]
property stashes: defaultdict[str, list[SimState]]
mulpyplex(*stashes)

Mulpyplex across several stashes.

Parameters:

stashes – the stashes to mulpyplex

Returns:

a mulpyplexed list of states from the stashes in question, in the specified order

copy(deep=False)

Make a copy of this simulation manager. Pass deep=True to copy all the states in it as well.

If the current callstack includes hooked methods, the already-called methods will not be included in the copy.

use_technique(tech)

Use an exploration technique with this SimulationManager.

Techniques can be found in angr.exploration_techniques.

Parameters:

tech (ExplorationTechnique) – An ExplorationTechnique object that contains code to modify this SimulationManager’s behavior.

Returns:

The technique that was added, for convenience

remove_technique(tech)

Remove an exploration technique from a list of active techniques.

Parameters:

tech (ExplorationTechnique) – An ExplorationTechnique object.

explore(stash='active', n=None, find=None, avoid=None, find_stash='found', avoid_stash='avoid', cfg=None, num_find=1, avoid_priority=False, **kwargs)

Tick stash “stash” forward (up to “n” times or until “num_find” states are found), looking for condition “find”, avoiding condition “avoid”. Stores found states into “find_stash’ and avoided states into “avoid_stash”.

The “find” and “avoid” parameters may be any of:

  • An address to find

  • A set or list of addresses to find

  • A function that takes a state and returns whether or not it matches.

If an angr CFG is passed in as the “cfg” parameter and “find” is either a number or a list or a set, then any states which cannot possibly reach a success state without going through a failure state will be preemptively avoided.

run(stash='active', n=None, until=None, **kwargs)

Run until the SimulationManager has reached a completed state, according to the current exploration techniques. If no exploration techniques that define a completion state are being used, run until there is nothing left to run.

Parameters:
  • stash – Operate on this stash

  • n – Step at most this many times

  • until – If provided, should be a function that takes a SimulationManager and returns True or False. Stepping will terminate when it is True.

Returns:

The simulation manager, for chaining.

Return type:

SimulationManager

complete()

Returns whether or not this manager has reached a “completed” state.

step(stash='active', target_stash=None, n=None, selector_func=None, step_func=None, error_list=None, successor_func=None, until=None, filter_func=None, **run_args)

Step a stash of states forward and categorize the successors appropriately.

The parameters to this function allow you to control everything about the stepping and categorization process.

Parameters:
  • stash – The name of the stash to step (default: ‘active’)

  • target_stash – The name of the stash to put the results in (default: same as stash)

  • error_list – The list to put ErrorRecord objects in (default: self.errored)

  • selector_func – If provided, should be a function that takes a state and returns a boolean. If True, the state will be stepped. Otherwise, it will be kept as-is.

  • step_func – If provided, should be a function that takes a SimulationManager and returns a SimulationManager. Will be called with the SimulationManager at every step. Note that this function should not actually perform any stepping - it is meant to be a maintenance function called after each step.

  • successor_func – If provided, should be a function that takes a state and return its successors. Otherwise, project.factory.successors will be used.

  • filter_func – If provided, should be a function that takes a state and return the name of the stash, to which the state should be moved.

  • until – (DEPRECATED) If provided, should be a function that takes a SimulationManager and returns True or False. Stepping will terminate when it is True.

  • n – (DEPRECATED) The number of times to step (default: 1 if “until” is not provided)

Additionally, you can pass in any of the following keyword args for project.factory.successors:

Parameters:
  • jumpkind – The jumpkind of the previous exit

  • addr – An address to execute at instead of the state’s ip.

  • stmt_whitelist – A list of stmt indexes to which to confine execution.

  • last_stmt – A statement index at which to stop execution.

  • thumb – Whether the block should be lifted in ARM’s THUMB mode.

  • backup_state – A state to read bytes from instead of using project memory.

  • opt_level – The VEX optimization level to use.

  • insn_bytes – A string of bytes to use for the block instead of the project.

  • size – The maximum size of the block, in bytes.

  • num_inst – The maximum number of instructions.

  • traceflags – traceflags to be passed to VEX. Default: 0

Returns:

The simulation manager, for chaining.

Return type:

SimulationManager

step_state(state, successor_func=None, error_list=None, **run_args)

Don’t use this function manually - it is meant to interface with exploration techniques.

filter(state, filter_func=None)

Don’t use this function manually - it is meant to interface with exploration techniques.

selector(state, selector_func=None)

Don’t use this function manually - it is meant to interface with exploration techniques.

successors(state, successor_func=None, **run_args)

Don’t use this function manually - it is meant to interface with exploration techniques.

prune(filter_func=None, from_stash='active', to_stash='pruned')

Prune unsatisfiable states from a stash.

This function will move all unsatisfiable states in the given stash into a different stash.

Parameters:
  • filter_func – Only prune states that match this filter.

  • from_stash – Prune states from this stash. (default: ‘active’)

  • to_stash – Put pruned states in this stash. (default: ‘pruned’)

Returns:

The simulation manager, for chaining.

Return type:

SimulationManager

populate(stash, states)

Populate a stash with a collection of states.

Parameters:
  • stash – A stash to populate.

  • states – A list of states with which to populate the stash.

absorb(simgr)

Collect all the states from simgr and put them in their corresponding stashes in this manager. This will not modify simgr.

move(from_stash, to_stash, filter_func=None)

Move states from one stash to another.

Parameters:
  • from_stash – Take matching states from this stash.

  • to_stash – Put matching states into this stash.

  • filter_func – Stash states that match this filter. Should be a function that takes a state and returns True or False. (default: stash all states)

Returns:

The simulation manager, for chaining.

Return type:

SimulationManager

stash(filter_func=None, from_stash='active', to_stash='stashed')

Stash some states. This is an alias for move(), with defaults for the stashes.

Parameters:
  • filter_func – Stash states that match this filter. Should be a function that takes a state and returns True or False. (default: stash all states)

  • from_stash – Take matching states from this stash. (default: ‘active’)

  • to_stash – Put matching states into this stash. (default: ‘stashed’)

Returns:

The simulation manager, for chaining.

Return type:

SimulationManager

unstash(filter_func=None, to_stash='active', from_stash='stashed')

Unstash some states. This is an alias for move(), with defaults for the stashes.

Parameters:
  • filter_func – Unstash states that match this filter. Should be a function that takes a state and returns True or False. (default: unstash all states)

  • from_stash – take matching states from this stash. (default: ‘stashed’)

  • to_stash – put matching states into this stash. (default: ‘active’)

Returns:

The simulation manager, for chaining.

Return type:

SimulationManager

drop(filter_func=None, stash='active')

Drops states from a stash. This is an alias for move(), with defaults for the stashes.

Parameters:
  • filter_func – Drop states that match this filter. Should be a function that takes a state and returns True or False. (default: drop all states)

  • stash – Drop matching states from this stash. (default: ‘active’)

Returns:

The simulation manager, for chaining.

Return type:

SimulationManager

apply(state_func=None, stash_func=None, stash='active', to_stash=None)

Applies a given function to a given stash.

Parameters:
  • state_func – A function to apply to every state. Should take a state and return a state. The returned state will take the place of the old state. If the function doesn’t return a state, the old state will be used. If the function returns a list of states, they will replace the original states.

  • stash_func – A function to apply to the whole stash. Should take a list of states and return a list of states. The resulting list will replace the stash. If both state_func and stash_func are provided state_func is applied first, then stash_func is applied on the results.

  • stash – A stash to work with.

  • to_stash – If specified, this stash will be used to store the resulting states instead.

Returns:

The simulation manager, for chaining.

Return type:

SimulationManager

split(stash_splitter=None, stash_ranker=None, state_ranker=None, limit=8, from_stash='active', to_stash='stashed')

Split a stash of states into two stashes depending on the specified options.

The stash from_stash will be split into two stashes depending on the other options passed in. If to_stash is provided, the second stash will be written there.

stash_splitter overrides stash_ranker, which in turn overrides state_ranker. If no functions are provided, the states are simply split according to the limit.

The sort done with state_ranker is ascending.

Parameters:
  • stash_splitter – A function that should take a list of states and return a tuple of two lists (the two resulting stashes).

  • stash_ranker – A function that should take a list of states and return a sorted list of states. This list will then be split according to “limit”.

  • state_ranker – An alternative to stash_splitter. States will be sorted with outputs of this function, which are to be used as a key. The first “limit” of them will be kept, the rest split off.

  • limit – For use with state_ranker. The number of states to keep. Default: 8

  • from_stash – The stash to split (default: ‘active’)

  • to_stash – The stash to write to (default: ‘stashed’)

Returns:

The simulation manager, for chaining.

Return type:

SimulationManager

merge(merge_func=None, merge_key=None, stash='active', prune=True)

Merge the states in a given stash.

Parameters:
  • stash – The stash (default: ‘active’)

  • merge_func – If provided, instead of using state.merge, call this function with the states as the argument. Should return the merged state.

  • merge_key – If provided, should be a function that takes a state and returns a key that will compare equal for all states that are allowed to be merged together, as a first approximation. By default: uses PC, callstack, and open file descriptors.

  • prune – Whether to prune the stash prior to merging it

Returns:

The simulation manager, for chaining.

Return type:

SimulationManager

exception angr.SimulationManagerError

Bases: AngrError

class angr.StateHierarchy

Bases: object

The state hierarchy holds weak references to SimStateHistory objects in a directed acyclic graph. It is useful for queries about a state’s ancestry, notably “what is the best ancestor state for a merge among these states” and “what is the most recent unsatisfiable state while using LAZY_SOLVES”

__init__()
get_ref(obj)
dead_ref(ref)
defer_cleanup()
add_state(s)
add_history(h)
simplify()
full_simplify()
lineage(h)

Returns the lineage of histories leading up to h.

all_successors(h)
history_successors(h)
history_predecessors(h)
history_contains(h)
unreachable_state(state)
unreachable_history(h)
most_mergeable(states)

Find the “most mergeable” set of states from those provided.

Parameters:

states – a list of states

Returns:

a tuple of: (list of states to merge, those states’ common history, list of states to not merge yet)

exception angr.TracerEnvironmentError

Bases: AngrError

exception angr.UnsupportedCCallError

Bases: SimCCallError, SimUnsupportedError

exception angr.UnsupportedDirtyError

Bases: UnsupportedIRStmtError, SimUnsupportedError

exception angr.UnsupportedIRExprError

Bases: SimExpressionError, SimUnsupportedError

exception angr.UnsupportedIROpError

Bases: SimOperationError, SimUnsupportedError

exception angr.UnsupportedIRStmtError

Bases: SimStatementError, SimUnsupportedError

exception angr.UnsupportedNodeTypeError

Bases: AngrError, NotImplementedError

angr.UnsupportedSyscallError

alias of AngrUnsupportedSyscallError

angr.default_cc(arch, platform='Linux', language=None, syscall=False, default=None)

Return the default calling convention for a given architecture, platform, and language combination.

Parameters:
  • arch (str) – The architecture name.

  • platform (str | None) – The platform name (e.g., “Linux” or “Win32”).

  • language (Optional[str]) – The programming language name (e.g., “go”).

  • syscall (bool) – Return syscall convention (True), or normal calling convention (False, default).

  • default (Optional[type[SimCC]]) – The default calling convention to return if nothing fits.

Return type:

type[SimCC] | None

Returns:

A default calling convention class if we can find one for the architecture, platform, and language combination, or the default if nothing fits.

angr.load_shellcode(shellcode, arch, start_offset=0, load_address=0, thumb=False, **kwargs)

Load a new project based on a snippet of assembly or bytecode.

Parameters:
  • shellcode (bytes | str) – The data to load, as either a bytestring of instructions or a string of assembly text

  • arch – The name of the arch to use, or an archinfo class

  • start_offset – The offset into the data to start analysis (default 0)

  • load_address – The address to place the data in memory (default 0)

  • thumb – Whether this is ARM Thumb shellcode

angr.register_analysis(cls, name)

Project

angr.project.load_shellcode(shellcode, arch, start_offset=0, load_address=0, thumb=False, **kwargs)

Load a new project based on a snippet of assembly or bytecode.

Parameters:
  • shellcode (bytes | str) – The data to load, as either a bytestring of instructions or a string of assembly text

  • arch – The name of the arch to use, or an archinfo class

  • start_offset – The offset into the data to start analysis (default 0)

  • load_address – The address to place the data in memory (default 0)

  • thumb – Whether this is ARM Thumb shellcode

class angr.project.Project(thing, default_analysis_mode=None, ignore_functions=None, use_sim_procedures=True, exclude_sim_procedures_func=None, exclude_sim_procedures_list=(), arch=None, simos=None, engine=None, load_options=None, translation_cache=True, selfmodifying_code=False, support_selfmodifying_code=None, store_function=None, load_function=None, analyses_preset=None, concrete_target=None, eager_ifunc_resolution=None, **kwargs)

Bases: object

This is the main class of the angr module. It is meant to contain a set of binaries and the relationships between them, and perform analyses on them.

Parameters:
  • thing – The path to the main executable object to analyze, or a CLE Loader object.

  • arch (Arch)

  • load_options (dict[str, Any] | None)

  • selfmodifying_code (bool)

  • support_selfmodifying_code (bool | None)

The following parameters are optional.

Parameters:
  • default_analysis_mode – The mode of analysis to use by default. Defaults to ‘symbolic’.

  • ignore_functions – A list of function names that, when imported from shared libraries, should never be stepped into in analysis (calls will return an unconstrained value).

  • use_sim_procedures – Whether to replace resolved dependencies for which simprocedures are available with said simprocedures.

  • exclude_sim_procedures_func – A function that, when passed a function name, returns whether or not to wrap it with a simprocedure.

  • exclude_sim_procedures_list – A list of functions to not wrap with simprocedures.

  • arch – The target architecture (auto-detected otherwise).

  • simos – a SimOS class to use for this project.

  • engine – The SimEngine class to use for this project.

  • translation_cache (bool) – If True, cache translated basic blocks rather than re-translating them.

  • selfmodifying_code (bool) – Whether we aggressively support self-modifying code. When enabled, emulation will try to read code from the current state instead of the original memory, regardless of the current memory protections.

  • store_function – A function that defines how the Project should be stored. Default to pickling.

  • load_function – A function that defines how the Project should be loaded. Default to unpickling.

  • analyses_preset (angr.misc.PluginPreset) – The plugin preset for the analyses provider (i.e. Analyses instance).

  • load_options (dict[str, Any] | None)

  • support_selfmodifying_code (bool | None)

Any additional keyword arguments passed will be passed onto cle.Loader.

Variables:
  • analyses – The available analyses.

  • entry – The program entrypoint.

  • factory – Provides access to important analysis elements such as path groups and symbolic execution results.

  • filename – The filename of the executable.

  • loader – The program loader.

  • storage – Dictionary of things that should be loaded/stored with the Project.

Parameters:
  • arch (Arch)

  • load_options (dict[str, Any] | None)

  • selfmodifying_code (bool)

  • support_selfmodifying_code (bool | None)

__init__(thing, default_analysis_mode=None, ignore_functions=None, use_sim_procedures=True, exclude_sim_procedures_func=None, exclude_sim_procedures_list=(), arch=None, simos=None, engine=None, load_options=None, translation_cache=True, selfmodifying_code=False, support_selfmodifying_code=None, store_function=None, load_function=None, analyses_preset=None, concrete_target=None, eager_ifunc_resolution=None, **kwargs)
Parameters:
  • load_options (dict[str, Any] | None)

  • selfmodifying_code (bool)

  • support_selfmodifying_code (bool | None)

arch: Arch
property kb
get_kb(name)
property analyses: AnalysesHubWithDefault
hook(addr, hook=None, length=0, kwargs=None, replace=False)

Hook a section of code with a custom function. This is used internally to provide symbolic summaries of library functions, and can be used to instrument execution or to modify control flow.

When hook is not specified, it returns a function decorator that allows easy hooking. Usage:

# Assuming proj is an instance of angr.Project, we will add a custom hook at the entry
# point of the project.
@proj.hook(proj.entry)
def my_hook(state):
    print("Welcome to execution!")
Parameters:
  • addr – The address to hook.

  • hook – A angr.project.Hook describing a procedure to run at the given address. You may also pass in a SimProcedure class or a function directly and it will be wrapped in a Hook object for you.

  • length – If you provide a function for the hook, this is the number of bytes that will be skipped by executing the hook by default.

  • kwargs – If you provide a SimProcedure for the hook, these are the keyword arguments that will be passed to the procedure’s run method eventually.

  • replace (bool | None) – Control the behavior on finding that the address is already hooked. If true, silently replace the hook. If false (default), warn and do not replace the hook. If none, warn and replace the hook.

is_hooked(addr)

Returns True if addr is hooked.

Parameters:

addr – An address.

Return type:

bool

Returns:

True if addr is hooked, False otherwise.

hooked_by(addr)

Returns the current hook for addr.

Parameters:

addr – An address.

Return type:

SimProcedure | None

Returns:

None if the address is not hooked.

unhook(addr)

Remove a hook.

Parameters:

addr – The address of the hook.

hook_symbol(symbol_name, simproc, kwargs=None, replace=None)

Resolve a dependency in a binary. Looks up the address of the given symbol, and then hooks that address. If the symbol was not available in the loaded libraries, this address may be provided by the CLE externs object.

Additionally, if instead of a symbol name you provide an address, some secret functionality will kick in and you will probably just hook that address, UNLESS you’re on powerpc64 ABIv1 or some yet-unknown scary ABI that has its function pointers point to something other than the actual functions, in which case it’ll do the right thing.

Parameters:
  • symbol_name – The name of the dependency to resolve.

  • simproc – The SimProcedure instance (or function) with which to hook the symbol

  • kwargs – If you provide a SimProcedure for the hook, these are the keyword arguments that will be passed to the procedure’s run method eventually.

  • replace (Optional[bool]) – Control the behavior on finding that the address is already hooked. If true, silently replace the hook. If false, warn and do not replace the hook. If none (default), warn and replace the hook.

Returns:

The address of the new symbol.

Return type:

int

symbol_hooked_by(symbol_name)

Return the SimProcedure, if it exists, for the given symbol name.

Parameters:

symbol_name (str) – Name of the symbol.

Return type:

SimProcedure | None

Returns:

None if the address is not hooked.

is_symbol_hooked(symbol_name)

Check if a symbol is already hooked.

Parameters:

symbol_name (str) – Name of the symbol.

Returns:

True if the symbol can be resolved and is hooked, False otherwise.

Return type:

bool

unhook_symbol(symbol_name)

Remove the hook on a symbol. This function will fail if the symbol is provided by the extern object, as that would result in a state where analysis would be unable to cope with a call to this symbol.

rehook_symbol(new_address, symbol_name, stubs_on_sync)

Move the hook for a symbol to a specific address :type new_address: :param new_address: the new address that will trigger the SimProc execution :type symbol_name: :param symbol_name: the name of the symbol (f.i. strcmp ) :return: None

execute(*args, **kwargs)

This function is a symbolic execution helper in the simple style supported by triton and manticore. It designed to be run after setting up hooks (see Project.hook), in which the symbolic state can be checked.

This function can be run in three different ways:

  • When run with no parameters, this function begins symbolic execution from the entrypoint.

  • It can also be run with a “state” parameter specifying a SimState to begin symbolic execution from.

  • Finally, it can accept any arbitrary keyword arguments, which are all passed to project.factory.full_init_state.

If symbolic execution finishes, this function returns the resulting simulation manager.

terminate_execution()

Terminates a symbolic execution that was started with Project.execute().

class angr.factory.AngrObjectFactory(project, default_engine=None)

Bases: object

This factory provides access to important analysis elements.

Parameters:

default_engine (type[SimEngine] | None)

__init__(project, default_engine=None)
Parameters:

default_engine (type[SimEngine] | None)

default_engine_factory: type[SimEngine]
project: Project
procedure_engine: ProcedureEngine
property default_engine
snippet(addr, jumpkind=None, **block_opts)
successors(*args, engine=None, **kwargs)

Perform execution using an engine. Generally, return a SimSuccessors object classifying the results of the run.

Parameters:
  • state – The state to analyze

  • engine – The engine to use. If not provided, will use the project default.

  • addr – optional, an address to execute at instead of the state’s ip

  • jumpkind – optional, the jumpkind of the previous exit

  • inline – This is an inline execution. Do not bother copying the state.

Additional keyword arguments will be passed directly into each engine’s process method.

blank_state(**kwargs)

Returns a mostly-uninitialized state object. All parameters are optional.

Parameters:
  • addr – The address the state should start at instead of the entry point.

  • initial_prefix – If this is provided, all symbolic registers will hold symbolic values with names prefixed by this string.

  • fs – A dictionary of file names with associated preset SimFile objects.

  • concrete_fs – bool describing whether the host filesystem should be consulted when opening files.

  • chroot – A path to use as a fake root directory, Behaves similarly to a real chroot. Used only when concrete_fs is set to True.

  • kwargs – Any additional keyword args will be passed to the SimState constructor.

Returns:

The blank state.

Return type:

SimState

entry_state(**kwargs)

Returns a state object representing the program at its entry point. All parameters are optional.

Parameters:
  • addr – The address the state should start at instead of the entry point.

  • initial_prefix – If this is provided, all symbolic registers will hold symbolic values with names prefixed by this string.

  • fs – a dictionary of file names with associated preset SimFile objects.

  • concrete_fs – boolean describing whether the host filesystem should be consulted when opening files.

  • chroot – a path to use as a fake root directory, behaves similar to a real chroot. used only when concrete_fs is set to True.

  • argc – a custom value to use for the program’s argc. May be either an int or a bitvector. If not provided, defaults to the length of args.

  • args – a list of values to use as the program’s argv. May be mixed strings and bitvectors.

  • env – a dictionary to use as the environment for the program. Both keys and values may be mixed strings and bitvectors.

Returns:

The entry state.

Return type:

SimState

full_init_state(**kwargs)

Very much like entry_state(), except that instead of starting execution at the program entry point, execution begins at a special SimProcedure that plays the role of the dynamic loader, calling each of the initializer functions that should be called before execution reaches the entry point.

It can take any of the arguments that can be provided to entry_state, except for addr.

call_state(addr, *args, **kwargs)

Returns a state object initialized to the start of a given function, as if it were called with given parameters.

Parameters:
  • addr – The address the state should start at instead of the entry point.

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

The following parameters are optional.

Parameters:
  • base_state – Use this SimState as the base for the new state instead of a blank state.

  • cc – Optionally provide a SimCC object to use a specific calling convention.

  • ret_addr – Use this address as the function’s return target.

  • stack_base – An optional pointer to use as the top of the stack, circa the function entry point

  • alloc_base – An optional pointer to use as the place to put excess argument data

  • grow_like_stack – When allocating data at alloc_base, whether to allocate at decreasing addresses

  • toc – The address of the table of contents for ppc64

  • initial_prefix – If this is provided, all symbolic registers will hold symbolic values with names prefixed by this string.

  • fs – A dictionary of file names with associated preset SimFile objects.

  • concrete_fs – bool describing whether the host filesystem should be consulted when opening files.

  • chroot – A path to use as a fake root directory, Behaves similarly to a real chroot. Used only when concrete_fs is set to True.

  • kwargs – Any additional keyword args will be passed to the SimState constructor.

Returns:

The state at the beginning of the function.

Return type:

SimState

The idea here is that you can provide almost any kind of python type in args and it’ll be translated to a binary format to be placed into simulated memory. Lists (representing arrays) must be entirely elements of the same type and size, while tuples (representing structs) can be elements of any type and size. If you’d like there to be a pointer to a given value, wrap the value in a SimCC.PointerWrapper. Any value that can’t fit in a register will be automatically put in a PointerWrapper.

If stack_base is not provided, the current stack pointer will be used, and it will be updated. If alloc_base is not provided, the current stack pointer will be used, and it will be updated. You might not like the results if you provide stack_base but not alloc_base.

grow_like_stack controls the behavior of allocating data at alloc_base. When data from args needs to be wrapped in a pointer, the pointer needs to point somewhere, so that data is dumped into memory at alloc_base. If you set alloc_base to point to somewhere other than the stack, set grow_like_stack to False so that sequential allocations happen at increasing addresses.

simulation_manager(thing=None, **kwargs)

Constructs a new simulation manager.

Parameters:
  • thing (Union[list[SimState], SimState, None]) – What to put in the new SimulationManager’s active stash (either a SimState or a list of SimStates).

  • kwargs – Any additional keyword arguments will be passed to the SimulationManager constructor

Returns:

The new SimulationManager

Return type:

angr.sim_manager.SimulationManager

Many different types can be passed to this method:

  • If nothing is passed in, the SimulationManager is seeded with a state initialized for the program entry point, i.e. entry_state().

  • If a SimState is passed in, the SimulationManager is seeded with that state.

  • If a list is passed in, the list must contain only SimStates and the whole list will be used to seed the SimulationManager.

simgr(*args, **kwargs)

Alias for simulation_manager to save our poor fingers

callable(addr, prototype=None, concrete_only=False, perform_merge=True, base_state=None, toc=None, cc=None, add_options=None, remove_options=None, step_limit=None)

A Callable is a representation of a function in the binary that can be interacted with like a native python function.

Parameters:
  • addr (int | Function) – The address of the function to use. If you pass in the function object, we will take its addr.

  • prototype – The prototype of the call to use, as a string or a SimTypeFunction

  • concrete_only – Throw an exception if the execution splits into multiple states

  • perform_merge – Merge all result states into one at the end (only relevant if concrete_only=False)

  • base_state – The state from which to do these runs

  • toc – The address of the table of contents for ppc64

  • cc – The SimCC to use for a calling convention

  • step_limit (Optional[int]) – The maximum number of blocks that Callable will execute before pruning the path.

Returns:

A Callable object that can be used as a interface for executing guest code like a python function.

Return type:

angr.callable.Callable

cc()

Return a SimCC (calling convention) parameterized for this project.

Relevant subclasses of SimFunctionArgument are SimRegArg and SimStackArg, and shortcuts to them can be found on this cc object.

For stack arguments, offsets are relative to the stack pointer on function entry.

function_prototype()

Return a default function prototype parameterized for this project and SimOS.

block(addr, size=None, max_size=None, byte_string=None, thumb=False, backup_state=None, extra_stop_points=None, opt_level=None, num_inst=None, traceflags=0, insn_bytes=None, strict_block_end=None, collect_data_refs=False, cross_insn_opt=True, load_from_ro_regions=False, const_prop=False, initial_regs=None, skip_stmts=False)
fresh_block(addr, size, backup_state=None)
class angr.block.DisassemblerBlock(addr, insns, thumb, arch)

Bases: object

Helper class to represent a block of disassembled target architecture instructions

__init__(addr, insns, thumb, arch)
addr
insns
thumb
arch
pp()
class angr.block.DisassemblerInsn

Bases: object

Helper class to represent a disassembled target architecture instruction

property size: int
property address: int
property mnemonic: str
property op_str: str
class angr.block.CapstoneBlock(addr, insns, thumb, arch)

Bases: DisassemblerBlock

Deep copy of the capstone blocks, which have serious issues with having extended lifespans outside of capstone itself

class angr.block.CapstoneInsn(capstone_insn)

Bases: DisassemblerInsn

Represents a capstone instruction.

__init__(capstone_insn)
insn
property size: int
property address: int
property mnemonic: str
property op_str: str
class angr.block.Block(addr, project=None, arch=None, size=None, max_size=None, byte_string=None, thumb=False, backup_state=None, extra_stop_points=None, opt_level=None, num_inst=None, traceflags=0, strict_block_end=None, collect_data_refs=False, cross_insn_opt=True, load_from_ro_regions=False, const_prop=False, initial_regs=None, skip_stmts=False)

Bases: Serializable

Represents a basic block in a binary or a program.

Parameters:

arch (Arch | None)

BLOCK_MAX_SIZE = 4096
__init__(addr, project=None, arch=None, size=None, max_size=None, byte_string=None, thumb=False, backup_state=None, extra_stop_points=None, opt_level=None, num_inst=None, traceflags=0, strict_block_end=None, collect_data_refs=False, cross_insn_opt=True, load_from_ro_regions=False, const_prop=False, initial_regs=None, skip_stmts=False)
Parameters:

arch (Arch | None)

arch
addr
thumb
size
pp(**kwargs)
set_initial_regs()
static reset_initial_regs()
property vex: IRSB | IRSB
property vex_nostmt
property disassembly: DisassemblerBlock

Provide a disassembly object using whatever disassembler is available

property capstone: CapstoneBlock
property codenode
property bytes: bytes | None
property instructions: int
property instruction_addrs
serialize_to_cmessage()

Serialize the class object and returns a protobuf cmessage object.

Returns:

A protobuf cmessage object.

Return type:

protobuf.cmessage

classmethod parse_from_cmessage(cmsg)

Parse a protobuf cmessage and create a class object.

Parameters:

cmsg – The probobuf cmessage object.

Returns:

A unserialized class object.

Return type:

cls

class angr.block.SootBlock(addr, *, project, arch)

Bases: object

Represents a Soot IR basic block.

Parameters:
__init__(addr, *, project, arch)
Parameters:
property soot
property size
property codenode

Plugin Ecosystem

class angr.misc.plugins.PluginHub

Bases: Generic[P]

A plugin hub is an object which contains many plugins, as well as the notion of a “preset”, or a backer that can provide default implementations of plugins which cater to a certain circumstance.

Objects in angr like the SimState, the Analyses hub, the SimEngine selector, etc all use this model to unify their mechanisms for automatically collecting and selecting components to use. If you’re familiar with design patterns this is a configurable Strategy Pattern.

Each PluginHub subclass should have a corresponding Plugin subclass, and perhaps a PluginPreset subclass if it wants its presets to be able to specify anything more interesting than a list of defaults.

__init__()
classmethod register_default(name, plugin_cls, preset='default')
classmethod register_preset(name, preset)

Register a preset instance with the class of the hub it corresponds to. This allows individual plugin objects to automatically register themselves with a preset by using a classmethod of their own with only the name of the preset to register with.

property plugin_preset

Get the current active plugin preset

property has_plugin_preset: bool

Check whether or not there is a plugin preset in use on this hub right now

use_plugin_preset(preset)

Apply a preset to the hub. If there was a previously active preset, discard it.

Preset can be either the string name of a preset or a PluginPreset instance.

discard_plugin_preset()

Discard the current active preset. Will release any active plugins that could have come from the old preset.

get_plugin(name)

Get the plugin named name. If no such plugin is currently active, try to activate a new one using the current preset.

Return type:

TypeVar(P)

Parameters:

name (str)

has_plugin(name)

Return whether or not a plugin with the name name is currently active.

register_plugin(name, plugin)

Add a new plugin plugin with name name to the active plugins.

Parameters:

name (str)

release_plugin(name)

Deactivate and remove the plugin with name name.

class angr.misc.plugins.PluginPreset

Bases: object

A plugin preset object contains a mapping from name to a plugin class. A preset can be active on a hub, which will cause it to handle requests for plugins which are not already present on the hub.

Unlike Plugins and PluginHubs, instances of PluginPresets are defined on the module level for individual presets. You should register the preset instance with a hub to allow plugins to easily add themselves to the preset without an explicit reference to the preset itself.

__init__()
activate(hub)

This method is called when the preset becomes active on a hub.

deactivate(hub)

This method is called when the preset is discarded from the hub.

add_default_plugin(name, plugin_cls)

Add a plugin to the preset.

list_default_plugins()

Return a list of the names of available default plugins.

request_plugin(name)

Return the plugin class which is registered under the name name, or raise NoPlugin if the name isn’t available.

Return type:

type[TypeVar(P)]

Parameters:

name (str)

copy()

Return a copy of self.

class angr.misc.plugins.PluginVendor

Bases: Generic[P], PluginHub[P]

A specialized hub which serves only as a plugin vendor, never having any “active” plugins. It will directly return the plugins provided by the preset instead of instantiating them.

release_plugin(name)

Deactivate and remove the plugin with name name.

register_plugin(name, plugin)

Add a new plugin plugin with name name to the active plugins.

class angr.misc.plugins.VendorPreset

Bases: PluginPreset

A specialized preset class for use with the PluginVendor.

Program State

angr.sim_state.arch_overridable(f)
class angr.sim_state.SimState(project=None, arch=None, plugins=None, mode=None, options=None, add_options=None, remove_options=None, special_memory_filler=None, os_name=None, plugin_preset='default', cle_memory_backer=None, dict_memory_backer=None, permissions_map=None, default_permissions=3, stack_perms=None, stack_end=None, stack_size=None, regioned_memory_cls=None, **kwargs)

Bases: Generic[IPTypeConc, IPTypeSym], PluginHub[SimStatePlugin]

The SimState represents the state of a program, including its memory, registers, and so forth.

Parameters:
Variables:
  • regs – A convenient view of the state’s registers, where each register is a property

  • mem – A convenient view of the state’s memory, a angr.state_plugins.view.SimMemView

  • registers – The state’s register file as a flat memory region

  • memory – The state’s memory as a flat memory region

  • solver – The symbolic solver and variable manager for this state

  • inspect – The breakpoint manager, a angr.state_plugins.inspect.SimInspector

  • log – Information about the state’s history

  • scratch – Information about the current execution step

  • posix – MISNOMER: information about the operating system or environment model

  • fs – The current state of the simulated filesystem

  • libc – Information about the standard library we are emulating

  • cgc – Information about the cgc environment

  • uc_manager – Control of under-constrained symbolic execution

  • unicorn – Control of the Unicorn Engine

solver: SimSolver
posix: SimSystemPosix
registers: DefaultMemory
regs: SimRegNameView
memory: DefaultMemory
callstack: CallStack
mem: SimMemView
history: SimStateHistory
inspect: SimInspector
jni_references: SimStateJNIReferences
scratch: SimStateScratch
__init__(project=None, arch=None, plugins=None, mode=None, options=None, add_options=None, remove_options=None, special_memory_filler=None, os_name=None, plugin_preset='default', cle_memory_backer=None, dict_memory_backer=None, permissions_map=None, default_permissions=3, stack_perms=None, stack_end=None, stack_size=None, regioned_memory_cls=None, **kwargs)
Parameters:
property plugins
property ip

Get the instruction pointer expression, trigger SimInspect breakpoints, and generate SimActions. Use _ip to not trigger breakpoints or generate actions.

Returns:

an expression

property addr: IPTypeConc

Get the concrete address of the instruction pointer, without triggering SimInspect breakpoints or generating SimActions. An integer is returned, or an exception is raised if the instruction pointer is symbolic.

Returns:

an int

property arch: Arch
T = ~T
get_plugin(name)

Get the plugin named name. If no such plugin is currently active, try to activate a new one using the current preset.

has_plugin(name)

Return whether or not a plugin with the name name is currently active.

register_plugin(name, plugin, inhibit_init=False)

Add a new plugin plugin with name name to the active plugins.

property javavm_memory

In case of an JavaVM with JNI support, a state can store the memory plugin twice; one for the native and one for the java view of the state.

Returns:

The JavaVM view of the memory plugin.

property javavm_registers

In case of an JavaVM with JNI support, a state can store the registers plugin twice; one for the native and one for the java view of the state.

Returns:

The JavaVM view of the registers plugin.

simplify(*args)

Simplify this state’s constraints.

add_constraints(*constraints)

Add some constraints to the state.

You may pass in any number of symbolic booleans as variadic positional arguments.

satisfiable(**kwargs)

Whether the state’s constraints are satisfiable

downsize()

Clean up after the solver engine. Calling this when a state no longer needs to be solved on will reduce memory usage.

step(**kwargs)

Perform a step of symbolic execution using this state. Any arguments to AngrObjectFactory.successors can be passed to this.

Returns:

A SimSuccessors object categorizing the results of the step.

block(*args, **kwargs)

Represent the basic block at this state’s instruction pointer. Any arguments to AngrObjectFactory.block can ba passed to this.

Returns:

A Block object describing the basic block of code at this point.

copy()

Returns a copy of the state.

merge(*others, **kwargs)

Merges this state with the other states. Returns the merging result, merged state, and the merge flag.

Parameters:
  • states – the states to merge

  • merge_conditions – a tuple of the conditions under which each state holds

  • common_ancestor – a state that represents the common history between the states being merged. Usually it is only available when EFFICIENT_STATE_MERGING is enabled, otherwise weak-refed states might be dropped from state history instances.

  • plugin_whitelist – a list of plugin names that will be merged. If this option is given and is not None, any plugin that is not inside this list will not be merged, and will be created as a fresh instance in the new state.

  • common_ancestor_history – a SimStateHistory instance that represents the common history between the states being merged. This is to allow optimal state merging when EFFICIENT_STATE_MERGING is disabled.

Returns:

(merged state, merge flag, a bool indicating if any merging occurred)

widen(*others)

Perform a widening between self and other states :type others: :param others: :return:

reg_concrete(*args, **kwargs)

Returns the contents of a register but, if that register is symbolic, raises a SimValueError.

mem_concrete(*args, **kwargs)

Returns the contents of a memory but, if the contents are symbolic, raises a SimValueError.

stack_push(thing)

Push ‘thing’ to the stack, writing the thing to memory and adjusting the stack pointer.

stack_pop()

Pops from the stack and returns the popped thing. The length will be the architecture word size.

stack_read(offset, length, bp=False)

Reads length bytes, at an offset into the stack.

Parameters:
  • offset – The offset from the stack pointer.

  • length – The number of bytes to read.

  • bp – If True, offset from the BP instead of the SP. Default: False.

make_concrete_int(expr)
prepare_callsite(retval, args, cc='wtf')
dbg_print_stack(depth=None, sp=None)

Only used for debugging purposes. Return the current stack info in formatted string. If depth is None, the current stack frame (from sp to bp) will be printed out.

set_mode(mode)
property thumb
property with_condition
class angr.sim_state_options.StateOption(name, types, default='_NO_DEFAULT_VALUE', description=None)

Bases: object

Describes a state option.

__init__(name, types, default='_NO_DEFAULT_VALUE', description=None)
name
types
default
description
property has_default_value
one_type()
class angr.sim_state_options.SimStateOptions(thing)

Bases: object

A per-state manager of state options. An option can be either a key-valued entry or a Boolean switch (which can be seen as a key-valued entry whose value can only be either True or False).

OPTIONS = {'ABSTRACT_MEMORY': <O ABSTRACT_MEMORY[bool]>, 'ABSTRACT_SOLVER': <O ABSTRACT_SOLVER[bool]>, 'ACTION_DEPS': <O ACTION_DEPS[bool]>, 'ADD_AUTO_REFS': <O ADD_AUTO_REFS[bool]>, 'ALLOW_SEND_FAILURES': <O ALLOW_SEND_FAILURES[bool]>, 'ALL_FILES_EXIST': <O ALL_FILES_EXIST[bool]>, 'ANY_FILE_MIGHT_EXIST': <O ANY_FILE_MIGHT_EXIST[bool]>, 'APPROXIMATE_FIRST': <O APPROXIMATE_FIRST[bool]>, 'APPROXIMATE_GUARDS': <O APPROXIMATE_GUARDS[bool]>, 'APPROXIMATE_MEMORY_INDICES': <O APPROXIMATE_MEMORY_INDICES[bool]>, 'APPROXIMATE_MEMORY_SIZES': <O APPROXIMATE_MEMORY_SIZES[bool]>, 'APPROXIMATE_SATISFIABILITY': <O APPROXIMATE_SATISFIABILITY[bool]>, 'AST_DEPS': <O AST_DEPS[bool]>, 'AUTO_REFS': <O AUTO_REFS[bool]>, 'AVOID_MULTIVALUED_READS': <O AVOID_MULTIVALUED_READS[bool]>, 'AVOID_MULTIVALUED_WRITES': <O AVOID_MULTIVALUED_WRITES[bool]>, 'BEST_EFFORT_MEMORY_STORING': <O BEST_EFFORT_MEMORY_STORING[bool]>, 'BYPASS_ERRORED_IRCCALL': <O BYPASS_ERRORED_IRCCALL[bool]>, 'BYPASS_ERRORED_IROP': <O BYPASS_ERRORED_IROP[bool]>, 'BYPASS_ERRORED_IRSTMT': <O BYPASS_ERRORED_IRSTMT[bool]>, 'BYPASS_UNSUPPORTED_IRCCALL': <O BYPASS_UNSUPPORTED_IRCCALL[bool]>, 'BYPASS_UNSUPPORTED_IRDIRTY': <O BYPASS_UNSUPPORTED_IRDIRTY[bool]>, 'BYPASS_UNSUPPORTED_IREXPR': <O BYPASS_UNSUPPORTED_IREXPR[bool]>, 'BYPASS_UNSUPPORTED_IROP': <O BYPASS_UNSUPPORTED_IROP[bool]>, 'BYPASS_UNSUPPORTED_IRSTMT': <O BYPASS_UNSUPPORTED_IRSTMT[bool]>, 'BYPASS_UNSUPPORTED_SYSCALL': <O BYPASS_UNSUPPORTED_SYSCALL[bool]>, 'BYPASS_VERITESTING_EXCEPTIONS': <O BYPASS_VERITESTING_EXCEPTIONS[bool]>, 'CACHELESS_SOLVER': <O CACHELESS_SOLVER[bool]>, 'CALLLESS': <O CALLLESS[bool]>, 'CGC_ENFORCE_FD': <O CGC_ENFORCE_FD[bool]>, 'CGC_NON_BLOCKING_FDS': <O CGC_NON_BLOCKING_FDS[bool]>, 'CGC_NO_SYMBOLIC_RECEIVE_LENGTH': <O CGC_NO_SYMBOLIC_RECEIVE_LENGTH[bool]>, 'COMPOSITE_SOLVER': <O COMPOSITE_SOLVER[bool]>, 'CONCRETIZE': <O CONCRETIZE[bool]>, 'CONCRETIZE_SYMBOLIC_FILE_READ_SIZES': <O CONCRETIZE_SYMBOLIC_FILE_READ_SIZES[bool]>, 'CONCRETIZE_SYMBOLIC_WRITE_SIZES': <O CONCRETIZE_SYMBOLIC_WRITE_SIZES[bool]>, 'CONSERVATIVE_READ_STRATEGY': <O CONSERVATIVE_READ_STRATEGY[bool]>, 'CONSERVATIVE_WRITE_STRATEGY': <O CONSERVATIVE_WRITE_STRATEGY[bool]>, 'CONSTRAINT_TRACKING_IN_SOLVER': <O CONSTRAINT_TRACKING_IN_SOLVER[bool]>, 'COPY_STATES': <O COPY_STATES[bool]>, 'CPUID_SYMBOLIC': <O CPUID_SYMBOLIC[bool]>, 'DOWNSIZE_Z3': <O DOWNSIZE_Z3[bool]>, 'DO_CCALLS': <O DO_CCALLS[bool]>, 'DO_RET_EMULATION': <O DO_RET_EMULATION[bool]>, 'EFFICIENT_STATE_MERGING': <O EFFICIENT_STATE_MERGING[bool]>, 'ENABLE_NX': <O ENABLE_NX[bool]>, 'EXCEPTION_HANDLING': <O EXCEPTION_HANDLING[bool]>, 'EXTENDED_IROP_SUPPORT': <O EXTENDED_IROP_SUPPORT[bool]>, 'FAST_MEMORY': <O FAST_MEMORY[bool]>, 'FAST_REGISTERS': <O FAST_REGISTERS[bool]>, 'FILES_HAVE_EOF': <O FILES_HAVE_EOF[bool]>, 'HYBRID_SOLVER': <O HYBRID_SOLVER[bool]>, 'JAVA_IDENTIFY_GETTER_SETTER': <O JAVA_IDENTIFY_GETTER_SETTER[bool]>, 'JAVA_TRACK_ATTRIBUTES': <O JAVA_TRACK_ATTRIBUTES[bool]>, 'KEEP_IP_SYMBOLIC': <O KEEP_IP_SYMBOLIC[bool]>, 'LAZY_SOLVES': <O LAZY_SOLVES[bool]>, 'MEMORY_CHUNK_INDIVIDUAL_READS': <O MEMORY_CHUNK_INDIVIDUAL_READS[bool]>, 'MEMORY_FIND_STRICT_SIZE_LIMIT': <O MEMORY_FIND_STRICT_SIZE_LIMIT[bool]>, 'MEMORY_SYMBOLIC_BYTES_MAP': <O MEMORY_SYMBOLIC_BYTES_MAP[bool]>, 'NO_CROSS_INSN_OPT': <O NO_CROSS_INSN_OPT[bool]>, 'NO_IP_CONCRETIZATION': <O NO_IP_CONCRETIZATION[bool]>, 'NO_SYMBOLIC_JUMP_RESOLUTION': <O NO_SYMBOLIC_JUMP_RESOLUTION[bool]>, 'NO_SYMBOLIC_SYSCALL_RESOLUTION': <O NO_SYMBOLIC_SYSCALL_RESOLUTION[bool]>, 'OPTIMIZE_IR': <O OPTIMIZE_IR[bool]>, 'PRODUCE_ZERODIV_SUCCESSORS': <O PRODUCE_ZERODIV_SUCCESSORS[bool]>, 'REGION_MAPPING': <O REGION_MAPPING[bool]>, 'REPLACEMENT_SOLVER': <O REPLACEMENT_SOLVER[bool]>, 'REVERSE_MEMORY_HASH_MAP': <O REVERSE_MEMORY_HASH_MAP[bool]>, 'REVERSE_MEMORY_NAME_MAP': <O REVERSE_MEMORY_NAME_MAP[bool]>, 'SHORT_READS': <O SHORT_READS[bool]>, 'SIMPLIFY_CONSTRAINTS': <O SIMPLIFY_CONSTRAINTS[bool]>, 'SIMPLIFY_EXIT_GUARD': <O SIMPLIFY_EXIT_GUARD[bool]>, 'SIMPLIFY_EXIT_STATE': <O SIMPLIFY_EXIT_STATE[bool]>, 'SIMPLIFY_EXIT_TARGET': <O SIMPLIFY_EXIT_TARGET[bool]>, 'SIMPLIFY_EXPRS': <O SIMPLIFY_EXPRS[bool]>, 'SIMPLIFY_MEMORY_READS': <O SIMPLIFY_MEMORY_READS[bool]>, 'SIMPLIFY_MEMORY_WRITES': <O SIMPLIFY_MEMORY_WRITES[bool]>, 'SIMPLIFY_MERGED_CONSTRAINTS': <O SIMPLIFY_MERGED_CONSTRAINTS[bool]>, 'SIMPLIFY_REGISTER_READS': <O SIMPLIFY_REGISTER_READS[bool]>, 'SIMPLIFY_REGISTER_WRITES': <O SIMPLIFY_REGISTER_WRITES[bool]>, 'SIMPLIFY_RETS': <O SIMPLIFY_RETS[bool]>, 'SPECIAL_MEMORY_FILL': <O SPECIAL_MEMORY_FILL[bool]>, 'STRICT_PAGE_ACCESS': <O STRICT_PAGE_ACCESS[bool]>, 'SUPER_FASTPATH': <O SUPER_FASTPATH[bool]>, 'SUPPORT_FLOATING_POINT': <O SUPPORT_FLOATING_POINT[bool]>, 'SYMBION_KEEP_STUBS_ON_SYNC': <O SYMBION_KEEP_STUBS_ON_SYNC[bool]>, 'SYMBION_SYNC_CLE': <O SYMBION_SYNC_CLE[bool]>, 'SYMBOLIC': <O SYMBOLIC[bool]>, 'SYMBOLIC_INITIAL_VALUES': <O SYMBOLIC_INITIAL_VALUES[bool]>, 'SYMBOLIC_MEMORY_NO_SINGLEVALUE_OPTIMIZATIONS': <O SYMBOLIC_MEMORY_NO_SINGLEVALUE_OPTIMIZATIONS[bool]>, 'SYMBOLIC_TEMPS': <O SYMBOLIC_TEMPS[bool]>, 'SYMBOLIC_WRITE_ADDRESSES': <O SYMBOLIC_WRITE_ADDRESSES[bool]>, 'SYMBOL_FILL_UNCONSTRAINED_MEMORY': <O SYMBOL_FILL_UNCONSTRAINED_MEMORY[bool]>, 'SYMBOL_FILL_UNCONSTRAINED_REGISTERS': <O SYMBOL_FILL_UNCONSTRAINED_REGISTERS[bool]>, 'SYNC_CLE_BACKEND_CONCRETE': <O SYNC_CLE_BACKEND_CONCRETE[bool]>, 'TRACK_ACTION_HISTORY': <O TRACK_ACTION_HISTORY[bool]>, 'TRACK_CONSTRAINTS': <O TRACK_CONSTRAINTS[bool]>, 'TRACK_CONSTRAINT_ACTIONS': <O TRACK_CONSTRAINT_ACTIONS[bool]>, 'TRACK_JMP_ACTIONS': <O TRACK_JMP_ACTIONS[bool]>, 'TRACK_MEMORY_ACTIONS': <O TRACK_MEMORY_ACTIONS[bool]>, 'TRACK_MEMORY_MAPPING': <O TRACK_MEMORY_MAPPING[bool]>, 'TRACK_OP_ACTIONS': <O TRACK_OP_ACTIONS[bool]>, 'TRACK_REGISTER_ACTIONS': <O TRACK_REGISTER_ACTIONS[bool]>, 'TRACK_SOLVER_VARIABLES': <O TRACK_SOLVER_VARIABLES[bool]>, 'TRACK_TMP_ACTIONS': <O TRACK_TMP_ACTIONS[bool]>, 'TRUE_RET_EMULATION_GUARD': <O TRUE_RET_EMULATION_GUARD[bool]>, 'UNDER_CONSTRAINED_SYMEXEC': <O UNDER_CONSTRAINED_SYMEXEC[bool]>, 'UNICORN': <O UNICORN[bool]>, 'UNICORN_AGGRESSIVE_CONCRETIZATION': <O UNICORN_AGGRESSIVE_CONCRETIZATION[bool]>, 'UNICORN_HANDLE_CGC_RANDOM_SYSCALL': <O UNICORN_HANDLE_CGC_RANDOM_SYSCALL[bool]>, 'UNICORN_HANDLE_CGC_RECEIVE_SYSCALL': <O UNICORN_HANDLE_CGC_RECEIVE_SYSCALL[bool]>, 'UNICORN_HANDLE_CGC_TRANSMIT_SYSCALL': <O UNICORN_HANDLE_CGC_TRANSMIT_SYSCALL[bool]>, 'UNICORN_HANDLE_SYMBOLIC_ADDRESSES': <O UNICORN_HANDLE_SYMBOLIC_ADDRESSES[bool]>, 'UNICORN_HANDLE_SYMBOLIC_CONDITIONS': <O UNICORN_HANDLE_SYMBOLIC_CONDITIONS[bool]>, 'UNICORN_HANDLE_SYMBOLIC_SYSCALLS': <O UNICORN_HANDLE_SYMBOLIC_SYSCALLS[bool]>, 'UNICORN_SYM_REGS_SUPPORT': <O UNICORN_SYM_REGS_SUPPORT[bool]>, 'UNICORN_THRESHOLD_CONCRETIZATION': <O UNICORN_THRESHOLD_CONCRETIZATION[bool]>, 'UNICORN_TRACK_BBL_ADDRS': <O UNICORN_TRACK_BBL_ADDRS[bool]>, 'UNICORN_TRACK_STACK_POINTERS': <O UNICORN_TRACK_STACK_POINTERS[bool]>, 'UNICORN_ZEROPAGE_GUARD': <O UNICORN_ZEROPAGE_GUARD[bool]>, 'UNINITIALIZED_ACCESS_AWARENESS': <O UNINITIALIZED_ACCESS_AWARENESS[bool]>, 'UNSUPPORTED_BYPASS_ZERO_DEFAULT': <O UNSUPPORTED_BYPASS_ZERO_DEFAULT[bool]>, 'UNSUPPORTED_FORCE_CONCRETIZE': <O UNSUPPORTED_FORCE_CONCRETIZE[bool]>, 'USE_SIMPLIFIED_CCALLS': <O USE_SIMPLIFIED_CCALLS[bool]>, 'USE_SYSTEM_TIMES': <O USE_SYSTEM_TIMES[bool]>, 'VALIDATE_APPROXIMATIONS': <O VALIDATE_APPROXIMATIONS[bool]>, 'ZERO_FILL_UNCONSTRAINED_MEMORY': <O ZERO_FILL_UNCONSTRAINED_MEMORY[bool]>, 'ZERO_FILL_UNCONSTRAINED_REGISTERS': <O ZERO_FILL_UNCONSTRAINED_REGISTERS[bool]>, 'jumptable_symbolic_ip_max_targets': <O jumptable_symbolic_ip_max_targets[int]: The maximum number of concrete addresses a symbolic instruction pointer can be concretized to if it is part of a jump table.>, 'symbolic_ip_max_targets': <O symbolic_ip_max_targets[int]: The maximum number of concrete addresses a symbolic instruction pointer can be concretized to.>}
__init__(thing)
Parameters:

thing – Either a set of Boolean switches to enable, or an existing SimStateOptions instance.

add(boolean_switch)

[COMPATIBILITY] Enable a Boolean switch.

Parameters:

boolean_switch (str) – Name of the Boolean switch.

Returns:

None

update(boolean_switches)

[COMPATIBILITY] In order to be compatible with the old interface, you can enable a collection of Boolean switches at the same time by doing the following:

>>> state.options.update({sim_options.SYMBOLIC, sim_options.ABSTRACT_MEMORY})

or

>>> state.options.update(sim_options.unicorn)
Parameters:

boolean_switches (set) – A collection of Boolean switches to enable.

Returns:

None

remove(name)

Drop a state option if it exists, or raise a KeyError if the state option is not set.

[COMPATIBILITY] Remove a Boolean switch.

Parameters:

name (str) – Name of the state option.

Returns:

NNone

discard(name)

Drop a state option if it exists, or silently return if the state option is not set.

[COMPATIBILITY] Disable a Boolean switch.

Parameters:

name (str) – Name of the Boolean switch.

Returns:

None

difference(boolean_switches)

[COMPATIBILITY] Make a copy of the current instance, and then discard all options that are in boolean_switches.

Parameters:

boolean_switches (set) – A collection of Boolean switches to disable.

Returns:

A new SimStateOptions instance.

copy()

Get a copy of the current SimStateOptions instance.

Returns:

A new SimStateOptions instance.

Return type:

SimStateOptions

tally(exclude_false=True, description=False)

Return a string representation of all state options.

Parameters:
  • exclude_false (bool) – Whether to exclude Boolean switches that are disabled.

  • description (bool) – Whether to display the description of each option.

Returns:

A string representation.

Return type:

str

classmethod register_option(name, types, default=None, description=None)

Register a state option.

Parameters:
  • name (str) – Name of the state option.

  • types – A collection of allowed types of this state option.

  • default – The default value of this state option.

  • description (str) – The description of this state option.

Returns:

None

classmethod register_bool_option(name, description=None)

Register a Boolean switch as state option. This is equivalent to cls.register_option(name, set([bool]), description=description)

Parameters:
  • name (str) – Name of the state option.

  • description (str) – The description of this state option.

Returns:

None

class angr.state_plugins.GDB(omit_fp=False, adjust_stack=False)

Bases: SimStatePlugin

Initialize or update a state from gdb dumps of the stack, heap, registers and data (or arbitrary) segments.

__init__(omit_fp=False, adjust_stack=False)
Parameters:
  • omit_fp – The frame pointer register is used for something else. (i.e. –omit_frame_pointer)

  • adjust_stack – Use different stack addresses than the gdb session (not recommended).

set_stack(stack_dump, stack_top)

Stack dump is a dump of the stack from gdb, i.e. the result of the following gdb command :

dump binary memory [stack_dump] [begin_addr] [end_addr]

We set the stack to the same addresses as the gdb session to avoid pointers corruption.

Parameters:
  • stack_dump – The dump file.

  • stack_top – The address of the top of the stack in the gdb session.

set_heap(heap_dump, heap_base)

Heap dump is a dump of the heap from gdb, i.e. the result of the following gdb command:

dump binary memory [stack_dump] [begin] [end]

Parameters:
  • heap_dump – The dump file.

  • heap_base – The start address of the heap in the gdb session.

set_data(addr, data_dump)

Update any data range (most likely use is the data segments of loaded objects)

set_regs(regs_dump)

Initialize register values within the state

Parameters:

regs_dump – The output of info registers in gdb.

copy(memo: dict[int, Any] | None = None, **kwargs: Any) S_co

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:
  • memo (Optional[dict[int, Any]]) – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

  • kwargs (Any)

Return type:

TypeVar(S_co, covariant=True)

class angr.state_plugins.CallStack(call_site_addr=0, func_addr=0, stack_ptr=0, ret_addr=0, jumpkind='Ijk_Call', next_frame=None, invoke_return_variable=None)

Bases: SimStatePlugin

Stores the address of the function you’re in and the value of SP at the VERY BOTTOM of the stack, i.e. points to the return address.

Parameters:

next_frame (CallStack | None)

__init__(call_site_addr=0, func_addr=0, stack_ptr=0, ret_addr=0, jumpkind='Ijk_Call', next_frame=None, invoke_return_variable=None)
Parameters:

next_frame (CallStack | None)

copy(memo: dict[int, Any] | None = None, **kwargs: Any) S_co

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:
  • memo (Optional[dict[int, Any]]) – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

  • kwargs (Any)

Return type:

TypeVar(S_co, covariant=True)

set_state(state)

Sets a new state (for example, if the state has been branched)

merge(others, merge_conditions, common_ancestor=None)

Should merge the state plugin with the provided others. This will be called by state.merge() after copying the target state, so this should mutate the current instance to merge with the others.

Note that when multiple instances of a single plugin object (for example, a file) are referenced in the state, it is important that merge only ever be called once. This should be solved by designating one of the plugin’s referees as the “real owner”, who should be the one to actually merge it. This technique doesn’t work to resolve the similar issue that arises during copying because merging doesn’t produce a new reference to insert.

There will be n others and n+1 merge conditions, since the first condition corresponds to self. To match elements up to conditions, say zip([self] + others, merge_conditions)

When implementing this, make sure that you “deepen” both others and common_ancestor before calling sub-elements’ merge methods, e.g.

self.foo.merge(
    [o.foo for o in others],
    merge_conditions,
    common_ancestor=common_ancestor.foo if common_ancestor is not None else None
)

During static analysis, merge_conditions can be None, in which case you should use state.solver.union(values). TODO: fish please make this less bullshit

There is a utility claripy.ite_cases which will help with constructing arbitrarily large merged ASTs. Use it like self.bar = claripy.ite_cases(zip(conditions[1:], [o.bar for o in others]), self.bar)

Parameters:
  • others – the other state plugins to merge with

  • merge_conditions – a symbolic condition for each of the plugins

  • common_ancestor – a common ancestor of this plugin and the others being merged

Returns:

True if the state plugins are actually merged.

Return type:

bool

widen(others)

The widening operation for plugins. Widening is a special kind of merging that produces a more general state from several more specific states. It is used only during intensive static analysis. The same behavior regarding copying and mutation from merge should be followed.

Parameters:

others – the other state plugin

Returns:

True if the state plugin is actually widened.

Return type:

bool

property current_function_address

Address of the current function.

Returns:

the address of the function

Return type:

int

property current_stack_pointer

Get the value of the stack pointer.

Returns:

Value of the stack pointer

Return type:

int

property current_return_target

Get the return target.

Returns:

The address of return target.

Return type:

int

static stack_suffix_to_string(stack_suffix)

Convert a stack suffix to a human-readable string representation. :param tuple stack_suffix: The stack suffix. :return: A string representation :rtype: str

property top

Returns the element at the top of the callstack without removing it.

Returns:

A CallStack.

push(cf)

Push the frame cf onto the stack. Return the new stack.

pop()

Pop the top frame from the stack. Return the new stack.

call(callsite_addr, addr, retn_target=None, stack_pointer=None)

Push a stack frame into the call stack. This method is called when calling a function in CFG recovery.

Parameters:
  • callsite_addr (int) – Address of the call site

  • addr (int) – Address of the call target

  • retn_target (int or None) – Address of the return target

  • stack_pointer (int) – Value of the stack pointer

Returns:

None

ret(retn_target=None)

Pop one or many call frames from the stack. This method is called when returning from a function in CFG recovery.

Parameters:

retn_target (int) – The target to return to.

Returns:

None

dbg_repr()

Debugging representation of this CallStack object.

Returns:

Details of this CalLStack

Return type:

str

stack_suffix(context_sensitivity_level)

Generate the stack suffix. A stack suffix can be used as the key to a SimRun in CFG recovery.

Parameters:

context_sensitivity_level (int) – Level of context sensitivity.

Returns:

A tuple of stack suffix.

Return type:

tuple

class angr.state_plugins.PTChunk(base, sim_state, heap=None)

Bases: Chunk

A chunk, inspired by the implementation of chunks in ptmalloc. Provides a representation of a chunk via a view into the memory plugin. For the chunk definitions and docs that this was loosely based off of, see glibc malloc/malloc.c, line 1033, as of commit 5a580643111ef6081be7b4c7bd1997a5447c903f. Alternatively, take the following link. https://sourceware.org/git/?p=glibc.git;a=blob;f=malloc/malloc.c;h=67cdfd0ad2f003964cd0f7dfe3bcd85ca98528a7;hb=5a580643111ef6081be7b4c7bd1997a5447c903f#l1033

Variables:
  • base – the location of the base of the chunk in memory

  • state – the program state that the chunk is resident in

  • heap – the heap plugin that the chunk is managed by

__init__(base, sim_state, heap=None)
get_size()

Returns the actual size of a chunk (as opposed to the entire size field, which may include some flags).

get_data_size()

Returns the size of the data portion of a chunk.

set_size(size, is_free=None)

Use this to set the size on a chunk. When the chunk is new (such as when a free chunk is shrunk to form an allocated chunk and a remainder free chunk) it is recommended that the is_free hint be used since setting the size depends on the chunk’s freeness, and vice versa.

Parameters:
  • size – size of the chunk

  • is_free – boolean indicating the chunk’s freeness

set_prev_freeness(is_free)

Sets (or unsets) the flag controlling whether the previous chunk is free.

Parameters:

is_free – if True, sets the previous chunk to be free; if False, sets it to be allocated

is_prev_free()

Returns a concrete state of the flag indicating whether the previous chunk is free or not. Issues a warning if that flag is symbolic and has multiple solutions, and then assumes that the previous chunk is free.

Returns:

True if the previous chunk is free; False otherwise

prev_size()

Returns the size of the previous chunk, masking off what would be the flag bits if it were in the actual size field. Performs NO CHECKING to determine whether the previous chunk size is valid (for example, when the previous chunk is not free, its size cannot be determined).

is_free()

Returns a concrete determination as to whether the chunk is free.

data_ptr()

Returns the address of the payload of the chunk.

next_chunk()

Returns the chunk immediately following (and adjacent to) this one, if it exists.

Returns:

The following chunk, or None if applicable

prev_chunk()

Returns the chunk immediately prior (and adjacent) to this one, if that chunk is free. If the prior chunk is not free, then its base cannot be located and this method raises an error.

Returns:

If possible, the previous chunk; otherwise, raises an error

fwd_chunk()

Returns the chunk following this chunk in the list of free chunks. If this chunk is not free, then it resides in no such list and this method raises an error.

Returns:

If possible, the forward chunk; otherwise, raises an error

set_fwd_chunk(fwd)

Sets the chunk following this chunk in the list of free chunks.

Parameters:

fwd – the chunk to follow this chunk in the list of free chunks

bck_chunk()

Returns the chunk backward from this chunk in the list of free chunks. If this chunk is not free, then it resides in no such list and this method raises an error.

Returns:

If possible, the backward chunk; otherwise, raises an error

set_bck_chunk(bck)

Sets the chunk backward from this chunk in the list of free chunks.

Parameters:

bck – the chunk to precede this chunk in the list of free chunks

class angr.state_plugins.PTChunkIterator(chunk, cond=<function PTChunkIterator.<lambda>>)

Bases: object

__init__(chunk, cond=<function PTChunkIterator.<lambda>>)
class angr.state_plugins.PosixDevFS

Bases: SimMount

get(path)

Implement this function to instrument file lookups.

Parameters:

path_elements – A list of path elements traversing from the mountpoint to the file

Returns:

A SimFile, or None

insert(path, simfile)

Implement this function to instrument file creation.

Parameters:
  • path_elements – A list of path elements traversing from the mountpoint to the file

  • simfile – The file to insert

Returns:

A bool indicating whether the insert occurred

delete(path)

Implement this function to instrument file deletion.

Parameters:

path_elements – A list of path elements traversing from the mountpoint to the file

Returns:

A bool indicating whether the delete occurred

lookup(_)

Look up the path of a SimFile in the mountpoint

Parameters:

sim_file – A SimFile object needs to be looked up

Returns:

A string representing the path of the file in the mountpoint Or None if the SimFile does not exist in the mountpoint

merge(others, conditions, common_ancestor=None)

Should merge the state plugin with the provided others. This will be called by state.merge() after copying the target state, so this should mutate the current instance to merge with the others.

Note that when multiple instances of a single plugin object (for example, a file) are referenced in the state, it is important that merge only ever be called once. This should be solved by designating one of the plugin’s referees as the “real owner”, who should be the one to actually merge it. This technique doesn’t work to resolve the similar issue that arises during copying because merging doesn’t produce a new reference to insert.

There will be n others and n+1 merge conditions, since the first condition corresponds to self. To match elements up to conditions, say zip([self] + others, merge_conditions)

When implementing this, make sure that you “deepen” both others and common_ancestor before calling sub-elements’ merge methods, e.g.

self.foo.merge(
    [o.foo for o in others],
    merge_conditions,
    common_ancestor=common_ancestor.foo if common_ancestor is not None else None
)

During static analysis, merge_conditions can be None, in which case you should use state.solver.union(values). TODO: fish please make this less bullshit

There is a utility claripy.ite_cases which will help with constructing arbitrarily large merged ASTs. Use it like self.bar = claripy.ite_cases(zip(conditions[1:], [o.bar for o in others]), self.bar)

Parameters:
  • others – the other state plugins to merge with

  • merge_conditions – a symbolic condition for each of the plugins

  • common_ancestor – a common ancestor of this plugin and the others being merged

Returns:

True if the state plugins are actually merged.

Return type:

bool

widen(others)

The widening operation for plugins. Widening is a special kind of merging that produces a more general state from several more specific states. It is used only during intensive static analysis. The same behavior regarding copying and mutation from merge should be followed.

Parameters:

others – the other state plugin

Returns:

True if the state plugin is actually widened.

Return type:

bool

copy(_)

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:

memo – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

class angr.state_plugins.PosixProcFS

Bases: SimMount

The virtual file system mounted at /proc (as of now, on Linux).

get(path)

Implement this function to instrument file lookups.

Parameters:

path_elements – A list of path elements traversing from the mountpoint to the file

Returns:

A SimFile, or None

insert(path, simfile)

Implement this function to instrument file creation.

Parameters:
  • path_elements – A list of path elements traversing from the mountpoint to the file

  • simfile – The file to insert

Returns:

A bool indicating whether the insert occurred

delete(path)

Implement this function to instrument file deletion.

Parameters:

path_elements – A list of path elements traversing from the mountpoint to the file

Returns:

A bool indicating whether the delete occurred

lookup(_)

Look up the path of a SimFile in the mountpoint

Parameters:

sim_file – A SimFile object needs to be looked up

Returns:

A string representing the path of the file in the mountpoint Or None if the SimFile does not exist in the mountpoint

merge(others, conditions, common_ancestor=None)

Should merge the state plugin with the provided others. This will be called by state.merge() after copying the target state, so this should mutate the current instance to merge with the others.

Note that when multiple instances of a single plugin object (for example, a file) are referenced in the state, it is important that merge only ever be called once. This should be solved by designating one of the plugin’s referees as the “real owner”, who should be the one to actually merge it. This technique doesn’t work to resolve the similar issue that arises during copying because merging doesn’t produce a new reference to insert.

There will be n others and n+1 merge conditions, since the first condition corresponds to self. To match elements up to conditions, say zip([self] + others, merge_conditions)

When implementing this, make sure that you “deepen” both others and common_ancestor before calling sub-elements’ merge methods, e.g.

self.foo.merge(
    [o.foo for o in others],
    merge_conditions,
    common_ancestor=common_ancestor.foo if common_ancestor is not None else None
)

During static analysis, merge_conditions can be None, in which case you should use state.solver.union(values). TODO: fish please make this less bullshit

There is a utility claripy.ite_cases which will help with constructing arbitrarily large merged ASTs. Use it like self.bar = claripy.ite_cases(zip(conditions[1:], [o.bar for o in others]), self.bar)

Parameters:
  • others – the other state plugins to merge with

  • merge_conditions – a symbolic condition for each of the plugins

  • common_ancestor – a common ancestor of this plugin and the others being merged

Returns:

True if the state plugins are actually merged.

Return type:

bool

widen(others)

The widening operation for plugins. Widening is a special kind of merging that produces a more general state from several more specific states. It is used only during intensive static analysis. The same behavior regarding copying and mutation from merge should be followed.

Parameters:

others – the other state plugin

Returns:

True if the state plugin is actually widened.

Return type:

bool

copy(_)

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:

memo – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

class angr.state_plugins.SimAction(state, region_type)

Bases: SimEvent

A SimAction represents a semantic action that an analyzed program performs.

TMP = 'tmp'
REG = 'reg'
MEM = 'mem'
__init__(state, region_type)

Initializes the SimAction.

Parameters:

state – the state that’s the SimAction is taking place in.

property all_objects
property is_symbolic
property tmp_deps
property reg_deps
copy()
downsize()

Clears some low-level details (that take up memory) out of the SimAction.

class angr.state_plugins.SimActionConstraint(state, constraint, condition=None)

Bases: SimAction

A constraint action represents an extra constraint added during execution of a path.

__init__(state, constraint, condition=None)

Initializes the SimAction.

Parameters:

state – the state that’s the SimAction is taking place in.

property all_objects
property is_symbolic
class angr.state_plugins.SimActionData(state, region_type, action, tmp=None, addr=None, size=None, data=None, condition=None, fallback=None, fd=None)

Bases: SimAction

A Data action represents a read or a write from memory, registers or a file.

READ = 'read'
WRITE = 'write'
OPERATE = 'operate'
__init__(state, region_type, action, tmp=None, addr=None, size=None, data=None, condition=None, fallback=None, fd=None)

Initializes the SimAction.

Parameters:

state – the state that’s the SimAction is taking place in.

downsize()

Clears some low-level details (that take up memory) out of the SimAction.

property all_objects
property is_symbolic
property tmp_deps
property reg_deps
property storage
class angr.state_plugins.SimActionExit(state, target, condition=None, exit_type=None)

Bases: SimAction

An Exit action represents a (possibly conditional) jump.

CONDITIONAL = 'conditional'
DEFAULT = 'default'
__init__(state, target, condition=None, exit_type=None)

Initializes the SimAction.

Parameters:

state – the state that’s the SimAction is taking place in.

property all_objects
property is_symbolic
class angr.state_plugins.SimActionObject(ast, reg_deps=frozenset({}), tmp_deps=frozenset({}), deps=frozenset({}), state=None)

Bases: object

A SimActionObject tracks an AST and its dependencies.

Parameters:
__init__(ast, reg_deps=frozenset({}), tmp_deps=frozenset({}), deps=frozenset({}), state=None)
Parameters:
ast: Base
reg_deps: frozenset[SimActionData | SimActionOperation]
tmp_deps: frozenset[SimActionData | SimActionOperation]
to_claripy()
Return type:

Base

copy()
Return type:

SimActionObject

is_leaf()
Return type:

bool

property op: str
property args: tuple[ArgType, ...]
property length: int | None
property variables: frozenset[str]
property symbolic: bool
property annotations: tuple[Annotation, ...]
property depth: int
SDiv(other)
Return type:

SimActionObject

SMod(other)
Return type:

SimActionObject

union(other)
Return type:

SimActionObject

intersection(other)
Return type:

SimActionObject

widen(other)
Return type:

SimActionObject

raw_to_bv()
Return type:

SimActionObject

bv_to_fp()
Return type:

SimActionObject

class angr.state_plugins.SimActionOperation(state, op, exprs, result)

Bases: SimAction

An action representing an operation between variables and/or constants.

__init__(state, op, exprs, result)

Initializes the SimAction.

Parameters:

state – the state that’s the SimAction is taking place in.

property all_objects
property is_symbolic
class angr.state_plugins.SimDebugVariable(state, addr, var_type)

Bases: object

A SimDebugVariable will get dynamically created when queriyng for variable in a state with the SimDebugVariablePlugin. It features a link to the state, an address and a type.

Parameters:
__init__(state, addr, var_type)
Parameters:
static from_cle_variable(state, cle_variable, dwarf_cfa)
Return type:

SimDebugVariable

Parameters:
property mem_untyped: SimMemView
property mem: SimMemView
property string: SimMemView
with_type(sim_type)
Return type:

SimMemView

Parameters:

sim_type (SimType)

property resolvable
property resolved
property concrete
store(value)
property deref: SimDebugVariable
array(i)
Return type:

SimDebugVariable

member(member_name)
Return type:

SimDebugVariable

Parameters:

member_name (str)

class angr.state_plugins.SimDebugVariablePlugin

Bases: SimStatePlugin

This is the plugin you’ll use to interact with (global/local) program variables. These variables have a name and a visibility scope which depends on the pc address of the state. With this plugin, you can access/modify the value of such variable or find its memory address. For creating program variables, or for importing them from cle, see the knowledge plugin debug_variables. Run p.kb.dvars.load_from_dwarf() before using this plugin.

Example

>>> p = angr.Project("various_variables", load_debug_info=True)
>>> p.kb.dvars.load_from_dwarf()
>>> state =  # navigate to the state you want
>>> state.dvars.get_variable("pointer2").deref.mem
<int (32 bits) <BV32 0x1> at 0x404020>
get_variable(var_name)

Returns the visible variable (if any) with name var_name based on the current state.ip.

Return type:

SimDebugVariable

Parameters:

var_name (str)

property dwarf_cfa

Returns the current cfa computation. Set this property to the correct value if needed.

property dwarf_cfa_approx
class angr.state_plugins.SimEvent(state, event_type, **kwargs)

Bases: object

A SimEvent is a log entry for some notable event during symbolic execution. It logs the location it was generated (ins_addr, bbl_addr, stmt_idx, and sim_procedure) as well as arbitrary tags (objects).

You may also be interested in SimAction, which is a specialization of SimEvent for CPU events.

__init__(state, event_type, **kwargs)
class angr.state_plugins.SimFilesystem(files=None, pathsep=None, cwd=None, mountpoints=None)

Bases: SimStatePlugin

angr’s emulated filesystem. Available as state.fs. When constructing, all parameters are optional.

Parameters:
  • files – A mapping from filepath to SimFile

  • pathsep – The character used to separate path elements, default forward slash.

  • cwd – The path of the current working directory to use

  • mountpoints – A mapping from filepath to SimMountpoint

Variables:
  • pathsep – The current pathsep

  • cwd – The current working directory

  • unlinks – A list of unlink operations, tuples of filename and simfile. Be careful, this list is shallow-copied from successor to successor, so don’t mutate anything in it without copying.

__init__(files=None, pathsep=None, cwd=None, mountpoints=None)
copy(memo: dict[int, Any] | None = None, **kwargs: Any) S_co

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:
  • memo (Optional[dict[int, Any]]) – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

  • kwargs (Any)

Return type:

TypeVar(S_co, covariant=True)

set_state(state)

Sets a new state (for example, if the state has been branched)

merge(others, merge_conditions, common_ancestor=None)

Should merge the state plugin with the provided others. This will be called by state.merge() after copying the target state, so this should mutate the current instance to merge with the others.

Note that when multiple instances of a single plugin object (for example, a file) are referenced in the state, it is important that merge only ever be called once. This should be solved by designating one of the plugin’s referees as the “real owner”, who should be the one to actually merge it. This technique doesn’t work to resolve the similar issue that arises during copying because merging doesn’t produce a new reference to insert.

There will be n others and n+1 merge conditions, since the first condition corresponds to self. To match elements up to conditions, say zip([self] + others, merge_conditions)

When implementing this, make sure that you “deepen” both others and common_ancestor before calling sub-elements’ merge methods, e.g.

self.foo.merge(
    [o.foo for o in others],
    merge_conditions,
    common_ancestor=common_ancestor.foo if common_ancestor is not None else None
)

During static analysis, merge_conditions can be None, in which case you should use state.solver.union(values). TODO: fish please make this less bullshit

There is a utility claripy.ite_cases which will help with constructing arbitrarily large merged ASTs. Use it like self.bar = claripy.ite_cases(zip(conditions[1:], [o.bar for o in others]), self.bar)

Parameters:
  • others – the other state plugins to merge with

  • merge_conditions – a symbolic condition for each of the plugins

  • common_ancestor – a common ancestor of this plugin and the others being merged

Returns:

True if the state plugins are actually merged.

Return type:

bool

widen(others)

The widening operation for plugins. Widening is a special kind of merging that produces a more general state from several more specific states. It is used only during intensive static analysis. The same behavior regarding copying and mutation from merge should be followed.

Parameters:

others – the other state plugin

Returns:

True if the state plugin is actually widened.

Return type:

bool

chdir(path)

Changes the current directory to the given path

get(path)

Get a file from the filesystem. Returns a SimFile or None.

insert(path, simfile)

Insert a file into the filesystem. Returns whether the operation was successful.

delete(path)

Remove a file from the filesystem. Returns whether the operation was successful.

This will add a fs_unlink event with the path of the file and also the index into the unlinks list.

mount(path, mount)

Add a mountpoint to the filesystem.

unmount(path)

Remove a mountpoint from the filesystem.

get_mountpoint(path)

Look up the mountpoint servicing the given path.

Returns:

A tuple of the mount and a list of path elements traversing from the mountpoint to the specified file.

class angr.state_plugins.SimHeapBase(heap_base=None, heap_size=None)

Bases: SimStatePlugin

This is the base heap class that all heap implementations should subclass. It defines a few handlers for common heap functions (the libc memory management functions). Heap implementations are expected to override these functions regardless of whether they implement the SimHeapLibc interface. For an example, see the SimHeapBrk implementation, which is based on the original libc SimProcedure implementations.

Variables:
  • heap_base – the address of the base of the heap in memory

  • heap_size – the total size of the main memory region managed by the heap in memory

  • mmap_base – the address of the region from which large mmap allocations will be made

__init__(heap_base=None, heap_size=None)
copy(memo)

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:

memo – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

init_state()

Use this function to perform any initialization on the state at plugin-add time

class angr.state_plugins.SimHeapBrk(heap_base=None, heap_size=None)

Bases: SimHeapBase

SimHeapBrk represents a trivial heap implementation based on the Unix brk system call. This type of heap stores virtually no metadata, so it is up to the user to determine when it is safe to release memory. This also means that it does not properly support standard heap operations like realloc.

This heap implementation is a holdover from before any more proper implementations were modelled. At the time, various libc (or win32) SimProcedures handled the heap in the same way that this plugin does now. To make future heap implementations plug-and-playable, they should implement the necessary logic themselves, and dependent SimProcedures should invoke a method by the same name as theirs (prepended with an underscore) upon the heap plugin. Depending on the heap implementation, if the method is not supported, an error should be raised.

Out of consideration for the original way the heap was handled, this plugin implements functionality for all relevant SimProcedures (even those that would not normally be supported together in a single heap implementation).

Variables:

heap_location – the address of the top of the heap, bounding the allocations made starting from heap_base

__init__(heap_base=None, heap_size=None)
copy(memo: dict[int, Any] | None = None, **kwargs: Any) S_co

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:
  • memo (Optional[dict[int, Any]]) – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

  • kwargs (Any)

Return type:

TypeVar(S_co, covariant=True)

allocate(sim_size)

The actual allocation primitive for this heap implementation. Increases the position of the break to allocate space. Has no guards against the heap growing too large.

Parameters:

sim_size – a size specifying how much to increase the break pointer by

Returns:

a pointer to the previous break position, above which there is now allocated space

release(sim_size)

The memory release primitive for this heap implementation. Decreases the position of the break to deallocate space. Guards against releasing beyond the initial heap base.

Parameters:

sim_size – a size specifying how much to decrease the break pointer by (may be symbolic or not)

merge(others, merge_conditions, common_ancestor=None)

Should merge the state plugin with the provided others. This will be called by state.merge() after copying the target state, so this should mutate the current instance to merge with the others.

Note that when multiple instances of a single plugin object (for example, a file) are referenced in the state, it is important that merge only ever be called once. This should be solved by designating one of the plugin’s referees as the “real owner”, who should be the one to actually merge it. This technique doesn’t work to resolve the similar issue that arises during copying because merging doesn’t produce a new reference to insert.

There will be n others and n+1 merge conditions, since the first condition corresponds to self. To match elements up to conditions, say zip([self] + others, merge_conditions)

When implementing this, make sure that you “deepen” both others and common_ancestor before calling sub-elements’ merge methods, e.g.

self.foo.merge(
    [o.foo for o in others],
    merge_conditions,
    common_ancestor=common_ancestor.foo if common_ancestor is not None else None
)

During static analysis, merge_conditions can be None, in which case you should use state.solver.union(values). TODO: fish please make this less bullshit

There is a utility claripy.ite_cases which will help with constructing arbitrarily large merged ASTs. Use it like self.bar = claripy.ite_cases(zip(conditions[1:], [o.bar for o in others]), self.bar)

Parameters:
  • others – the other state plugins to merge with

  • merge_conditions – a symbolic condition for each of the plugins

  • common_ancestor – a common ancestor of this plugin and the others being merged

Returns:

True if the state plugins are actually merged.

Return type:

bool

widen(others)

The widening operation for plugins. Widening is a special kind of merging that produces a more general state from several more specific states. It is used only during intensive static analysis. The same behavior regarding copying and mutation from merge should be followed.

Parameters:

others – the other state plugin

Returns:

True if the state plugin is actually widened.

Return type:

bool

class angr.state_plugins.SimHeapLibc(heap_base=None, heap_size=None)

Bases: SimHeapBase

A class of heap that implements the major libc heap management functions.

malloc(sim_size)

A somewhat faithful implementation of libc malloc.

Parameters:

sim_size – the amount of memory (in bytes) to be allocated

Returns:

the address of the allocation, or a NULL pointer if the allocation failed

free(ptr)

A somewhat faithful implementation of libc free.

Parameters:

ptr – the location in memory to be freed

calloc(sim_nmemb, sim_size)

A somewhat faithful implementation of libc calloc.

Parameters:
  • sim_nmemb – the number of elements to allocated

  • sim_size – the size of each element (in bytes)

Returns:

the address of the allocation, or a NULL pointer if the allocation failed

realloc(ptr, size)

A somewhat faithful implementation of libc realloc.

Parameters:
  • ptr – the location in memory to be reallocated

  • size – the new size desired for the allocation

Returns:

the address of the allocation, or a NULL pointer if the allocation was freed or if no new allocation was made

class angr.state_plugins.SimHeapPTMalloc(heap_base=None, heap_size=None)

Bases: SimHeapFreelist

A freelist-style heap implementation inspired by ptmalloc. The chunks used by this heap contain heap metadata in addition to user data. While the real-world ptmalloc is implemented using multiple lists of free chunks (corresponding to their different sizes), this more basic model uses a single list of chunks and searches for free chunks using a first-fit algorithm.

NOTE: The plugin must be registered using register_plugin with name heap in order to function properly.

Variables:
  • heap_base – the address of the base of the heap in memory

  • heap_size – the total size of the main memory region managed by the heap in memory

  • mmap_base – the address of the region from which large mmap allocations will be made

  • free_head_chunk – the head of the linked list of free chunks in the heap

__init__(heap_base=None, heap_size=None)
copy(memo: dict[int, Any] | None = None, **kwargs: Any) S_co

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:
  • memo (Optional[dict[int, Any]]) – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

  • kwargs (Any)

Return type:

TypeVar(S_co, covariant=True)

chunks()

Returns an iterator over all the chunks in the heap.

allocated_chunks()

Returns an iterator over all the allocated chunks in the heap.

free_chunks()

Returns an iterator over all the free chunks in the heap.

chunk_from_mem(ptr)

Given a pointer to a user payload, return the base of the chunk associated with that payload (i.e. the chunk pointer). Returns None if ptr is null.

Parameters:

ptr – a pointer to the base of a user payload in the heap

Returns:

a pointer to the base of the associated heap chunk, or None if ptr is null

malloc(sim_size)

A somewhat faithful implementation of libc malloc.

Parameters:

sim_size – the amount of memory (in bytes) to be allocated

Returns:

the address of the allocation, or a NULL pointer if the allocation failed

free(ptr)

A somewhat faithful implementation of libc free.

Parameters:

ptr – the location in memory to be freed

calloc(sim_nmemb, sim_size)

A somewhat faithful implementation of libc calloc.

Parameters:
  • sim_nmemb – the number of elements to allocated

  • sim_size – the size of each element (in bytes)

Returns:

the address of the allocation, or a NULL pointer if the allocation failed

realloc(ptr, size)

A somewhat faithful implementation of libc realloc.

Parameters:
  • ptr – the location in memory to be reallocated

  • size – the new size desired for the allocation

Returns:

the address of the allocation, or a NULL pointer if the allocation was freed or if no new allocation was made

merge(others, merge_conditions, common_ancestor=None)

Should merge the state plugin with the provided others. This will be called by state.merge() after copying the target state, so this should mutate the current instance to merge with the others.

Note that when multiple instances of a single plugin object (for example, a file) are referenced in the state, it is important that merge only ever be called once. This should be solved by designating one of the plugin’s referees as the “real owner”, who should be the one to actually merge it. This technique doesn’t work to resolve the similar issue that arises during copying because merging doesn’t produce a new reference to insert.

There will be n others and n+1 merge conditions, since the first condition corresponds to self. To match elements up to conditions, say zip([self] + others, merge_conditions)

When implementing this, make sure that you “deepen” both others and common_ancestor before calling sub-elements’ merge methods, e.g.

self.foo.merge(
    [o.foo for o in others],
    merge_conditions,
    common_ancestor=common_ancestor.foo if common_ancestor is not None else None
)

During static analysis, merge_conditions can be None, in which case you should use state.solver.union(values). TODO: fish please make this less bullshit

There is a utility claripy.ite_cases which will help with constructing arbitrarily large merged ASTs. Use it like self.bar = claripy.ite_cases(zip(conditions[1:], [o.bar for o in others]), self.bar)

Parameters:
  • others – the other state plugins to merge with

  • merge_conditions – a symbolic condition for each of the plugins

  • common_ancestor – a common ancestor of this plugin and the others being merged

Returns:

True if the state plugins are actually merged.

Return type:

bool

widen(others)

The widening operation for plugins. Widening is a special kind of merging that produces a more general state from several more specific states. It is used only during intensive static analysis. The same behavior regarding copying and mutation from merge should be followed.

Parameters:

others – the other state plugin

Returns:

True if the state plugin is actually widened.

Return type:

bool

init_state()

Use this function to perform any initialization on the state at plugin-add time

class angr.state_plugins.SimHostFilesystem(host_path=None, **kwargs)

Bases: SimConcreteFilesystem

Simulated mount that makes some piece from the host filesystem available to the guest.

Parameters:
  • host_path (str) – The path on the host to mount

  • pathsep (str) – The host path separator character, default os.path.sep

__init__(host_path=None, **kwargs)
copy(memo: dict[int, Any] | None = None, **kwargs: Any) S_co

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:
  • memo (Optional[dict[int, Any]]) – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

  • kwargs (Any)

Return type:

TypeVar(S_co, covariant=True)

class angr.state_plugins.SimInspector

Bases: SimStatePlugin

The breakpoint interface, used to instrument execution. For usage information, look here: https://docs.angr.io/core-concepts/simulation#breakpoints

BP_AFTER = 'after'
BP_BEFORE = 'before'
BP_BOTH = 'both'
__init__()
action(event_type, when, **kwargs)

Called from within the engine when events happens. This function checks all breakpoints registered for that event and fires the ones whose conditions match.

make_breakpoint(event_type, *args, **kwargs)

Creates and adds a breakpoint which would trigger on event_type. Additional arguments are passed to the BP constructor.

Returns:

The created breakpoint, so that it can be removed later.

b(event_type, *args, **kwargs)

Creates and adds a breakpoint which would trigger on event_type. Additional arguments are passed to the BP constructor.

Returns:

The created breakpoint, so that it can be removed later.

add_breakpoint(event_type, bp)

Adds a breakpoint which would trigger on event_type.

Parameters:
  • event_type – The event type to trigger on

  • bp – The breakpoint

Returns:

The created breakpoint.

remove_breakpoint(event_type, bp=None, filter_func=None)

Removes a breakpoint.

Parameters:
  • bp – The breakpoint to remove.

  • filter_func – A filter function to specify whether each breakpoint should be removed or not.

copy(memo: dict[int, Any] | None = None, **kwargs: Any) S_co

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:
  • memo (Optional[dict[int, Any]]) – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

  • kwargs (Any)

Return type:

TypeVar(S_co, covariant=True)

downsize()

Remove previously stored attributes from this plugin instance to save memory. This method is supposed to be called by breakpoint implementors. A typical workflow looks like the following :

>>> # Add `attr0` and `attr1` to `self.state.inspect`
>>> self.state.inspect(xxxxxx, attr0=yyyy, attr1=zzzz)
>>> # Get new attributes out of SimInspect in case they are modified by the user
>>> new_attr0 = self.state._inspect.attr0
>>> new_attr1 = self.state._inspect.attr1
>>> # Remove them from SimInspect
>>> self.state._inspect.downsize()
merge(others, merge_conditions, common_ancestor=None)

Should merge the state plugin with the provided others. This will be called by state.merge() after copying the target state, so this should mutate the current instance to merge with the others.

Note that when multiple instances of a single plugin object (for example, a file) are referenced in the state, it is important that merge only ever be called once. This should be solved by designating one of the plugin’s referees as the “real owner”, who should be the one to actually merge it. This technique doesn’t work to resolve the similar issue that arises during copying because merging doesn’t produce a new reference to insert.

There will be n others and n+1 merge conditions, since the first condition corresponds to self. To match elements up to conditions, say zip([self] + others, merge_conditions)

When implementing this, make sure that you “deepen” both others and common_ancestor before calling sub-elements’ merge methods, e.g.

self.foo.merge(
    [o.foo for o in others],
    merge_conditions,
    common_ancestor=common_ancestor.foo if common_ancestor is not None else None
)

During static analysis, merge_conditions can be None, in which case you should use state.solver.union(values). TODO: fish please make this less bullshit

There is a utility claripy.ite_cases which will help with constructing arbitrarily large merged ASTs. Use it like self.bar = claripy.ite_cases(zip(conditions[1:], [o.bar for o in others]), self.bar)

Parameters:
  • others – the other state plugins to merge with

  • merge_conditions – a symbolic condition for each of the plugins

  • common_ancestor – a common ancestor of this plugin and the others being merged

Returns:

True if the state plugins are actually merged.

Return type:

bool

widen(others)

The widening operation for plugins. Widening is a special kind of merging that produces a more general state from several more specific states. It is used only during intensive static analysis. The same behavior regarding copying and mutation from merge should be followed.

Parameters:

others – the other state plugin

Returns:

True if the state plugin is actually widened.

Return type:

bool

set_state(state)

Sets a new state (for example, if the state has been branched)

class angr.state_plugins.SimJavaVmClassloader(initialized_classes=None)

Bases: SimStatePlugin

JavaVM Classloader is used as an interface for resolving and initializing Java classes.

__init__(initialized_classes=None)
get_class(class_name, init_class=False, step_func=None)

Get a class descriptor for the class.

Parameters:
  • class_name (str) – Name of class.

  • init_class (bool) – Whether the class initializer <clinit> should be executed.

  • step_func (func) – Callback function executed at every step of the simulation manager during the execution of the main <clinit> method

get_superclass(class_)

Get the superclass of the class.

get_class_hierarchy(base_class)

Walks up the class hierarchy and returns a list of all classes between base class (inclusive) and java.lang.Object (exclusive).

is_class_initialized(class_)

Indicates whether the classes initializing method <clinit> was already executed on the state.

init_class(class_, step_func=None)

This method simulates the loading of a class by the JVM, during which parts of the class (e.g. static fields) are initialized. For this, we run the class initializer method <clinit> (if available) and update the state accordingly.

Note: Initialization is skipped, if the class has already been

initialized (or if it’s not loaded in CLE).

property initialized_classes

List of all initialized classes.

copy(memo: dict[int, Any] | None = None, **kwargs: Any) S_co

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:
  • memo (Optional[dict[int, Any]]) – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

  • kwargs (Any)

Return type:

TypeVar(S_co, covariant=True)

merge(others, merge_conditions, common_ancestor=None)

Should merge the state plugin with the provided others. This will be called by state.merge() after copying the target state, so this should mutate the current instance to merge with the others.

Note that when multiple instances of a single plugin object (for example, a file) are referenced in the state, it is important that merge only ever be called once. This should be solved by designating one of the plugin’s referees as the “real owner”, who should be the one to actually merge it. This technique doesn’t work to resolve the similar issue that arises during copying because merging doesn’t produce a new reference to insert.

There will be n others and n+1 merge conditions, since the first condition corresponds to self. To match elements up to conditions, say zip([self] + others, merge_conditions)

When implementing this, make sure that you “deepen” both others and common_ancestor before calling sub-elements’ merge methods, e.g.

self.foo.merge(
    [o.foo for o in others],
    merge_conditions,
    common_ancestor=common_ancestor.foo if common_ancestor is not None else None
)

During static analysis, merge_conditions can be None, in which case you should use state.solver.union(values). TODO: fish please make this less bullshit

There is a utility claripy.ite_cases which will help with constructing arbitrarily large merged ASTs. Use it like self.bar = claripy.ite_cases(zip(conditions[1:], [o.bar for o in others]), self.bar)

Parameters:
  • others – the other state plugins to merge with

  • merge_conditions – a symbolic condition for each of the plugins

  • common_ancestor – a common ancestor of this plugin and the others being merged

Returns:

True if the state plugins are actually merged.

Return type:

bool

widen(others)

The widening operation for plugins. Widening is a special kind of merging that produces a more general state from several more specific states. It is used only during intensive static analysis. The same behavior regarding copying and mutation from merge should be followed.

Parameters:

others – the other state plugin

Returns:

True if the state plugin is actually widened.

Return type:

bool

class angr.state_plugins.SimLightRegisters(reg_map=None, registers=None)

Bases: SimStatePlugin

__init__(reg_map=None, registers=None)
copy(memo: dict[int, Any] | None = None, **kwargs: Any) S_co

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:
  • memo (Optional[dict[int, Any]]) – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

  • kwargs (Any)

Return type:

TypeVar(S_co, covariant=True)

set_state(state)

Sets a new state (for example, if the state has been branched)

resolve_register(offset, size)
load(offset, size=None, **kwargs)
store(offset, value, size=None, endness=None, **kwargs)
class angr.state_plugins.SimMemView(ty=None, addr=None, state=None)

Bases: SimStatePlugin

This is a convenient interface with which you can access a program’s memory.

The interface works like this:

  • You first use [array index notation] to specify the address you’d like to load from

  • If at that address is a pointer, you may access the deref property to return a SimMemView at the address present in memory.

  • You then specify a type for the data by simply accessing a property of that name. For a list of supported types, look at state.mem.types.

  • You can then refine the type. Any type may support any refinement it likes. Right now the only refinements supported are that you may access any member of a struct by its member name, and you may index into a string or array to access that element.

  • If the address you specified initially points to an array of that type, you can say .array(n) to view the data as an array of n elements.

  • Finally, extract the structured data with .resolved or .concrete. .resolved will return bitvector values, while .concrete will return integer, string, array, etc values, whatever best represents the data.

  • Alternately, you may store a value to memory, by assigning to the chain of properties that you’ve constructed. Note that because of the way python works, x = s.mem[...].prop; x = val will NOT work, you must say s.mem[...].prop = val.

For example:

>>> s.mem[0x601048].long
<long (64 bits) <BV64 0x4008d0> at 0x601048>
>>> s.mem[0x601048].long.resolved
<BV64 0x4008d0>
>>> s.mem[0x601048].deref
<<untyped> <unresolvable> at 0x4008d0>
>>> s.mem[0x601048].deref.string.concrete
'SOSNEAKY'
Parameters:

state (SimState)

__init__(ty=None, addr=None, state=None)
set_state(state)

Sets a new state (for example, if the state has been branched)

types: ClassVar[dict] = {'CharT': char, 'FILE_t': struct FILE_t, '_Bool': bool, '_ENTRY': struct _ENTRY, '_IO_codecvt': struct _IO_codecvt, '_IO_iconv_t': struct _IO_iconv_t, '_IO_lock_t': struct pthread_mutex_t, '_IO_marker': struct _IO_marker, '_IO_wide_data': struct _IO_wide_data, '__clock_t': uint32_t, '__dev_t': uint64_t, '__gid_t': unsigned int, '__ino64_t': unsigned long long, '__ino_t': unsigned long, '__int128': int128_t, '__int256': int256_t, '__mbstate_t': struct __mbstate_t, '__mode_t': unsigned int, '__nlink_t': unsigned int, '__off64_t': long long, '__off_t': long, '__pid_t': int, '__suseconds_t': int64_t, '__time_t': long, '__uid_t': unsigned int, '_obstack_chunk': struct _obstack_chunk, 'aiocb': struct aiocb, 'aiocb64': struct aiocb64, 'aioinit': struct aioinit, 'argp': struct argp, 'argp_child': struct argp_child, 'argp_option': struct argp_option, 'argp_parser_t': (int, char*, struct argp_state*) -> int, 'argp_state': struct argp_state, 'basic_string': string_t, 'bool': bool, 'byte': uint8_t, 'cc_t': char, 'char': char, 'clock_t': uint32_t, 'crypt_data': struct crypt_data, 'dirent': struct dirent, 'dirent64': struct dirent64, 'double': double, 'drand48_data': struct <anon>, 'dword': uint32_t, 'error_t': int, 'exit_status': struct exit_status, 'float': float, 'fstab': struct fstab, 'group': struct group, 'hostent': struct hostent, 'hsearch_data': struct hsearch_data, 'if_nameindex': struct if_nameindex, 'in_addr': struct in_addr, 'in_port_t': uint16_t, 'ino64_t': unsigned long long, 'ino_t': unsigned long, 'int': int, 'int16_t': int16_t, 'int32_t': int32_t, 'int64_t': int64_t, 'int8_t': int8_t, 'iovec': struct <anon>, 'itimerval': struct itimerval, 'lconv': struct lconv, 'long': long, 'long double': double, 'long int': long, 'long long': long long, 'long long int': long long, 'long signed': long, 'long unsigned int': unsigned long, 'mallinfo': struct mallinfo, 'mallinfo2': struct mallinfo2, 'mntent': struct mntent, 'netent': struct netent, 'ntptimeval': struct ntptimeval, 'obstack': struct obstack, 'off64_t': long long, 'off_t': long, 'option': struct option, 'passwd': struct passwd, 'pid_t': int, 'printf_info': struct printf_info, 'protoent': struct protoent, 'ptrdiff_t': long, 'qword': uint64_t, 'random_data': struct <anon>, 'rlim64_t': uint64_t, 'rlim_t': unsigned long, 'rlimit': struct rlimit, 'rlimit64': struct rlimit64, 'rusage': struct rusage, 'sa_family_t': unsigned short, 'sched_param': struct sched_param, 'sembuf': struct sembuf, 'servent': struct servent, 'sgttyb': struct sgttyb, 'short': short, 'short int': short, 'sigevent': struct sigevent, 'signed': int, 'signed char': char, 'signed int': int, 'signed long': long, 'signed long int': long, 'signed long long': long long, 'signed long long int': long long, 'signed short': short, 'signed short int': short, 'sigstack': struct sigstack, 'sigval': union sigval { sival_int int; sival_ptr void*; }, 'size_t': size_t, 'sockaddr': struct sockaddr, 'sockaddr_in': struct sockaddr_in, 'speed_t': long, 'ssize': size_t, 'ssize_t': size_t, 'stat': struct stat, 'stat64': struct stat64, 'std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>': string_t, 'string': string_t, 'struct iovec': struct iovec, 'struct timespec': struct timespec, 'struct timeval': struct timeval, 'tcflag_t': unsigned long, 'termios': struct termios, 'time_t': long, 'timespec': struct timeval, 'timeval': struct timeval, 'timex': struct timex, 'timezone': struct timezone, 'tm': struct tm, 'tms': struct tms, 'uint16_t': uint16_t, 'uint32_t': uint32_t, 'uint64_t': uint64_t, 'uint8_t': uint8_t, 'uintptr_t': unsigned long, 'unsigned': unsigned int, 'unsigned __int128': uint128_t, 'unsigned __int256': uint256_t, 'unsigned char': char, 'unsigned int': unsigned int, 'unsigned long': unsigned long, 'unsigned long int': unsigned long, 'unsigned long long': unsigned long long, 'unsigned long long int': unsigned long long, 'unsigned short': unsigned short, 'unsigned short int': unsigned short, 'utimbuf': struct utimbuf, 'utmp': struct utmp, 'utmpx': struct utmx, 'utsname': struct utsname, 'va_list': struct va_list[1], 'void': void, 'vtimes': struct vtimes, 'wchar_t': short, 'winsize': struct winsize, 'word': uint16_t, 'wstring': wstring_t}
state: angr.SimState = None
struct: StructMode
with_type(sim_type)

Returns a copy of the SimMemView with a type.

Parameters:

sim_type (SimType) – The new type.

Return type:

SimMemView

Returns:

The typed SimMemView copy.

copy(memo: dict[int, Any] | None = None, **kwargs: Any) S_co

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:
  • memo (Optional[dict[int, Any]]) – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

  • kwargs (Any)

Return type:

TypeVar(S_co, covariant=True)

merge(others, merge_conditions, common_ancestor=None)

Should merge the state plugin with the provided others. This will be called by state.merge() after copying the target state, so this should mutate the current instance to merge with the others.

Note that when multiple instances of a single plugin object (for example, a file) are referenced in the state, it is important that merge only ever be called once. This should be solved by designating one of the plugin’s referees as the “real owner”, who should be the one to actually merge it. This technique doesn’t work to resolve the similar issue that arises during copying because merging doesn’t produce a new reference to insert.

There will be n others and n+1 merge conditions, since the first condition corresponds to self. To match elements up to conditions, say zip([self] + others, merge_conditions)

When implementing this, make sure that you “deepen” both others and common_ancestor before calling sub-elements’ merge methods, e.g.

self.foo.merge(
    [o.foo for o in others],
    merge_conditions,
    common_ancestor=common_ancestor.foo if common_ancestor is not None else None
)

During static analysis, merge_conditions can be None, in which case you should use state.solver.union(values). TODO: fish please make this less bullshit

There is a utility claripy.ite_cases which will help with constructing arbitrarily large merged ASTs. Use it like self.bar = claripy.ite_cases(zip(conditions[1:], [o.bar for o in others]), self.bar)

Parameters:
  • others – the other state plugins to merge with

  • merge_conditions – a symbolic condition for each of the plugins

  • common_ancestor – a common ancestor of this plugin and the others being merged

Returns:

True if the state plugins are actually merged.

Return type:

bool

widen(others)

The widening operation for plugins. Widening is a special kind of merging that produces a more general state from several more specific states. It is used only during intensive static analysis. The same behavior regarding copying and mutation from merge should be followed.

Parameters:

others – the other state plugin

Returns:

True if the state plugin is actually widened.

Return type:

bool

property resolvable
property resolved
property concrete
property deref: SimMemView
array(n)
Return type:

SimMemView

member(member_name)

If self is a struct and member_name is a member of the struct, return that member element. Otherwise raise an exception.

Return type:

SimMemView

Parameters:

member_name (str)

store(value)
class angr.state_plugins.SimMount

Bases: SimStatePlugin

This is the base class for “mount points” in angr’s simulated filesystem. Subclass this class and give it to the filesystem to intercept all file creations and opens below the mountpoint. Since this a SimStatePlugin you may also want to implement set_state, copy, merge, etc.

get(path_elements)

Implement this function to instrument file lookups.

Parameters:

path_elements – A list of path elements traversing from the mountpoint to the file

Returns:

A SimFile, or None

insert(path_elements, simfile)

Implement this function to instrument file creation.

Parameters:
  • path_elements – A list of path elements traversing from the mountpoint to the file

  • simfile – The file to insert

Returns:

A bool indicating whether the insert occurred

delete(path_elements)

Implement this function to instrument file deletion.

Parameters:

path_elements – A list of path elements traversing from the mountpoint to the file

Returns:

A bool indicating whether the delete occurred

lookup(sim_file)

Look up the path of a SimFile in the mountpoint

Parameters:

sim_file – A SimFile object needs to be looked up

Returns:

A string representing the path of the file in the mountpoint Or None if the SimFile does not exist in the mountpoint

class angr.state_plugins.SimRegNameView

Bases: SimStatePlugin

copy(memo: dict[int, Any] | None = None, **kwargs: Any) S_co

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:
  • memo (Optional[dict[int, Any]]) – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

  • kwargs (Any)

Return type:

TypeVar(S_co, covariant=True)

merge(others, merge_conditions, common_ancestor=None)

Should merge the state plugin with the provided others. This will be called by state.merge() after copying the target state, so this should mutate the current instance to merge with the others.

Note that when multiple instances of a single plugin object (for example, a file) are referenced in the state, it is important that merge only ever be called once. This should be solved by designating one of the plugin’s referees as the “real owner”, who should be the one to actually merge it. This technique doesn’t work to resolve the similar issue that arises during copying because merging doesn’t produce a new reference to insert.

There will be n others and n+1 merge conditions, since the first condition corresponds to self. To match elements up to conditions, say zip([self] + others, merge_conditions)

When implementing this, make sure that you “deepen” both others and common_ancestor before calling sub-elements’ merge methods, e.g.

self.foo.merge(
    [o.foo for o in others],
    merge_conditions,
    common_ancestor=common_ancestor.foo if common_ancestor is not None else None
)

During static analysis, merge_conditions can be None, in which case you should use state.solver.union(values). TODO: fish please make this less bullshit

There is a utility claripy.ite_cases which will help with constructing arbitrarily large merged ASTs. Use it like self.bar = claripy.ite_cases(zip(conditions[1:], [o.bar for o in others]), self.bar)

Parameters:
  • others – the other state plugins to merge with

  • merge_conditions – a symbolic condition for each of the plugins

  • common_ancestor – a common ancestor of this plugin and the others being merged

Returns:

True if the state plugins are actually merged.

Return type:

bool

widen(others)

The widening operation for plugins. Widening is a special kind of merging that produces a more general state from several more specific states. It is used only during intensive static analysis. The same behavior regarding copying and mutation from merge should be followed.

Parameters:

others – the other state plugin

Returns:

True if the state plugin is actually widened.

Return type:

bool

get(reg_name)
class angr.state_plugins.SimSolver(solver=None, all_variables=None, temporal_tracked_variables=None, eternal_tracked_variables=None)

Bases: SimStatePlugin

This is the plugin you’ll use to interact with symbolic variables, creating them and evaluating them. It should be available on a state as state.solver.

Any top-level variable of the claripy module can be accessed as a property of this object.

__init__(solver=None, all_variables=None, temporal_tracked_variables=None, eternal_tracked_variables=None)
reload_solver(constraints=None)

Reloads the solver. Useful when changing solver options.

Parameters:

constraints (list) – A new list of constraints to use in the reloaded solver instead of the current one

get_variables(*keys)

Iterate over all variables for which their tracking key is a prefix of the values provided.

Elements are a tuple, the first element is the full tracking key, the second is the symbol.

>>> list(s.solver.get_variables('mem'))
[(('mem', 0x1000), <BV64 mem_1000_4_64>), (('mem', 0x1008), <BV64 mem_1008_5_64>)]
>>> list(s.solver.get_variables('file'))
[(('file', 1, 0), <BV8 file_1_0_6_8>), (('file', 1, 1), <BV8 file_1_1_7_8>),
    (('file', 2, 0), <BV8 file_2_0_8_8>)]
>>> list(s.solver.get_variables('file', 2))
[(('file', 2, 0), <BV8 file_2_0_8_8>)]
>>> list(s.solver.get_variables())
[(('mem', 0x1000), <BV64 mem_1000_4_64>), (('mem', 0x1008), <BV64 mem_1008_5_64>),
    (('file', 1, 0), <BV8 file_1_0_6_8>), (('file', 1, 1), <BV8 file_1_1_7_8>),
    (('file', 2, 0), <BV8 file_2_0_8_8>)]
register_variable(v, key, eternal=True)

Register a value with the variable tracking system

Parameters:
  • v – The BVS to register

  • key – A tuple to register the variable under

Parma eternal:

Whether this is an eternal variable, default True. If False, an incrementing counter will be appended to the key.

describe_variables(v)

Given an AST, iterate over all the keys of all the BVS leaves in the tree which are registered.

Unconstrained(name, bits, uninitialized=True, inspect=True, events=True, key=None, eternal=False, uc_alloc_depth=None, **kwargs)

Creates an unconstrained symbol or a default concrete value (0), based on the state options.

Parameters:
  • name – The name of the symbol.

  • bits – The size (in bits) of the symbol.

  • uninitialized – Whether this value should be counted as an “uninitialized” value in the course of an analysis.

  • inspect – Set to False to avoid firing SimInspect breakpoints

  • events – Set to False to avoid generating a SimEvent for the occasion

  • key – Set this to a tuple of increasingly specific identifiers (for example, ('mem', 0xffbeff00) or ('file', 4, 0x20) to cause it to be tracked, i.e. accessible through solver.get_variables.

  • eternal – Set to True in conjunction with setting a key to cause all states with the same ancestry to retrieve the same symbol when trying to create the value. If False, a counter will be appended to the key.

Returns:

an unconstrained symbol (or a concrete value of 0).

BVS(name, size, min=None, max=None, stride=None, uninitialized=False, explicit_name=False, key=None, eternal=False, inspect=True, events=True, **kwargs)

Creates a bit-vector symbol (i.e., a variable). Other keyword parameters are passed directly on to the constructor of claripy.ast.BV.

Parameters:
  • name – The name of the symbol.

  • size – The size (in bits) of the bit-vector.

  • min – The minimum value of the symbol. Note that this only work when using VSA.

  • max – The maximum value of the symbol. Note that this only work when using VSA.

  • stride – The stride of the symbol. Note that this only work when using VSA.

  • uninitialized – Whether this value should be counted as an “uninitialized” value in the course of an analysis.

  • explicit_name – Set to True to prevent an identifier from appended to the name to ensure uniqueness.

  • key – Set this to a tuple of increasingly specific identifiers (for example, ('mem', 0xffbeff00) or ('file', 4, 0x20) to cause it to be tracked, i.e. accessible through solver.get_variables.

  • eternal – Set to True in conjunction with setting a key to cause all states with the same ancestry to retrieve the same symbol when trying to create the value. If False, a counter will be appended to the key.

  • inspect – Set to False to avoid firing SimInspect breakpoints

  • events – Set to False to avoid generating a SimEvent for the occasion

Returns:

A BV object representing this symbol.

copy(memo: dict[int, Any] | None = None, **kwargs: Any) S_co

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:
  • memo (Optional[dict[int, Any]]) – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

  • kwargs (Any)

Return type:

TypeVar(S_co, covariant=True)

merge(others, merge_conditions, common_ancestor=None)

Should merge the state plugin with the provided others. This will be called by state.merge() after copying the target state, so this should mutate the current instance to merge with the others.

Note that when multiple instances of a single plugin object (for example, a file) are referenced in the state, it is important that merge only ever be called once. This should be solved by designating one of the plugin’s referees as the “real owner”, who should be the one to actually merge it. This technique doesn’t work to resolve the similar issue that arises during copying because merging doesn’t produce a new reference to insert.

There will be n others and n+1 merge conditions, since the first condition corresponds to self. To match elements up to conditions, say zip([self] + others, merge_conditions)

When implementing this, make sure that you “deepen” both others and common_ancestor before calling sub-elements’ merge methods, e.g.

self.foo.merge(
    [o.foo for o in others],
    merge_conditions,
    common_ancestor=common_ancestor.foo if common_ancestor is not None else None
)

During static analysis, merge_conditions can be None, in which case you should use state.solver.union(values). TODO: fish please make this less bullshit

There is a utility claripy.ite_cases which will help with constructing arbitrarily large merged ASTs. Use it like self.bar = claripy.ite_cases(zip(conditions[1:], [o.bar for o in others]), self.bar)

Parameters:
  • others – the other state plugins to merge with

  • merge_conditions – a symbolic condition for each of the plugins

  • common_ancestor – a common ancestor of this plugin and the others being merged

Returns:

True if the state plugins are actually merged.

Return type:

bool

widen(others)

The widening operation for plugins. Widening is a special kind of merging that produces a more general state from several more specific states. It is used only during intensive static analysis. The same behavior regarding copying and mutation from merge should be followed.

Parameters:

others – the other state plugin

Returns:

True if the state plugin is actually widened.

Return type:

bool

downsize()

Frees memory associated with the constraint solver by clearing all of its internal caches.

property constraints

Returns the constraints of the state stored by the solver.

eval_to_ast(e, n, extra_constraints=(), exact=None)

Evaluate an expression, using the solver if necessary. Returns AST objects.

Parameters:
  • e – the expression

  • n – the number of desired solutions

  • extra_constraints – extra constraints to apply to the solver

  • exact – if False, returns approximate solutions

Returns:

a tuple of the solutions, in the form of claripy AST nodes

Return type:

tuple

max(e, extra_constraints=(), exact=None, signed=False)

Return the maximum value of expression e.

:param e : expression (an AST) to evaluate :type extra_constraints: :param extra_constraints: extra constraints (as ASTs) to add to the solver for this solve :param exact : if False, return approximate solutions. :param signed : Whether the expression should be treated as a signed value. :return: the maximum possible value of e (backend object)

min(e, extra_constraints=(), exact=None, signed=False)

Return the minimum value of expression e.

:param e : expression (an AST) to evaluate :type extra_constraints: :param extra_constraints: extra constraints (as ASTs) to add to the solver for this solve :param exact : if False, return approximate solutions. :param signed : Whether the expression should be treated as a signed value. :return: the minimum possible value of e (backend object)

solution(e, v, extra_constraints=(), exact=None)

Return True if v is a solution of expr with the extra constraints, False otherwise.

Parameters:
  • e – An expression (an AST) to evaluate

  • v – The proposed solution (an AST)

  • extra_constraints – Extra constraints (as ASTs) to add to the solver for this solve.

  • exact – If False, return approximate solutions.

Returns:

True if v is a solution of expr, False otherwise

is_true(e, extra_constraints=(), exact=None)

If the expression provided is absolutely, definitely a true boolean, return True. Note that returning False doesn’t necessarily mean that the expression can be false, just that we couldn’t figure that out easily.

Parameters:
  • e – An expression (an AST) to evaluate

  • extra_constraints – Extra constraints (as ASTs) to add to the solver for this solve.

  • exact – If False, return approximate solutions.

Returns:

True if v is definitely true, False otherwise

is_false(e, extra_constraints=(), exact=None)

If the expression provided is absolutely, definitely a false boolean, return True. Note that returning False doesn’t necessarily mean that the expression can be true, just that we couldn’t figure that out easily.

Parameters:
  • e – An expression (an AST) to evaluate

  • extra_constraints – Extra constraints (as ASTs) to add to the solver for this solve.

  • exact – If False, return approximate solutions.

Returns:

True if v is definitely false, False otherwise

unsat_core(extra_constraints=())

This function returns the unsat core from the backend solver.

Parameters:

extra_constraints – Extra constraints (as ASTs) to add to the solver for this solve.

Returns:

The unsat core.

satisfiable(extra_constraints=(), exact=None)

This function does a constraint check and checks if the solver is in a sat state.

Parameters:
  • extra_constraints – Extra constraints (as ASTs) to add to s for this solve

  • exact – If False, return approximate solutions.

Returns:

True if sat, otherwise false

add(*constraints)

Add some constraints to the solver.

Parameters:

constraints – Pass any constraints that you want to add (ASTs) as varargs.

CastType = ~CastType
eval_upto(e, n, cast_to=None, **kwargs)

Evaluate an expression, using the solver if necessary. Returns primitives as specified by the cast_to parameter. Only certain primitives are supported, check the implementation of _cast_to to see which ones.

Parameters:
  • e – the expression

  • n – the number of desired solutions

  • extra_constraints – extra constraints to apply to the solver

  • exact – if False, returns approximate solutions

  • cast_to – desired type of resulting values

Returns:

a tuple of the solutions, in the form of Python primitives

Return type:

tuple

eval(e, cast_to=None, **kwargs)

Evaluate an expression to get any possible solution. The desired output types can be specified using the cast_to parameter. extra_constraints can be used to specify additional constraints the returned values must satisfy.

Parameters:
  • e – the expression to get a solution for

  • kwargs – Any additional kwargs will be passed down to eval_upto

  • cast_to – desired type of resulting values

Raises:

SimUnsatError – if no solution could be found satisfying the given constraints

Returns:

eval_one(e, cast_to=None, **kwargs)

Evaluate an expression to get the only possible solution. Errors if either no or more than one solution is returned. A kwarg parameter default can be specified to be returned instead of failure!

Parameters:
  • e – the expression to get a solution for

  • cast_to – desired type of resulting values

  • default – A value can be passed as a kwarg here. It will be returned in case of failure.

  • kwargs – Any additional kwargs will be passed down to eval_upto

Raises:
  • SimUnsatError – if no solution could be found satisfying the given constraints

  • SimValueError – if more than one solution was found to satisfy the given constraints

Returns:

The value for e

eval_atmost(e, n, cast_to=None, **kwargs)

Evaluate an expression to get at most n possible solutions. Errors if either none or more than n solutions are returned.

Parameters:
  • e – the expression to get a solution for

  • n – the inclusive upper limit on the number of solutions

  • cast_to – desired type of resulting values

  • kwargs – Any additional kwargs will be passed down to eval_upto

Raises:
  • SimUnsatError – if no solution could be found satisfying the given constraints

  • SimValueError – if more than n solutions were found to satisfy the given constraints

Returns:

The solutions for e

eval_atleast(e, n, cast_to=None, **kwargs)

Evaluate an expression to get at least n possible solutions. Errors if less than n solutions were found.

Parameters:
  • e – the expression to get a solution for

  • n – the inclusive lower limit on the number of solutions

  • cast_to – desired type of resulting values

  • kwargs – Any additional kwargs will be passed down to eval_upto

Raises:
  • SimUnsatError – if no solution could be found satisfying the given constraints

  • SimValueError – if less than n solutions were found to satisfy the given constraints

Returns:

The solutions for e

eval_exact(e, n, cast_to=None, **kwargs)

Evaluate an expression to get exactly the n possible solutions. Errors if any number of solutions other than n was found to exist.

Parameters:
  • e – the expression to get a solution for

  • n – the inclusive lower limit on the number of solutions

  • cast_to – desired type of resulting values

  • kwargs – Any additional kwargs will be passed down to eval_upto

Raises:
  • SimUnsatError – if no solution could be found satisfying the given constraints

  • SimValueError – if any number of solutions other than n were found to satisfy the given constraints

Returns:

The solutions for e

min_int(e, extra_constraints=(), exact=None, signed=False)

Return the minimum value of expression e.

:param e : expression (an AST) to evaluate :type extra_constraints: :param extra_constraints: extra constraints (as ASTs) to add to the solver for this solve :param exact : if False, return approximate solutions. :param signed : Whether the expression should be treated as a signed value. :return: the minimum possible value of e (backend object)

max_int(e, extra_constraints=(), exact=None, signed=False)

Return the maximum value of expression e.

:param e : expression (an AST) to evaluate :type extra_constraints: :param extra_constraints: extra constraints (as ASTs) to add to the solver for this solve :param exact : if False, return approximate solutions. :param signed : Whether the expression should be treated as a signed value. :return: the maximum possible value of e (backend object)

unique(e, **kwargs)

Returns True if the expression e has only one solution by querying the constraint solver. It does also add that unique solution to the solver’s constraints.

symbolic(e)

Returns True if the expression e is symbolic.

single_valued(e)

Returns True whether e is a concrete value or is a value set with only 1 possible value. This differs from unique in that this does not query the constraint solver.

simplify(e=None)

Simplifies e. If e is None, simplifies the constraints of this state.

variables(e)

Returns the symbolic variables present in the AST of e.

class angr.state_plugins.SimStateCGC

Bases: SimStatePlugin

This state plugin keeps track of CGC state.

EBADF = 1
EFAULT = 2
EINVAL = 3
ENOMEM = 4
ENOSYS = 5
EPIPE = 6
FD_SETSIZE = 1024
max_allocation = 268435456
__init__()
copy(memo: dict[int, Any] | None = None, **kwargs: Any) S_co

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:
  • memo (Optional[dict[int, Any]]) – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

  • kwargs (Any)

Return type:

TypeVar(S_co, covariant=True)

peek_input()
discard_input(num_bytes)
peek_output()
discard_output(num_bytes)
addr_invalid(a)
merge(others, merge_conditions, common_ancestor=None)

Should merge the state plugin with the provided others. This will be called by state.merge() after copying the target state, so this should mutate the current instance to merge with the others.

Note that when multiple instances of a single plugin object (for example, a file) are referenced in the state, it is important that merge only ever be called once. This should be solved by designating one of the plugin’s referees as the “real owner”, who should be the one to actually merge it. This technique doesn’t work to resolve the similar issue that arises during copying because merging doesn’t produce a new reference to insert.

There will be n others and n+1 merge conditions, since the first condition corresponds to self. To match elements up to conditions, say zip([self] + others, merge_conditions)

When implementing this, make sure that you “deepen” both others and common_ancestor before calling sub-elements’ merge methods, e.g.

self.foo.merge(
    [o.foo for o in others],
    merge_conditions,
    common_ancestor=common_ancestor.foo if common_ancestor is not None else None
)

During static analysis, merge_conditions can be None, in which case you should use state.solver.union(values). TODO: fish please make this less bullshit

There is a utility claripy.ite_cases which will help with constructing arbitrarily large merged ASTs. Use it like self.bar = claripy.ite_cases(zip(conditions[1:], [o.bar for o in others]), self.bar)

Parameters:
  • others – the other state plugins to merge with

  • merge_conditions – a symbolic condition for each of the plugins

  • common_ancestor – a common ancestor of this plugin and the others being merged

Returns:

True if the state plugins are actually merged.

Return type:

bool

widen(others)

The widening operation for plugins. Widening is a special kind of merging that produces a more general state from several more specific states. It is used only during intensive static analysis. The same behavior regarding copying and mutation from merge should be followed.

Parameters:

others – the other state plugin

Returns:

True if the state plugin is actually widened.

Return type:

bool

get_max_sinkhole(length)

Find a sinkhole which is large enough to support length bytes.

This uses first-fit. The first sinkhole (ordered in descending order by their address) which can hold length bytes is chosen. If there are more than length bytes in the sinkhole, a new sinkhole is created representing the remaining bytes while the old sinkhole is removed.

add_sinkhole(address, length)

Add a sinkhole.

Allow the possibility for the program to reuse the memory represented by the address length pair.

class angr.state_plugins.SimStateGlobals(backer=None)

Bases: SimStatePlugin

__init__(backer=None)
set_state(state)

Sets a new state (for example, if the state has been branched)

merge(others, merge_conditions, common_ancestor=None)

Should merge the state plugin with the provided others. This will be called by state.merge() after copying the target state, so this should mutate the current instance to merge with the others.

Note that when multiple instances of a single plugin object (for example, a file) are referenced in the state, it is important that merge only ever be called once. This should be solved by designating one of the plugin’s referees as the “real owner”, who should be the one to actually merge it. This technique doesn’t work to resolve the similar issue that arises during copying because merging doesn’t produce a new reference to insert.

There will be n others and n+1 merge conditions, since the first condition corresponds to self. To match elements up to conditions, say zip([self] + others, merge_conditions)

When implementing this, make sure that you “deepen” both others and common_ancestor before calling sub-elements’ merge methods, e.g.

self.foo.merge(
    [o.foo for o in others],
    merge_conditions,
    common_ancestor=common_ancestor.foo if common_ancestor is not None else None
)

During static analysis, merge_conditions can be None, in which case you should use state.solver.union(values). TODO: fish please make this less bullshit

There is a utility claripy.ite_cases which will help with constructing arbitrarily large merged ASTs. Use it like self.bar = claripy.ite_cases(zip(conditions[1:], [o.bar for o in others]), self.bar)

Parameters:
  • others – the other state plugins to merge with

  • merge_conditions – a symbolic condition for each of the plugins

  • common_ancestor – a common ancestor of this plugin and the others being merged

Returns:

True if the state plugins are actually merged.

Return type:

bool

widen(others)

The widening operation for plugins. Widening is a special kind of merging that produces a more general state from several more specific states. It is used only during intensive static analysis. The same behavior regarding copying and mutation from merge should be followed.

Parameters:

others – the other state plugin

Returns:

True if the state plugin is actually widened.

Return type:

bool

keys()
values()
items()
get(k, alt=None)
pop(k, alt=None)
copy(memo: dict[int, Any] | None = None, **kwargs: Any) S_co

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:
  • memo (Optional[dict[int, Any]]) – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

  • kwargs (Any)

Return type:

TypeVar(S_co, covariant=True)

class angr.state_plugins.SimStateHistory(parent=None, clone=None)

Bases: SimStatePlugin

This class keeps track of historically-relevant information for paths.

STRONGREF_STATE = True
__init__(parent=None, clone=None)
init_state()

Use this function to perform any initialization on the state at plugin-add time

set_strongref_state(state)
property addr
merge(others, merge_conditions, common_ancestor=None)

Should merge the state plugin with the provided others. This will be called by state.merge() after copying the target state, so this should mutate the current instance to merge with the others.

Note that when multiple instances of a single plugin object (for example, a file) are referenced in the state, it is important that merge only ever be called once. This should be solved by designating one of the plugin’s referees as the “real owner”, who should be the one to actually merge it. This technique doesn’t work to resolve the similar issue that arises during copying because merging doesn’t produce a new reference to insert.

There will be n others and n+1 merge conditions, since the first condition corresponds to self. To match elements up to conditions, say zip([self] + others, merge_conditions)

When implementing this, make sure that you “deepen” both others and common_ancestor before calling sub-elements’ merge methods, e.g.

self.foo.merge(
    [o.foo for o in others],
    merge_conditions,
    common_ancestor=common_ancestor.foo if common_ancestor is not None else None
)

During static analysis, merge_conditions can be None, in which case you should use state.solver.union(values). TODO: fish please make this less bullshit

There is a utility claripy.ite_cases which will help with constructing arbitrarily large merged ASTs. Use it like self.bar = claripy.ite_cases(zip(conditions[1:], [o.bar for o in others]), self.bar)

Parameters:
  • others – the other state plugins to merge with

  • merge_conditions – a symbolic condition for each of the plugins

  • common_ancestor – a common ancestor of this plugin and the others being merged

Returns:

True if the state plugins are actually merged.

Return type:

bool

widen(others)

The widening operation for plugins. Widening is a special kind of merging that produces a more general state from several more specific states. It is used only during intensive static analysis. The same behavior regarding copying and mutation from merge should be followed.

Parameters:

others – the other state plugin

Returns:

True if the state plugin is actually widened.

Return type:

bool

copy(memo: dict[int, Any] | None = None, **kwargs: Any) S_co

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:
  • memo (Optional[dict[int, Any]]) – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

  • kwargs (Any)

Return type:

TypeVar(S_co, covariant=True)

trim()

Discard the ancestry of this state.

filter_actions(start_block_addr=None, end_block_addr=None, block_stmt=None, insn_addr=None, read_from=None, write_to=None)

Filter self.actions based on some common parameters.

[start_block_addr, end_block_addr]

Parameters:
  • start_block_addr – Only return actions generated in blocks starting at this address.

  • end_block_addr – Only return actions generated in blocks ending at this address.

  • block_stmt – Only return actions generated in the nth statement of each block.

  • insn_addr – Only return actions generated in the assembly instruction at this address.

  • read_from – Only return actions that perform a read from the specified location.

  • write_to – Only return actions that perform a write to the specified location.

Notes: If IR optimization is turned on, reads and writes may not occur in the instruction they originally came from. Most commonly, If a register is read from twice in the same block, the second read will not happen, instead reusing the temp the value is already stored in.

Valid values for read_from and write_to are the string literals ‘reg’ or ‘mem’ (matching any read or write to registers or memory, respectively), any string (representing a read or write to the named register), and any integer (representing a read or write to the memory at this address).

demote()

Demotes this history node, causing it to drop the strong state reference.

reachable()
add_event(event_type, **kwargs)
add_action(action)
extend_actions(new_actions)
subscribe_actions()
property recent_constraints
property recent_actions
property block_count
property lineage
property parents
property events: Reversible[SimEvent]
property actions: Reversible[SimAction]
property jumpkinds: Reversible[str]
property jump_guards: Reversible[Bool]
property jump_targets
property jump_sources
property descriptions: Reversible[str]
property bbl_addrs: Reversible[int]
property ins_addrs: Reversible[int]
property stack_actions
closest_common_ancestor(other)

Find the common ancestor between this history node and ‘other’.

Parameters:

other – the PathHistory to find a common ancestor with.

Returns:

the common ancestor SimStateHistory, or None if there isn’t one

constraints_since(other)

Returns the constraints that have been accumulated since other.

Parameters:

other – a prior PathHistory object

Returns:

a list of constraints

make_child()
class angr.state_plugins.SimStateJNIReferences(local_refs=None, global_refs=None)

Bases: SimStatePlugin

Management of the mapping between opaque JNI references and the corresponding Java objects.

__init__(local_refs=None, global_refs=None)
lookup(opaque_ref)

Lookups the object that was used for creating the reference.

create_new_reference(obj, global_ref=False)

Create a new reference thats maps to the given object.

Parameters:
  • obj – Object which gets referenced.

  • global_ref (bool) – Whether a local or global reference is created.

clear_local_references()

Clear all local references.

delete_reference(opaque_ref, global_ref=False)

Delete the stored mapping of a reference.

Parameters:
  • opaque_ref – Reference which should be removed.

  • global_ref (bool) – Whether opaque_ref is a local or global reference.

copy(memo: dict[int, Any] | None = None, **kwargs: Any) S_co

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:
  • memo (Optional[dict[int, Any]]) – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

  • kwargs (Any)

Return type:

TypeVar(S_co, covariant=True)

merge(others, merge_conditions, common_ancestor=None)

Should merge the state plugin with the provided others. This will be called by state.merge() after copying the target state, so this should mutate the current instance to merge with the others.

Note that when multiple instances of a single plugin object (for example, a file) are referenced in the state, it is important that merge only ever be called once. This should be solved by designating one of the plugin’s referees as the “real owner”, who should be the one to actually merge it. This technique doesn’t work to resolve the similar issue that arises during copying because merging doesn’t produce a new reference to insert.

There will be n others and n+1 merge conditions, since the first condition corresponds to self. To match elements up to conditions, say zip([self] + others, merge_conditions)

When implementing this, make sure that you “deepen” both others and common_ancestor before calling sub-elements’ merge methods, e.g.

self.foo.merge(
    [o.foo for o in others],
    merge_conditions,
    common_ancestor=common_ancestor.foo if common_ancestor is not None else None
)

During static analysis, merge_conditions can be None, in which case you should use state.solver.union(values). TODO: fish please make this less bullshit

There is a utility claripy.ite_cases which will help with constructing arbitrarily large merged ASTs. Use it like self.bar = claripy.ite_cases(zip(conditions[1:], [o.bar for o in others]), self.bar)

Parameters:
  • others – the other state plugins to merge with

  • merge_conditions – a symbolic condition for each of the plugins

  • common_ancestor – a common ancestor of this plugin and the others being merged

Returns:

True if the state plugins are actually merged.

Return type:

bool

widen(others)

The widening operation for plugins. Widening is a special kind of merging that produces a more general state from several more specific states. It is used only during intensive static analysis. The same behavior regarding copying and mutation from merge should be followed.

Parameters:

others – the other state plugin

Returns:

True if the state plugin is actually widened.

Return type:

bool

class angr.state_plugins.SimStateLibc

Bases: SimStatePlugin

This state plugin keeps track of various libc stuff:

LOCALE_ARRAY = [b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x02\x00', b'\x02\x00', b'\x02\x00', b'\x02\x00', b'\x02\x00', b'\x02\x00', b'\x02\x00', b'\x02\x00', b'\x02\x00', b'\x03 ', b'\x02 ', b'\x02 ', b'\x02 ', b'\x02 ', b'\x02\x00', b'\x02\x00', b'\x02\x00', b'\x02\x00', b'\x02\x00', b'\x02\x00', b'\x02\x00', b'\x02\x00', b'\x02\x00', b'\x02\x00', b'\x02\x00', b'\x02\x00', b'\x02\x00', b'\x02\x00', b'\x02\x00', b'\x02\x00', b'\x02\x00', b'\x02\x00', b'\x01`', b'\x04\xc0', b'\x04\xc0', b'\x04\xc0', b'\x04\xc0', b'\x04\xc0', b'\x04\xc0', b'\x04\xc0', b'\x04\xc0', b'\x04\xc0', b'\x04\xc0', b'\x04\xc0', b'\x04\xc0', b'\x04\xc0', b'\x04\xc0', b'\x04\xc0', b'\x08\xd8', b'\x08\xd8', b'\x08\xd8', b'\x08\xd8', b'\x08\xd8', b'\x08\xd8', b'\x08\xd8', b'\x08\xd8', b'\x08\xd8', b'\x08\xd8', b'\x04\xc0', b'\x04\xc0', b'\x04\xc0', b'\x04\xc0', b'\x04\xc0', b'\x04\xc0', b'\x04\xc0', b'\x08\xd5', b'\x08\xd5', b'\x08\xd5', b'\x08\xd5', b'\x08\xd5', b'\x08\xd5', b'\x08\xc5', b'\x08\xc5', b'\x08\xc5', b'\x08\xc5', b'\x08\xc5', b'\x08\xc5', b'\x08\xc5', b'\x08\xc5', b'\x08\xc5', b'\x08\xc5', b'\x08\xc5', b'\x08\xc5', b'\x08\xc5', b'\x08\xc5', b'\x08\xc5', b'\x08\xc5', b'\x08\xc5', b'\x08\xc5', b'\x08\xc5', b'\x08\xc5', b'\x04\xc0', b'\x04\xc0', b'\x04\xc0', b'\x04\xc0', b'\x04\xc0', b'\x04\xc0', b'\x08\xd6', b'\x08\xd6', b'\x08\xd6', b'\x08\xd6', b'\x08\xd6', b'\x08\xd6', b'\x08\xc6', b'\x08\xc6', b'\x08\xc6', b'\x08\xc6', b'\x08\xc6', b'\x08\xc6', b'\x08\xc6', b'\x08\xc6', b'\x08\xc6', b'\x08\xc6', b'\x08\xc6', b'\x08\xc6', b'\x08\xc6', b'\x08\xc6', b'\x08\xc6', b'\x08\xc6', b'\x08\xc6', b'\x08\xc6', b'\x08\xc6', b'\x08\xc6', b'\x04\xc0', b'\x04\xc0', b'\x04\xc0', b'\x04\xc0', b'\x02\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00']
TOLOWER_LOC_ARRAY = [128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 4294967295, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255]
TOUPPER_LOC_ARRAY = [128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 4294967295, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255]
__init__()
copy(memo: dict[int, Any] | None = None, **kwargs: Any) S_co

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:
  • memo (Optional[dict[int, Any]]) – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

  • kwargs (Any)

Return type:

TypeVar(S_co, covariant=True)

merge(others, merge_conditions, common_ancestor=None)

Should merge the state plugin with the provided others. This will be called by state.merge() after copying the target state, so this should mutate the current instance to merge with the others.

Note that when multiple instances of a single plugin object (for example, a file) are referenced in the state, it is important that merge only ever be called once. This should be solved by designating one of the plugin’s referees as the “real owner”, who should be the one to actually merge it. This technique doesn’t work to resolve the similar issue that arises during copying because merging doesn’t produce a new reference to insert.

There will be n others and n+1 merge conditions, since the first condition corresponds to self. To match elements up to conditions, say zip([self] + others, merge_conditions)

When implementing this, make sure that you “deepen” both others and common_ancestor before calling sub-elements’ merge methods, e.g.

self.foo.merge(
    [o.foo for o in others],
    merge_conditions,
    common_ancestor=common_ancestor.foo if common_ancestor is not None else None
)

During static analysis, merge_conditions can be None, in which case you should use state.solver.union(values). TODO: fish please make this less bullshit

There is a utility claripy.ite_cases which will help with constructing arbitrarily large merged ASTs. Use it like self.bar = claripy.ite_cases(zip(conditions[1:], [o.bar for o in others]), self.bar)

Parameters:
  • others – the other state plugins to merge with

  • merge_conditions – a symbolic condition for each of the plugins

  • common_ancestor – a common ancestor of this plugin and the others being merged

Returns:

True if the state plugins are actually merged.

Return type:

bool

widen(others)

The widening operation for plugins. Widening is a special kind of merging that produces a more general state from several more specific states. It is used only during intensive static analysis. The same behavior regarding copying and mutation from merge should be followed.

Parameters:

others – the other state plugin

Returns:

True if the state plugin is actually widened.

Return type:

bool

property errno
ret_errno(val)
class angr.state_plugins.SimStateLog(log=None)

Bases: SimStatePlugin

__init__(log=None)
property actions
add_event(event_type, **kwargs)
add_action(action)
extend_actions(new_actions)
events_of_type(event_type)
actions_of_type(action_type)
property fresh_constraints
copy(memo: dict[int, Any] | None = None, **kwargs: Any) S_co

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:
  • memo (Optional[dict[int, Any]]) – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

  • kwargs (Any)

Return type:

TypeVar(S_co, covariant=True)

merge(others, merge_conditions, common_ancestor=None)

Should merge the state plugin with the provided others. This will be called by state.merge() after copying the target state, so this should mutate the current instance to merge with the others.

Note that when multiple instances of a single plugin object (for example, a file) are referenced in the state, it is important that merge only ever be called once. This should be solved by designating one of the plugin’s referees as the “real owner”, who should be the one to actually merge it. This technique doesn’t work to resolve the similar issue that arises during copying because merging doesn’t produce a new reference to insert.

There will be n others and n+1 merge conditions, since the first condition corresponds to self. To match elements up to conditions, say zip([self] + others, merge_conditions)

When implementing this, make sure that you “deepen” both others and common_ancestor before calling sub-elements’ merge methods, e.g.

self.foo.merge(
    [o.foo for o in others],
    merge_conditions,
    common_ancestor=common_ancestor.foo if common_ancestor is not None else None
)

During static analysis, merge_conditions can be None, in which case you should use state.solver.union(values). TODO: fish please make this less bullshit

There is a utility claripy.ite_cases which will help with constructing arbitrarily large merged ASTs. Use it like self.bar = claripy.ite_cases(zip(conditions[1:], [o.bar for o in others]), self.bar)

Parameters:
  • others – the other state plugins to merge with

  • merge_conditions – a symbolic condition for each of the plugins

  • common_ancestor – a common ancestor of this plugin and the others being merged

Returns:

True if the state plugins are actually merged.

Return type:

bool

widen(others)

The widening operation for plugins. Widening is a special kind of merging that produces a more general state from several more specific states. It is used only during intensive static analysis. The same behavior regarding copying and mutation from merge should be followed.

Parameters:

others – the other state plugin

Returns:

True if the state plugin is actually widened.

Return type:

bool

clear()
class angr.state_plugins.SimStateLoopData(back_edge_trip_counts=None, header_trip_counts=None, current_loop=None)

Bases: SimStatePlugin

This class keeps track of loop-related information for states. Note that we have 2 counters for loop iterations (trip counts): the first recording the number of times one of the back edges (or continue edges) of a loop is taken, whereas the second recording the number of times the loop header (or loop entry) is executed. These 2 counters may differ since compilers usually optimize loops hence completely change the loop structure at the binary level. This is supposed to be used with LoopSeer exploration technique, which monitors loop execution. For the moment, the only thing we want to analyze is loop trip counts, but nothing prevents us from extending this plugin for other loop analyses.

__init__(back_edge_trip_counts=None, header_trip_counts=None, current_loop=None)
Parameters:
  • back_edge_trip_counts – Dictionary that stores back edge based trip counts for each loop. Keys are address of loop headers.

  • header_trip_counts – Dictionary that stores header based trip counts for each loop. Keys are address of loop headers.

  • current_loop – List of currently running loops. Each element is a tuple (loop object, list of loop exits).

merge(others, merge_conditions, common_ancestor=None)

Should merge the state plugin with the provided others. This will be called by state.merge() after copying the target state, so this should mutate the current instance to merge with the others.

Note that when multiple instances of a single plugin object (for example, a file) are referenced in the state, it is important that merge only ever be called once. This should be solved by designating one of the plugin’s referees as the “real owner”, who should be the one to actually merge it. This technique doesn’t work to resolve the similar issue that arises during copying because merging doesn’t produce a new reference to insert.

There will be n others and n+1 merge conditions, since the first condition corresponds to self. To match elements up to conditions, say zip([self] + others, merge_conditions)

When implementing this, make sure that you “deepen” both others and common_ancestor before calling sub-elements’ merge methods, e.g.

self.foo.merge(
    [o.foo for o in others],
    merge_conditions,
    common_ancestor=common_ancestor.foo if common_ancestor is not None else None
)

During static analysis, merge_conditions can be None, in which case you should use state.solver.union(values). TODO: fish please make this less bullshit

There is a utility claripy.ite_cases which will help with constructing arbitrarily large merged ASTs. Use it like self.bar = claripy.ite_cases(zip(conditions[1:], [o.bar for o in others]), self.bar)

Parameters:
  • others – the other state plugins to merge with

  • merge_conditions – a symbolic condition for each of the plugins

  • common_ancestor – a common ancestor of this plugin and the others being merged

Returns:

True if the state plugins are actually merged.

Return type:

bool

widen(others)

The widening operation for plugins. Widening is a special kind of merging that produces a more general state from several more specific states. It is used only during intensive static analysis. The same behavior regarding copying and mutation from merge should be followed.

Parameters:

others – the other state plugin

Returns:

True if the state plugin is actually widened.

Return type:

bool

copy(memo: dict[int, Any] | None = None, **kwargs: Any) S_co

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:
  • memo (Optional[dict[int, Any]]) – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

  • kwargs (Any)

Return type:

TypeVar(S_co, covariant=True)

class angr.state_plugins.SimStatePlugin

Bases: object

This is a base class for SimState plugins. A SimState plugin will be copied along with the state when the state is branched. They are intended to be used for things such as tracking open files, tracking heap details, and providing storage and persistence for SimProcedures.

STRONGREF_STATE = False
__init__()
state: SimState
set_state(state)

Sets a new state (for example, if the state has been branched)

set_strongref_state(state)
copy(_memo)

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:

memo – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

static memo(f)

A decorator function you should apply to copy

Return type:

_CopyFunc[TypeVar(S_co, covariant=True)]

Parameters:

f (Callable[[T, dict[int, Any]], S_co])

merge(others, merge_conditions, common_ancestor=None)

Should merge the state plugin with the provided others. This will be called by state.merge() after copying the target state, so this should mutate the current instance to merge with the others.

Note that when multiple instances of a single plugin object (for example, a file) are referenced in the state, it is important that merge only ever be called once. This should be solved by designating one of the plugin’s referees as the “real owner”, who should be the one to actually merge it. This technique doesn’t work to resolve the similar issue that arises during copying because merging doesn’t produce a new reference to insert.

There will be n others and n+1 merge conditions, since the first condition corresponds to self. To match elements up to conditions, say zip([self] + others, merge_conditions)

When implementing this, make sure that you “deepen” both others and common_ancestor before calling sub-elements’ merge methods, e.g.

self.foo.merge(
    [o.foo for o in others],
    merge_conditions,
    common_ancestor=common_ancestor.foo if common_ancestor is not None else None
)

During static analysis, merge_conditions can be None, in which case you should use state.solver.union(values). TODO: fish please make this less bullshit

There is a utility claripy.ite_cases which will help with constructing arbitrarily large merged ASTs. Use it like self.bar = claripy.ite_cases(zip(conditions[1:], [o.bar for o in others]), self.bar)

Parameters:
  • others – the other state plugins to merge with

  • merge_conditions – a symbolic condition for each of the plugins

  • common_ancestor – a common ancestor of this plugin and the others being merged

Returns:

True if the state plugins are actually merged.

Return type:

bool

widen(others)

The widening operation for plugins. Widening is a special kind of merging that produces a more general state from several more specific states. It is used only during intensive static analysis. The same behavior regarding copying and mutation from merge should be followed.

Parameters:

others – the other state plugin

Returns:

True if the state plugin is actually widened.

Return type:

bool

classmethod register_default(name, xtr=None)
init_state()

Use this function to perform any initialization on the state at plugin-add time

class angr.state_plugins.SimStatePreconstrainer(constrained_addrs=None)

Bases: SimStatePlugin

This state plugin manages the concept of preconstraining - adding constraints which you would like to remove later.

Parameters:

constrained_addrs – SimActions for memory operations whose addresses should be constrained during crash analysis

__init__(constrained_addrs=None)
merge(others, merge_conditions, common_ancestor=None)

Should merge the state plugin with the provided others. This will be called by state.merge() after copying the target state, so this should mutate the current instance to merge with the others.

Note that when multiple instances of a single plugin object (for example, a file) are referenced in the state, it is important that merge only ever be called once. This should be solved by designating one of the plugin’s referees as the “real owner”, who should be the one to actually merge it. This technique doesn’t work to resolve the similar issue that arises during copying because merging doesn’t produce a new reference to insert.

There will be n others and n+1 merge conditions, since the first condition corresponds to self. To match elements up to conditions, say zip([self] + others, merge_conditions)

When implementing this, make sure that you “deepen” both others and common_ancestor before calling sub-elements’ merge methods, e.g.

self.foo.merge(
    [o.foo for o in others],
    merge_conditions,
    common_ancestor=common_ancestor.foo if common_ancestor is not None else None
)

During static analysis, merge_conditions can be None, in which case you should use state.solver.union(values). TODO: fish please make this less bullshit

There is a utility claripy.ite_cases which will help with constructing arbitrarily large merged ASTs. Use it like self.bar = claripy.ite_cases(zip(conditions[1:], [o.bar for o in others]), self.bar)

Parameters:
  • others – the other state plugins to merge with

  • merge_conditions – a symbolic condition for each of the plugins

  • common_ancestor – a common ancestor of this plugin and the others being merged

Returns:

True if the state plugins are actually merged.

Return type:

bool

widen(others)

The widening operation for plugins. Widening is a special kind of merging that produces a more general state from several more specific states. It is used only during intensive static analysis. The same behavior regarding copying and mutation from merge should be followed.

Parameters:

others – the other state plugin

Returns:

True if the state plugin is actually widened.

Return type:

bool

copy(memo: dict[int, Any] | None = None, **kwargs: Any) S_co

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:
  • memo (Optional[dict[int, Any]]) – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

  • kwargs (Any)

Return type:

TypeVar(S_co, covariant=True)

preconstrain(value, variable)

Add a preconstraint that variable == value to the state.

Parameters:
  • value – The concrete value. Can be a bitvector or a bytestring or an integer.

  • variable – The BVS to preconstrain.

preconstrain_file(content, simfile, set_length=False)

Preconstrain the contents of a file.

Parameters:
  • content – The content to preconstrain the file to. Can be a bytestring or a list thereof.

  • simfile – The actual simfile to preconstrain

preconstrain_flag_page(magic_content)

Preconstrain the data in the flag page.

Parameters:

magic_content – The content of the magic page as a bytestring.

remove_preconstraints(to_composite_solver=True, simplify=True)

Remove the preconstraints from the state.

If you are using the zen plugin, this will also use that to filter the constraints.

Parameters:
  • to_composite_solver – Whether to convert the replacement solver to a composite solver. You probably want this if you’re switching from tracing to symbolic analysis.

  • simplify – Whether to simplify the resulting set of constraints.

reconstrain()

Split the solver. If any of the subsolvers time out after a short timeout (10 seconds), re-add the preconstraints associated with each of its variables. Hopefully these constraints still allow us to do meaningful things to the state.

class angr.state_plugins.SimStateScratch(scratch=None)

Bases: SimStatePlugin

Implements the scratch state plugin.

__init__(scratch=None)
property priv
push_priv(priv)
pop_priv()
set_tyenv(tyenv)
tmp_expr(tmp)

Returns the Claripy expression of a VEX temp value.

Parameters:
  • tmp – the number of the tmp

  • simplify – simplify the tmp before returning it

Returns:

a Claripy expression of the tmp

store_tmp(tmp, content, reg_deps=frozenset({}), tmp_deps=frozenset({}), deps=None, **kwargs)

Stores a Claripy expression in a VEX temp value. If in symbolic mode, this involves adding a constraint for the tmp’s symbolic variable.

Parameters:
  • tmp – the number of the tmp

  • content – a Claripy expression of the content

  • reg_deps – the register dependencies of the content

  • tmp_deps – the temporary value dependencies of the content

copy(memo: dict[int, Any] | None = None, **kwargs: Any) S_co

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:
  • memo (Optional[dict[int, Any]]) – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

  • kwargs (Any)

Return type:

TypeVar(S_co, covariant=True)

merge(others, merge_conditions, common_ancestor=None)

Should merge the state plugin with the provided others. This will be called by state.merge() after copying the target state, so this should mutate the current instance to merge with the others.

Note that when multiple instances of a single plugin object (for example, a file) are referenced in the state, it is important that merge only ever be called once. This should be solved by designating one of the plugin’s referees as the “real owner”, who should be the one to actually merge it. This technique doesn’t work to resolve the similar issue that arises during copying because merging doesn’t produce a new reference to insert.

There will be n others and n+1 merge conditions, since the first condition corresponds to self. To match elements up to conditions, say zip([self] + others, merge_conditions)

When implementing this, make sure that you “deepen” both others and common_ancestor before calling sub-elements’ merge methods, e.g.

self.foo.merge(
    [o.foo for o in others],
    merge_conditions,
    common_ancestor=common_ancestor.foo if common_ancestor is not None else None
)

During static analysis, merge_conditions can be None, in which case you should use state.solver.union(values). TODO: fish please make this less bullshit

There is a utility claripy.ite_cases which will help with constructing arbitrarily large merged ASTs. Use it like self.bar = claripy.ite_cases(zip(conditions[1:], [o.bar for o in others]), self.bar)

Parameters:
  • others – the other state plugins to merge with

  • merge_conditions – a symbolic condition for each of the plugins

  • common_ancestor – a common ancestor of this plugin and the others being merged

Returns:

True if the state plugins are actually merged.

Return type:

bool

widen(others)

The widening operation for plugins. Widening is a special kind of merging that produces a more general state from several more specific states. It is used only during intensive static analysis. The same behavior regarding copying and mutation from merge should be followed.

Parameters:

others – the other state plugin

Returns:

True if the state plugin is actually widened.

Return type:

bool

clear()
class angr.state_plugins.SimSymbolizer

Bases: SimStatePlugin

The symbolizer state plugin ensures that pointers that are stored in memory are symbolic. This allows for the tracking of and reasoning over these pointers (for example, to reason about memory disclosure).

__init__()
init_state()

Use this function to perform any initialization on the state at plugin-add time

set_symbolization_for_all_pages()

Sets the symbolizer to symbolize pointers to all pages as they are written to memory..

set_symbolized_target_range(base, length)

All pointers to the target range will be symbolized as they are written to memory.

Due to optimizations, the _pages_ containing this range will be set as symbolization targets, not just the range itself.

resymbolize()

Re-symbolizes all pointers in memory. This can be called to symbolize any pointers to target regions that were written (and not mangled beyond recognition) before symbolization was set.

copy(memo: dict[int, Any] | None = None, **kwargs: Any) S_co

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:
  • memo (Optional[dict[int, Any]]) – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

  • kwargs (Any)

Return type:

TypeVar(S_co, covariant=True)

class angr.state_plugins.SimSystemPosix(stdin=None, stdout=None, stderr=None, fd=None, sockets=None, socket_queue=None, argv=None, argc=None, environ=None, auxv=None, tls_modules=None, sigmask=None, pid=None, ppid=None, uid=None, gid=None, brk=None)

Bases: SimStatePlugin

Data storage and interaction mechanisms for states with an environment conforming to posix. Available as state.posix.

SIG_BLOCK = 0
SIG_UNBLOCK = 1
SIG_SETMASK = 2
EPERM = 1
ENOENT = 2
ESRCH = 3
EINTR = 4
EIO = 5
ENXIO = 6
E2BIG = 7
ENOEXEC = 8
EBADF = 9
ECHILD = 10
EAGAIN = 11
ENOMEM = 12
EACCES = 13
EFAULT = 14
ENOTBLK = 15
EBUSY = 16
EEXIST = 17
EXDEV = 18
ENODEV = 19
ENOTDIR = 20
EISDIR = 21
EINVAL = 22
ENFILE = 23
EMFILE = 24
ENOTTY = 25
ETXTBSY = 26
EFBIG = 27
ENOSPC = 28
ESPIPE = 29
EROFS = 30
EPIPE = 32
EDOM = 33
ERANGE = 34
__init__(stdin=None, stdout=None, stderr=None, fd=None, sockets=None, socket_queue=None, argv=None, argc=None, environ=None, auxv=None, tls_modules=None, sigmask=None, pid=None, ppid=None, uid=None, gid=None, brk=None)
copy(memo: dict[int, Any] | None = None, **kwargs: Any) S_co

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:
  • memo (Optional[dict[int, Any]]) – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

  • kwargs (Any)

Return type:

TypeVar(S_co, covariant=True)

property closed_fds
init_state()

Use this function to perform any initialization on the state at plugin-add time

set_brk(new_brk)
set_state(state)

Sets a new state (for example, if the state has been branched)

open(name, flags, preferred_fd=None)

Open a symbolic file. Basically open(2).

Parameters:
  • name (string or bytes) – Path of the symbolic file, as a string or bytes.

  • flags – File operation flags, a bitfield of constants from open(2), as an AST

  • preferred_fd – Assign this fd if it’s not already claimed.

Returns:

The file descriptor number allocated (maps through posix.get_fd to a SimFileDescriptor) or -1 if the open fails.

mode from open(2) is unsupported at present.

open_socket(ident)
get_fd(fd, create_file=True)

Looks up the SimFileDescriptor associated with the given number (an AST). If the number is concrete and does not map to anything, return None. If the number is symbolic, constrain it to an open fd and create a new file for it. Set create_file to False if no write-access is planned (i.e. fd is read-only).

get_concrete_fd(fd, create_file=True)

Same behavior as get_fd(fd), only the result is a concrete integer fd (or -1) instead of a SimFileDescriptor.

close(fd)

Closes the given file descriptor (an AST). Returns whether the operation succeeded (a concrete boolean)

fstat(fd)
fstat_with_result(sim_fd)
sigmask(sigsetsize=None)

Gets the current sigmask. If it’s blank, a new one is created (of sigsetsize).

Parameters:

sigsetsize – the size (in bytes of the sigmask set)

Returns:

the sigmask

sigprocmask(how, new_mask, sigsetsize, valid_ptr=True)

Updates the signal mask.

Parameters:
  • how – the “how” argument of sigprocmask (see manpage)

  • new_mask – the mask modification to apply

  • sigsetsize – the size (in bytes of the sigmask set)

  • valid_ptr – is set if the new_mask was not NULL

merge(others, merge_conditions, common_ancestor=None)

Should merge the state plugin with the provided others. This will be called by state.merge() after copying the target state, so this should mutate the current instance to merge with the others.

Note that when multiple instances of a single plugin object (for example, a file) are referenced in the state, it is important that merge only ever be called once. This should be solved by designating one of the plugin’s referees as the “real owner”, who should be the one to actually merge it. This technique doesn’t work to resolve the similar issue that arises during copying because merging doesn’t produce a new reference to insert.

There will be n others and n+1 merge conditions, since the first condition corresponds to self. To match elements up to conditions, say zip([self] + others, merge_conditions)

When implementing this, make sure that you “deepen” both others and common_ancestor before calling sub-elements’ merge methods, e.g.

self.foo.merge(
    [o.foo for o in others],
    merge_conditions,
    common_ancestor=common_ancestor.foo if common_ancestor is not None else None
)

During static analysis, merge_conditions can be None, in which case you should use state.solver.union(values). TODO: fish please make this less bullshit

There is a utility claripy.ite_cases which will help with constructing arbitrarily large merged ASTs. Use it like self.bar = claripy.ite_cases(zip(conditions[1:], [o.bar for o in others]), self.bar)

Parameters:
  • others – the other state plugins to merge with

  • merge_conditions – a symbolic condition for each of the plugins

  • common_ancestor – a common ancestor of this plugin and the others being merged

Returns:

True if the state plugins are actually merged.

Return type:

bool

widen(_)

The widening operation for plugins. Widening is a special kind of merging that produces a more general state from several more specific states. It is used only during intensive static analysis. The same behavior regarding copying and mutation from merge should be followed.

Parameters:

others – the other state plugin

Returns:

True if the state plugin is actually widened.

Return type:

bool

dump_file_by_path(path, **kwargs)

Returns the concrete content for a file by path.

Parameters:
  • path – file path as string

  • kwargs – passed to state.solver.eval

Returns:

file contents as string

dumps(fd, **kwargs)

Returns the concrete content for a file descriptor.

BACKWARD COMPATIBILITY: if you ask for file descriptors 0 1 or 2, it will return the data from stdin, stdout, or stderr as a flat string.

Parameters:

fd – A file descriptor.

Returns:

The concrete content.

Return type:

str

class angr.state_plugins.SimUCManager(man=None)

Bases: SimStatePlugin

__init__(man=None)
assign(dst_addr_ast)

Assign a new region for under-constrained symbolic execution.

Parameters:

dst_addr_ast – the symbolic AST which address of the new allocated region will be assigned to.

Returns:

as ast of memory address that points to a new region

copy(memo: dict[int, Any] | None = None, **kwargs: Any) S_co

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:
  • memo (Optional[dict[int, Any]]) – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

  • kwargs (Any)

Return type:

TypeVar(S_co, covariant=True)

get_alloc_depth(addr)
Return type:

int | None

Parameters:

addr (int | Base)

set_alloc_depth(addr, depth)
Parameters:
is_bounded(ast)

Test whether an AST is bounded by any existing constraint in the related solver.

Parameters:

ast – an claripy.AST object

Returns:

True if there is at least one related constraint, False otherwise

set_state(state)

Sets a new state (for example, if the state has been branched)

class angr.state_plugins.Stat(st_dev, st_ino, st_nlink, st_mode, st_uid, st_gid, st_rdev, st_size, st_blksize, st_blocks, st_atime, st_atimensec, st_mtime, st_mtimensec, st_ctime, st_ctimensec)

Bases: tuple

st_atime

Alias for field number 10

st_atimensec

Alias for field number 11

st_blksize

Alias for field number 8

st_blocks

Alias for field number 9

st_ctime

Alias for field number 14

st_ctimensec

Alias for field number 15

st_dev

Alias for field number 0

st_gid

Alias for field number 5

st_ino

Alias for field number 1

st_mode

Alias for field number 3

st_mtime

Alias for field number 12

st_mtimensec

Alias for field number 13

Alias for field number 2

st_rdev

Alias for field number 6

st_size

Alias for field number 7

st_uid

Alias for field number 4

class angr.state_plugins.StructMode(view)

Bases: object

__init__(view)
class angr.state_plugins.Unicorn(syscall_hooks=None, cache_key=None, unicount=None, symbolic_var_counts=None, symbolic_inst_counts=None, concretized_asts=None, always_concretize=None, never_concretize=None, concretize_at=None, concretization_threshold_memory=None, concretization_threshold_registers=None, concretization_threshold_instruction=None, cooldown_symbolic_stop=2, cooldown_unsupported_stop=2, cooldown_nonunicorn_blocks=100, cooldown_stop_point=1, max_steps=1000000)

Bases: SimStatePlugin

setup the unicorn engine for a state

UC_CONFIG = {}
__init__(syscall_hooks=None, cache_key=None, unicount=None, symbolic_var_counts=None, symbolic_inst_counts=None, concretized_asts=None, always_concretize=None, never_concretize=None, concretize_at=None, concretization_threshold_memory=None, concretization_threshold_registers=None, concretization_threshold_instruction=None, cooldown_symbolic_stop=2, cooldown_unsupported_stop=2, cooldown_nonunicorn_blocks=100, cooldown_stop_point=1, max_steps=1000000)

Initializes the Unicorn plugin for angr. This plugin handles communication with UnicornEngine.

copy(memo: dict[int, Any] | None = None, **kwargs: Any) S_co

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:
  • memo (Optional[dict[int, Any]]) – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

  • kwargs (Any)

Return type:

TypeVar(S_co, covariant=True)

merge(others, merge_conditions, common_ancestor=None)

Should merge the state plugin with the provided others. This will be called by state.merge() after copying the target state, so this should mutate the current instance to merge with the others.

Note that when multiple instances of a single plugin object (for example, a file) are referenced in the state, it is important that merge only ever be called once. This should be solved by designating one of the plugin’s referees as the “real owner”, who should be the one to actually merge it. This technique doesn’t work to resolve the similar issue that arises during copying because merging doesn’t produce a new reference to insert.

There will be n others and n+1 merge conditions, since the first condition corresponds to self. To match elements up to conditions, say zip([self] + others, merge_conditions)

When implementing this, make sure that you “deepen” both others and common_ancestor before calling sub-elements’ merge methods, e.g.

self.foo.merge(
    [o.foo for o in others],
    merge_conditions,
    common_ancestor=common_ancestor.foo if common_ancestor is not None else None
)

During static analysis, merge_conditions can be None, in which case you should use state.solver.union(values). TODO: fish please make this less bullshit

There is a utility claripy.ite_cases which will help with constructing arbitrarily large merged ASTs. Use it like self.bar = claripy.ite_cases(zip(conditions[1:], [o.bar for o in others]), self.bar)

Parameters:
  • others – the other state plugins to merge with

  • merge_conditions – a symbolic condition for each of the plugins

  • common_ancestor – a common ancestor of this plugin and the others being merged

Returns:

True if the state plugins are actually merged.

Return type:

bool

widen(others)

The widening operation for plugins. Widening is a special kind of merging that produces a more general state from several more specific states. It is used only during intensive static analysis. The same behavior regarding copying and mutation from merge should be followed.

Parameters:

others – the other state plugin

Returns:

True if the state plugin is actually widened.

Return type:

bool

set_state(state)

Sets a new state (for example, if the state has been branched)

property uc
static delete_uc()
set_last_block_details(details)
set_stops(stop_points)
set_tracking(track_bbls, track_stack)
hook()
uncache_region(addr, length)
clear_page_cache()
setup(syscall_data=None, fd_bytes=None)
start(step=None)
get_recent_bbl_addrs()
get_stop_details()
finish(succ_state)
destroy(succ_state)
set_regs()

setting unicorn registers

setup_flags()
setup_gdt(fs, gs)
read_msr(msr=3221225728)
write_msr(val, msr=3221225728)
get_regs(succ_state)

loading registers from unicorn. If succ_state is not None, update it instead of self.state. Needed when handling symbolic exits in native interface

angr.state_plugins.resource_event(state, exception)
class angr.state_plugins.plugin.SimStatePlugin

Bases: object

This is a base class for SimState plugins. A SimState plugin will be copied along with the state when the state is branched. They are intended to be used for things such as tracking open files, tracking heap details, and providing storage and persistence for SimProcedures.

STRONGREF_STATE = False
__init__()
state: SimState
set_state(state)

Sets a new state (for example, if the state has been branched)

set_strongref_state(state)
copy(_memo)

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:

memo – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

static memo(f)

A decorator function you should apply to copy

Return type:

_CopyFunc[TypeVar(S_co, covariant=True)]

Parameters:

f (Callable[[T, dict[int, Any]], S_co])

merge(others, merge_conditions, common_ancestor=None)

Should merge the state plugin with the provided others. This will be called by state.merge() after copying the target state, so this should mutate the current instance to merge with the others.

Note that when multiple instances of a single plugin object (for example, a file) are referenced in the state, it is important that merge only ever be called once. This should be solved by designating one of the plugin’s referees as the “real owner”, who should be the one to actually merge it. This technique doesn’t work to resolve the similar issue that arises during copying because merging doesn’t produce a new reference to insert.

There will be n others and n+1 merge conditions, since the first condition corresponds to self. To match elements up to conditions, say zip([self] + others, merge_conditions)

When implementing this, make sure that you “deepen” both others and common_ancestor before calling sub-elements’ merge methods, e.g.

self.foo.merge(
    [o.foo for o in others],
    merge_conditions,
    common_ancestor=common_ancestor.foo if common_ancestor is not None else None
)

During static analysis, merge_conditions can be None, in which case you should use state.solver.union(values). TODO: fish please make this less bullshit

There is a utility claripy.ite_cases which will help with constructing arbitrarily large merged ASTs. Use it like self.bar = claripy.ite_cases(zip(conditions[1:], [o.bar for o in others]), self.bar)

Parameters:
  • others – the other state plugins to merge with

  • merge_conditions – a symbolic condition for each of the plugins

  • common_ancestor – a common ancestor of this plugin and the others being merged

Returns:

True if the state plugins are actually merged.

Return type:

bool

widen(others)

The widening operation for plugins. Widening is a special kind of merging that produces a more general state from several more specific states. It is used only during intensive static analysis. The same behavior regarding copying and mutation from merge should be followed.

Parameters:

others – the other state plugin

Returns:

True if the state plugin is actually widened.

Return type:

bool

classmethod register_default(name, xtr=None)
init_state()

Use this function to perform any initialization on the state at plugin-add time

class angr.state_plugins.inspect.BP(when='before', enabled=None, condition=None, action=None, **kwargs)

Bases: object

A breakpoint.

__init__(when='before', enabled=None, condition=None, action=None, **kwargs)
check(state, when)

Checks state state to see if the breakpoint should fire.

Parameters:
  • state – The state.

  • when – Whether the check is happening before or after the event.

Returns:

A boolean representing whether the checkpoint should fire.

fire(state)

Trigger the breakpoint.

Parameters:

state – The state.

class angr.state_plugins.inspect.SimInspector

Bases: SimStatePlugin

The breakpoint interface, used to instrument execution. For usage information, look here: https://docs.angr.io/core-concepts/simulation#breakpoints

BP_AFTER = 'after'
BP_BEFORE = 'before'
BP_BOTH = 'both'
__init__()
action(event_type, when, **kwargs)

Called from within the engine when events happens. This function checks all breakpoints registered for that event and fires the ones whose conditions match.

make_breakpoint(event_type, *args, **kwargs)

Creates and adds a breakpoint which would trigger on event_type. Additional arguments are passed to the BP constructor.

Returns:

The created breakpoint, so that it can be removed later.

b(event_type, *args, **kwargs)

Creates and adds a breakpoint which would trigger on event_type. Additional arguments are passed to the BP constructor.

Returns:

The created breakpoint, so that it can be removed later.

add_breakpoint(event_type, bp)

Adds a breakpoint which would trigger on event_type.

Parameters:
  • event_type – The event type to trigger on

  • bp – The breakpoint

Returns:

The created breakpoint.

remove_breakpoint(event_type, bp=None, filter_func=None)

Removes a breakpoint.

Parameters:
  • bp – The breakpoint to remove.

  • filter_func – A filter function to specify whether each breakpoint should be removed or not.

copy(memo: dict[int, Any] | None = None, **kwargs: Any) S_co

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:
  • memo (Optional[dict[int, Any]]) – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

  • kwargs (Any)

Return type:

TypeVar(S_co, covariant=True)

downsize()

Remove previously stored attributes from this plugin instance to save memory. This method is supposed to be called by breakpoint implementors. A typical workflow looks like the following :

>>> # Add `attr0` and `attr1` to `self.state.inspect`
>>> self.state.inspect(xxxxxx, attr0=yyyy, attr1=zzzz)
>>> # Get new attributes out of SimInspect in case they are modified by the user
>>> new_attr0 = self.state._inspect.attr0
>>> new_attr1 = self.state._inspect.attr1
>>> # Remove them from SimInspect
>>> self.state._inspect.downsize()
merge(others, merge_conditions, common_ancestor=None)

Should merge the state plugin with the provided others. This will be called by state.merge() after copying the target state, so this should mutate the current instance to merge with the others.

Note that when multiple instances of a single plugin object (for example, a file) are referenced in the state, it is important that merge only ever be called once. This should be solved by designating one of the plugin’s referees as the “real owner”, who should be the one to actually merge it. This technique doesn’t work to resolve the similar issue that arises during copying because merging doesn’t produce a new reference to insert.

There will be n others and n+1 merge conditions, since the first condition corresponds to self. To match elements up to conditions, say zip([self] + others, merge_conditions)

When implementing this, make sure that you “deepen” both others and common_ancestor before calling sub-elements’ merge methods, e.g.

self.foo.merge(
    [o.foo for o in others],
    merge_conditions,
    common_ancestor=common_ancestor.foo if common_ancestor is not None else None
)

During static analysis, merge_conditions can be None, in which case you should use state.solver.union(values). TODO: fish please make this less bullshit

There is a utility claripy.ite_cases which will help with constructing arbitrarily large merged ASTs. Use it like self.bar = claripy.ite_cases(zip(conditions[1:], [o.bar for o in others]), self.bar)

Parameters:
  • others – the other state plugins to merge with

  • merge_conditions – a symbolic condition for each of the plugins

  • common_ancestor – a common ancestor of this plugin and the others being merged

Returns:

True if the state plugins are actually merged.

Return type:

bool

widen(others)

The widening operation for plugins. Widening is a special kind of merging that produces a more general state from several more specific states. It is used only during intensive static analysis. The same behavior regarding copying and mutation from merge should be followed.

Parameters:

others – the other state plugin

Returns:

True if the state plugin is actually widened.

Return type:

bool

set_state(state)

Sets a new state (for example, if the state has been branched)

state: angr.SimState
class angr.state_plugins.libc.SimStateLibc

Bases: SimStatePlugin

This state plugin keeps track of various libc stuff:

LOCALE_ARRAY = [b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x02\x00', b'\x02\x00', b'\x02\x00', b'\x02\x00', b'\x02\x00', b'\x02\x00', b'\x02\x00', b'\x02\x00', b'\x02\x00', b'\x03 ', b'\x02 ', b'\x02 ', b'\x02 ', b'\x02 ', b'\x02\x00', b'\x02\x00', b'\x02\x00', b'\x02\x00', b'\x02\x00', b'\x02\x00', b'\x02\x00', b'\x02\x00', b'\x02\x00', b'\x02\x00', b'\x02\x00', b'\x02\x00', b'\x02\x00', b'\x02\x00', b'\x02\x00', b'\x02\x00', b'\x02\x00', b'\x02\x00', b'\x01`', b'\x04\xc0', b'\x04\xc0', b'\x04\xc0', b'\x04\xc0', b'\x04\xc0', b'\x04\xc0', b'\x04\xc0', b'\x04\xc0', b'\x04\xc0', b'\x04\xc0', b'\x04\xc0', b'\x04\xc0', b'\x04\xc0', b'\x04\xc0', b'\x04\xc0', b'\x08\xd8', b'\x08\xd8', b'\x08\xd8', b'\x08\xd8', b'\x08\xd8', b'\x08\xd8', b'\x08\xd8', b'\x08\xd8', b'\x08\xd8', b'\x08\xd8', b'\x04\xc0', b'\x04\xc0', b'\x04\xc0', b'\x04\xc0', b'\x04\xc0', b'\x04\xc0', b'\x04\xc0', b'\x08\xd5', b'\x08\xd5', b'\x08\xd5', b'\x08\xd5', b'\x08\xd5', b'\x08\xd5', b'\x08\xc5', b'\x08\xc5', b'\x08\xc5', b'\x08\xc5', b'\x08\xc5', b'\x08\xc5', b'\x08\xc5', b'\x08\xc5', b'\x08\xc5', b'\x08\xc5', b'\x08\xc5', b'\x08\xc5', b'\x08\xc5', b'\x08\xc5', b'\x08\xc5', b'\x08\xc5', b'\x08\xc5', b'\x08\xc5', b'\x08\xc5', b'\x08\xc5', b'\x04\xc0', b'\x04\xc0', b'\x04\xc0', b'\x04\xc0', b'\x04\xc0', b'\x04\xc0', b'\x08\xd6', b'\x08\xd6', b'\x08\xd6', b'\x08\xd6', b'\x08\xd6', b'\x08\xd6', b'\x08\xc6', b'\x08\xc6', b'\x08\xc6', b'\x08\xc6', b'\x08\xc6', b'\x08\xc6', b'\x08\xc6', b'\x08\xc6', b'\x08\xc6', b'\x08\xc6', b'\x08\xc6', b'\x08\xc6', b'\x08\xc6', b'\x08\xc6', b'\x08\xc6', b'\x08\xc6', b'\x08\xc6', b'\x08\xc6', b'\x08\xc6', b'\x08\xc6', b'\x04\xc0', b'\x04\xc0', b'\x04\xc0', b'\x04\xc0', b'\x02\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00', b'\x00\x00']
TOLOWER_LOC_ARRAY = [128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 4294967295, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255]
TOUPPER_LOC_ARRAY = [128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 4294967295, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255]
__init__()
copy(memo: dict[int, Any] | None = None, **kwargs: Any) S_co

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:
  • memo (Optional[dict[int, Any]]) – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

  • kwargs (Any)

Return type:

TypeVar(S_co, covariant=True)

merge(others, merge_conditions, common_ancestor=None)

Should merge the state plugin with the provided others. This will be called by state.merge() after copying the target state, so this should mutate the current instance to merge with the others.

Note that when multiple instances of a single plugin object (for example, a file) are referenced in the state, it is important that merge only ever be called once. This should be solved by designating one of the plugin’s referees as the “real owner”, who should be the one to actually merge it. This technique doesn’t work to resolve the similar issue that arises during copying because merging doesn’t produce a new reference to insert.

There will be n others and n+1 merge conditions, since the first condition corresponds to self. To match elements up to conditions, say zip([self] + others, merge_conditions)

When implementing this, make sure that you “deepen” both others and common_ancestor before calling sub-elements’ merge methods, e.g.

self.foo.merge(
    [o.foo for o in others],
    merge_conditions,
    common_ancestor=common_ancestor.foo if common_ancestor is not None else None
)

During static analysis, merge_conditions can be None, in which case you should use state.solver.union(values). TODO: fish please make this less bullshit

There is a utility claripy.ite_cases which will help with constructing arbitrarily large merged ASTs. Use it like self.bar = claripy.ite_cases(zip(conditions[1:], [o.bar for o in others]), self.bar)

Parameters:
  • others – the other state plugins to merge with

  • merge_conditions – a symbolic condition for each of the plugins

  • common_ancestor – a common ancestor of this plugin and the others being merged

Returns:

True if the state plugins are actually merged.

Return type:

bool

widen(others)

The widening operation for plugins. Widening is a special kind of merging that produces a more general state from several more specific states. It is used only during intensive static analysis. The same behavior regarding copying and mutation from merge should be followed.

Parameters:

others – the other state plugin

Returns:

True if the state plugin is actually widened.

Return type:

bool

property errno
ret_errno(val)
state: angr.SimState
class angr.state_plugins.posix.PosixDevFS

Bases: SimMount

get(path)

Implement this function to instrument file lookups.

Parameters:

path_elements – A list of path elements traversing from the mountpoint to the file

Returns:

A SimFile, or None

insert(path, simfile)

Implement this function to instrument file creation.

Parameters:
  • path_elements – A list of path elements traversing from the mountpoint to the file

  • simfile – The file to insert

Returns:

A bool indicating whether the insert occurred

delete(path)

Implement this function to instrument file deletion.

Parameters:

path_elements – A list of path elements traversing from the mountpoint to the file

Returns:

A bool indicating whether the delete occurred

lookup(_)

Look up the path of a SimFile in the mountpoint

Parameters:

sim_file – A SimFile object needs to be looked up

Returns:

A string representing the path of the file in the mountpoint Or None if the SimFile does not exist in the mountpoint

merge(others, conditions, common_ancestor=None)

Should merge the state plugin with the provided others. This will be called by state.merge() after copying the target state, so this should mutate the current instance to merge with the others.

Note that when multiple instances of a single plugin object (for example, a file) are referenced in the state, it is important that merge only ever be called once. This should be solved by designating one of the plugin’s referees as the “real owner”, who should be the one to actually merge it. This technique doesn’t work to resolve the similar issue that arises during copying because merging doesn’t produce a new reference to insert.

There will be n others and n+1 merge conditions, since the first condition corresponds to self. To match elements up to conditions, say zip([self] + others, merge_conditions)

When implementing this, make sure that you “deepen” both others and common_ancestor before calling sub-elements’ merge methods, e.g.

self.foo.merge(
    [o.foo for o in others],
    merge_conditions,
    common_ancestor=common_ancestor.foo if common_ancestor is not None else None
)

During static analysis, merge_conditions can be None, in which case you should use state.solver.union(values). TODO: fish please make this less bullshit

There is a utility claripy.ite_cases which will help with constructing arbitrarily large merged ASTs. Use it like self.bar = claripy.ite_cases(zip(conditions[1:], [o.bar for o in others]), self.bar)

Parameters:
  • others – the other state plugins to merge with

  • merge_conditions – a symbolic condition for each of the plugins

  • common_ancestor – a common ancestor of this plugin and the others being merged

Returns:

True if the state plugins are actually merged.

Return type:

bool

widen(others)

The widening operation for plugins. Widening is a special kind of merging that produces a more general state from several more specific states. It is used only during intensive static analysis. The same behavior regarding copying and mutation from merge should be followed.

Parameters:

others – the other state plugin

Returns:

True if the state plugin is actually widened.

Return type:

bool

copy(_)

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:

memo – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

class angr.state_plugins.posix.PosixProcFS

Bases: SimMount

The virtual file system mounted at /proc (as of now, on Linux).

get(path)

Implement this function to instrument file lookups.

Parameters:

path_elements – A list of path elements traversing from the mountpoint to the file

Returns:

A SimFile, or None

insert(path, simfile)

Implement this function to instrument file creation.

Parameters:
  • path_elements – A list of path elements traversing from the mountpoint to the file

  • simfile – The file to insert

Returns:

A bool indicating whether the insert occurred

delete(path)

Implement this function to instrument file deletion.

Parameters:

path_elements – A list of path elements traversing from the mountpoint to the file

Returns:

A bool indicating whether the delete occurred

lookup(_)

Look up the path of a SimFile in the mountpoint

Parameters:

sim_file – A SimFile object needs to be looked up

Returns:

A string representing the path of the file in the mountpoint Or None if the SimFile does not exist in the mountpoint

merge(others, conditions, common_ancestor=None)

Should merge the state plugin with the provided others. This will be called by state.merge() after copying the target state, so this should mutate the current instance to merge with the others.

Note that when multiple instances of a single plugin object (for example, a file) are referenced in the state, it is important that merge only ever be called once. This should be solved by designating one of the plugin’s referees as the “real owner”, who should be the one to actually merge it. This technique doesn’t work to resolve the similar issue that arises during copying because merging doesn’t produce a new reference to insert.

There will be n others and n+1 merge conditions, since the first condition corresponds to self. To match elements up to conditions, say zip([self] + others, merge_conditions)

When implementing this, make sure that you “deepen” both others and common_ancestor before calling sub-elements’ merge methods, e.g.

self.foo.merge(
    [o.foo for o in others],
    merge_conditions,
    common_ancestor=common_ancestor.foo if common_ancestor is not None else None
)

During static analysis, merge_conditions can be None, in which case you should use state.solver.union(values). TODO: fish please make this less bullshit

There is a utility claripy.ite_cases which will help with constructing arbitrarily large merged ASTs. Use it like self.bar = claripy.ite_cases(zip(conditions[1:], [o.bar for o in others]), self.bar)

Parameters:
  • others – the other state plugins to merge with

  • merge_conditions – a symbolic condition for each of the plugins

  • common_ancestor – a common ancestor of this plugin and the others being merged

Returns:

True if the state plugins are actually merged.

Return type:

bool

widen(others)

The widening operation for plugins. Widening is a special kind of merging that produces a more general state from several more specific states. It is used only during intensive static analysis. The same behavior regarding copying and mutation from merge should be followed.

Parameters:

others – the other state plugin

Returns:

True if the state plugin is actually widened.

Return type:

bool

copy(_)

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:

memo – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

class angr.state_plugins.posix.SimSystemPosix(stdin=None, stdout=None, stderr=None, fd=None, sockets=None, socket_queue=None, argv=None, argc=None, environ=None, auxv=None, tls_modules=None, sigmask=None, pid=None, ppid=None, uid=None, gid=None, brk=None)

Bases: SimStatePlugin

Data storage and interaction mechanisms for states with an environment conforming to posix. Available as state.posix.

SIG_BLOCK = 0
SIG_UNBLOCK = 1
SIG_SETMASK = 2
EPERM = 1
ENOENT = 2
ESRCH = 3
EINTR = 4
EIO = 5
ENXIO = 6
E2BIG = 7
ENOEXEC = 8
EBADF = 9
ECHILD = 10
EAGAIN = 11
ENOMEM = 12
EACCES = 13
EFAULT = 14
ENOTBLK = 15
EBUSY = 16
EEXIST = 17
EXDEV = 18
ENODEV = 19
ENOTDIR = 20
EISDIR = 21
EINVAL = 22
ENFILE = 23
EMFILE = 24
ENOTTY = 25
ETXTBSY = 26
EFBIG = 27
ENOSPC = 28
ESPIPE = 29
EROFS = 30
EPIPE = 32
EDOM = 33
ERANGE = 34
__init__(stdin=None, stdout=None, stderr=None, fd=None, sockets=None, socket_queue=None, argv=None, argc=None, environ=None, auxv=None, tls_modules=None, sigmask=None, pid=None, ppid=None, uid=None, gid=None, brk=None)
copy(memo: dict[int, Any] | None = None, **kwargs: Any) S_co

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:
  • memo (Optional[dict[int, Any]]) – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

  • kwargs (Any)

Return type:

TypeVar(S_co, covariant=True)

property closed_fds
init_state()

Use this function to perform any initialization on the state at plugin-add time

set_brk(new_brk)
set_state(state)

Sets a new state (for example, if the state has been branched)

open(name, flags, preferred_fd=None)

Open a symbolic file. Basically open(2).

Parameters:
  • name (string or bytes) – Path of the symbolic file, as a string or bytes.

  • flags – File operation flags, a bitfield of constants from open(2), as an AST

  • preferred_fd – Assign this fd if it’s not already claimed.

Returns:

The file descriptor number allocated (maps through posix.get_fd to a SimFileDescriptor) or -1 if the open fails.

mode from open(2) is unsupported at present.

open_socket(ident)
get_fd(fd, create_file=True)

Looks up the SimFileDescriptor associated with the given number (an AST). If the number is concrete and does not map to anything, return None. If the number is symbolic, constrain it to an open fd and create a new file for it. Set create_file to False if no write-access is planned (i.e. fd is read-only).

get_concrete_fd(fd, create_file=True)

Same behavior as get_fd(fd), only the result is a concrete integer fd (or -1) instead of a SimFileDescriptor.

close(fd)

Closes the given file descriptor (an AST). Returns whether the operation succeeded (a concrete boolean)

fstat(fd)
fstat_with_result(sim_fd)
sigmask(sigsetsize=None)

Gets the current sigmask. If it’s blank, a new one is created (of sigsetsize).

Parameters:

sigsetsize – the size (in bytes of the sigmask set)

Returns:

the sigmask

sigprocmask(how, new_mask, sigsetsize, valid_ptr=True)

Updates the signal mask.

Parameters:
  • how – the “how” argument of sigprocmask (see manpage)

  • new_mask – the mask modification to apply

  • sigsetsize – the size (in bytes of the sigmask set)

  • valid_ptr – is set if the new_mask was not NULL

merge(others, merge_conditions, common_ancestor=None)

Should merge the state plugin with the provided others. This will be called by state.merge() after copying the target state, so this should mutate the current instance to merge with the others.

Note that when multiple instances of a single plugin object (for example, a file) are referenced in the state, it is important that merge only ever be called once. This should be solved by designating one of the plugin’s referees as the “real owner”, who should be the one to actually merge it. This technique doesn’t work to resolve the similar issue that arises during copying because merging doesn’t produce a new reference to insert.

There will be n others and n+1 merge conditions, since the first condition corresponds to self. To match elements up to conditions, say zip([self] + others, merge_conditions)

When implementing this, make sure that you “deepen” both others and common_ancestor before calling sub-elements’ merge methods, e.g.

self.foo.merge(
    [o.foo for o in others],
    merge_conditions,
    common_ancestor=common_ancestor.foo if common_ancestor is not None else None
)

During static analysis, merge_conditions can be None, in which case you should use state.solver.union(values). TODO: fish please make this less bullshit

There is a utility claripy.ite_cases which will help with constructing arbitrarily large merged ASTs. Use it like self.bar = claripy.ite_cases(zip(conditions[1:], [o.bar for o in others]), self.bar)

Parameters:
  • others – the other state plugins to merge with

  • merge_conditions – a symbolic condition for each of the plugins

  • common_ancestor – a common ancestor of this plugin and the others being merged

Returns:

True if the state plugins are actually merged.

Return type:

bool

widen(_)

The widening operation for plugins. Widening is a special kind of merging that produces a more general state from several more specific states. It is used only during intensive static analysis. The same behavior regarding copying and mutation from merge should be followed.

Parameters:

others – the other state plugin

Returns:

True if the state plugin is actually widened.

Return type:

bool

dump_file_by_path(path, **kwargs)

Returns the concrete content for a file by path.

Parameters:
  • path – file path as string

  • kwargs – passed to state.solver.eval

Returns:

file contents as string

dumps(fd, **kwargs)

Returns the concrete content for a file descriptor.

BACKWARD COMPATIBILITY: if you ask for file descriptors 0 1 or 2, it will return the data from stdin, stdout, or stderr as a flat string.

Parameters:

fd – A file descriptor.

Returns:

The concrete content.

Return type:

str

state: angr.SimState
class angr.state_plugins.filesystem.Stat(st_dev, st_ino, st_nlink, st_mode, st_uid, st_gid, st_rdev, st_size, st_blksize, st_blocks, st_atime, st_atimensec, st_mtime, st_mtimensec, st_ctime, st_ctimensec)

Bases: tuple

st_atime

Alias for field number 10

st_atimensec

Alias for field number 11

st_blksize

Alias for field number 8

st_blocks

Alias for field number 9

st_ctime

Alias for field number 14

st_ctimensec

Alias for field number 15

st_dev

Alias for field number 0

st_gid

Alias for field number 5

st_ino

Alias for field number 1

st_mode

Alias for field number 3

st_mtime

Alias for field number 12

st_mtimensec

Alias for field number 13

Alias for field number 2

st_rdev

Alias for field number 6

st_size

Alias for field number 7

st_uid

Alias for field number 4

class angr.state_plugins.filesystem.SimFilesystem(files=None, pathsep=None, cwd=None, mountpoints=None)

Bases: SimStatePlugin

angr’s emulated filesystem. Available as state.fs. When constructing, all parameters are optional.

Parameters:
  • files – A mapping from filepath to SimFile

  • pathsep – The character used to separate path elements, default forward slash.

  • cwd – The path of the current working directory to use

  • mountpoints – A mapping from filepath to SimMountpoint

Variables:
  • pathsep – The current pathsep

  • cwd – The current working directory

  • unlinks – A list of unlink operations, tuples of filename and simfile. Be careful, this list is shallow-copied from successor to successor, so don’t mutate anything in it without copying.

__init__(files=None, pathsep=None, cwd=None, mountpoints=None)
copy(memo: dict[int, Any] | None = None, **kwargs: Any) S_co

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:
  • memo (Optional[dict[int, Any]]) – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

  • kwargs (Any)

Return type:

TypeVar(S_co, covariant=True)

set_state(state)

Sets a new state (for example, if the state has been branched)

merge(others, merge_conditions, common_ancestor=None)

Should merge the state plugin with the provided others. This will be called by state.merge() after copying the target state, so this should mutate the current instance to merge with the others.

Note that when multiple instances of a single plugin object (for example, a file) are referenced in the state, it is important that merge only ever be called once. This should be solved by designating one of the plugin’s referees as the “real owner”, who should be the one to actually merge it. This technique doesn’t work to resolve the similar issue that arises during copying because merging doesn’t produce a new reference to insert.

There will be n others and n+1 merge conditions, since the first condition corresponds to self. To match elements up to conditions, say zip([self] + others, merge_conditions)

When implementing this, make sure that you “deepen” both others and common_ancestor before calling sub-elements’ merge methods, e.g.

self.foo.merge(
    [o.foo for o in others],
    merge_conditions,
    common_ancestor=common_ancestor.foo if common_ancestor is not None else None
)

During static analysis, merge_conditions can be None, in which case you should use state.solver.union(values). TODO: fish please make this less bullshit

There is a utility claripy.ite_cases which will help with constructing arbitrarily large merged ASTs. Use it like self.bar = claripy.ite_cases(zip(conditions[1:], [o.bar for o in others]), self.bar)

Parameters:
  • others – the other state plugins to merge with

  • merge_conditions – a symbolic condition for each of the plugins

  • common_ancestor – a common ancestor of this plugin and the others being merged

Returns:

True if the state plugins are actually merged.

Return type:

bool

widen(others)

The widening operation for plugins. Widening is a special kind of merging that produces a more general state from several more specific states. It is used only during intensive static analysis. The same behavior regarding copying and mutation from merge should be followed.

Parameters:

others – the other state plugin

Returns:

True if the state plugin is actually widened.

Return type:

bool

chdir(path)

Changes the current directory to the given path

get(path)

Get a file from the filesystem. Returns a SimFile or None.

insert(path, simfile)

Insert a file into the filesystem. Returns whether the operation was successful.

delete(path)

Remove a file from the filesystem. Returns whether the operation was successful.

This will add a fs_unlink event with the path of the file and also the index into the unlinks list.

mount(path, mount)

Add a mountpoint to the filesystem.

unmount(path)

Remove a mountpoint from the filesystem.

get_mountpoint(path)

Look up the mountpoint servicing the given path.

Returns:

A tuple of the mount and a list of path elements traversing from the mountpoint to the specified file.

class angr.state_plugins.filesystem.SimMount

Bases: SimStatePlugin

This is the base class for “mount points” in angr’s simulated filesystem. Subclass this class and give it to the filesystem to intercept all file creations and opens below the mountpoint. Since this a SimStatePlugin you may also want to implement set_state, copy, merge, etc.

get(path_elements)

Implement this function to instrument file lookups.

Parameters:

path_elements – A list of path elements traversing from the mountpoint to the file

Returns:

A SimFile, or None

insert(path_elements, simfile)

Implement this function to instrument file creation.

Parameters:
  • path_elements – A list of path elements traversing from the mountpoint to the file

  • simfile – The file to insert

Returns:

A bool indicating whether the insert occurred

delete(path_elements)

Implement this function to instrument file deletion.

Parameters:

path_elements – A list of path elements traversing from the mountpoint to the file

Returns:

A bool indicating whether the delete occurred

lookup(sim_file)

Look up the path of a SimFile in the mountpoint

Parameters:

sim_file – A SimFile object needs to be looked up

Returns:

A string representing the path of the file in the mountpoint Or None if the SimFile does not exist in the mountpoint

class angr.state_plugins.filesystem.SimConcreteFilesystem(pathsep='/')

Bases: SimMount

Abstract SimMount allowing the user to import files from some external source into the guest

Parameters:

pathsep (str) – The host path separator character, default os.path.sep

__init__(pathsep='/')
get(path_elements)

Implement this function to instrument file lookups.

Parameters:

path_elements – A list of path elements traversing from the mountpoint to the file

Returns:

A SimFile, or None

insert(path_elements, simfile)

Implement this function to instrument file creation.

Parameters:
  • path_elements – A list of path elements traversing from the mountpoint to the file

  • simfile – The file to insert

Returns:

A bool indicating whether the insert occurred

delete(path_elements)

Implement this function to instrument file deletion.

Parameters:

path_elements – A list of path elements traversing from the mountpoint to the file

Returns:

A bool indicating whether the delete occurred

lookup(sim_file)

Look up the path of a SimFile in the mountpoint

Parameters:

sim_file – A SimFile object needs to be looked up

Returns:

A string representing the path of the file in the mountpoint Or None if the SimFile does not exist in the mountpoint

copy(memo: dict[int, Any] | None = None, **kwargs: Any) S_co

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:
  • memo (Optional[dict[int, Any]]) – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

  • kwargs (Any)

Return type:

TypeVar(S_co, covariant=True)

set_state(state)

Sets a new state (for example, if the state has been branched)

merge(others, merge_conditions, common_ancestor=None)

Should merge the state plugin with the provided others. This will be called by state.merge() after copying the target state, so this should mutate the current instance to merge with the others.

Note that when multiple instances of a single plugin object (for example, a file) are referenced in the state, it is important that merge only ever be called once. This should be solved by designating one of the plugin’s referees as the “real owner”, who should be the one to actually merge it. This technique doesn’t work to resolve the similar issue that arises during copying because merging doesn’t produce a new reference to insert.

There will be n others and n+1 merge conditions, since the first condition corresponds to self. To match elements up to conditions, say zip([self] + others, merge_conditions)

When implementing this, make sure that you “deepen” both others and common_ancestor before calling sub-elements’ merge methods, e.g.

self.foo.merge(
    [o.foo for o in others],
    merge_conditions,
    common_ancestor=common_ancestor.foo if common_ancestor is not None else None
)

During static analysis, merge_conditions can be None, in which case you should use state.solver.union(values). TODO: fish please make this less bullshit

There is a utility claripy.ite_cases which will help with constructing arbitrarily large merged ASTs. Use it like self.bar = claripy.ite_cases(zip(conditions[1:], [o.bar for o in others]), self.bar)

Parameters:
  • others – the other state plugins to merge with

  • merge_conditions – a symbolic condition for each of the plugins

  • common_ancestor – a common ancestor of this plugin and the others being merged

Returns:

True if the state plugins are actually merged.

Return type:

bool

widen(others)

The widening operation for plugins. Widening is a special kind of merging that produces a more general state from several more specific states. It is used only during intensive static analysis. The same behavior regarding copying and mutation from merge should be followed.

Parameters:

others – the other state plugin

Returns:

True if the state plugin is actually widened.

Return type:

bool

class angr.state_plugins.filesystem.SimHostFilesystem(host_path=None, **kwargs)

Bases: SimConcreteFilesystem

Simulated mount that makes some piece from the host filesystem available to the guest.

Parameters:
  • host_path (str) – The path on the host to mount

  • pathsep (str) – The host path separator character, default os.path.sep

__init__(host_path=None, **kwargs)
copy(memo: dict[int, Any] | None = None, **kwargs: Any) S_co

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:
  • memo (Optional[dict[int, Any]]) – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

  • kwargs (Any)

Return type:

TypeVar(S_co, covariant=True)

angr.state_plugins.solver.timed_function(f)
angr.state_plugins.solver.enable_timing()
angr.state_plugins.solver.disable_timing()
angr.state_plugins.solver.error_converter(f)
angr.state_plugins.solver.concrete_path_bool(f)
angr.state_plugins.solver.concrete_path_not_bool(f)
angr.state_plugins.solver.concrete_path_scalar(f)
angr.state_plugins.solver.concrete_path_tuple(f)
angr.state_plugins.solver.concrete_path_list(f)
class angr.state_plugins.solver.SimSolver(solver=None, all_variables=None, temporal_tracked_variables=None, eternal_tracked_variables=None)

Bases: SimStatePlugin

This is the plugin you’ll use to interact with symbolic variables, creating them and evaluating them. It should be available on a state as state.solver.

Any top-level variable of the claripy module can be accessed as a property of this object.

__init__(solver=None, all_variables=None, temporal_tracked_variables=None, eternal_tracked_variables=None)
reload_solver(constraints=None)

Reloads the solver. Useful when changing solver options.

Parameters:

constraints (list) – A new list of constraints to use in the reloaded solver instead of the current one

get_variables(*keys)

Iterate over all variables for which their tracking key is a prefix of the values provided.

Elements are a tuple, the first element is the full tracking key, the second is the symbol.

>>> list(s.solver.get_variables('mem'))
[(('mem', 0x1000), <BV64 mem_1000_4_64>), (('mem', 0x1008), <BV64 mem_1008_5_64>)]
>>> list(s.solver.get_variables('file'))
[(('file', 1, 0), <BV8 file_1_0_6_8>), (('file', 1, 1), <BV8 file_1_1_7_8>),
    (('file', 2, 0), <BV8 file_2_0_8_8>)]
>>> list(s.solver.get_variables('file', 2))
[(('file', 2, 0), <BV8 file_2_0_8_8>)]
>>> list(s.solver.get_variables())
[(('mem', 0x1000), <BV64 mem_1000_4_64>), (('mem', 0x1008), <BV64 mem_1008_5_64>),
    (('file', 1, 0), <BV8 file_1_0_6_8>), (('file', 1, 1), <BV8 file_1_1_7_8>),
    (('file', 2, 0), <BV8 file_2_0_8_8>)]
register_variable(v, key, eternal=True)

Register a value with the variable tracking system

Parameters:
  • v – The BVS to register

  • key – A tuple to register the variable under

Parma eternal:

Whether this is an eternal variable, default True. If False, an incrementing counter will be appended to the key.

describe_variables(v)

Given an AST, iterate over all the keys of all the BVS leaves in the tree which are registered.

Unconstrained(name, bits, uninitialized=True, inspect=True, events=True, key=None, eternal=False, uc_alloc_depth=None, **kwargs)

Creates an unconstrained symbol or a default concrete value (0), based on the state options.

Parameters:
  • name – The name of the symbol.

  • bits – The size (in bits) of the symbol.

  • uninitialized – Whether this value should be counted as an “uninitialized” value in the course of an analysis.

  • inspect – Set to False to avoid firing SimInspect breakpoints

  • events – Set to False to avoid generating a SimEvent for the occasion

  • key – Set this to a tuple of increasingly specific identifiers (for example, ('mem', 0xffbeff00) or ('file', 4, 0x20) to cause it to be tracked, i.e. accessible through solver.get_variables.

  • eternal – Set to True in conjunction with setting a key to cause all states with the same ancestry to retrieve the same symbol when trying to create the value. If False, a counter will be appended to the key.

Returns:

an unconstrained symbol (or a concrete value of 0).

BVS(name, size, min=None, max=None, stride=None, uninitialized=False, explicit_name=False, key=None, eternal=False, inspect=True, events=True, **kwargs)

Creates a bit-vector symbol (i.e., a variable). Other keyword parameters are passed directly on to the constructor of claripy.ast.BV.

Parameters:
  • name – The name of the symbol.

  • size – The size (in bits) of the bit-vector.

  • min – The minimum value of the symbol. Note that this only work when using VSA.

  • max – The maximum value of the symbol. Note that this only work when using VSA.

  • stride – The stride of the symbol. Note that this only work when using VSA.

  • uninitialized – Whether this value should be counted as an “uninitialized” value in the course of an analysis.

  • explicit_name – Set to True to prevent an identifier from appended to the name to ensure uniqueness.

  • key – Set this to a tuple of increasingly specific identifiers (for example, ('mem', 0xffbeff00) or ('file', 4, 0x20) to cause it to be tracked, i.e. accessible through solver.get_variables.

  • eternal – Set to True in conjunction with setting a key to cause all states with the same ancestry to retrieve the same symbol when trying to create the value. If False, a counter will be appended to the key.

  • inspect – Set to False to avoid firing SimInspect breakpoints

  • events – Set to False to avoid generating a SimEvent for the occasion

Returns:

A BV object representing this symbol.

copy(memo: dict[int, Any] | None = None, **kwargs: Any) S_co

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:
  • memo (Optional[dict[int, Any]]) – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

  • kwargs (Any)

Return type:

TypeVar(S_co, covariant=True)

merge(others, merge_conditions, common_ancestor=None)

Should merge the state plugin with the provided others. This will be called by state.merge() after copying the target state, so this should mutate the current instance to merge with the others.

Note that when multiple instances of a single plugin object (for example, a file) are referenced in the state, it is important that merge only ever be called once. This should be solved by designating one of the plugin’s referees as the “real owner”, who should be the one to actually merge it. This technique doesn’t work to resolve the similar issue that arises during copying because merging doesn’t produce a new reference to insert.

There will be n others and n+1 merge conditions, since the first condition corresponds to self. To match elements up to conditions, say zip([self] + others, merge_conditions)

When implementing this, make sure that you “deepen” both others and common_ancestor before calling sub-elements’ merge methods, e.g.

self.foo.merge(
    [o.foo for o in others],
    merge_conditions,
    common_ancestor=common_ancestor.foo if common_ancestor is not None else None
)

During static analysis, merge_conditions can be None, in which case you should use state.solver.union(values). TODO: fish please make this less bullshit

There is a utility claripy.ite_cases which will help with constructing arbitrarily large merged ASTs. Use it like self.bar = claripy.ite_cases(zip(conditions[1:], [o.bar for o in others]), self.bar)

Parameters:
  • others – the other state plugins to merge with

  • merge_conditions – a symbolic condition for each of the plugins

  • common_ancestor – a common ancestor of this plugin and the others being merged

Returns:

True if the state plugins are actually merged.

Return type:

bool

widen(others)

The widening operation for plugins. Widening is a special kind of merging that produces a more general state from several more specific states. It is used only during intensive static analysis. The same behavior regarding copying and mutation from merge should be followed.

Parameters:

others – the other state plugin

Returns:

True if the state plugin is actually widened.

Return type:

bool

downsize()

Frees memory associated with the constraint solver by clearing all of its internal caches.

property constraints

Returns the constraints of the state stored by the solver.

eval_to_ast(e, n, extra_constraints=(), exact=None)

Evaluate an expression, using the solver if necessary. Returns AST objects.

Parameters:
  • e – the expression

  • n – the number of desired solutions

  • extra_constraints – extra constraints to apply to the solver

  • exact – if False, returns approximate solutions

Returns:

a tuple of the solutions, in the form of claripy AST nodes

Return type:

tuple

max(e, extra_constraints=(), exact=None, signed=False)

Return the maximum value of expression e.

:param e : expression (an AST) to evaluate :type extra_constraints: :param extra_constraints: extra constraints (as ASTs) to add to the solver for this solve :param exact : if False, return approximate solutions. :param signed : Whether the expression should be treated as a signed value. :return: the maximum possible value of e (backend object)

min(e, extra_constraints=(), exact=None, signed=False)

Return the minimum value of expression e.

:param e : expression (an AST) to evaluate :type extra_constraints: :param extra_constraints: extra constraints (as ASTs) to add to the solver for this solve :param exact : if False, return approximate solutions. :param signed : Whether the expression should be treated as a signed value. :return: the minimum possible value of e (backend object)

solution(e, v, extra_constraints=(), exact=None)

Return True if v is a solution of expr with the extra constraints, False otherwise.

Parameters:
  • e – An expression (an AST) to evaluate

  • v – The proposed solution (an AST)

  • extra_constraints – Extra constraints (as ASTs) to add to the solver for this solve.

  • exact – If False, return approximate solutions.

Returns:

True if v is a solution of expr, False otherwise

is_true(e, extra_constraints=(), exact=None)

If the expression provided is absolutely, definitely a true boolean, return True. Note that returning False doesn’t necessarily mean that the expression can be false, just that we couldn’t figure that out easily.

Parameters:
  • e – An expression (an AST) to evaluate

  • extra_constraints – Extra constraints (as ASTs) to add to the solver for this solve.

  • exact – If False, return approximate solutions.

Returns:

True if v is definitely true, False otherwise

is_false(e, extra_constraints=(), exact=None)

If the expression provided is absolutely, definitely a false boolean, return True. Note that returning False doesn’t necessarily mean that the expression can be true, just that we couldn’t figure that out easily.

Parameters:
  • e – An expression (an AST) to evaluate

  • extra_constraints – Extra constraints (as ASTs) to add to the solver for this solve.

  • exact – If False, return approximate solutions.

Returns:

True if v is definitely false, False otherwise

unsat_core(extra_constraints=())

This function returns the unsat core from the backend solver.

Parameters:

extra_constraints – Extra constraints (as ASTs) to add to the solver for this solve.

Returns:

The unsat core.

satisfiable(extra_constraints=(), exact=None)

This function does a constraint check and checks if the solver is in a sat state.

Parameters:
  • extra_constraints – Extra constraints (as ASTs) to add to s for this solve

  • exact – If False, return approximate solutions.

Returns:

True if sat, otherwise false

add(*constraints)

Add some constraints to the solver.

Parameters:

constraints – Pass any constraints that you want to add (ASTs) as varargs.

CastType = ~CastType
eval_upto(e, n, cast_to=None, **kwargs)

Evaluate an expression, using the solver if necessary. Returns primitives as specified by the cast_to parameter. Only certain primitives are supported, check the implementation of _cast_to to see which ones.

Parameters:
  • e – the expression

  • n – the number of desired solutions

  • extra_constraints – extra constraints to apply to the solver

  • exact – if False, returns approximate solutions

  • cast_to – desired type of resulting values

Returns:

a tuple of the solutions, in the form of Python primitives

Return type:

tuple

eval(e, cast_to=None, **kwargs)

Evaluate an expression to get any possible solution. The desired output types can be specified using the cast_to parameter. extra_constraints can be used to specify additional constraints the returned values must satisfy.

Parameters:
  • e – the expression to get a solution for

  • kwargs – Any additional kwargs will be passed down to eval_upto

  • cast_to – desired type of resulting values

Raises:

SimUnsatError – if no solution could be found satisfying the given constraints

Returns:

state: angr.SimState
eval_one(e, cast_to=None, **kwargs)

Evaluate an expression to get the only possible solution. Errors if either no or more than one solution is returned. A kwarg parameter default can be specified to be returned instead of failure!

Parameters:
  • e – the expression to get a solution for

  • cast_to – desired type of resulting values

  • default – A value can be passed as a kwarg here. It will be returned in case of failure.

  • kwargs – Any additional kwargs will be passed down to eval_upto

Raises:
  • SimUnsatError – if no solution could be found satisfying the given constraints

  • SimValueError – if more than one solution was found to satisfy the given constraints

Returns:

The value for e

eval_atmost(e, n, cast_to=None, **kwargs)

Evaluate an expression to get at most n possible solutions. Errors if either none or more than n solutions are returned.

Parameters:
  • e – the expression to get a solution for

  • n – the inclusive upper limit on the number of solutions

  • cast_to – desired type of resulting values

  • kwargs – Any additional kwargs will be passed down to eval_upto

Raises:
  • SimUnsatError – if no solution could be found satisfying the given constraints

  • SimValueError – if more than n solutions were found to satisfy the given constraints

Returns:

The solutions for e

eval_atleast(e, n, cast_to=None, **kwargs)

Evaluate an expression to get at least n possible solutions. Errors if less than n solutions were found.

Parameters:
  • e – the expression to get a solution for

  • n – the inclusive lower limit on the number of solutions

  • cast_to – desired type of resulting values

  • kwargs – Any additional kwargs will be passed down to eval_upto

Raises:
  • SimUnsatError – if no solution could be found satisfying the given constraints

  • SimValueError – if less than n solutions were found to satisfy the given constraints

Returns:

The solutions for e

eval_exact(e, n, cast_to=None, **kwargs)

Evaluate an expression to get exactly the n possible solutions. Errors if any number of solutions other than n was found to exist.

Parameters:
  • e – the expression to get a solution for

  • n – the inclusive lower limit on the number of solutions

  • cast_to – desired type of resulting values

  • kwargs – Any additional kwargs will be passed down to eval_upto

Raises:
  • SimUnsatError – if no solution could be found satisfying the given constraints

  • SimValueError – if any number of solutions other than n were found to satisfy the given constraints

Returns:

The solutions for e

min_int(e, extra_constraints=(), exact=None, signed=False)

Return the minimum value of expression e.

:param e : expression (an AST) to evaluate :type extra_constraints: :param extra_constraints: extra constraints (as ASTs) to add to the solver for this solve :param exact : if False, return approximate solutions. :param signed : Whether the expression should be treated as a signed value. :return: the minimum possible value of e (backend object)

max_int(e, extra_constraints=(), exact=None, signed=False)

Return the maximum value of expression e.

:param e : expression (an AST) to evaluate :type extra_constraints: :param extra_constraints: extra constraints (as ASTs) to add to the solver for this solve :param exact : if False, return approximate solutions. :param signed : Whether the expression should be treated as a signed value. :return: the maximum possible value of e (backend object)

unique(e, **kwargs)

Returns True if the expression e has only one solution by querying the constraint solver. It does also add that unique solution to the solver’s constraints.

symbolic(e)

Returns True if the expression e is symbolic.

single_valued(e)

Returns True whether e is a concrete value or is a value set with only 1 possible value. This differs from unique in that this does not query the constraint solver.

simplify(e=None)

Simplifies e. If e is None, simplifies the constraints of this state.

variables(e)

Returns the symbolic variables present in the AST of e.

class angr.state_plugins.log.SimStateLog(log=None)

Bases: SimStatePlugin

__init__(log=None)
property actions
add_event(event_type, **kwargs)
add_action(action)
extend_actions(new_actions)
events_of_type(event_type)
actions_of_type(action_type)
property fresh_constraints
copy(memo: dict[int, Any] | None = None, **kwargs: Any) S_co

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:
  • memo (Optional[dict[int, Any]]) – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

  • kwargs (Any)

Return type:

TypeVar(S_co, covariant=True)

merge(others, merge_conditions, common_ancestor=None)

Should merge the state plugin with the provided others. This will be called by state.merge() after copying the target state, so this should mutate the current instance to merge with the others.

Note that when multiple instances of a single plugin object (for example, a file) are referenced in the state, it is important that merge only ever be called once. This should be solved by designating one of the plugin’s referees as the “real owner”, who should be the one to actually merge it. This technique doesn’t work to resolve the similar issue that arises during copying because merging doesn’t produce a new reference to insert.

There will be n others and n+1 merge conditions, since the first condition corresponds to self. To match elements up to conditions, say zip([self] + others, merge_conditions)

When implementing this, make sure that you “deepen” both others and common_ancestor before calling sub-elements’ merge methods, e.g.

self.foo.merge(
    [o.foo for o in others],
    merge_conditions,
    common_ancestor=common_ancestor.foo if common_ancestor is not None else None
)

During static analysis, merge_conditions can be None, in which case you should use state.solver.union(values). TODO: fish please make this less bullshit

There is a utility claripy.ite_cases which will help with constructing arbitrarily large merged ASTs. Use it like self.bar = claripy.ite_cases(zip(conditions[1:], [o.bar for o in others]), self.bar)

Parameters:
  • others – the other state plugins to merge with

  • merge_conditions – a symbolic condition for each of the plugins

  • common_ancestor – a common ancestor of this plugin and the others being merged

Returns:

True if the state plugins are actually merged.

Return type:

bool

widen(others)

The widening operation for plugins. Widening is a special kind of merging that produces a more general state from several more specific states. It is used only during intensive static analysis. The same behavior regarding copying and mutation from merge should be followed.

Parameters:

others – the other state plugin

Returns:

True if the state plugin is actually widened.

Return type:

bool

clear()
class angr.state_plugins.callstack.CallStack(call_site_addr=0, func_addr=0, stack_ptr=0, ret_addr=0, jumpkind='Ijk_Call', next_frame=None, invoke_return_variable=None)

Bases: SimStatePlugin

Stores the address of the function you’re in and the value of SP at the VERY BOTTOM of the stack, i.e. points to the return address.

Parameters:

next_frame (CallStack | None)

__init__(call_site_addr=0, func_addr=0, stack_ptr=0, ret_addr=0, jumpkind='Ijk_Call', next_frame=None, invoke_return_variable=None)
Parameters:

next_frame (CallStack | None)

copy(memo: dict[int, Any] | None = None, **kwargs: Any) S_co

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:
  • memo (Optional[dict[int, Any]]) – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

  • kwargs (Any)

Return type:

TypeVar(S_co, covariant=True)

set_state(state)

Sets a new state (for example, if the state has been branched)

merge(others, merge_conditions, common_ancestor=None)

Should merge the state plugin with the provided others. This will be called by state.merge() after copying the target state, so this should mutate the current instance to merge with the others.

Note that when multiple instances of a single plugin object (for example, a file) are referenced in the state, it is important that merge only ever be called once. This should be solved by designating one of the plugin’s referees as the “real owner”, who should be the one to actually merge it. This technique doesn’t work to resolve the similar issue that arises during copying because merging doesn’t produce a new reference to insert.

There will be n others and n+1 merge conditions, since the first condition corresponds to self. To match elements up to conditions, say zip([self] + others, merge_conditions)

When implementing this, make sure that you “deepen” both others and common_ancestor before calling sub-elements’ merge methods, e.g.

self.foo.merge(
    [o.foo for o in others],
    merge_conditions,
    common_ancestor=common_ancestor.foo if common_ancestor is not None else None
)

During static analysis, merge_conditions can be None, in which case you should use state.solver.union(values). TODO: fish please make this less bullshit

There is a utility claripy.ite_cases which will help with constructing arbitrarily large merged ASTs. Use it like self.bar = claripy.ite_cases(zip(conditions[1:], [o.bar for o in others]), self.bar)

Parameters:
  • others – the other state plugins to merge with

  • merge_conditions – a symbolic condition for each of the plugins

  • common_ancestor – a common ancestor of this plugin and the others being merged

Returns:

True if the state plugins are actually merged.

Return type:

bool

widen(others)

The widening operation for plugins. Widening is a special kind of merging that produces a more general state from several more specific states. It is used only during intensive static analysis. The same behavior regarding copying and mutation from merge should be followed.

Parameters:

others – the other state plugin

Returns:

True if the state plugin is actually widened.

Return type:

bool

property current_function_address

Address of the current function.

Returns:

the address of the function

Return type:

int

property current_stack_pointer

Get the value of the stack pointer.

Returns:

Value of the stack pointer

Return type:

int

property current_return_target

Get the return target.

Returns:

The address of return target.

Return type:

int

static stack_suffix_to_string(stack_suffix)

Convert a stack suffix to a human-readable string representation. :param tuple stack_suffix: The stack suffix. :return: A string representation :rtype: str

property top

Returns the element at the top of the callstack without removing it.

Returns:

A CallStack.

push(cf)

Push the frame cf onto the stack. Return the new stack.

pop()

Pop the top frame from the stack. Return the new stack.

call(callsite_addr, addr, retn_target=None, stack_pointer=None)

Push a stack frame into the call stack. This method is called when calling a function in CFG recovery.

Parameters:
  • callsite_addr (int) – Address of the call site

  • addr (int) – Address of the call target

  • retn_target (int or None) – Address of the return target

  • stack_pointer (int) – Value of the stack pointer

Returns:

None

ret(retn_target=None)

Pop one or many call frames from the stack. This method is called when returning from a function in CFG recovery.

Parameters:

retn_target (int) – The target to return to.

Returns:

None

dbg_repr()

Debugging representation of this CallStack object.

Returns:

Details of this CalLStack

Return type:

str

stack_suffix(context_sensitivity_level)

Generate the stack suffix. A stack suffix can be used as the key to a SimRun in CFG recovery.

Parameters:

context_sensitivity_level (int) – Level of context sensitivity.

Returns:

A tuple of stack suffix.

Return type:

tuple

class angr.state_plugins.callstack.CallStackAction(callstack_hash, callstack_depth, action, callframe=None, ret_site_addr=None)

Bases: object

Used in callstack backtrace, which is a history of callstacks along a path, to record individual actions occurred each time the callstack is changed.

__init__(callstack_hash, callstack_depth, action, callframe=None, ret_site_addr=None)
class angr.state_plugins.light_registers.SimLightRegisters(reg_map=None, registers=None)

Bases: SimStatePlugin

__init__(reg_map=None, registers=None)
copy(memo: dict[int, Any] | None = None, **kwargs: Any) S_co

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:
  • memo (Optional[dict[int, Any]]) – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

  • kwargs (Any)

Return type:

TypeVar(S_co, covariant=True)

set_state(state)

Sets a new state (for example, if the state has been branched)

resolve_register(offset, size)
load(offset, size=None, **kwargs)
store(offset, value, size=None, endness=None, **kwargs)
class angr.state_plugins.history.SimStateHistory(parent=None, clone=None)

Bases: SimStatePlugin

This class keeps track of historically-relevant information for paths.

STRONGREF_STATE = True
__init__(parent=None, clone=None)
jump_guard: claripy.ast.BV | None
jumpkind: str | None
init_state()

Use this function to perform any initialization on the state at plugin-add time

set_strongref_state(state)
property addr
merge(others, merge_conditions, common_ancestor=None)

Should merge the state plugin with the provided others. This will be called by state.merge() after copying the target state, so this should mutate the current instance to merge with the others.

Note that when multiple instances of a single plugin object (for example, a file) are referenced in the state, it is important that merge only ever be called once. This should be solved by designating one of the plugin’s referees as the “real owner”, who should be the one to actually merge it. This technique doesn’t work to resolve the similar issue that arises during copying because merging doesn’t produce a new reference to insert.

There will be n others and n+1 merge conditions, since the first condition corresponds to self. To match elements up to conditions, say zip([self] + others, merge_conditions)

When implementing this, make sure that you “deepen” both others and common_ancestor before calling sub-elements’ merge methods, e.g.

self.foo.merge(
    [o.foo for o in others],
    merge_conditions,
    common_ancestor=common_ancestor.foo if common_ancestor is not None else None
)

During static analysis, merge_conditions can be None, in which case you should use state.solver.union(values). TODO: fish please make this less bullshit

There is a utility claripy.ite_cases which will help with constructing arbitrarily large merged ASTs. Use it like self.bar = claripy.ite_cases(zip(conditions[1:], [o.bar for o in others]), self.bar)

Parameters:
  • others – the other state plugins to merge with

  • merge_conditions – a symbolic condition for each of the plugins

  • common_ancestor – a common ancestor of this plugin and the others being merged

Returns:

True if the state plugins are actually merged.

Return type:

bool

widen(others)

The widening operation for plugins. Widening is a special kind of merging that produces a more general state from several more specific states. It is used only during intensive static analysis. The same behavior regarding copying and mutation from merge should be followed.

Parameters:

others – the other state plugin

Returns:

True if the state plugin is actually widened.

Return type:

bool

copy(memo: dict[int, Any] | None = None, **kwargs: Any) S_co

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:
  • memo (Optional[dict[int, Any]]) – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

  • kwargs (Any)

Return type:

TypeVar(S_co, covariant=True)

trim()

Discard the ancestry of this state.

filter_actions(start_block_addr=None, end_block_addr=None, block_stmt=None, insn_addr=None, read_from=None, write_to=None)

Filter self.actions based on some common parameters.

[start_block_addr, end_block_addr]

Parameters:
  • start_block_addr – Only return actions generated in blocks starting at this address.

  • end_block_addr – Only return actions generated in blocks ending at this address.

  • block_stmt – Only return actions generated in the nth statement of each block.

  • insn_addr – Only return actions generated in the assembly instruction at this address.

  • read_from – Only return actions that perform a read from the specified location.

  • write_to – Only return actions that perform a write to the specified location.

Notes: If IR optimization is turned on, reads and writes may not occur in the instruction they originally came from. Most commonly, If a register is read from twice in the same block, the second read will not happen, instead reusing the temp the value is already stored in.

Valid values for read_from and write_to are the string literals ‘reg’ or ‘mem’ (matching any read or write to registers or memory, respectively), any string (representing a read or write to the named register), and any integer (representing a read or write to the memory at this address).

demote()

Demotes this history node, causing it to drop the strong state reference.

reachable()
add_event(event_type, **kwargs)
add_action(action)
extend_actions(new_actions)
subscribe_actions()
property recent_constraints
property recent_actions
property block_count
property lineage
property parents
property events: Reversible[SimEvent]
property actions: Reversible[SimAction]
property jumpkinds: Reversible[str]
property jump_guards: Reversible[Bool]
property jump_targets
property jump_sources
property descriptions: Reversible[str]
property bbl_addrs: Reversible[int]
property ins_addrs: Reversible[int]
property stack_actions
closest_common_ancestor(other)

Find the common ancestor between this history node and ‘other’.

Parameters:

other – the PathHistory to find a common ancestor with.

Returns:

the common ancestor SimStateHistory, or None if there isn’t one

constraints_since(other)

Returns the constraints that have been accumulated since other.

Parameters:

other – a prior PathHistory object

Returns:

a list of constraints

make_child()
state: angr.SimState
class angr.state_plugins.history.TreeIter(start, end=None)

Bases: object

__init__(start, end=None)
property hardcopy
count(v)

Count occurrences of value v in the entire history. Note that the subclass must implement the __reversed__ method, otherwise an exception will be thrown. :param object v: The value to look for :return: The number of occurrences :rtype: int

class angr.state_plugins.history.HistoryIter(start, end=None)

Bases: TreeIter

class angr.state_plugins.history.LambdaAttrIter(start, f, **kwargs)

Bases: TreeIter

__init__(start, f, **kwargs)
class angr.state_plugins.history.LambdaIterIter(start, f, reverse=True, **kwargs)

Bases: LambdaAttrIter

__init__(start, f, reverse=True, **kwargs)
class angr.state_plugins.gdb.GDB(omit_fp=False, adjust_stack=False)

Bases: SimStatePlugin

Initialize or update a state from gdb dumps of the stack, heap, registers and data (or arbitrary) segments.

__init__(omit_fp=False, adjust_stack=False)
Parameters:
  • omit_fp – The frame pointer register is used for something else. (i.e. –omit_frame_pointer)

  • adjust_stack – Use different stack addresses than the gdb session (not recommended).

set_stack(stack_dump, stack_top)

Stack dump is a dump of the stack from gdb, i.e. the result of the following gdb command :

dump binary memory [stack_dump] [begin_addr] [end_addr]

We set the stack to the same addresses as the gdb session to avoid pointers corruption.

Parameters:
  • stack_dump – The dump file.

  • stack_top – The address of the top of the stack in the gdb session.

set_heap(heap_dump, heap_base)

Heap dump is a dump of the heap from gdb, i.e. the result of the following gdb command:

dump binary memory [stack_dump] [begin] [end]

Parameters:
  • heap_dump – The dump file.

  • heap_base – The start address of the heap in the gdb session.

set_data(addr, data_dump)

Update any data range (most likely use is the data segments of loaded objects)

set_regs(regs_dump)

Initialize register values within the state

Parameters:

regs_dump – The output of info registers in gdb.

copy(memo: dict[int, Any] | None = None, **kwargs: Any) S_co

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:
  • memo (Optional[dict[int, Any]]) – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

  • kwargs (Any)

Return type:

TypeVar(S_co, covariant=True)

class angr.state_plugins.cgc.SimStateCGC

Bases: SimStatePlugin

This state plugin keeps track of CGC state.

EBADF = 1
EFAULT = 2
EINVAL = 3
ENOMEM = 4
ENOSYS = 5
EPIPE = 6
FD_SETSIZE = 1024
max_allocation = 268435456
__init__()
copy(memo: dict[int, Any] | None = None, **kwargs: Any) S_co

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:
  • memo (Optional[dict[int, Any]]) – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

  • kwargs (Any)

Return type:

TypeVar(S_co, covariant=True)

peek_input()
discard_input(num_bytes)
peek_output()
discard_output(num_bytes)
addr_invalid(a)
merge(others, merge_conditions, common_ancestor=None)

Should merge the state plugin with the provided others. This will be called by state.merge() after copying the target state, so this should mutate the current instance to merge with the others.

Note that when multiple instances of a single plugin object (for example, a file) are referenced in the state, it is important that merge only ever be called once. This should be solved by designating one of the plugin’s referees as the “real owner”, who should be the one to actually merge it. This technique doesn’t work to resolve the similar issue that arises during copying because merging doesn’t produce a new reference to insert.

There will be n others and n+1 merge conditions, since the first condition corresponds to self. To match elements up to conditions, say zip([self] + others, merge_conditions)

When implementing this, make sure that you “deepen” both others and common_ancestor before calling sub-elements’ merge methods, e.g.

self.foo.merge(
    [o.foo for o in others],
    merge_conditions,
    common_ancestor=common_ancestor.foo if common_ancestor is not None else None
)

During static analysis, merge_conditions can be None, in which case you should use state.solver.union(values). TODO: fish please make this less bullshit

There is a utility claripy.ite_cases which will help with constructing arbitrarily large merged ASTs. Use it like self.bar = claripy.ite_cases(zip(conditions[1:], [o.bar for o in others]), self.bar)

Parameters:
  • others – the other state plugins to merge with

  • merge_conditions – a symbolic condition for each of the plugins

  • common_ancestor – a common ancestor of this plugin and the others being merged

Returns:

True if the state plugins are actually merged.

Return type:

bool

widen(others)

The widening operation for plugins. Widening is a special kind of merging that produces a more general state from several more specific states. It is used only during intensive static analysis. The same behavior regarding copying and mutation from merge should be followed.

Parameters:

others – the other state plugin

Returns:

True if the state plugin is actually widened.

Return type:

bool

get_max_sinkhole(length)

Find a sinkhole which is large enough to support length bytes.

This uses first-fit. The first sinkhole (ordered in descending order by their address) which can hold length bytes is chosen. If there are more than length bytes in the sinkhole, a new sinkhole is created representing the remaining bytes while the old sinkhole is removed.

add_sinkhole(address, length)

Add a sinkhole.

Allow the possibility for the program to reuse the memory represented by the address length pair.

state: angr.SimState

This file contains objects to track additional information during a trace or modify symbolic variables during a trace.

The ChallRespInfo plugin tracks variables in stdin and stdout to enable handling of challenge response It handles atoi/int2str in a special manner since path constraints will usually prevent their values from being modified

The Zen plugin simplifies expressions created from variables in the flag page (losing some accuracy) to avoid situations where they become to complex for z3, but the actual equation doesn’t matter much. This can happen in challenge response if all of the values in the flag page are multiplied together before being printed.

class angr.state_plugins.trace_additions.FormatInfo

Bases: object

copy()
compute(state)
get_type()
class angr.state_plugins.trace_additions.FormatInfoStrToInt(addr, func_name, str_arg_num, base, base_arg, allows_negative)

Bases: FormatInfo

__init__(addr, func_name, str_arg_num, base, base_arg, allows_negative)
copy()
compute(state)
get_type()
class angr.state_plugins.trace_additions.FormatInfoIntToStr(addr, func_name, int_arg_num, str_dst_num, base, base_arg)

Bases: FormatInfo

__init__(addr, func_name, int_arg_num, str_dst_num, base, base_arg)
copy()
compute(state)
get_type()
class angr.state_plugins.trace_additions.FormatInfoDontConstrain(addr, func_name, check_symbolic_arg)

Bases: FormatInfo

__init__(addr, func_name, check_symbolic_arg)
copy()
compute(state)
get_type()
angr.state_plugins.trace_additions.int2base(x, base)
angr.state_plugins.trace_additions.generic_info_hook(state)
angr.state_plugins.trace_additions.end_info_hook(state)
angr.state_plugins.trace_additions.exit_hook(state)
angr.state_plugins.trace_additions.syscall_hook(state)
angr.state_plugins.trace_additions.constraint_hook(state)
class angr.state_plugins.trace_additions.ChallRespInfo

Bases: SimStatePlugin

This state plugin keeps track of the reads and writes to symbolic addresses

__init__()
copy(memo: dict[int, Any] | None = None, **kwargs: Any) S_co

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:
  • memo (Optional[dict[int, Any]]) – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

  • kwargs (Any)

Return type:

TypeVar(S_co, covariant=True)

merge(others, merge_conditions, common_ancestor=None)

Should merge the state plugin with the provided others. This will be called by state.merge() after copying the target state, so this should mutate the current instance to merge with the others.

Note that when multiple instances of a single plugin object (for example, a file) are referenced in the state, it is important that merge only ever be called once. This should be solved by designating one of the plugin’s referees as the “real owner”, who should be the one to actually merge it. This technique doesn’t work to resolve the similar issue that arises during copying because merging doesn’t produce a new reference to insert.

There will be n others and n+1 merge conditions, since the first condition corresponds to self. To match elements up to conditions, say zip([self] + others, merge_conditions)

When implementing this, make sure that you “deepen” both others and common_ancestor before calling sub-elements’ merge methods, e.g.

self.foo.merge(
    [o.foo for o in others],
    merge_conditions,
    common_ancestor=common_ancestor.foo if common_ancestor is not None else None
)

During static analysis, merge_conditions can be None, in which case you should use state.solver.union(values). TODO: fish please make this less bullshit

There is a utility claripy.ite_cases which will help with constructing arbitrarily large merged ASTs. Use it like self.bar = claripy.ite_cases(zip(conditions[1:], [o.bar for o in others]), self.bar)

Parameters:
  • others – the other state plugins to merge with

  • merge_conditions – a symbolic condition for each of the plugins

  • common_ancestor – a common ancestor of this plugin and the others being merged

Returns:

True if the state plugins are actually merged.

Return type:

bool

widen(others)

The widening operation for plugins. Widening is a special kind of merging that produces a more general state from several more specific states. It is used only during intensive static analysis. The same behavior regarding copying and mutation from merge should be followed.

Parameters:

others – the other state plugin

Returns:

True if the state plugin is actually widened.

Return type:

bool

static get_byte(var_name)
lookup_original(replacement)
pop_from_backup()
get_stdin_indices(variable)
get_stdout_indices(variable)
get_real_len(input_val, base, result_bv, allows_negative)
get_possible_len(input_val, base, allows_negative)
get_same_length_constraints()
static atoi_dumps(state, require_same_length=True)
static prep_tracer(state, format_infos=None)
angr.state_plugins.trace_additions.zen_hook(state, expr)
angr.state_plugins.trace_additions.zen_memory_write(state)
angr.state_plugins.trace_additions.zen_register_write(state)
class angr.state_plugins.trace_additions.ZenPlugin(max_depth=13)

Bases: SimStatePlugin

__init__(max_depth=13)
static get_flag_rand_args(expr)
get_expr_depth(expr)
copy(memo: dict[int, Any] | None = None, **kwargs: Any) S_co

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:
  • memo (Optional[dict[int, Any]]) – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

  • kwargs (Any)

Return type:

TypeVar(S_co, covariant=True)

merge(others, merge_conditions, common_ancestor=None)

Should merge the state plugin with the provided others. This will be called by state.merge() after copying the target state, so this should mutate the current instance to merge with the others.

Note that when multiple instances of a single plugin object (for example, a file) are referenced in the state, it is important that merge only ever be called once. This should be solved by designating one of the plugin’s referees as the “real owner”, who should be the one to actually merge it. This technique doesn’t work to resolve the similar issue that arises during copying because merging doesn’t produce a new reference to insert.

There will be n others and n+1 merge conditions, since the first condition corresponds to self. To match elements up to conditions, say zip([self] + others, merge_conditions)

When implementing this, make sure that you “deepen” both others and common_ancestor before calling sub-elements’ merge methods, e.g.

self.foo.merge(
    [o.foo for o in others],
    merge_conditions,
    common_ancestor=common_ancestor.foo if common_ancestor is not None else None
)

During static analysis, merge_conditions can be None, in which case you should use state.solver.union(values). TODO: fish please make this less bullshit

There is a utility claripy.ite_cases which will help with constructing arbitrarily large merged ASTs. Use it like self.bar = claripy.ite_cases(zip(conditions[1:], [o.bar for o in others]), self.bar)

Parameters:
  • others – the other state plugins to merge with

  • merge_conditions – a symbolic condition for each of the plugins

  • common_ancestor – a common ancestor of this plugin and the others being merged

Returns:

True if the state plugins are actually merged.

Return type:

bool

widen(others)

The widening operation for plugins. Widening is a special kind of merging that produces a more general state from several more specific states. It is used only during intensive static analysis. The same behavior regarding copying and mutation from merge should be followed.

Parameters:

others – the other state plugin

Returns:

True if the state plugin is actually widened.

Return type:

bool

get_flag_bytes(ast)
filter_constraints(constraints)
analyze_transmit(state, buf)
static prep_tracer(state)
class angr.state_plugins.globals.SimStateGlobals(backer=None)

Bases: SimStatePlugin

__init__(backer=None)
set_state(state)

Sets a new state (for example, if the state has been branched)

merge(others, merge_conditions, common_ancestor=None)

Should merge the state plugin with the provided others. This will be called by state.merge() after copying the target state, so this should mutate the current instance to merge with the others.

Note that when multiple instances of a single plugin object (for example, a file) are referenced in the state, it is important that merge only ever be called once. This should be solved by designating one of the plugin’s referees as the “real owner”, who should be the one to actually merge it. This technique doesn’t work to resolve the similar issue that arises during copying because merging doesn’t produce a new reference to insert.

There will be n others and n+1 merge conditions, since the first condition corresponds to self. To match elements up to conditions, say zip([self] + others, merge_conditions)

When implementing this, make sure that you “deepen” both others and common_ancestor before calling sub-elements’ merge methods, e.g.

self.foo.merge(
    [o.foo for o in others],
    merge_conditions,
    common_ancestor=common_ancestor.foo if common_ancestor is not None else None
)

During static analysis, merge_conditions can be None, in which case you should use state.solver.union(values). TODO: fish please make this less bullshit

There is a utility claripy.ite_cases which will help with constructing arbitrarily large merged ASTs. Use it like self.bar = claripy.ite_cases(zip(conditions[1:], [o.bar for o in others]), self.bar)

Parameters:
  • others – the other state plugins to merge with

  • merge_conditions – a symbolic condition for each of the plugins

  • common_ancestor – a common ancestor of this plugin and the others being merged

Returns:

True if the state plugins are actually merged.

Return type:

bool

widen(others)

The widening operation for plugins. Widening is a special kind of merging that produces a more general state from several more specific states. It is used only during intensive static analysis. The same behavior regarding copying and mutation from merge should be followed.

Parameters:

others – the other state plugin

Returns:

True if the state plugin is actually widened.

Return type:

bool

keys()
values()
items()
get(k, alt=None)
pop(k, alt=None)
copy(memo: dict[int, Any] | None = None, **kwargs: Any) S_co

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:
  • memo (Optional[dict[int, Any]]) – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

  • kwargs (Any)

Return type:

TypeVar(S_co, covariant=True)

class angr.state_plugins.uc_manager.SimUCManager(man=None)

Bases: SimStatePlugin

__init__(man=None)
assign(dst_addr_ast)

Assign a new region for under-constrained symbolic execution.

Parameters:

dst_addr_ast – the symbolic AST which address of the new allocated region will be assigned to.

Returns:

as ast of memory address that points to a new region

copy(memo: dict[int, Any] | None = None, **kwargs: Any) S_co

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:
  • memo (Optional[dict[int, Any]]) – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

  • kwargs (Any)

Return type:

TypeVar(S_co, covariant=True)

get_alloc_depth(addr)
Return type:

int | None

Parameters:

addr (int | Base)

set_alloc_depth(addr, depth)
Parameters:
is_bounded(ast)

Test whether an AST is bounded by any existing constraint in the related solver.

Parameters:

ast – an claripy.AST object

Returns:

True if there is at least one related constraint, False otherwise

set_state(state)

Sets a new state (for example, if the state has been branched)

class angr.state_plugins.scratch.SimStateScratch(scratch=None)

Bases: SimStatePlugin

Implements the scratch state plugin.

__init__(scratch=None)
property priv
push_priv(priv)
pop_priv()
set_tyenv(tyenv)
tmp_expr(tmp)

Returns the Claripy expression of a VEX temp value.

Parameters:
  • tmp – the number of the tmp

  • simplify – simplify the tmp before returning it

Returns:

a Claripy expression of the tmp

store_tmp(tmp, content, reg_deps=frozenset({}), tmp_deps=frozenset({}), deps=None, **kwargs)

Stores a Claripy expression in a VEX temp value. If in symbolic mode, this involves adding a constraint for the tmp’s symbolic variable.

Parameters:
  • tmp – the number of the tmp

  • content – a Claripy expression of the content

  • reg_deps – the register dependencies of the content

  • tmp_deps – the temporary value dependencies of the content

copy(memo: dict[int, Any] | None = None, **kwargs: Any) S_co

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:
  • memo (Optional[dict[int, Any]]) – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

  • kwargs (Any)

Return type:

TypeVar(S_co, covariant=True)

merge(others, merge_conditions, common_ancestor=None)

Should merge the state plugin with the provided others. This will be called by state.merge() after copying the target state, so this should mutate the current instance to merge with the others.

Note that when multiple instances of a single plugin object (for example, a file) are referenced in the state, it is important that merge only ever be called once. This should be solved by designating one of the plugin’s referees as the “real owner”, who should be the one to actually merge it. This technique doesn’t work to resolve the similar issue that arises during copying because merging doesn’t produce a new reference to insert.

There will be n others and n+1 merge conditions, since the first condition corresponds to self. To match elements up to conditions, say zip([self] + others, merge_conditions)

When implementing this, make sure that you “deepen” both others and common_ancestor before calling sub-elements’ merge methods, e.g.

self.foo.merge(
    [o.foo for o in others],
    merge_conditions,
    common_ancestor=common_ancestor.foo if common_ancestor is not None else None
)

During static analysis, merge_conditions can be None, in which case you should use state.solver.union(values). TODO: fish please make this less bullshit

There is a utility claripy.ite_cases which will help with constructing arbitrarily large merged ASTs. Use it like self.bar = claripy.ite_cases(zip(conditions[1:], [o.bar for o in others]), self.bar)

Parameters:
  • others – the other state plugins to merge with

  • merge_conditions – a symbolic condition for each of the plugins

  • common_ancestor – a common ancestor of this plugin and the others being merged

Returns:

True if the state plugins are actually merged.

Return type:

bool

widen(others)

The widening operation for plugins. Widening is a special kind of merging that produces a more general state from several more specific states. It is used only during intensive static analysis. The same behavior regarding copying and mutation from merge should be followed.

Parameters:

others – the other state plugin

Returns:

True if the state plugin is actually widened.

Return type:

bool

clear()
class angr.state_plugins.preconstrainer.SimStatePreconstrainer(constrained_addrs=None)

Bases: SimStatePlugin

This state plugin manages the concept of preconstraining - adding constraints which you would like to remove later.

Parameters:

constrained_addrs – SimActions for memory operations whose addresses should be constrained during crash analysis

__init__(constrained_addrs=None)
merge(others, merge_conditions, common_ancestor=None)

Should merge the state plugin with the provided others. This will be called by state.merge() after copying the target state, so this should mutate the current instance to merge with the others.

Note that when multiple instances of a single plugin object (for example, a file) are referenced in the state, it is important that merge only ever be called once. This should be solved by designating one of the plugin’s referees as the “real owner”, who should be the one to actually merge it. This technique doesn’t work to resolve the similar issue that arises during copying because merging doesn’t produce a new reference to insert.

There will be n others and n+1 merge conditions, since the first condition corresponds to self. To match elements up to conditions, say zip([self] + others, merge_conditions)

When implementing this, make sure that you “deepen” both others and common_ancestor before calling sub-elements’ merge methods, e.g.

self.foo.merge(
    [o.foo for o in others],
    merge_conditions,
    common_ancestor=common_ancestor.foo if common_ancestor is not None else None
)

During static analysis, merge_conditions can be None, in which case you should use state.solver.union(values). TODO: fish please make this less bullshit

There is a utility claripy.ite_cases which will help with constructing arbitrarily large merged ASTs. Use it like self.bar = claripy.ite_cases(zip(conditions[1:], [o.bar for o in others]), self.bar)

Parameters:
  • others – the other state plugins to merge with

  • merge_conditions – a symbolic condition for each of the plugins

  • common_ancestor – a common ancestor of this plugin and the others being merged

Returns:

True if the state plugins are actually merged.

Return type:

bool

widen(others)

The widening operation for plugins. Widening is a special kind of merging that produces a more general state from several more specific states. It is used only during intensive static analysis. The same behavior regarding copying and mutation from merge should be followed.

Parameters:

others – the other state plugin

Returns:

True if the state plugin is actually widened.

Return type:

bool

copy(memo: dict[int, Any] | None = None, **kwargs: Any) S_co

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:
  • memo (Optional[dict[int, Any]]) – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

  • kwargs (Any)

Return type:

TypeVar(S_co, covariant=True)

preconstrain(value, variable)

Add a preconstraint that variable == value to the state.

Parameters:
  • value – The concrete value. Can be a bitvector or a bytestring or an integer.

  • variable – The BVS to preconstrain.

preconstrain_file(content, simfile, set_length=False)

Preconstrain the contents of a file.

Parameters:
  • content – The content to preconstrain the file to. Can be a bytestring or a list thereof.

  • simfile – The actual simfile to preconstrain

preconstrain_flag_page(magic_content)

Preconstrain the data in the flag page.

Parameters:

magic_content – The content of the magic page as a bytestring.

remove_preconstraints(to_composite_solver=True, simplify=True)

Remove the preconstraints from the state.

If you are using the zen plugin, this will also use that to filter the constraints.

Parameters:
  • to_composite_solver – Whether to convert the replacement solver to a composite solver. You probably want this if you’re switching from tracing to symbolic analysis.

  • simplify – Whether to simplify the resulting set of constraints.

reconstrain()

Split the solver. If any of the subsolvers time out after a short timeout (10 seconds), re-add the preconstraints associated with each of its variables. Hopefully these constraints still allow us to do meaningful things to the state.

class angr.state_plugins.unicorn_engine.MEM_PATCH

Bases: Structure

struct mem_update_t

address

Structure/Union member

length

Structure/Union member

next

Structure/Union member

class angr.state_plugins.unicorn_engine.TRANSMIT_RECORD

Bases: Structure

struct transmit_record_t

count

Structure/Union member

data

Structure/Union member

fd

Structure/Union member

class angr.state_plugins.unicorn_engine.TaintEntityEnum

Bases: object

taint_entity_enum_t

TAINT_ENTITY_REG = 0
TAINT_ENTITY_TMP = 1
TAINT_ENTITY_MEM = 2
TAINT_ENTITY_NONE = 3
class angr.state_plugins.unicorn_engine.MemoryValue

Bases: Structure

struct memory_value_t

address

Structure/Union member

is_value_set

Structure/Union member

is_value_symbolic

Structure/Union member

value

Structure/Union member

class angr.state_plugins.unicorn_engine.RegisterValue

Bases: Structure

struct register_value_t

offset

Structure/Union member

size

Structure/Union member

value

Structure/Union member

class angr.state_plugins.unicorn_engine.VEXStmtDetails

Bases: Structure

struct sym_vex_stmt_details_t

has_memory_dep

Structure/Union member

memory_values

Structure/Union member

memory_values_count

Structure/Union member

stmt_idx

Structure/Union member

class angr.state_plugins.unicorn_engine.BlockDetails

Bases: Structure

struct sym_block_details_ret_t

block_addr

Structure/Union member

block_size

Structure/Union member

block_trace_ind

Structure/Union member

has_symbolic_exit

Structure/Union member

register_values

Structure/Union member

register_values_count

Structure/Union member

symbolic_vex_stmts

Structure/Union member

symbolic_vex_stmts_count

Structure/Union member

class angr.state_plugins.unicorn_engine.STOP

Bases: object

enum stop_t

STOP_NORMAL = 0
STOP_STOPPOINT = 1
STOP_ERROR = 2
STOP_SYSCALL = 3
STOP_EXECNONE = 4
STOP_ZEROPAGE = 5
STOP_NOSTART = 6
STOP_SEGFAULT = 7
STOP_ZERO_DIV = 8
STOP_NODECODE = 9
STOP_HLT = 10
STOP_VEX_LIFT_FAILED = 11
STOP_SYMBOLIC_PC = 12
STOP_SYMBOLIC_READ_ADDR = 13
STOP_SYMBOLIC_READ_SYMBOLIC_TRACKING_DISABLED = 14
STOP_SYMBOLIC_WRITE_ADDR = 15
STOP_SYMBOLIC_BLOCK_EXIT_CONDITION = 16
STOP_SYMBOLIC_BLOCK_EXIT_TARGET = 17
STOP_UNSUPPORTED_STMT_PUTI = 18
STOP_UNSUPPORTED_STMT_STOREG = 19
STOP_UNSUPPORTED_STMT_LOADG = 20
STOP_UNSUPPORTED_STMT_CAS = 21
STOP_UNSUPPORTED_STMT_LLSC = 22
STOP_UNSUPPORTED_STMT_DIRTY = 23
STOP_UNSUPPORTED_EXPR_GETI = 24
STOP_UNSUPPORTED_STMT_UNKNOWN = 25
STOP_UNSUPPORTED_EXPR_UNKNOWN = 26
STOP_UNKNOWN_MEMORY_WRITE_SIZE = 27
STOP_SYSCALL_ARM = 28
STOP_X86_CPUID = 29
stop_message = {0: 'Reached maximum steps', 1: 'Hit a stop point', 2: 'Something wrong', 3: 'Unable to handle syscall', 4: 'Fetching empty page', 5: 'Accessing zero page', 6: 'Failed to start', 7: 'Permissions or mapping error', 8: 'Divide by zero', 9: 'Instruction decoding error', 10: 'hlt instruction encountered', 11: 'Failed to lift block to VEX', 12: 'Instruction pointer became symbolic', 13: 'Attempted to read from symbolic address', 14: 'Attempted to read symbolic data from memory but symbolic tracking is disabled', 15: 'Attempted to write to symbolic address', 16: "Guard condition of block's exit statement is symbolic", 17: 'Target of default exit of block is symbolic', 18: 'Symbolic taint propagation for PutI statement not yet supported', 19: 'Symbolic taint propagation for StoreG statement not yet supported', 20: 'Symbolic taint propagation for LoadG statement not yet supported', 21: 'Symbolic taint propagation for CAS statement not yet supported', 22: 'Symbolic taint propagation for LLSC statement not yet supported', 23: 'Symbolic taint propagation for Dirty statement not yet supported', 24: 'Symbolic taint propagation for GetI expression not yet supported', 25: 'Canoo propagate symbolic taint for unsupported VEX statement type', 26: 'Cannot propagate symbolic taint for unsupported VEX expression', 27: 'Unicorn failed to determine size of memory write', 28: 'ARM syscalls are currently not supported by SimEngineUnicorn', 29: 'Block executes cpuid which should be handled in VEX engine'}
symbolic_stop_reasons = {12, 13, 14, 15, 16, 17, 28, 29}
unsupported_reasons = {11, 18, 19, 20, 21, 22, 23, 25, 26}
static name_stop(num)
static get_stop_msg(stop_reason)
class angr.state_plugins.unicorn_engine.StopDetails

Bases: Structure

struct stop_details_t

block_addr

Structure/Union member

block_size

Structure/Union member

stop_reason

Structure/Union member

class angr.state_plugins.unicorn_engine.SimOSEnum

Bases: object

enum simos_t

SIMOS_CGC = 0
SIMOS_LINUX = 1
SIMOS_OTHER = 2
exception angr.state_plugins.unicorn_engine.MemoryMappingError

Bases: Exception

exception angr.state_plugins.unicorn_engine.AccessingZeroPageError

Bases: MemoryMappingError

exception angr.state_plugins.unicorn_engine.FetchingZeroPageError

Bases: MemoryMappingError

exception angr.state_plugins.unicorn_engine.SegfaultError

Bases: MemoryMappingError

exception angr.state_plugins.unicorn_engine.MixedPermissonsError

Bases: MemoryMappingError

class angr.state_plugins.unicorn_engine.AggressiveConcretizationAnnotation(addr)

Bases: SimplificationAvoidanceAnnotation

__init__(addr)
class angr.state_plugins.unicorn_engine.Uniwrapper(arch, cache_key, thumb=False)

Bases: Uc

__init__(arch, cache_key, thumb=False)
hook_add(htype, callback, user_data=None, begin=1, end=0, arg1=0)
hook_del(h)
mem_map(addr, size, perms=7)
mem_map_ptr(addr, size, perms, ptr)
mem_unmap(addr, size)
mem_reset()
hook_reset()
reset()
class angr.state_plugins.unicorn_engine.Unicorn(syscall_hooks=None, cache_key=None, unicount=None, symbolic_var_counts=None, symbolic_inst_counts=None, concretized_asts=None, always_concretize=None, never_concretize=None, concretize_at=None, concretization_threshold_memory=None, concretization_threshold_registers=None, concretization_threshold_instruction=None, cooldown_symbolic_stop=2, cooldown_unsupported_stop=2, cooldown_nonunicorn_blocks=100, cooldown_stop_point=1, max_steps=1000000)

Bases: SimStatePlugin

setup the unicorn engine for a state

UC_CONFIG = {}
__init__(syscall_hooks=None, cache_key=None, unicount=None, symbolic_var_counts=None, symbolic_inst_counts=None, concretized_asts=None, always_concretize=None, never_concretize=None, concretize_at=None, concretization_threshold_memory=None, concretization_threshold_registers=None, concretization_threshold_instruction=None, cooldown_symbolic_stop=2, cooldown_unsupported_stop=2, cooldown_nonunicorn_blocks=100, cooldown_stop_point=1, max_steps=1000000)

Initializes the Unicorn plugin for angr. This plugin handles communication with UnicornEngine.

copy(memo: dict[int, Any] | None = None, **kwargs: Any) S_co

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:
  • memo (Optional[dict[int, Any]]) – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

  • kwargs (Any)

Return type:

TypeVar(S_co, covariant=True)

merge(others, merge_conditions, common_ancestor=None)

Should merge the state plugin with the provided others. This will be called by state.merge() after copying the target state, so this should mutate the current instance to merge with the others.

Note that when multiple instances of a single plugin object (for example, a file) are referenced in the state, it is important that merge only ever be called once. This should be solved by designating one of the plugin’s referees as the “real owner”, who should be the one to actually merge it. This technique doesn’t work to resolve the similar issue that arises during copying because merging doesn’t produce a new reference to insert.

There will be n others and n+1 merge conditions, since the first condition corresponds to self. To match elements up to conditions, say zip([self] + others, merge_conditions)

When implementing this, make sure that you “deepen” both others and common_ancestor before calling sub-elements’ merge methods, e.g.

self.foo.merge(
    [o.foo for o in others],
    merge_conditions,
    common_ancestor=common_ancestor.foo if common_ancestor is not None else None
)

During static analysis, merge_conditions can be None, in which case you should use state.solver.union(values). TODO: fish please make this less bullshit

There is a utility claripy.ite_cases which will help with constructing arbitrarily large merged ASTs. Use it like self.bar = claripy.ite_cases(zip(conditions[1:], [o.bar for o in others]), self.bar)

Parameters:
  • others – the other state plugins to merge with

  • merge_conditions – a symbolic condition for each of the plugins

  • common_ancestor – a common ancestor of this plugin and the others being merged

Returns:

True if the state plugins are actually merged.

Return type:

bool

widen(others)

The widening operation for plugins. Widening is a special kind of merging that produces a more general state from several more specific states. It is used only during intensive static analysis. The same behavior regarding copying and mutation from merge should be followed.

Parameters:

others – the other state plugin

Returns:

True if the state plugin is actually widened.

Return type:

bool

set_state(state)

Sets a new state (for example, if the state has been branched)

property uc
static delete_uc()
set_last_block_details(details)
set_stops(stop_points)
set_tracking(track_bbls, track_stack)
hook()
uncache_region(addr, length)
clear_page_cache()
setup(syscall_data=None, fd_bytes=None)
start(step=None)
get_recent_bbl_addrs()
get_stop_details()
finish(succ_state)
destroy(succ_state)
set_regs()

setting unicorn registers

setup_flags()
setup_gdt(fs, gs)
read_msr(msr=3221225728)
write_msr(val, msr=3221225728)
get_regs(succ_state)

loading registers from unicorn. If succ_state is not None, update it instead of self.state. Needed when handling symbolic exits in native interface

state: angr.SimState
class angr.state_plugins.loop_data.SimStateLoopData(back_edge_trip_counts=None, header_trip_counts=None, current_loop=None)

Bases: SimStatePlugin

This class keeps track of loop-related information for states. Note that we have 2 counters for loop iterations (trip counts): the first recording the number of times one of the back edges (or continue edges) of a loop is taken, whereas the second recording the number of times the loop header (or loop entry) is executed. These 2 counters may differ since compilers usually optimize loops hence completely change the loop structure at the binary level. This is supposed to be used with LoopSeer exploration technique, which monitors loop execution. For the moment, the only thing we want to analyze is loop trip counts, but nothing prevents us from extending this plugin for other loop analyses.

__init__(back_edge_trip_counts=None, header_trip_counts=None, current_loop=None)
Parameters:
  • back_edge_trip_counts – Dictionary that stores back edge based trip counts for each loop. Keys are address of loop headers.

  • header_trip_counts – Dictionary that stores header based trip counts for each loop. Keys are address of loop headers.

  • current_loop – List of currently running loops. Each element is a tuple (loop object, list of loop exits).

merge(others, merge_conditions, common_ancestor=None)

Should merge the state plugin with the provided others. This will be called by state.merge() after copying the target state, so this should mutate the current instance to merge with the others.

Note that when multiple instances of a single plugin object (for example, a file) are referenced in the state, it is important that merge only ever be called once. This should be solved by designating one of the plugin’s referees as the “real owner”, who should be the one to actually merge it. This technique doesn’t work to resolve the similar issue that arises during copying because merging doesn’t produce a new reference to insert.

There will be n others and n+1 merge conditions, since the first condition corresponds to self. To match elements up to conditions, say zip([self] + others, merge_conditions)

When implementing this, make sure that you “deepen” both others and common_ancestor before calling sub-elements’ merge methods, e.g.

self.foo.merge(
    [o.foo for o in others],
    merge_conditions,
    common_ancestor=common_ancestor.foo if common_ancestor is not None else None
)

During static analysis, merge_conditions can be None, in which case you should use state.solver.union(values). TODO: fish please make this less bullshit

There is a utility claripy.ite_cases which will help with constructing arbitrarily large merged ASTs. Use it like self.bar = claripy.ite_cases(zip(conditions[1:], [o.bar for o in others]), self.bar)

Parameters:
  • others – the other state plugins to merge with

  • merge_conditions – a symbolic condition for each of the plugins

  • common_ancestor – a common ancestor of this plugin and the others being merged

Returns:

True if the state plugins are actually merged.

Return type:

bool

widen(others)

The widening operation for plugins. Widening is a special kind of merging that produces a more general state from several more specific states. It is used only during intensive static analysis. The same behavior regarding copying and mutation from merge should be followed.

Parameters:

others – the other state plugin

Returns:

True if the state plugin is actually widened.

Return type:

bool

copy(memo: dict[int, Any] | None = None, **kwargs: Any) S_co

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:
  • memo (Optional[dict[int, Any]]) – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

  • kwargs (Any)

Return type:

TypeVar(S_co, covariant=True)

class angr.state_plugins.javavm_classloader.SimJavaVmClassloader(initialized_classes=None)

Bases: SimStatePlugin

JavaVM Classloader is used as an interface for resolving and initializing Java classes.

__init__(initialized_classes=None)
get_class(class_name, init_class=False, step_func=None)

Get a class descriptor for the class.

Parameters:
  • class_name (str) – Name of class.

  • init_class (bool) – Whether the class initializer <clinit> should be executed.

  • step_func (func) – Callback function executed at every step of the simulation manager during the execution of the main <clinit> method

get_superclass(class_)

Get the superclass of the class.

get_class_hierarchy(base_class)

Walks up the class hierarchy and returns a list of all classes between base class (inclusive) and java.lang.Object (exclusive).

is_class_initialized(class_)

Indicates whether the classes initializing method <clinit> was already executed on the state.

init_class(class_, step_func=None)

This method simulates the loading of a class by the JVM, during which parts of the class (e.g. static fields) are initialized. For this, we run the class initializer method <clinit> (if available) and update the state accordingly.

Note: Initialization is skipped, if the class has already been

initialized (or if it’s not loaded in CLE).

property initialized_classes

List of all initialized classes.

copy(memo: dict[int, Any] | None = None, **kwargs: Any) S_co

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:
  • memo (Optional[dict[int, Any]]) – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

  • kwargs (Any)

Return type:

TypeVar(S_co, covariant=True)

merge(others, merge_conditions, common_ancestor=None)

Should merge the state plugin with the provided others. This will be called by state.merge() after copying the target state, so this should mutate the current instance to merge with the others.

Note that when multiple instances of a single plugin object (for example, a file) are referenced in the state, it is important that merge only ever be called once. This should be solved by designating one of the plugin’s referees as the “real owner”, who should be the one to actually merge it. This technique doesn’t work to resolve the similar issue that arises during copying because merging doesn’t produce a new reference to insert.

There will be n others and n+1 merge conditions, since the first condition corresponds to self. To match elements up to conditions, say zip([self] + others, merge_conditions)

When implementing this, make sure that you “deepen” both others and common_ancestor before calling sub-elements’ merge methods, e.g.

self.foo.merge(
    [o.foo for o in others],
    merge_conditions,
    common_ancestor=common_ancestor.foo if common_ancestor is not None else None
)

During static analysis, merge_conditions can be None, in which case you should use state.solver.union(values). TODO: fish please make this less bullshit

There is a utility claripy.ite_cases which will help with constructing arbitrarily large merged ASTs. Use it like self.bar = claripy.ite_cases(zip(conditions[1:], [o.bar for o in others]), self.bar)

Parameters:
  • others – the other state plugins to merge with

  • merge_conditions – a symbolic condition for each of the plugins

  • common_ancestor – a common ancestor of this plugin and the others being merged

Returns:

True if the state plugins are actually merged.

Return type:

bool

widen(others)

The widening operation for plugins. Widening is a special kind of merging that produces a more general state from several more specific states. It is used only during intensive static analysis. The same behavior regarding copying and mutation from merge should be followed.

Parameters:

others – the other state plugin

Returns:

True if the state plugin is actually widened.

Return type:

bool

class angr.state_plugins.jni_references.SimStateJNIReferences(local_refs=None, global_refs=None)

Bases: SimStatePlugin

Management of the mapping between opaque JNI references and the corresponding Java objects.

__init__(local_refs=None, global_refs=None)
lookup(opaque_ref)

Lookups the object that was used for creating the reference.

create_new_reference(obj, global_ref=False)

Create a new reference thats maps to the given object.

Parameters:
  • obj – Object which gets referenced.

  • global_ref (bool) – Whether a local or global reference is created.

clear_local_references()

Clear all local references.

delete_reference(opaque_ref, global_ref=False)

Delete the stored mapping of a reference.

Parameters:
  • opaque_ref – Reference which should be removed.

  • global_ref (bool) – Whether opaque_ref is a local or global reference.

copy(memo: dict[int, Any] | None = None, **kwargs: Any) S_co

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:
  • memo (Optional[dict[int, Any]]) – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

  • kwargs (Any)

Return type:

TypeVar(S_co, covariant=True)

merge(others, merge_conditions, common_ancestor=None)

Should merge the state plugin with the provided others. This will be called by state.merge() after copying the target state, so this should mutate the current instance to merge with the others.

Note that when multiple instances of a single plugin object (for example, a file) are referenced in the state, it is important that merge only ever be called once. This should be solved by designating one of the plugin’s referees as the “real owner”, who should be the one to actually merge it. This technique doesn’t work to resolve the similar issue that arises during copying because merging doesn’t produce a new reference to insert.

There will be n others and n+1 merge conditions, since the first condition corresponds to self. To match elements up to conditions, say zip([self] + others, merge_conditions)

When implementing this, make sure that you “deepen” both others and common_ancestor before calling sub-elements’ merge methods, e.g.

self.foo.merge(
    [o.foo for o in others],
    merge_conditions,
    common_ancestor=common_ancestor.foo if common_ancestor is not None else None
)

During static analysis, merge_conditions can be None, in which case you should use state.solver.union(values). TODO: fish please make this less bullshit

There is a utility claripy.ite_cases which will help with constructing arbitrarily large merged ASTs. Use it like self.bar = claripy.ite_cases(zip(conditions[1:], [o.bar for o in others]), self.bar)

Parameters:
  • others – the other state plugins to merge with

  • merge_conditions – a symbolic condition for each of the plugins

  • common_ancestor – a common ancestor of this plugin and the others being merged

Returns:

True if the state plugins are actually merged.

Return type:

bool

widen(others)

The widening operation for plugins. Widening is a special kind of merging that produces a more general state from several more specific states. It is used only during intensive static analysis. The same behavior regarding copying and mutation from merge should be followed.

Parameters:

others – the other state plugin

Returns:

True if the state plugin is actually widened.

Return type:

bool

class angr.state_plugins.heap.PTChunk(base, sim_state, heap=None)

Bases: Chunk

A chunk, inspired by the implementation of chunks in ptmalloc. Provides a representation of a chunk via a view into the memory plugin. For the chunk definitions and docs that this was loosely based off of, see glibc malloc/malloc.c, line 1033, as of commit 5a580643111ef6081be7b4c7bd1997a5447c903f. Alternatively, take the following link. https://sourceware.org/git/?p=glibc.git;a=blob;f=malloc/malloc.c;h=67cdfd0ad2f003964cd0f7dfe3bcd85ca98528a7;hb=5a580643111ef6081be7b4c7bd1997a5447c903f#l1033

Variables:
  • base – the location of the base of the chunk in memory

  • state – the program state that the chunk is resident in

  • heap – the heap plugin that the chunk is managed by

__init__(base, sim_state, heap=None)
get_size()

Returns the actual size of a chunk (as opposed to the entire size field, which may include some flags).

get_data_size()

Returns the size of the data portion of a chunk.

set_size(size, is_free=None)

Use this to set the size on a chunk. When the chunk is new (such as when a free chunk is shrunk to form an allocated chunk and a remainder free chunk) it is recommended that the is_free hint be used since setting the size depends on the chunk’s freeness, and vice versa.

Parameters:
  • size – size of the chunk

  • is_free – boolean indicating the chunk’s freeness

set_prev_freeness(is_free)

Sets (or unsets) the flag controlling whether the previous chunk is free.

Parameters:

is_free – if True, sets the previous chunk to be free; if False, sets it to be allocated

is_prev_free()

Returns a concrete state of the flag indicating whether the previous chunk is free or not. Issues a warning if that flag is symbolic and has multiple solutions, and then assumes that the previous chunk is free.

Returns:

True if the previous chunk is free; False otherwise

prev_size()

Returns the size of the previous chunk, masking off what would be the flag bits if it were in the actual size field. Performs NO CHECKING to determine whether the previous chunk size is valid (for example, when the previous chunk is not free, its size cannot be determined).

is_free()

Returns a concrete determination as to whether the chunk is free.

data_ptr()

Returns the address of the payload of the chunk.

next_chunk()

Returns the chunk immediately following (and adjacent to) this one, if it exists.

Returns:

The following chunk, or None if applicable

prev_chunk()

Returns the chunk immediately prior (and adjacent) to this one, if that chunk is free. If the prior chunk is not free, then its base cannot be located and this method raises an error.

Returns:

If possible, the previous chunk; otherwise, raises an error

fwd_chunk()

Returns the chunk following this chunk in the list of free chunks. If this chunk is not free, then it resides in no such list and this method raises an error.

Returns:

If possible, the forward chunk; otherwise, raises an error

set_fwd_chunk(fwd)

Sets the chunk following this chunk in the list of free chunks.

Parameters:

fwd – the chunk to follow this chunk in the list of free chunks

bck_chunk()

Returns the chunk backward from this chunk in the list of free chunks. If this chunk is not free, then it resides in no such list and this method raises an error.

Returns:

If possible, the backward chunk; otherwise, raises an error

set_bck_chunk(bck)

Sets the chunk backward from this chunk in the list of free chunks.

Parameters:

bck – the chunk to precede this chunk in the list of free chunks

class angr.state_plugins.heap.PTChunkIterator(chunk, cond=<function PTChunkIterator.<lambda>>)

Bases: object

__init__(chunk, cond=<function PTChunkIterator.<lambda>>)
class angr.state_plugins.heap.SimHeapBase(heap_base=None, heap_size=None)

Bases: SimStatePlugin

This is the base heap class that all heap implementations should subclass. It defines a few handlers for common heap functions (the libc memory management functions). Heap implementations are expected to override these functions regardless of whether they implement the SimHeapLibc interface. For an example, see the SimHeapBrk implementation, which is based on the original libc SimProcedure implementations.

Variables:
  • heap_base – the address of the base of the heap in memory

  • heap_size – the total size of the main memory region managed by the heap in memory

  • mmap_base – the address of the region from which large mmap allocations will be made

__init__(heap_base=None, heap_size=None)
copy(memo)

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:

memo – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

init_state()

Use this function to perform any initialization on the state at plugin-add time

class angr.state_plugins.heap.SimHeapBrk(heap_base=None, heap_size=None)

Bases: SimHeapBase

SimHeapBrk represents a trivial heap implementation based on the Unix brk system call. This type of heap stores virtually no metadata, so it is up to the user to determine when it is safe to release memory. This also means that it does not properly support standard heap operations like realloc.

This heap implementation is a holdover from before any more proper implementations were modelled. At the time, various libc (or win32) SimProcedures handled the heap in the same way that this plugin does now. To make future heap implementations plug-and-playable, they should implement the necessary logic themselves, and dependent SimProcedures should invoke a method by the same name as theirs (prepended with an underscore) upon the heap plugin. Depending on the heap implementation, if the method is not supported, an error should be raised.

Out of consideration for the original way the heap was handled, this plugin implements functionality for all relevant SimProcedures (even those that would not normally be supported together in a single heap implementation).

Variables:

heap_location – the address of the top of the heap, bounding the allocations made starting from heap_base

__init__(heap_base=None, heap_size=None)
copy(memo: dict[int, Any] | None = None, **kwargs: Any) S_co

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:
  • memo (Optional[dict[int, Any]]) – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

  • kwargs (Any)

Return type:

TypeVar(S_co, covariant=True)

allocate(sim_size)

The actual allocation primitive for this heap implementation. Increases the position of the break to allocate space. Has no guards against the heap growing too large.

Parameters:

sim_size – a size specifying how much to increase the break pointer by

Returns:

a pointer to the previous break position, above which there is now allocated space

release(sim_size)

The memory release primitive for this heap implementation. Decreases the position of the break to deallocate space. Guards against releasing beyond the initial heap base.

Parameters:

sim_size – a size specifying how much to decrease the break pointer by (may be symbolic or not)

merge(others, merge_conditions, common_ancestor=None)

Should merge the state plugin with the provided others. This will be called by state.merge() after copying the target state, so this should mutate the current instance to merge with the others.

Note that when multiple instances of a single plugin object (for example, a file) are referenced in the state, it is important that merge only ever be called once. This should be solved by designating one of the plugin’s referees as the “real owner”, who should be the one to actually merge it. This technique doesn’t work to resolve the similar issue that arises during copying because merging doesn’t produce a new reference to insert.

There will be n others and n+1 merge conditions, since the first condition corresponds to self. To match elements up to conditions, say zip([self] + others, merge_conditions)

When implementing this, make sure that you “deepen” both others and common_ancestor before calling sub-elements’ merge methods, e.g.

self.foo.merge(
    [o.foo for o in others],
    merge_conditions,
    common_ancestor=common_ancestor.foo if common_ancestor is not None else None
)

During static analysis, merge_conditions can be None, in which case you should use state.solver.union(values). TODO: fish please make this less bullshit

There is a utility claripy.ite_cases which will help with constructing arbitrarily large merged ASTs. Use it like self.bar = claripy.ite_cases(zip(conditions[1:], [o.bar for o in others]), self.bar)

Parameters:
  • others – the other state plugins to merge with

  • merge_conditions – a symbolic condition for each of the plugins

  • common_ancestor – a common ancestor of this plugin and the others being merged

Returns:

True if the state plugins are actually merged.

Return type:

bool

widen(others)

The widening operation for plugins. Widening is a special kind of merging that produces a more general state from several more specific states. It is used only during intensive static analysis. The same behavior regarding copying and mutation from merge should be followed.

Parameters:

others – the other state plugin

Returns:

True if the state plugin is actually widened.

Return type:

bool

class angr.state_plugins.heap.SimHeapLibc(heap_base=None, heap_size=None)

Bases: SimHeapBase

A class of heap that implements the major libc heap management functions.

malloc(sim_size)

A somewhat faithful implementation of libc malloc.

Parameters:

sim_size – the amount of memory (in bytes) to be allocated

Returns:

the address of the allocation, or a NULL pointer if the allocation failed

free(ptr)

A somewhat faithful implementation of libc free.

Parameters:

ptr – the location in memory to be freed

calloc(sim_nmemb, sim_size)

A somewhat faithful implementation of libc calloc.

Parameters:
  • sim_nmemb – the number of elements to allocated

  • sim_size – the size of each element (in bytes)

Returns:

the address of the allocation, or a NULL pointer if the allocation failed

realloc(ptr, size)

A somewhat faithful implementation of libc realloc.

Parameters:
  • ptr – the location in memory to be reallocated

  • size – the new size desired for the allocation

Returns:

the address of the allocation, or a NULL pointer if the allocation was freed or if no new allocation was made

class angr.state_plugins.heap.SimHeapPTMalloc(heap_base=None, heap_size=None)

Bases: SimHeapFreelist

A freelist-style heap implementation inspired by ptmalloc. The chunks used by this heap contain heap metadata in addition to user data. While the real-world ptmalloc is implemented using multiple lists of free chunks (corresponding to their different sizes), this more basic model uses a single list of chunks and searches for free chunks using a first-fit algorithm.

NOTE: The plugin must be registered using register_plugin with name heap in order to function properly.

Variables:
  • heap_base – the address of the base of the heap in memory

  • heap_size – the total size of the main memory region managed by the heap in memory

  • mmap_base – the address of the region from which large mmap allocations will be made

  • free_head_chunk – the head of the linked list of free chunks in the heap

__init__(heap_base=None, heap_size=None)
copy(memo: dict[int, Any] | None = None, **kwargs: Any) S_co

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:
  • memo (Optional[dict[int, Any]]) – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

  • kwargs (Any)

Return type:

TypeVar(S_co, covariant=True)

chunks()

Returns an iterator over all the chunks in the heap.

allocated_chunks()

Returns an iterator over all the allocated chunks in the heap.

free_chunks()

Returns an iterator over all the free chunks in the heap.

chunk_from_mem(ptr)

Given a pointer to a user payload, return the base of the chunk associated with that payload (i.e. the chunk pointer). Returns None if ptr is null.

Parameters:

ptr – a pointer to the base of a user payload in the heap

Returns:

a pointer to the base of the associated heap chunk, or None if ptr is null

malloc(sim_size)

A somewhat faithful implementation of libc malloc.

Parameters:

sim_size – the amount of memory (in bytes) to be allocated

Returns:

the address of the allocation, or a NULL pointer if the allocation failed

free(ptr)

A somewhat faithful implementation of libc free.

Parameters:

ptr – the location in memory to be freed

calloc(sim_nmemb, sim_size)

A somewhat faithful implementation of libc calloc.

Parameters:
  • sim_nmemb – the number of elements to allocated

  • sim_size – the size of each element (in bytes)

Returns:

the address of the allocation, or a NULL pointer if the allocation failed

realloc(ptr, size)

A somewhat faithful implementation of libc realloc.

Parameters:
  • ptr – the location in memory to be reallocated

  • size – the new size desired for the allocation

Returns:

the address of the allocation, or a NULL pointer if the allocation was freed or if no new allocation was made

merge(others, merge_conditions, common_ancestor=None)

Should merge the state plugin with the provided others. This will be called by state.merge() after copying the target state, so this should mutate the current instance to merge with the others.

Note that when multiple instances of a single plugin object (for example, a file) are referenced in the state, it is important that merge only ever be called once. This should be solved by designating one of the plugin’s referees as the “real owner”, who should be the one to actually merge it. This technique doesn’t work to resolve the similar issue that arises during copying because merging doesn’t produce a new reference to insert.

There will be n others and n+1 merge conditions, since the first condition corresponds to self. To match elements up to conditions, say zip([self] + others, merge_conditions)

When implementing this, make sure that you “deepen” both others and common_ancestor before calling sub-elements’ merge methods, e.g.

self.foo.merge(
    [o.foo for o in others],
    merge_conditions,
    common_ancestor=common_ancestor.foo if common_ancestor is not None else None
)

During static analysis, merge_conditions can be None, in which case you should use state.solver.union(values). TODO: fish please make this less bullshit

There is a utility claripy.ite_cases which will help with constructing arbitrarily large merged ASTs. Use it like self.bar = claripy.ite_cases(zip(conditions[1:], [o.bar for o in others]), self.bar)

Parameters:
  • others – the other state plugins to merge with

  • merge_conditions – a symbolic condition for each of the plugins

  • common_ancestor – a common ancestor of this plugin and the others being merged

Returns:

True if the state plugins are actually merged.

Return type:

bool

widen(others)

The widening operation for plugins. Widening is a special kind of merging that produces a more general state from several more specific states. It is used only during intensive static analysis. The same behavior regarding copying and mutation from merge should be followed.

Parameters:

others – the other state plugin

Returns:

True if the state plugin is actually widened.

Return type:

bool

init_state()

Use this function to perform any initialization on the state at plugin-add time

class angr.state_plugins.heap.heap_base.SimHeapBase(heap_base=None, heap_size=None)

Bases: SimStatePlugin

This is the base heap class that all heap implementations should subclass. It defines a few handlers for common heap functions (the libc memory management functions). Heap implementations are expected to override these functions regardless of whether they implement the SimHeapLibc interface. For an example, see the SimHeapBrk implementation, which is based on the original libc SimProcedure implementations.

Variables:
  • heap_base – the address of the base of the heap in memory

  • heap_size – the total size of the main memory region managed by the heap in memory

  • mmap_base – the address of the region from which large mmap allocations will be made

__init__(heap_base=None, heap_size=None)
copy(memo)

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:

memo – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

init_state()

Use this function to perform any initialization on the state at plugin-add time

class angr.state_plugins.heap.heap_brk.SimHeapBrk(heap_base=None, heap_size=None)

Bases: SimHeapBase

SimHeapBrk represents a trivial heap implementation based on the Unix brk system call. This type of heap stores virtually no metadata, so it is up to the user to determine when it is safe to release memory. This also means that it does not properly support standard heap operations like realloc.

This heap implementation is a holdover from before any more proper implementations were modelled. At the time, various libc (or win32) SimProcedures handled the heap in the same way that this plugin does now. To make future heap implementations plug-and-playable, they should implement the necessary logic themselves, and dependent SimProcedures should invoke a method by the same name as theirs (prepended with an underscore) upon the heap plugin. Depending on the heap implementation, if the method is not supported, an error should be raised.

Out of consideration for the original way the heap was handled, this plugin implements functionality for all relevant SimProcedures (even those that would not normally be supported together in a single heap implementation).

Variables:

heap_location – the address of the top of the heap, bounding the allocations made starting from heap_base

__init__(heap_base=None, heap_size=None)
copy(memo: dict[int, Any] | None = None, **kwargs: Any) S_co

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:
  • memo (Optional[dict[int, Any]]) – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

  • kwargs (Any)

Return type:

TypeVar(S_co, covariant=True)

allocate(sim_size)

The actual allocation primitive for this heap implementation. Increases the position of the break to allocate space. Has no guards against the heap growing too large.

Parameters:

sim_size – a size specifying how much to increase the break pointer by

Returns:

a pointer to the previous break position, above which there is now allocated space

release(sim_size)

The memory release primitive for this heap implementation. Decreases the position of the break to deallocate space. Guards against releasing beyond the initial heap base.

Parameters:

sim_size – a size specifying how much to decrease the break pointer by (may be symbolic or not)

merge(others, merge_conditions, common_ancestor=None)

Should merge the state plugin with the provided others. This will be called by state.merge() after copying the target state, so this should mutate the current instance to merge with the others.

Note that when multiple instances of a single plugin object (for example, a file) are referenced in the state, it is important that merge only ever be called once. This should be solved by designating one of the plugin’s referees as the “real owner”, who should be the one to actually merge it. This technique doesn’t work to resolve the similar issue that arises during copying because merging doesn’t produce a new reference to insert.

There will be n others and n+1 merge conditions, since the first condition corresponds to self. To match elements up to conditions, say zip([self] + others, merge_conditions)

When implementing this, make sure that you “deepen” both others and common_ancestor before calling sub-elements’ merge methods, e.g.

self.foo.merge(
    [o.foo for o in others],
    merge_conditions,
    common_ancestor=common_ancestor.foo if common_ancestor is not None else None
)

During static analysis, merge_conditions can be None, in which case you should use state.solver.union(values). TODO: fish please make this less bullshit

There is a utility claripy.ite_cases which will help with constructing arbitrarily large merged ASTs. Use it like self.bar = claripy.ite_cases(zip(conditions[1:], [o.bar for o in others]), self.bar)

Parameters:
  • others – the other state plugins to merge with

  • merge_conditions – a symbolic condition for each of the plugins

  • common_ancestor – a common ancestor of this plugin and the others being merged

Returns:

True if the state plugins are actually merged.

Return type:

bool

widen(others)

The widening operation for plugins. Widening is a special kind of merging that produces a more general state from several more specific states. It is used only during intensive static analysis. The same behavior regarding copying and mutation from merge should be followed.

Parameters:

others – the other state plugin

Returns:

True if the state plugin is actually widened.

Return type:

bool

class angr.state_plugins.heap.heap_freelist.Chunk(base, sim_state)

Bases: object

The sort of chunk as would typically be found in a freelist-style heap implementation. Provides a representation of a chunk via a view into the memory plugin. Chunks may be adjacent, in different senses, to as many as four other chunks. For any given chunk, two of these chunks are adjacent to it in memory, and are referred to as the “previous” and “next” chunks throughout this implementation. For any given free chunk, there may also be two significant chunks that are adjacent to it in some linked list of free chunks. These chunks are referred to the “backward” and “forward” chunks relative to the chunk in question.

Variables:
  • base – the location of the base of the chunk in memory

  • state – the program state that the chunk is resident in

__init__(base, sim_state)
get_size()

Returns the actual size of a chunk (as opposed to the entire size field, which may include some flags).

get_data_size()

Returns the size of the data portion of a chunk.

set_size(size)

Sets the size of the chunk, preserving any flags.

data_ptr()

Returns the address of the payload of the chunk.

is_free()

Returns a concrete determination as to whether the chunk is free.

next_chunk()

Returns the chunk immediately following (and adjacent to) this one.

prev_chunk()

Returns the chunk immediately prior (and adjacent) to this one.

fwd_chunk()

Returns the chunk following this chunk in the list of free chunks.

set_fwd_chunk(fwd)

Sets the chunk following this chunk in the list of free chunks.

Parameters:

fwd – the chunk to follow this chunk in the list of free chunks

bck_chunk()

Returns the chunk backward from this chunk in the list of free chunks.

set_bck_chunk(bck)

Sets the chunk backward from this chunk in the list of free chunks.

Parameters:

bck – the chunk to precede this chunk in the list of free chunks

class angr.state_plugins.heap.heap_freelist.SimHeapFreelist(heap_base=None, heap_size=None)

Bases: SimHeapLibc

A freelist-style heap implementation. Distinguishing features of such heaps include chunks containing heap metadata in addition to user data and at least (but often more than) one linked list of free chunks.

chunks()

Returns an iterator over all the chunks in the heap.

allocated_chunks()

Returns an iterator over all the allocated chunks in the heap.

free_chunks()

Returns an iterator over all the free chunks in the heap.

chunk_from_mem(ptr)

Given a pointer to a user payload, return the chunk associated with that payload.

Parameters:

ptr – a pointer to the base of a user payload in the heap

Returns:

the associated heap chunk

print_heap_state()
print_all_chunks()
class angr.state_plugins.heap.heap_libc.SimHeapLibc(heap_base=None, heap_size=None)

Bases: SimHeapBase

A class of heap that implements the major libc heap management functions.

malloc(sim_size)

A somewhat faithful implementation of libc malloc.

Parameters:

sim_size – the amount of memory (in bytes) to be allocated

Returns:

the address of the allocation, or a NULL pointer if the allocation failed

free(ptr)

A somewhat faithful implementation of libc free.

Parameters:

ptr – the location in memory to be freed

calloc(sim_nmemb, sim_size)

A somewhat faithful implementation of libc calloc.

Parameters:
  • sim_nmemb – the number of elements to allocated

  • sim_size – the size of each element (in bytes)

Returns:

the address of the allocation, or a NULL pointer if the allocation failed

realloc(ptr, size)

A somewhat faithful implementation of libc realloc.

Parameters:
  • ptr – the location in memory to be reallocated

  • size – the new size desired for the allocation

Returns:

the address of the allocation, or a NULL pointer if the allocation was freed or if no new allocation was made

class angr.state_plugins.heap.heap_ptmalloc.PTChunk(base, sim_state, heap=None)

Bases: Chunk

A chunk, inspired by the implementation of chunks in ptmalloc. Provides a representation of a chunk via a view into the memory plugin. For the chunk definitions and docs that this was loosely based off of, see glibc malloc/malloc.c, line 1033, as of commit 5a580643111ef6081be7b4c7bd1997a5447c903f. Alternatively, take the following link. https://sourceware.org/git/?p=glibc.git;a=blob;f=malloc/malloc.c;h=67cdfd0ad2f003964cd0f7dfe3bcd85ca98528a7;hb=5a580643111ef6081be7b4c7bd1997a5447c903f#l1033

Variables:
  • base – the location of the base of the chunk in memory

  • state – the program state that the chunk is resident in

  • heap – the heap plugin that the chunk is managed by

__init__(base, sim_state, heap=None)
get_size()

Returns the actual size of a chunk (as opposed to the entire size field, which may include some flags).

get_data_size()

Returns the size of the data portion of a chunk.

set_size(size, is_free=None)

Use this to set the size on a chunk. When the chunk is new (such as when a free chunk is shrunk to form an allocated chunk and a remainder free chunk) it is recommended that the is_free hint be used since setting the size depends on the chunk’s freeness, and vice versa.

Parameters:
  • size – size of the chunk

  • is_free – boolean indicating the chunk’s freeness

set_prev_freeness(is_free)

Sets (or unsets) the flag controlling whether the previous chunk is free.

Parameters:

is_free – if True, sets the previous chunk to be free; if False, sets it to be allocated

is_prev_free()

Returns a concrete state of the flag indicating whether the previous chunk is free or not. Issues a warning if that flag is symbolic and has multiple solutions, and then assumes that the previous chunk is free.

Returns:

True if the previous chunk is free; False otherwise

prev_size()

Returns the size of the previous chunk, masking off what would be the flag bits if it were in the actual size field. Performs NO CHECKING to determine whether the previous chunk size is valid (for example, when the previous chunk is not free, its size cannot be determined).

is_free()

Returns a concrete determination as to whether the chunk is free.

data_ptr()

Returns the address of the payload of the chunk.

next_chunk()

Returns the chunk immediately following (and adjacent to) this one, if it exists.

Returns:

The following chunk, or None if applicable

prev_chunk()

Returns the chunk immediately prior (and adjacent) to this one, if that chunk is free. If the prior chunk is not free, then its base cannot be located and this method raises an error.

Returns:

If possible, the previous chunk; otherwise, raises an error

fwd_chunk()

Returns the chunk following this chunk in the list of free chunks. If this chunk is not free, then it resides in no such list and this method raises an error.

Returns:

If possible, the forward chunk; otherwise, raises an error

set_fwd_chunk(fwd)

Sets the chunk following this chunk in the list of free chunks.

Parameters:

fwd – the chunk to follow this chunk in the list of free chunks

bck_chunk()

Returns the chunk backward from this chunk in the list of free chunks. If this chunk is not free, then it resides in no such list and this method raises an error.

Returns:

If possible, the backward chunk; otherwise, raises an error

set_bck_chunk(bck)

Sets the chunk backward from this chunk in the list of free chunks.

Parameters:

bck – the chunk to precede this chunk in the list of free chunks

class angr.state_plugins.heap.heap_ptmalloc.PTChunkIterator(chunk, cond=<function PTChunkIterator.<lambda>>)

Bases: object

__init__(chunk, cond=<function PTChunkIterator.<lambda>>)
class angr.state_plugins.heap.heap_ptmalloc.SimHeapPTMalloc(heap_base=None, heap_size=None)

Bases: SimHeapFreelist

A freelist-style heap implementation inspired by ptmalloc. The chunks used by this heap contain heap metadata in addition to user data. While the real-world ptmalloc is implemented using multiple lists of free chunks (corresponding to their different sizes), this more basic model uses a single list of chunks and searches for free chunks using a first-fit algorithm.

NOTE: The plugin must be registered using register_plugin with name heap in order to function properly.

Variables:
  • heap_base – the address of the base of the heap in memory

  • heap_size – the total size of the main memory region managed by the heap in memory

  • mmap_base – the address of the region from which large mmap allocations will be made

  • free_head_chunk – the head of the linked list of free chunks in the heap

__init__(heap_base=None, heap_size=None)
copy(memo: dict[int, Any] | None = None, **kwargs: Any) S_co

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:
  • memo (Optional[dict[int, Any]]) – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

  • kwargs (Any)

Return type:

TypeVar(S_co, covariant=True)

chunks()

Returns an iterator over all the chunks in the heap.

allocated_chunks()

Returns an iterator over all the allocated chunks in the heap.

free_chunks()

Returns an iterator over all the free chunks in the heap.

chunk_from_mem(ptr)

Given a pointer to a user payload, return the base of the chunk associated with that payload (i.e. the chunk pointer). Returns None if ptr is null.

Parameters:

ptr – a pointer to the base of a user payload in the heap

Returns:

a pointer to the base of the associated heap chunk, or None if ptr is null

malloc(sim_size)

A somewhat faithful implementation of libc malloc.

Parameters:

sim_size – the amount of memory (in bytes) to be allocated

Returns:

the address of the allocation, or a NULL pointer if the allocation failed

free(ptr)

A somewhat faithful implementation of libc free.

Parameters:

ptr – the location in memory to be freed

calloc(sim_nmemb, sim_size)

A somewhat faithful implementation of libc calloc.

Parameters:
  • sim_nmemb – the number of elements to allocated

  • sim_size – the size of each element (in bytes)

Returns:

the address of the allocation, or a NULL pointer if the allocation failed

realloc(ptr, size)

A somewhat faithful implementation of libc realloc.

Parameters:
  • ptr – the location in memory to be reallocated

  • size – the new size desired for the allocation

Returns:

the address of the allocation, or a NULL pointer if the allocation was freed or if no new allocation was made

merge(others, merge_conditions, common_ancestor=None)

Should merge the state plugin with the provided others. This will be called by state.merge() after copying the target state, so this should mutate the current instance to merge with the others.

Note that when multiple instances of a single plugin object (for example, a file) are referenced in the state, it is important that merge only ever be called once. This should be solved by designating one of the plugin’s referees as the “real owner”, who should be the one to actually merge it. This technique doesn’t work to resolve the similar issue that arises during copying because merging doesn’t produce a new reference to insert.

There will be n others and n+1 merge conditions, since the first condition corresponds to self. To match elements up to conditions, say zip([self] + others, merge_conditions)

When implementing this, make sure that you “deepen” both others and common_ancestor before calling sub-elements’ merge methods, e.g.

self.foo.merge(
    [o.foo for o in others],
    merge_conditions,
    common_ancestor=common_ancestor.foo if common_ancestor is not None else None
)

During static analysis, merge_conditions can be None, in which case you should use state.solver.union(values). TODO: fish please make this less bullshit

There is a utility claripy.ite_cases which will help with constructing arbitrarily large merged ASTs. Use it like self.bar = claripy.ite_cases(zip(conditions[1:], [o.bar for o in others]), self.bar)

Parameters:
  • others – the other state plugins to merge with

  • merge_conditions – a symbolic condition for each of the plugins

  • common_ancestor – a common ancestor of this plugin and the others being merged

Returns:

True if the state plugins are actually merged.

Return type:

bool

widen(others)

The widening operation for plugins. Widening is a special kind of merging that produces a more general state from several more specific states. It is used only during intensive static analysis. The same behavior regarding copying and mutation from merge should be followed.

Parameters:

others – the other state plugin

Returns:

True if the state plugin is actually widened.

Return type:

bool

init_state()

Use this function to perform any initialization on the state at plugin-add time

angr.state_plugins.heap.utils.concretize(x, solver, sym_handler)

For now a lot of naive concretization is done when handling heap metadata to keep things manageable. This idiom showed up a lot as a result, so to reduce code repetition this function uses a callback to handle the one or two operations that varied across invocations.

Parameters:
  • x – the item to be concretized

  • solver – the solver to evaluate the item with

  • sym_handler – the handler to be used when the item may take on more than one value

Returns:

a concrete value for the item

class angr.state_plugins.symbolizer.SimSymbolizer

Bases: SimStatePlugin

The symbolizer state plugin ensures that pointers that are stored in memory are symbolic. This allows for the tracking of and reasoning over these pointers (for example, to reason about memory disclosure).

__init__()
init_state()

Use this function to perform any initialization on the state at plugin-add time

set_symbolization_for_all_pages()

Sets the symbolizer to symbolize pointers to all pages as they are written to memory..

set_symbolized_target_range(base, length)

All pointers to the target range will be symbolized as they are written to memory.

Due to optimizations, the _pages_ containing this range will be set as symbolization targets, not just the range itself.

resymbolize()

Re-symbolizes all pointers in memory. This can be called to symbolize any pointers to target regions that were written (and not mangled beyond recognition) before symbolization was set.

copy(memo: dict[int, Any] | None = None, **kwargs: Any) S_co

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:
  • memo (Optional[dict[int, Any]]) – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

  • kwargs (Any)

Return type:

TypeVar(S_co, covariant=True)

class angr.state_plugins.debug_variables.SimDebugVariable(state, addr, var_type)

Bases: object

A SimDebugVariable will get dynamically created when queriyng for variable in a state with the SimDebugVariablePlugin. It features a link to the state, an address and a type.

Parameters:
__init__(state, addr, var_type)
Parameters:
static from_cle_variable(state, cle_variable, dwarf_cfa)
Return type:

SimDebugVariable

Parameters:
property mem_untyped: SimMemView
property mem: SimMemView
property string: SimMemView
with_type(sim_type)
Return type:

SimMemView

Parameters:

sim_type (SimType)

property resolvable
property resolved
property concrete
store(value)
property deref: SimDebugVariable
array(i)
Return type:

SimDebugVariable

member(member_name)
Return type:

SimDebugVariable

Parameters:

member_name (str)

class angr.state_plugins.debug_variables.SimDebugVariablePlugin

Bases: SimStatePlugin

This is the plugin you’ll use to interact with (global/local) program variables. These variables have a name and a visibility scope which depends on the pc address of the state. With this plugin, you can access/modify the value of such variable or find its memory address. For creating program variables, or for importing them from cle, see the knowledge plugin debug_variables. Run p.kb.dvars.load_from_dwarf() before using this plugin.

Example

>>> p = angr.Project("various_variables", load_debug_info=True)
>>> p.kb.dvars.load_from_dwarf()
>>> state =  # navigate to the state you want
>>> state.dvars.get_variable("pointer2").deref.mem
<int (32 bits) <BV32 0x1> at 0x404020>
get_variable(var_name)

Returns the visible variable (if any) with name var_name based on the current state.ip.

Return type:

SimDebugVariable

Parameters:

var_name (str)

property dwarf_cfa

Returns the current cfa computation. Set this property to the correct value if needed.

property dwarf_cfa_approx

Storage

class angr.storage.DefaultMemory(*args, **kwargs)

Bases: HexDumperMixin, SmartFindMixin, UnwrapperMixin, NameResolutionMixin, DataNormalizationMixin, SimplificationMixin, InspectMixinHigh, ActionsMixinHigh, UnderconstrainedMixin, SizeConcretizationMixin, SizeNormalizationMixin, AddressConcretizationMixin, ActionsMixinLow, ConditionalMixin, ConvenientMappingsMixin, DirtyAddrsMixin, StackAllocationMixin, ConcreteBackerMixin, ClemoryBackerMixin, DictBackerMixin, PrivilegedPagingMixin, UltraPagesMixin, DefaultFillerMixin, SymbolicMergerMixin, PagedMemoryMixin

class angr.storage.SimFile(name=None, content=None, size=None, has_end=None, seekable=True, writable=True, ident=None, concrete=None, **kwargs)

Bases: SimFileBase, DefaultMemory

The normal SimFile is meant to model files on disk. It subclasses SimSymbolicMemory so loads and stores to/from it are very simple.

Parameters:
  • name – The name of the file

  • content – Optional initial content for the file as a string or bitvector

  • size – Optional size of the file. If content is not specified, it defaults to zero

  • has_end – Whether the size boundary is treated as the end of the file or a frontier at which new content will be generated. If unspecified, will pick its value based on options.FILES_HAVE_EOF. Another caveat is that if the size is also unspecified this value will default to False.

  • seekable – Optional bool indicating whether seek operations on this file should succeed, default True.

  • writable – Whether writing to this file is allowed

  • concrete – Whether or not this file contains mostly concrete data. Will be used by some SimProcedures to choose how to handle variable-length operations like fgets.

Variables:

has_end – Whether this file has an EOF

__init__(name=None, content=None, size=None, has_end=None, seekable=True, writable=True, ident=None, concrete=None, **kwargs)
property category

reg, mem, or file.

Type:

Return the category of this SimMemory instance. It can be one of the three following categories

set_state(state)

Sets a new state (for example, if the state has been branched)

property size

The number of data bytes stored by the file at present. May be a symbolic value.

concretize(**kwargs)

Return a concretization of the contents of the file, as a flat bytestring.

read(pos, size, **kwargs)

Read some data from the file.

Parameters:
  • pos – The offset in the file to read from.

  • size – The size to read. May be symbolic.

Returns:

A tuple of the data read (a bitvector of the length that is the maximum length of the read), the actual size of the read, and the new file position pointer.

write(pos, data, size=None, events=True, **kwargs)

Write some data to the file.

Parameters:
  • pos – The offset in the file to write to. May be ignored if the file is a stream or device.

  • data – The data to write as a bitvector

  • size – The optional size of the data to write. If not provided will default to the length of the data. Must be constrained to less than or equal to the size of the data.

Returns:

The new file position pointer.

copy(memo: dict[int, Any] | None = None, **kwargs: Any) S_co

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:
  • memo (Optional[dict[int, Any]]) – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

  • kwargs (Any)

Return type:

TypeVar(S_co, covariant=True)

merge(others, merge_conditions, common_ancestor=None)

Should merge the state plugin with the provided others. This will be called by state.merge() after copying the target state, so this should mutate the current instance to merge with the others.

Note that when multiple instances of a single plugin object (for example, a file) are referenced in the state, it is important that merge only ever be called once. This should be solved by designating one of the plugin’s referees as the “real owner”, who should be the one to actually merge it. This technique doesn’t work to resolve the similar issue that arises during copying because merging doesn’t produce a new reference to insert.

There will be n others and n+1 merge conditions, since the first condition corresponds to self. To match elements up to conditions, say zip([self] + others, merge_conditions)

When implementing this, make sure that you “deepen” both others and common_ancestor before calling sub-elements’ merge methods, e.g.

self.foo.merge(
    [o.foo for o in others],
    merge_conditions,
    common_ancestor=common_ancestor.foo if common_ancestor is not None else None
)

During static analysis, merge_conditions can be None, in which case you should use state.solver.union(values). TODO: fish please make this less bullshit

There is a utility claripy.ite_cases which will help with constructing arbitrarily large merged ASTs. Use it like self.bar = claripy.ite_cases(zip(conditions[1:], [o.bar for o in others]), self.bar)

Parameters:
  • others – the other state plugins to merge with

  • merge_conditions – a symbolic condition for each of the plugins

  • common_ancestor – a common ancestor of this plugin and the others being merged

Returns:

True if the state plugins are actually merged.

Return type:

bool

widen(_)

The widening operation for plugins. Widening is a special kind of merging that produces a more general state from several more specific states. It is used only during intensive static analysis. The same behavior regarding copying and mutation from merge should be followed.

Parameters:

others – the other state plugin

Returns:

True if the state plugin is actually widened.

Return type:

bool

class angr.storage.SimMemoryObject(obj, base, endness, length=None, byte_width=8)

Bases: object

A SimMemoryObject is a reference to a byte or several bytes in a specific object in memory. It should be used only by the bottom layer of memory.

__init__(obj, base, endness, length=None, byte_width=8)
is_bytes
base
object: BV | FP
length
endness
size()
property variables
property symbolic
property last_addr
concrete_bytes(offset, size)
Return type:

bytes | None

Parameters:
includes(x)
bytes_at(addr, length, allow_concrete=False, endness='Iend_BE')
class angr.state_plugins.view.SimRegNameView

Bases: SimStatePlugin

copy(memo: dict[int, Any] | None = None, **kwargs: Any) S_co

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:
  • memo (Optional[dict[int, Any]]) – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

  • kwargs (Any)

Return type:

TypeVar(S_co, covariant=True)

merge(others, merge_conditions, common_ancestor=None)

Should merge the state plugin with the provided others. This will be called by state.merge() after copying the target state, so this should mutate the current instance to merge with the others.

Note that when multiple instances of a single plugin object (for example, a file) are referenced in the state, it is important that merge only ever be called once. This should be solved by designating one of the plugin’s referees as the “real owner”, who should be the one to actually merge it. This technique doesn’t work to resolve the similar issue that arises during copying because merging doesn’t produce a new reference to insert.

There will be n others and n+1 merge conditions, since the first condition corresponds to self. To match elements up to conditions, say zip([self] + others, merge_conditions)

When implementing this, make sure that you “deepen” both others and common_ancestor before calling sub-elements’ merge methods, e.g.

self.foo.merge(
    [o.foo for o in others],
    merge_conditions,
    common_ancestor=common_ancestor.foo if common_ancestor is not None else None
)

During static analysis, merge_conditions can be None, in which case you should use state.solver.union(values). TODO: fish please make this less bullshit

There is a utility claripy.ite_cases which will help with constructing arbitrarily large merged ASTs. Use it like self.bar = claripy.ite_cases(zip(conditions[1:], [o.bar for o in others]), self.bar)

Parameters:
  • others – the other state plugins to merge with

  • merge_conditions – a symbolic condition for each of the plugins

  • common_ancestor – a common ancestor of this plugin and the others being merged

Returns:

True if the state plugins are actually merged.

Return type:

bool

widen(others)

The widening operation for plugins. Widening is a special kind of merging that produces a more general state from several more specific states. It is used only during intensive static analysis. The same behavior regarding copying and mutation from merge should be followed.

Parameters:

others – the other state plugin

Returns:

True if the state plugin is actually widened.

Return type:

bool

get(reg_name)
class angr.state_plugins.view.SimMemView(ty=None, addr=None, state=None)

Bases: SimStatePlugin

This is a convenient interface with which you can access a program’s memory.

The interface works like this:

  • You first use [array index notation] to specify the address you’d like to load from

  • If at that address is a pointer, you may access the deref property to return a SimMemView at the address present in memory.

  • You then specify a type for the data by simply accessing a property of that name. For a list of supported types, look at state.mem.types.

  • You can then refine the type. Any type may support any refinement it likes. Right now the only refinements supported are that you may access any member of a struct by its member name, and you may index into a string or array to access that element.

  • If the address you specified initially points to an array of that type, you can say .array(n) to view the data as an array of n elements.

  • Finally, extract the structured data with .resolved or .concrete. .resolved will return bitvector values, while .concrete will return integer, string, array, etc values, whatever best represents the data.

  • Alternately, you may store a value to memory, by assigning to the chain of properties that you’ve constructed. Note that because of the way python works, x = s.mem[...].prop; x = val will NOT work, you must say s.mem[...].prop = val.

For example:

>>> s.mem[0x601048].long
<long (64 bits) <BV64 0x4008d0> at 0x601048>
>>> s.mem[0x601048].long.resolved
<BV64 0x4008d0>
>>> s.mem[0x601048].deref
<<untyped> <unresolvable> at 0x4008d0>
>>> s.mem[0x601048].deref.string.concrete
'SOSNEAKY'
__init__(ty=None, addr=None, state=None)
set_state(state)

Sets a new state (for example, if the state has been branched)

types: ClassVar[dict] = {'CharT': char, 'FILE_t': struct FILE_t, '_Bool': bool, '_ENTRY': struct _ENTRY, '_IO_codecvt': struct _IO_codecvt, '_IO_iconv_t': struct _IO_iconv_t, '_IO_lock_t': struct pthread_mutex_t, '_IO_marker': struct _IO_marker, '_IO_wide_data': struct _IO_wide_data, '__clock_t': uint32_t, '__dev_t': uint64_t, '__gid_t': unsigned int, '__ino64_t': unsigned long long, '__ino_t': unsigned long, '__int128': int128_t, '__int256': int256_t, '__mbstate_t': struct __mbstate_t, '__mode_t': unsigned int, '__nlink_t': unsigned int, '__off64_t': long long, '__off_t': long, '__pid_t': int, '__suseconds_t': int64_t, '__time_t': long, '__uid_t': unsigned int, '_obstack_chunk': struct _obstack_chunk, 'aiocb': struct aiocb, 'aiocb64': struct aiocb64, 'aioinit': struct aioinit, 'argp': struct argp, 'argp_child': struct argp_child, 'argp_option': struct argp_option, 'argp_parser_t': (int, char*, struct argp_state*) -> int, 'argp_state': struct argp_state, 'basic_string': string_t, 'bool': bool, 'byte': uint8_t, 'cc_t': char, 'char': char, 'clock_t': uint32_t, 'crypt_data': struct crypt_data, 'dirent': struct dirent, 'dirent64': struct dirent64, 'double': double, 'drand48_data': struct <anon>, 'dword': uint32_t, 'error_t': int, 'exit_status': struct exit_status, 'float': float, 'fstab': struct fstab, 'group': struct group, 'hostent': struct hostent, 'hsearch_data': struct hsearch_data, 'if_nameindex': struct if_nameindex, 'in_addr': struct in_addr, 'in_port_t': uint16_t, 'ino64_t': unsigned long long, 'ino_t': unsigned long, 'int': int, 'int16_t': int16_t, 'int32_t': int32_t, 'int64_t': int64_t, 'int8_t': int8_t, 'iovec': struct <anon>, 'itimerval': struct itimerval, 'lconv': struct lconv, 'long': long, 'long double': double, 'long int': long, 'long long': long long, 'long long int': long long, 'long signed': long, 'long unsigned int': unsigned long, 'mallinfo': struct mallinfo, 'mallinfo2': struct mallinfo2, 'mntent': struct mntent, 'netent': struct netent, 'ntptimeval': struct ntptimeval, 'obstack': struct obstack, 'off64_t': long long, 'off_t': long, 'option': struct option, 'passwd': struct passwd, 'pid_t': int, 'printf_info': struct printf_info, 'protoent': struct protoent, 'ptrdiff_t': long, 'qword': uint64_t, 'random_data': struct <anon>, 'rlim64_t': uint64_t, 'rlim_t': unsigned long, 'rlimit': struct rlimit, 'rlimit64': struct rlimit64, 'rusage': struct rusage, 'sa_family_t': unsigned short, 'sched_param': struct sched_param, 'sembuf': struct sembuf, 'servent': struct servent, 'sgttyb': struct sgttyb, 'short': short, 'short int': short, 'sigevent': struct sigevent, 'signed': int, 'signed char': char, 'signed int': int, 'signed long': long, 'signed long int': long, 'signed long long': long long, 'signed long long int': long long, 'signed short': short, 'signed short int': short, 'sigstack': struct sigstack, 'sigval': union sigval { sival_int int; sival_ptr void*; }, 'size_t': size_t, 'sockaddr': struct sockaddr, 'sockaddr_in': struct sockaddr_in, 'speed_t': long, 'ssize': size_t, 'ssize_t': size_t, 'stat': struct stat, 'stat64': struct stat64, 'std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>': string_t, 'string': string_t, 'struct iovec': struct iovec, 'struct timespec': struct timespec, 'struct timeval': struct timeval, 'tcflag_t': unsigned long, 'termios': struct termios, 'time_t': long, 'timespec': struct timeval, 'timeval': struct timeval, 'timex': struct timex, 'timezone': struct timezone, 'tm': struct tm, 'tms': struct tms, 'uint16_t': uint16_t, 'uint32_t': uint32_t, 'uint64_t': uint64_t, 'uint8_t': uint8_t, 'uintptr_t': unsigned long, 'unsigned': unsigned int, 'unsigned __int128': uint128_t, 'unsigned __int256': uint256_t, 'unsigned char': char, 'unsigned int': unsigned int, 'unsigned long': unsigned long, 'unsigned long int': unsigned long, 'unsigned long long': unsigned long long, 'unsigned long long int': unsigned long long, 'unsigned short': unsigned short, 'unsigned short int': unsigned short, 'utimbuf': struct utimbuf, 'utmp': struct utmp, 'utmpx': struct utmx, 'utsname': struct utsname, 'va_list': struct va_list[1], 'void': void, 'vtimes': struct vtimes, 'wchar_t': short, 'winsize': struct winsize, 'word': uint16_t, 'wstring': wstring_t}
state: angr.SimState = None
struct: StructMode
with_type(sim_type)

Returns a copy of the SimMemView with a type.

Parameters:

sim_type (SimType) – The new type.

Return type:

SimMemView

Returns:

The typed SimMemView copy.

copy(memo: dict[int, Any] | None = None, **kwargs: Any) S_co

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:
  • memo (Optional[dict[int, Any]]) – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

  • kwargs (Any)

Return type:

TypeVar(S_co, covariant=True)

merge(others, merge_conditions, common_ancestor=None)

Should merge the state plugin with the provided others. This will be called by state.merge() after copying the target state, so this should mutate the current instance to merge with the others.

Note that when multiple instances of a single plugin object (for example, a file) are referenced in the state, it is important that merge only ever be called once. This should be solved by designating one of the plugin’s referees as the “real owner”, who should be the one to actually merge it. This technique doesn’t work to resolve the similar issue that arises during copying because merging doesn’t produce a new reference to insert.

There will be n others and n+1 merge conditions, since the first condition corresponds to self. To match elements up to conditions, say zip([self] + others, merge_conditions)

When implementing this, make sure that you “deepen” both others and common_ancestor before calling sub-elements’ merge methods, e.g.

self.foo.merge(
    [o.foo for o in others],
    merge_conditions,
    common_ancestor=common_ancestor.foo if common_ancestor is not None else None
)

During static analysis, merge_conditions can be None, in which case you should use state.solver.union(values). TODO: fish please make this less bullshit

There is a utility claripy.ite_cases which will help with constructing arbitrarily large merged ASTs. Use it like self.bar = claripy.ite_cases(zip(conditions[1:], [o.bar for o in others]), self.bar)

Parameters:
  • others – the other state plugins to merge with

  • merge_conditions – a symbolic condition for each of the plugins

  • common_ancestor – a common ancestor of this plugin and the others being merged

Returns:

True if the state plugins are actually merged.

Return type:

bool

widen(others)

The widening operation for plugins. Widening is a special kind of merging that produces a more general state from several more specific states. It is used only during intensive static analysis. The same behavior regarding copying and mutation from merge should be followed.

Parameters:

others – the other state plugin

Returns:

True if the state plugin is actually widened.

Return type:

bool

property resolvable
property resolved
property concrete
property deref: SimMemView
array(n)
Return type:

SimMemView

member(member_name)

If self is a struct and member_name is a member of the struct, return that member element. Otherwise raise an exception.

Return type:

SimMemView

Parameters:

member_name (str)

store(value)
class angr.state_plugins.view.StructMode(view)

Bases: object

__init__(view)
class angr.storage.file.Flags

Bases: object

O_RDONLY = 0
O_WRONLY = 1
O_RDWR = 2
O_ACCMODE = 3
O_APPEND = 1024
O_ASYNC = 8192
O_CLOEXEC = 524288
O_CREAT = 64
O_DIRECT = 16384
O_DIRECTORY = 65536
O_DSYNC = 4096
O_EXCL = 128
O_LARGEFILE = 32768
O_NOATIME = 262144
O_NOCTTY = 256
O_NOFOLLOW = 131072
O_NONBLOCK = 2048
O_NDELAY = 2048
O_PATH = 2097152
O_SYNC = 1052672
O_TMPFILE = 4259840
O_TRUNC = 512
class angr.storage.file.SimFileBase(name=None, writable=True, ident=None, concrete=False, file_exists=True, **kwargs)

Bases: SimStatePlugin

SimFiles are the storage mechanisms used by SimFileDescriptors.

Different types of SimFiles can have drastically different interfaces, and as a result there’s not much that can be specified on this base class. All the read and write methods take a pos argument, which may have different semantics per-class. 0 will always be a valid position to use, though, and the next position you should use is part of the return tuple.

Some simfiles are “streams”, meaning that the position that reads come from is determined not by the position you pass in (it will in fact be ignored), but by an internal variable. This is stored as .pos if you care to read it. Don’t write to it. The same lack-of-semantics applies to this field as well.

Variables:
  • name – The name of the file. Purely for cosmetic purposes

  • ident – The identifier of the file, typically autogenerated from the name and a nonce. Purely for cosmetic purposes, but does appear in symbolic values autogenerated in the file.

  • seekable – Bool indicating whether seek operations on this file should succeed. If this is True, then pos must be a number of bytes from the start of the file.

  • writable – Bool indicating whether writing to this file is allowed.

  • pos – If the file is a stream, this will be the current position. Otherwise, None.

  • concrete – Whether or not this file contains mostly concrete data. Will be used by some SimProcedures to choose how to handle variable-length operations like fgets.

  • file_exists – Set to False, if file does not exists, set to a claripy Bool if unknown, default True.

seekable = False
pos = None
__init__(name=None, writable=True, ident=None, concrete=False, file_exists=True, **kwargs)
static make_ident(name)
concretize(**kwargs)

Return a concretization of the contents of the file. The type of the return value of this method will vary depending on which kind of SimFile you’re using.

read(pos, size, **kwargs)

Read some data from the file.

Parameters:
  • pos – The offset in the file to read from.

  • size – The size to read. May be symbolic.

Returns:

A tuple of the data read (a bitvector of the length that is the maximum length of the read), the actual size of the read, and the new file position pointer.

write(pos, data, size=None, **kwargs)

Write some data to the file.

Parameters:
  • pos – The offset in the file to write to. May be ignored if the file is a stream or device.

  • data – The data to write as a bitvector

  • size – The optional size of the data to write. If not provided will default to the length of the data. Must be constrained to less than or equal to the size of the data.

Returns:

The new file position pointer.

property size

The number of data bytes stored by the file at present. May be a symbolic value.

copy(memo: dict[int, Any] | None = None, **kwargs: Any) S_co

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:
  • memo (Optional[dict[int, Any]]) – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

  • kwargs (Any)

Return type:

TypeVar(S_co, covariant=True)

state: angr.SimState
class angr.storage.file.SimFile(name=None, content=None, size=None, has_end=None, seekable=True, writable=True, ident=None, concrete=None, **kwargs)

Bases: SimFileBase, DefaultMemory

The normal SimFile is meant to model files on disk. It subclasses SimSymbolicMemory so loads and stores to/from it are very simple.

Parameters:
  • name – The name of the file

  • content – Optional initial content for the file as a string or bitvector

  • size – Optional size of the file. If content is not specified, it defaults to zero

  • has_end – Whether the size boundary is treated as the end of the file or a frontier at which new content will be generated. If unspecified, will pick its value based on options.FILES_HAVE_EOF. Another caveat is that if the size is also unspecified this value will default to False.

  • seekable – Optional bool indicating whether seek operations on this file should succeed, default True.

  • writable – Whether writing to this file is allowed

  • concrete – Whether or not this file contains mostly concrete data. Will be used by some SimProcedures to choose how to handle variable-length operations like fgets.

Variables:

has_end – Whether this file has an EOF

__init__(name=None, content=None, size=None, has_end=None, seekable=True, writable=True, ident=None, concrete=None, **kwargs)
property category

reg, mem, or file.

Type:

Return the category of this SimMemory instance. It can be one of the three following categories

set_state(state)

Sets a new state (for example, if the state has been branched)

property size

The number of data bytes stored by the file at present. May be a symbolic value.

concretize(**kwargs)

Return a concretization of the contents of the file, as a flat bytestring.

read(pos, size, **kwargs)

Read some data from the file.

Parameters:
  • pos – The offset in the file to read from.

  • size – The size to read. May be symbolic.

Returns:

A tuple of the data read (a bitvector of the length that is the maximum length of the read), the actual size of the read, and the new file position pointer.

write(pos, data, size=None, events=True, **kwargs)

Write some data to the file.

Parameters:
  • pos – The offset in the file to write to. May be ignored if the file is a stream or device.

  • data – The data to write as a bitvector

  • size – The optional size of the data to write. If not provided will default to the length of the data. Must be constrained to less than or equal to the size of the data.

Returns:

The new file position pointer.

copy(memo: dict[int, Any] | None = None, **kwargs: Any) S_co

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:
  • memo (Optional[dict[int, Any]]) – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

  • kwargs (Any)

Return type:

TypeVar(S_co, covariant=True)

merge(others, merge_conditions, common_ancestor=None)

Should merge the state plugin with the provided others. This will be called by state.merge() after copying the target state, so this should mutate the current instance to merge with the others.

Note that when multiple instances of a single plugin object (for example, a file) are referenced in the state, it is important that merge only ever be called once. This should be solved by designating one of the plugin’s referees as the “real owner”, who should be the one to actually merge it. This technique doesn’t work to resolve the similar issue that arises during copying because merging doesn’t produce a new reference to insert.

There will be n others and n+1 merge conditions, since the first condition corresponds to self. To match elements up to conditions, say zip([self] + others, merge_conditions)

When implementing this, make sure that you “deepen” both others and common_ancestor before calling sub-elements’ merge methods, e.g.

self.foo.merge(
    [o.foo for o in others],
    merge_conditions,
    common_ancestor=common_ancestor.foo if common_ancestor is not None else None
)

During static analysis, merge_conditions can be None, in which case you should use state.solver.union(values). TODO: fish please make this less bullshit

There is a utility claripy.ite_cases which will help with constructing arbitrarily large merged ASTs. Use it like self.bar = claripy.ite_cases(zip(conditions[1:], [o.bar for o in others]), self.bar)

Parameters:
  • others – the other state plugins to merge with

  • merge_conditions – a symbolic condition for each of the plugins

  • common_ancestor – a common ancestor of this plugin and the others being merged

Returns:

True if the state plugins are actually merged.

Return type:

bool

widen(_)

The widening operation for plugins. Widening is a special kind of merging that produces a more general state from several more specific states. It is used only during intensive static analysis. The same behavior regarding copying and mutation from merge should be followed.

Parameters:

others – the other state plugin

Returns:

True if the state plugin is actually widened.

Return type:

bool

class angr.storage.file.SimFileStream(name=None, content=None, pos=0, **kwargs)

Bases: SimFile

A specialized SimFile that uses a flat memory backing, but functions as a stream, tracking its position internally.

The pos argument to the read and write methods will be ignored, and will return None. Instead, there is an attribute pos on the file itself, which will give you what you want.

Parameters:
  • name – The name of the file, for cosmetic purposes

  • pos – The initial position of the file, default zero

  • kwargs – Any other keyword arguments will go on to the SimFile constructor.

Variables:

pos – The current position in the file.

__init__(name=None, content=None, pos=0, **kwargs)
set_state(state)

Sets a new state (for example, if the state has been branched)

read(pos, size, **kwargs)

Read some data from the file.

Parameters:
  • pos – The offset in the file to read from.

  • size – The size to read. May be symbolic.

Returns:

A tuple of the data read (a bitvector of the length that is the maximum length of the read), the actual size of the read, and the new file position pointer.

write(_, data, size=None, **kwargs)

Write some data to the file.

Parameters:
  • pos – The offset in the file to write to. May be ignored if the file is a stream or device.

  • data – The data to write as a bitvector

  • size – The optional size of the data to write. If not provided will default to the length of the data. Must be constrained to less than or equal to the size of the data.

Returns:

The new file position pointer.

copy(memo: dict[int, Any] | None = None, **kwargs: Any) S_co

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:
  • memo (Optional[dict[int, Any]]) – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

  • kwargs (Any)

Return type:

TypeVar(S_co, covariant=True)

merge(others, merge_conditions, common_ancestor=None)

Should merge the state plugin with the provided others. This will be called by state.merge() after copying the target state, so this should mutate the current instance to merge with the others.

Note that when multiple instances of a single plugin object (for example, a file) are referenced in the state, it is important that merge only ever be called once. This should be solved by designating one of the plugin’s referees as the “real owner”, who should be the one to actually merge it. This technique doesn’t work to resolve the similar issue that arises during copying because merging doesn’t produce a new reference to insert.

There will be n others and n+1 merge conditions, since the first condition corresponds to self. To match elements up to conditions, say zip([self] + others, merge_conditions)

When implementing this, make sure that you “deepen” both others and common_ancestor before calling sub-elements’ merge methods, e.g.

self.foo.merge(
    [o.foo for o in others],
    merge_conditions,
    common_ancestor=common_ancestor.foo if common_ancestor is not None else None
)

During static analysis, merge_conditions can be None, in which case you should use state.solver.union(values). TODO: fish please make this less bullshit

There is a utility claripy.ite_cases which will help with constructing arbitrarily large merged ASTs. Use it like self.bar = claripy.ite_cases(zip(conditions[1:], [o.bar for o in others]), self.bar)

Parameters:
  • others – the other state plugins to merge with

  • merge_conditions – a symbolic condition for each of the plugins

  • common_ancestor – a common ancestor of this plugin and the others being merged

Returns:

True if the state plugins are actually merged.

Return type:

bool

class angr.storage.file.SimPackets(name, write_mode=None, content=None, writable=True, ident=None, **kwargs)

Bases: SimFileBase

The SimPackets is meant to model inputs whose content is delivered a series of asynchronous chunks. The data is stored as a list of read or write results. For symbolic sizes, state.libc.max_packet_size will be respected. If the SHORT_READS option is enabled, reads will return a symbolic size constrained to be less than or equal to the requested size.

A SimPackets cannot be used for both reading and writing - for socket objects that can be both read and written to you should use a file descriptor to multiplex the read and write operations into two separate file storage mechanisms.

Parameters:
  • name – The name of the file, for cosmetic purposes

  • write_mode – Whether this file is opened in read or write mode. If this is unspecified it will be autodetected.

  • content – Some initial content to use for the file. Can be a list of bytestrings or a list of tuples of content ASTs and size ASTs.

Variables:
  • write_mode – See the eponymous parameter

  • content – A list of packets, as tuples of content ASTs and size ASTs.

__init__(name, write_mode=None, content=None, writable=True, ident=None, **kwargs)
set_state(state)

Sets a new state (for example, if the state has been branched)

property size

The number of data bytes stored by the file at present. May be a symbolic value.

concretize(**kwargs)

Returns a list of the packets read or written as bytestrings.

read(pos, size, **kwargs)

Read a packet from the stream.

Parameters:
  • pos (int) – The packet number to read from the sequence of the stream. May be None to append to the stream.

  • size – The size to read. May be symbolic.

  • short_reads – Whether to replace the size with a symbolic value constrained to less than or equal to the original size. If unspecified, will be chosen based on the state option.

Returns:

A tuple of the data read (a bitvector of the length that is the maximum length of the read) and the actual size of the read.

write(pos, data, size=None, events=True, **kwargs)

Write a packet to the stream.

Parameters:
  • pos (int) – The packet number to write in the sequence of the stream. May be None to append to the stream.

  • data – The data to write, as a string or bitvector.

  • size – The optional size to write. May be symbolic; must be constrained to at most the size of data.

Returns:

The next packet to use after this

copy(memo: dict[int, Any] | None = None, **kwargs: Any) S_co

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:
  • memo (Optional[dict[int, Any]]) – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

  • kwargs (Any)

Return type:

TypeVar(S_co, covariant=True)

merge(others, merge_conditions, common_ancestor=None)

Should merge the state plugin with the provided others. This will be called by state.merge() after copying the target state, so this should mutate the current instance to merge with the others.

Note that when multiple instances of a single plugin object (for example, a file) are referenced in the state, it is important that merge only ever be called once. This should be solved by designating one of the plugin’s referees as the “real owner”, who should be the one to actually merge it. This technique doesn’t work to resolve the similar issue that arises during copying because merging doesn’t produce a new reference to insert.

There will be n others and n+1 merge conditions, since the first condition corresponds to self. To match elements up to conditions, say zip([self] + others, merge_conditions)

When implementing this, make sure that you “deepen” both others and common_ancestor before calling sub-elements’ merge methods, e.g.

self.foo.merge(
    [o.foo for o in others],
    merge_conditions,
    common_ancestor=common_ancestor.foo if common_ancestor is not None else None
)

During static analysis, merge_conditions can be None, in which case you should use state.solver.union(values). TODO: fish please make this less bullshit

There is a utility claripy.ite_cases which will help with constructing arbitrarily large merged ASTs. Use it like self.bar = claripy.ite_cases(zip(conditions[1:], [o.bar for o in others]), self.bar)

Parameters:
  • others – the other state plugins to merge with

  • merge_conditions – a symbolic condition for each of the plugins

  • common_ancestor – a common ancestor of this plugin and the others being merged

Returns:

True if the state plugins are actually merged.

Return type:

bool

widen(_)

The widening operation for plugins. Widening is a special kind of merging that produces a more general state from several more specific states. It is used only during intensive static analysis. The same behavior regarding copying and mutation from merge should be followed.

Parameters:

others – the other state plugin

Returns:

True if the state plugin is actually widened.

Return type:

bool

class angr.storage.file.SimPacketsStream(name, pos=0, **kwargs)

Bases: SimPackets

A specialized SimPackets that tracks its position internally.

The pos argument to the read and write methods will be ignored, and will return None. Instead, there is an attribute pos on the file itself, which will give you what you want.

Parameters:
  • name – The name of the file, for cosmetic purposes

  • pos – The initial position of the file, default zero

  • kwargs – Any other keyword arguments will go on to the SimPackets constructor.

Variables:

pos – The current position in the file.

__init__(name, pos=0, **kwargs)
read(pos, size, **kwargs)

Read a packet from the stream.

Parameters:
  • pos (int) – The packet number to read from the sequence of the stream. May be None to append to the stream.

  • size – The size to read. May be symbolic.

  • short_reads – Whether to replace the size with a symbolic value constrained to less than or equal to the original size. If unspecified, will be chosen based on the state option.

Returns:

A tuple of the data read (a bitvector of the length that is the maximum length of the read) and the actual size of the read.

write(_, data, size=None, **kwargs)

Write a packet to the stream.

Parameters:
  • pos (int) – The packet number to write in the sequence of the stream. May be None to append to the stream.

  • data – The data to write, as a string or bitvector.

  • size – The optional size to write. May be symbolic; must be constrained to at most the size of data.

Returns:

The next packet to use after this

copy(memo: dict[int, Any] | None = None, **kwargs: Any) S_co

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:
  • memo (Optional[dict[int, Any]]) – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

  • kwargs (Any)

Return type:

TypeVar(S_co, covariant=True)

merge(others, merge_conditions, common_ancestor=None)

Should merge the state plugin with the provided others. This will be called by state.merge() after copying the target state, so this should mutate the current instance to merge with the others.

Note that when multiple instances of a single plugin object (for example, a file) are referenced in the state, it is important that merge only ever be called once. This should be solved by designating one of the plugin’s referees as the “real owner”, who should be the one to actually merge it. This technique doesn’t work to resolve the similar issue that arises during copying because merging doesn’t produce a new reference to insert.

There will be n others and n+1 merge conditions, since the first condition corresponds to self. To match elements up to conditions, say zip([self] + others, merge_conditions)

When implementing this, make sure that you “deepen” both others and common_ancestor before calling sub-elements’ merge methods, e.g.

self.foo.merge(
    [o.foo for o in others],
    merge_conditions,
    common_ancestor=common_ancestor.foo if common_ancestor is not None else None
)

During static analysis, merge_conditions can be None, in which case you should use state.solver.union(values). TODO: fish please make this less bullshit

There is a utility claripy.ite_cases which will help with constructing arbitrarily large merged ASTs. Use it like self.bar = claripy.ite_cases(zip(conditions[1:], [o.bar for o in others]), self.bar)

Parameters:
  • others – the other state plugins to merge with

  • merge_conditions – a symbolic condition for each of the plugins

  • common_ancestor – a common ancestor of this plugin and the others being merged

Returns:

True if the state plugins are actually merged.

Return type:

bool

class angr.storage.file.SimFileDescriptorBase

Bases: SimStatePlugin

The base class for implementations of POSIX file descriptors.

All file descriptors should respect the CONCRETIZE_SYMBOLIC_{READ,WRITE}_SIZES state options.

read(pos, size, **kwargs)

Reads some data from the file, storing it into memory.

Parameters:
  • pos – The address to read data from file

  • size – The requested length of the read

Returns:

The real length of the read

write(pos, size, **kwargs)

Writes some data, loaded from the state, into the file.

Parameters:
  • pos – The address to read the data to write from in memory

  • size – The requested size of the write

Returns:

The real length of the write

read_data(size, **kwargs)

Reads some data from the file, returning the data.

Parameters:

size – The requested length of the read

Returns:

A tuple of the data read and the real length of the read

write_data(data, size=None, **kwargs)

Write some data, provided as an argument into the file.

Parameters:
  • data – A bitvector to write into the file

  • size – The requested size of the write (may be symbolic)

Returns:

The real length of the write

seek(offset, whence='start')

Seek the file descriptor to a different position in the file.

Parameters:
  • offset – The offset to seek to, interpreted according to whence

  • whence – What the offset is relative to; one of the strings “start”, “current”, or “end”

Returns:

A symbolic boolean describing whether the seek succeeded or not

tell()

Return the current position, or None if the concept doesn’t make sense for the given file.

eof()

Return the EOF status. May be a symbolic boolean.

size()

Return the size of the data stored in the file in bytes, or None if the concept doesn’t make sense for the given file.

property read_storage

Return the SimFile backing reads from this fd

property write_storage

Return the SimFile backing writes to this fd

property read_pos

Return the current position of the read file pointer.

If the underlying read file is a stream, this will return the position of the stream. Otherwise, will return the position of the file descriptor in the file.

property write_pos

Return the current position of the read file pointer.

If the underlying read file is a stream, this will return the position of the stream. Otherwise, will return the position of the file descriptor in the file.

concretize(**kwargs)

Return a concretizeation of the data in the underlying file. Has different return types to represent different data structures on a per-class basis.

Any arguments passed to this will be passed onto state.solver.eval.

property file_exists

This should be True in most cases. Only if we opened an fd of unknown existence, ALL_FILES_EXIST is False and ANY_FILE_MIGHT_EXIST is True, this is a symbolic boolean.

class angr.storage.file.SimFileDescriptor(simfile, flags=0)

Bases: SimFileDescriptorBase

A simple file descriptor forwarding reads and writes to a SimFile. Contains information about the current opened state of the file, such as the flags or (if relevant) the current position.

Variables:
  • file – The SimFile described to by this descriptor

  • flags – The mode that the file descriptor was opened with, a bitfield of flags

__init__(simfile, flags=0)
read_data(size, **kwargs)

Reads some data from the file, returning the data.

Parameters:

size – The requested length of the read

Returns:

A tuple of the data read and the real length of the read

write_data(data, size=None, **kwargs)

Write some data, provided as an argument into the file.

Parameters:
  • data – A bitvector to write into the file

  • size – The requested size of the write (may be symbolic)

Returns:

The real length of the write

seek(offset, whence='start')

Seek the file descriptor to a different position in the file.

Parameters:
  • offset – The offset to seek to, interpreted according to whence

  • whence – What the offset is relative to; one of the strings “start”, “current”, or “end”

Returns:

A symbolic boolean describing whether the seek succeeded or not

eof()

Return the EOF status. May be a symbolic boolean.

tell()

Return the current position, or None if the concept doesn’t make sense for the given file.

size()

Return the size of the data stored in the file in bytes, or None if the concept doesn’t make sense for the given file.

concretize(**kwargs)

Return a concretization of the underlying file. Returns whatever format is preferred by the file.

property file_exists

This should be True in most cases. Only if we opened an fd of unknown existence, ALL_FILES_EXIST is False and ANY_FILE_MIGHT_EXIST is True, this is a symbolic boolean.

property read_storage

Return the SimFile backing reads from this fd

property write_storage

Return the SimFile backing writes to this fd

property read_pos

Return the current position of the read file pointer.

If the underlying read file is a stream, this will return the position of the stream. Otherwise, will return the position of the file descriptor in the file.

property write_pos

Return the current position of the read file pointer.

If the underlying read file is a stream, this will return the position of the stream. Otherwise, will return the position of the file descriptor in the file.

set_state(state)

Sets a new state (for example, if the state has been branched)

copy(memo: dict[int, Any] | None = None, **kwargs: Any) S_co

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:
  • memo (Optional[dict[int, Any]]) – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

  • kwargs (Any)

Return type:

TypeVar(S_co, covariant=True)

merge(others, merge_conditions, common_ancestor=None)

Should merge the state plugin with the provided others. This will be called by state.merge() after copying the target state, so this should mutate the current instance to merge with the others.

Note that when multiple instances of a single plugin object (for example, a file) are referenced in the state, it is important that merge only ever be called once. This should be solved by designating one of the plugin’s referees as the “real owner”, who should be the one to actually merge it. This technique doesn’t work to resolve the similar issue that arises during copying because merging doesn’t produce a new reference to insert.

There will be n others and n+1 merge conditions, since the first condition corresponds to self. To match elements up to conditions, say zip([self] + others, merge_conditions)

When implementing this, make sure that you “deepen” both others and common_ancestor before calling sub-elements’ merge methods, e.g.

self.foo.merge(
    [o.foo for o in others],
    merge_conditions,
    common_ancestor=common_ancestor.foo if common_ancestor is not None else None
)

During static analysis, merge_conditions can be None, in which case you should use state.solver.union(values). TODO: fish please make this less bullshit

There is a utility claripy.ite_cases which will help with constructing arbitrarily large merged ASTs. Use it like self.bar = claripy.ite_cases(zip(conditions[1:], [o.bar for o in others]), self.bar)

Parameters:
  • others – the other state plugins to merge with

  • merge_conditions – a symbolic condition for each of the plugins

  • common_ancestor – a common ancestor of this plugin and the others being merged

Returns:

True if the state plugins are actually merged.

Return type:

bool

widen(_)

The widening operation for plugins. Widening is a special kind of merging that produces a more general state from several more specific states. It is used only during intensive static analysis. The same behavior regarding copying and mutation from merge should be followed.

Parameters:

others – the other state plugin

Returns:

True if the state plugin is actually widened.

Return type:

bool

class angr.storage.file.SimFileDescriptorDuplex(read_file, write_file)

Bases: SimFileDescriptorBase

A file descriptor that refers to two file storage mechanisms, one to read from and one to write to. As a result, operations like seek, eof, etc no longer make sense.

Parameters:
  • read_file – The SimFile to read from

  • write_file – The SimFile to write to

__init__(read_file, write_file)
read_data(size, **kwargs)

Reads some data from the file, returning the data.

Parameters:

size – The requested length of the read

Returns:

A tuple of the data read and the real length of the read

write_data(data, size=None, **kwargs)

Write some data, provided as an argument into the file.

Parameters:
  • data – A bitvector to write into the file

  • size – The requested size of the write (may be symbolic)

Returns:

The real length of the write

set_state(state)

Sets a new state (for example, if the state has been branched)

eof()

Return the EOF status. May be a symbolic boolean.

tell()

Return the current position, or None if the concept doesn’t make sense for the given file.

seek(offset, whence='start')

Seek the file descriptor to a different position in the file.

Parameters:
  • offset – The offset to seek to, interpreted according to whence

  • whence – What the offset is relative to; one of the strings “start”, “current”, or “end”

Returns:

A symbolic boolean describing whether the seek succeeded or not

size()

Return the size of the data stored in the file in bytes, or None if the concept doesn’t make sense for the given file.

concretize(**kwargs)

Return a concretization of the underlying files, as a tuple of (read file, write file).

property read_storage

Return the SimFile backing reads from this fd

property write_storage

Return the SimFile backing writes to this fd

property read_pos

Return the current position of the read file pointer.

If the underlying read file is a stream, this will return the position of the stream. Otherwise, will return the position of the file descriptor in the file.

property write_pos

Return the current position of the read file pointer.

If the underlying read file is a stream, this will return the position of the stream. Otherwise, will return the position of the file descriptor in the file.

copy(memo: dict[int, Any] | None = None, **kwargs: Any) S_co

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:
  • memo (Optional[dict[int, Any]]) – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

  • kwargs (Any)

Return type:

TypeVar(S_co, covariant=True)

merge(others, merge_conditions, common_ancestor=None)

Should merge the state plugin with the provided others. This will be called by state.merge() after copying the target state, so this should mutate the current instance to merge with the others.

Note that when multiple instances of a single plugin object (for example, a file) are referenced in the state, it is important that merge only ever be called once. This should be solved by designating one of the plugin’s referees as the “real owner”, who should be the one to actually merge it. This technique doesn’t work to resolve the similar issue that arises during copying because merging doesn’t produce a new reference to insert.

There will be n others and n+1 merge conditions, since the first condition corresponds to self. To match elements up to conditions, say zip([self] + others, merge_conditions)

When implementing this, make sure that you “deepen” both others and common_ancestor before calling sub-elements’ merge methods, e.g.

self.foo.merge(
    [o.foo for o in others],
    merge_conditions,
    common_ancestor=common_ancestor.foo if common_ancestor is not None else None
)

During static analysis, merge_conditions can be None, in which case you should use state.solver.union(values). TODO: fish please make this less bullshit

There is a utility claripy.ite_cases which will help with constructing arbitrarily large merged ASTs. Use it like self.bar = claripy.ite_cases(zip(conditions[1:], [o.bar for o in others]), self.bar)

Parameters:
  • others – the other state plugins to merge with

  • merge_conditions – a symbolic condition for each of the plugins

  • common_ancestor – a common ancestor of this plugin and the others being merged

Returns:

True if the state plugins are actually merged.

Return type:

bool

widen(_)

The widening operation for plugins. Widening is a special kind of merging that produces a more general state from several more specific states. It is used only during intensive static analysis. The same behavior regarding copying and mutation from merge should be followed.

Parameters:

others – the other state plugin

Returns:

True if the state plugin is actually widened.

Return type:

bool

class angr.storage.file.SimPacketsSlots(name, read_sizes, ident=None, **kwargs)

Bases: SimFileBase

SimPacketsSlots is the new SimDialogue, if you’ve ever seen that before.

The idea is that in some cases, the only thing you really care about is getting the lengths of reads right, and some of them should be short reads, and some of them should be truncated. You provide to this class a list of read lengths, and it figures out the length of each read, and delivers some content.

This class will NOT respect the position argument you pass it - this storage is not stateless.

seekable = False
__init__(name, read_sizes, ident=None, **kwargs)
concretize(**kwargs)

Return a concretization of the contents of the file. The type of the return value of this method will vary depending on which kind of SimFile you’re using.

read(pos, size, **kwargs)

Read some data from the file.

Parameters:
  • pos – The offset in the file to read from.

  • size – The size to read. May be symbolic.

Returns:

A tuple of the data read (a bitvector of the length that is the maximum length of the read), the actual size of the read, and the new file position pointer.

write(pos, data, size=None, **kwargs)

Write some data to the file.

Parameters:
  • pos – The offset in the file to write to. May be ignored if the file is a stream or device.

  • data – The data to write as a bitvector

  • size – The optional size of the data to write. If not provided will default to the length of the data. Must be constrained to less than or equal to the size of the data.

Returns:

The new file position pointer.

property size

The number of data bytes stored by the file at present. May be a symbolic value.

copy(memo: dict[int, Any] | None = None, **kwargs: Any) S_co

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:
  • memo (Optional[dict[int, Any]]) – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

  • kwargs (Any)

Return type:

TypeVar(S_co, covariant=True)

merge(others, merge_conditions, common_ancestor=None)

Should merge the state plugin with the provided others. This will be called by state.merge() after copying the target state, so this should mutate the current instance to merge with the others.

Note that when multiple instances of a single plugin object (for example, a file) are referenced in the state, it is important that merge only ever be called once. This should be solved by designating one of the plugin’s referees as the “real owner”, who should be the one to actually merge it. This technique doesn’t work to resolve the similar issue that arises during copying because merging doesn’t produce a new reference to insert.

There will be n others and n+1 merge conditions, since the first condition corresponds to self. To match elements up to conditions, say zip([self] + others, merge_conditions)

When implementing this, make sure that you “deepen” both others and common_ancestor before calling sub-elements’ merge methods, e.g.

self.foo.merge(
    [o.foo for o in others],
    merge_conditions,
    common_ancestor=common_ancestor.foo if common_ancestor is not None else None
)

During static analysis, merge_conditions can be None, in which case you should use state.solver.union(values). TODO: fish please make this less bullshit

There is a utility claripy.ite_cases which will help with constructing arbitrarily large merged ASTs. Use it like self.bar = claripy.ite_cases(zip(conditions[1:], [o.bar for o in others]), self.bar)

Parameters:
  • others – the other state plugins to merge with

  • merge_conditions – a symbolic condition for each of the plugins

  • common_ancestor – a common ancestor of this plugin and the others being merged

Returns:

True if the state plugins are actually merged.

Return type:

bool

widen(_)

The widening operation for plugins. Widening is a special kind of merging that produces a more general state from several more specific states. It is used only during intensive static analysis. The same behavior regarding copying and mutation from merge should be followed.

Parameters:

others – the other state plugin

Returns:

True if the state plugin is actually widened.

Return type:

bool

angr.storage.memory_object.obj_bit_size(o)
class angr.storage.memory_object.SimMemoryObject(obj, base, endness, length=None, byte_width=8)

Bases: object

A SimMemoryObject is a reference to a byte or several bytes in a specific object in memory. It should be used only by the bottom layer of memory.

__init__(obj, base, endness, length=None, byte_width=8)
is_bytes
base
object: BV | FP
length
endness
size()
property variables
property symbolic
property last_addr
concrete_bytes(offset, size)
Return type:

bytes | None

Parameters:
includes(x)
bytes_at(addr, length, allow_concrete=False, endness='Iend_BE')
class angr.storage.memory_object.SimLabeledMemoryObject(obj, base, endness, length=None, byte_width=8, label=None)

Bases: SimMemoryObject

SimLabeledMemoryObject is a SimMemoryObject with a label

__init__(obj, base, endness, length=None, byte_width=8, label=None)
label
angr.storage.memory_object.bv_slice(value, offset, size, rev, bw)

Extremely cute utility to pretend you’ve serialized a value to stored bytes, sliced it a la python slicing, and then deserialized those bytes to an integer again.

Parameters:
  • value (BV) – The bitvector to slice

  • offset (int) – The byte offset from the first stored byte to slice from, or a negative offset from the end.

  • size (int) – The number of bytes to return. If None, return all bytes from the offset to the end. If larger than the number of bytes from the offset to the end, return all bytes from the offset to the end.

  • rev (bool) – Whether the pretend-serialization should be little-endian

  • bw (int) – The byte width

Return type:

BV

Returns:

The new bitvector

class angr.concretization_strategies.SimConcretizationStrategy(filter=None, exact=True)

Bases: object

Concretization strategies control the resolution of symbolic memory indices in SimuVEX. By subclassing this class and setting it as a concretization strategy (on state.memory.read_strategies and state.memory.write_strategies), SimuVEX’s memory index concretization behavior can be modified.

__init__(filter=None, exact=True)

Initializes the base SimConcretizationStrategy.

Parameters:
  • filter – A function, taking arguments of (SimMemory, claripy.AST) that determines if this strategy can handle resolving the provided AST.

  • exact – A flag (default: True) that determines if the convenience resolution functions provided by this class use exact or approximate resolution.

concretize(memory, addr, **kwargs)

Concretizes the address into a list of values. If this strategy cannot handle this address, returns None.

copy()

Returns a copy of the strategy, if there is data that should be kept separate between states. If not, returns self.

merge(others)

Merges this strategy with others (if there is data that should be kept separate between states. If not, is a no-op.

class angr.concretization_strategies.SimConcretizationStrategyAny(filter=None, exact=True)

Bases: SimConcretizationStrategy

Concretization strategy that returns any single solution.

class angr.concretization_strategies.SimConcretizationStrategyControlledData(limit, fixed_addrs, **kwargs)

Bases: SimConcretizationStrategy

Concretization strategy that constraints the address to controlled data. Controlled data consists of symbolic data and the addresses given as arguments. memory.

__init__(limit, fixed_addrs, **kwargs)

Initializes the base SimConcretizationStrategy.

Parameters:
  • filter – A function, taking arguments of (SimMemory, claripy.AST) that determines if this strategy can handle resolving the provided AST.

  • exact – A flag (default: True) that determines if the convenience resolution functions provided by this class use exact or approximate resolution.

class angr.concretization_strategies.SimConcretizationStrategyEval(limit, **kwargs)

Bases: SimConcretizationStrategy

Concretization strategy that resolves an address into some limited number of solutions. Always handles the concretization, but only returns a maximum of limit number of solutions. Therefore, should only be used as the fallback strategy.

__init__(limit, **kwargs)

Initializes the base SimConcretizationStrategy.

Parameters:
  • filter – A function, taking arguments of (SimMemory, claripy.AST) that determines if this strategy can handle resolving the provided AST.

  • exact – A flag (default: True) that determines if the convenience resolution functions provided by this class use exact or approximate resolution.

class angr.concretization_strategies.SimConcretizationStrategyMax(max_addr=None)

Bases: SimConcretizationStrategy

Concretization strategy that returns the maximum address.

Parameters:

max_addr (int | None)

__init__(max_addr=None)

Initializes the base SimConcretizationStrategy.

Parameters:
  • filter – A function, taking arguments of (SimMemory, claripy.AST) that determines if this strategy can handle resolving the provided AST.

  • exact – A flag (default: True) that determines if the convenience resolution functions provided by this class use exact or approximate resolution.

  • max_addr (int | None)

class angr.concretization_strategies.SimConcretizationStrategyNonzero(filter=None, exact=True)

Bases: SimConcretizationStrategy

Concretization strategy that returns any non-zero solution.

class angr.concretization_strategies.SimConcretizationStrategyNonzeroRange(limit, **kwargs)

Bases: SimConcretizationStrategy

Concretization strategy that resolves a range in a non-zero location.

__init__(limit, **kwargs)

Initializes the base SimConcretizationStrategy.

Parameters:
  • filter – A function, taking arguments of (SimMemory, claripy.AST) that determines if this strategy can handle resolving the provided AST.

  • exact – A flag (default: True) that determines if the convenience resolution functions provided by this class use exact or approximate resolution.

class angr.concretization_strategies.SimConcretizationStrategyNorepeats(repeat_expr, repeat_constraints=None, **kwargs)

Bases: SimConcretizationStrategy

Concretization strategy that resolves addresses, without repeating.

__init__(repeat_expr, repeat_constraints=None, **kwargs)

Initializes the base SimConcretizationStrategy.

Parameters:
  • filter – A function, taking arguments of (SimMemory, claripy.AST) that determines if this strategy can handle resolving the provided AST.

  • exact – A flag (default: True) that determines if the convenience resolution functions provided by this class use exact or approximate resolution.

copy()

Returns a copy of the strategy, if there is data that should be kept separate between states. If not, returns self.

merge(others)

Merges this strategy with others (if there is data that should be kept separate between states. If not, is a no-op.

class angr.concretization_strategies.SimConcretizationStrategyNorepeatsRange(repeat_expr, min=None, granularity=None, **kwargs)

Bases: SimConcretizationStrategy

Concretization strategy that resolves a range, with no repeats.

__init__(repeat_expr, min=None, granularity=None, **kwargs)

Initializes the base SimConcretizationStrategy.

Parameters:
  • filter – A function, taking arguments of (SimMemory, claripy.AST) that determines if this strategy can handle resolving the provided AST.

  • exact – A flag (default: True) that determines if the convenience resolution functions provided by this class use exact or approximate resolution.

copy()

Returns a copy of the strategy, if there is data that should be kept separate between states. If not, returns self.

merge(others)

Merges this strategy with others (if there is data that should be kept separate between states. If not, is a no-op.

class angr.concretization_strategies.SimConcretizationStrategyRange(limit, **kwargs)

Bases: SimConcretizationStrategy

Concretization strategy that resolves addresses to a range.

__init__(limit, **kwargs)

Initializes the base SimConcretizationStrategy.

Parameters:
  • filter – A function, taking arguments of (SimMemory, claripy.AST) that determines if this strategy can handle resolving the provided AST.

  • exact – A flag (default: True) that determines if the convenience resolution functions provided by this class use exact or approximate resolution.

class angr.concretization_strategies.SimConcretizationStrategySingle(filter=None, exact=True)

Bases: SimConcretizationStrategy

Concretization strategy that ensures a single solution for an address.

class angr.concretization_strategies.SimConcretizationStrategySolutions(limit, **kwargs)

Bases: SimConcretizationStrategy

Concretization strategy that resolves an address into some limited number of solutions.

__init__(limit, **kwargs)

Initializes the base SimConcretizationStrategy.

Parameters:
  • filter – A function, taking arguments of (SimMemory, claripy.AST) that determines if this strategy can handle resolving the provided AST.

  • exact – A flag (default: True) that determines if the convenience resolution functions provided by this class use exact or approximate resolution.

class angr.concretization_strategies.SimConcretizationStrategyUnlimitedRange(limit, **kwargs)

Bases: SimConcretizationStrategy

Concretization strategy that resolves addresses to a range without checking if the number of possible addresses is within the limit.

__init__(limit, **kwargs)

Initializes the base SimConcretizationStrategy.

Parameters:
  • filter – A function, taking arguments of (SimMemory, claripy.AST) that determines if this strategy can handle resolving the provided AST.

  • exact – A flag (default: True) that determines if the convenience resolution functions provided by this class use exact or approximate resolution.

Memory Mixins

class angr.storage.memory_mixins.AbstractMemory(*args, **kwargs)

Bases: UnwrapperMixin, NameResolutionMixin, DataNormalizationMixin, SimplificationMixin, InspectMixinHigh, ActionsMixinHigh, UnderconstrainedMixin, SizeConcretizationMixin, SizeNormalizationMixin, ActionsMixinLow, ConditionalMixin, RegionedAddressConcretizationMixin, RegionedMemoryMixin

class angr.storage.memory_mixins.AbstractMergerMixin(memory_id=None, endness='Iend_BE')

Bases: MemoryMixin

AbstractMergerMixin handles merging initialized values.

Parameters:
  • memory_id (str | None)

  • endness (str)

class angr.storage.memory_mixins.ActionsMixinHigh(memory_id=None, endness='Iend_BE')

Bases: MemoryMixin

Parameters:
  • memory_id (str | None)

  • endness (str)

load(addr, size=None, *, condition=None, fallback=None, disable_actions=False, action=None, **kwargs)
store(addr, data, size=None, *, disable_actions=False, action=None, condition=None, **kwargs)
class angr.storage.memory_mixins.ActionsMixinLow(memory_id=None, endness='Iend_BE')

Bases: MemoryMixin

Parameters:
  • memory_id (str | None)

  • endness (str)

load(addr, size=None, *, action=None, **kwargs)
store(addr, data, size=None, *, action=None, **kwargs)
Parameters:

action (SimActionData | None)

class angr.storage.memory_mixins.AddressConcretizationMixin(read_strategies=None, write_strategies=None, **kwargs)

Bases: MemoryMixin

The address concretization mixin allows symbolic reads and writes to be handled sanely by dispatching them as a number of conditional concrete reads/writes. It provides a “concretization strategies” interface allowing the process of serializing symbolic addresses into concrete ones to be specified.

__init__(read_strategies=None, write_strategies=None, **kwargs)
set_state(state)

Sets a new state (for example, if the state has been branched)

copy(memo: dict[int, Any] | None = None, **kwargs: Any) S_co

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:
  • memo (Optional[dict[int, Any]]) – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

  • kwargs (Any)

Return type:

TypeVar(S_co, covariant=True)

merge(others, merge_conditions, common_ancestor=None)

Should merge the state plugin with the provided others. This will be called by state.merge() after copying the target state, so this should mutate the current instance to merge with the others.

Note that when multiple instances of a single plugin object (for example, a file) are referenced in the state, it is important that merge only ever be called once. This should be solved by designating one of the plugin’s referees as the “real owner”, who should be the one to actually merge it. This technique doesn’t work to resolve the similar issue that arises during copying because merging doesn’t produce a new reference to insert.

There will be n others and n+1 merge conditions, since the first condition corresponds to self. To match elements up to conditions, say zip([self] + others, merge_conditions)

When implementing this, make sure that you “deepen” both others and common_ancestor before calling sub-elements’ merge methods, e.g.

self.foo.merge(
    [o.foo for o in others],
    merge_conditions,
    common_ancestor=common_ancestor.foo if common_ancestor is not None else None
)

During static analysis, merge_conditions can be None, in which case you should use state.solver.union(values). TODO: fish please make this less bullshit

There is a utility claripy.ite_cases which will help with constructing arbitrarily large merged ASTs. Use it like self.bar = claripy.ite_cases(zip(conditions[1:], [o.bar for o in others]), self.bar)

Parameters:
  • others – the other state plugins to merge with

  • merge_conditions – a symbolic condition for each of the plugins

  • common_ancestor – a common ancestor of this plugin and the others being merged

Returns:

True if the state plugins are actually merged.

Return type:

bool

concretize_write_addr(addr, strategies=None, condition=None)

Concretizes an address meant for writing.

Parameters:
  • addr – An expression for the address.

  • strategies – A list of concretization strategies (to override the default).

  • condition – Any extra constraints that should be observed when determining address satisfiability

Returns:

A list of concrete addresses.

concretize_read_addr(addr, strategies=None, condition=None)

Concretizes an address meant for reading.

Parameters:
  • addr – An expression for the address.

  • strategies – A list of concretization strategies (to override the default).

Returns:

A list of concrete addresses.

load(addr, size=None, *, condition=None, **kwargs)
store(addr, data, size=None, *, condition=None, **kwargs)
permissions(addr, permissions=None, **kwargs)
map_region(addr, length, permissions, **kwargs)
unmap_region(addr, length, **kwargs)
concrete_load(addr, size, writing=False, **kwargs)

Set SUPPORTS_CONCRETE_LOAD to True and implement concrete_load if reading concrete bytes is faster in this memory model.

Parameters:
  • addr – The address to load from.

  • size – Size of the memory read.

  • writing

Returns:

A memoryview into the loaded bytes.

class angr.storage.memory_mixins.ClemoryBackerMixin(cle_memory_backer=None, **kwargs)

Bases: PagedMemoryMixin

Parameters:

cle_memory_backer (None | cle.Loader | cle.Clemory)

__init__(cle_memory_backer=None, **kwargs)
Parameters:

cle_memory_backer (None | Loader | Clemory)

copy(memo)

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:

memo – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

class angr.storage.memory_mixins.ConcreteBackerMixin(cle_memory_backer=None, **kwargs)

Bases: ClemoryBackerMixin

Parameters:

cle_memory_backer (None | cle.Loader | cle.Clemory)

class angr.storage.memory_mixins.ConditionalMixin(memory_id=None, endness='Iend_BE')

Bases: MemoryMixin

Parameters:
  • memory_id (str | None)

  • endness (str)

load(addr, size=None, *, condition=None, fallback=None, **kwargs)
store(addr, data, size=None, *, condition=None, **kwargs)
class angr.storage.memory_mixins.ConvenientMappingsMixin(**kwargs)

Bases: MemoryMixin

Implements mappings between names and hashes of symbolic variables and these variables themselves.

__init__(**kwargs)
copy(memo)

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:

memo – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

store(addr, data, size=None, **kwargs)
get_symbolic_addrs()
addrs_for_name(n)

Returns addresses that contain expressions that contain a variable named n.

addrs_for_hash(h)

Returns addresses that contain expressions that contain a variable with the hash of h.

replace_all(old, new)

Replaces all instances of expression old with expression new.

Parameters:
  • old (BV) – A claripy expression. Must contain at least one named variable (to make it possible to use the name index for speedup).

  • new (BV) – The new variable to replace it with.

class angr.storage.memory_mixins.CooperationBase

Bases: Generic[T]

Any given subclass of this class which is not a subclass of MemoryMixin should have the property that any subclass it which is a subclass of MemoryMixin should all work with the same datatypes

class angr.storage.memory_mixins.DataNormalizationMixin(memory_id=None, endness='Iend_BE')

Bases: MemoryMixin

Normalizes the data field for a store and the fallback field for a load to be BVs.

Parameters:
  • memory_id (str | None)

  • endness (str)

store(addr, data, size=None, **kwargs)
load(addr, size=None, *, fallback=None, **kwargs)
class angr.storage.memory_mixins.DefaultFillerMixin(memory_id=None, endness='Iend_BE')

Bases: MemoryMixin

Parameters:
  • memory_id (str | None)

  • endness (str)

class angr.storage.memory_mixins.DefaultListPagesMemory(*args, **kwargs)

Bases: HexDumperMixin, SmartFindMixin, UnwrapperMixin, NameResolutionMixin, DataNormalizationMixin, SimplificationMixin, ActionsMixinHigh, UnderconstrainedMixin, SizeConcretizationMixin, SizeNormalizationMixin, InspectMixinHigh, AddressConcretizationMixin, ActionsMixinLow, ConditionalMixin, ConvenientMappingsMixin, DirtyAddrsMixin, StackAllocationMixin, ClemoryBackerMixin, DictBackerMixin, PrivilegedPagingMixin, ListPagesMixin, DefaultFillerMixin, SymbolicMergerMixin, PagedMemoryMixin

class angr.storage.memory_mixins.DefaultMemory(*args, **kwargs)

Bases: HexDumperMixin, SmartFindMixin, UnwrapperMixin, NameResolutionMixin, DataNormalizationMixin, SimplificationMixin, InspectMixinHigh, ActionsMixinHigh, UnderconstrainedMixin, SizeConcretizationMixin, SizeNormalizationMixin, AddressConcretizationMixin, ActionsMixinLow, ConditionalMixin, ConvenientMappingsMixin, DirtyAddrsMixin, StackAllocationMixin, ConcreteBackerMixin, ClemoryBackerMixin, DictBackerMixin, PrivilegedPagingMixin, UltraPagesMixin, DefaultFillerMixin, SymbolicMergerMixin, PagedMemoryMixin

class angr.storage.memory_mixins.DictBackerMixin(dict_memory_backer=None, **kwargs)

Bases: PagedMemoryMixin

__init__(dict_memory_backer=None, **kwargs)
copy(memo)

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:

memo – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

class angr.storage.memory_mixins.DirtyAddrsMixin(memory_id=None, endness='Iend_BE')

Bases: MemoryMixin

Parameters:
  • memory_id (str | None)

  • endness (str)

store(addr, data, size=None, **kwargs)
class angr.storage.memory_mixins.ExplicitFillerMixin(uninitialized_read_handler=None, **kwargs)

Bases: MemoryMixin

__init__(uninitialized_read_handler=None, **kwargs)
copy(memo)

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:

memo – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

class angr.storage.memory_mixins.FastMemory(uninitialized_read_handler=None, **kwargs)

Bases: NameResolutionMixin, SimpleInterfaceMixin, SimplificationMixin, InspectMixinHigh, ConditionalMixin, ExplicitFillerMixin, DefaultFillerMixin, SlottedMemoryMixin

class angr.storage.memory_mixins.HexDumperMixin(memory_id=None, endness='Iend_BE')

Bases: MemoryMixin

Parameters:
  • memory_id (str | None)

  • endness (str)

hex_dump(start, size, word_size=4, words_per_row=4, endianness='Iend_BE', symbolic_char='?', unprintable_char='.', solve=False, extra_constraints=None, inspect=False, disable_actions=True)

Returns a hex dump as a string. The solver, if enabled, is called once for every byte potentially making this function very slow. It is meant to be used mainly as a “visualization” for debugging.

Warning: May read and display more bytes than size due to rounding. Particularly, if size is less than, or not a multiple of word_size*words_per_line.

Parameters:
  • start – starting address from which to print

  • size – number of bytes to display

  • word_size – number of bytes to group together as one space-delimited unit

  • words_per_row – number of words to display per row of output

  • endianness – endianness to use when displaying each word (ASCII representation is unchanged)

  • symbolic_char – the character to display when a byte is symbolic and has multiple solutions

  • unprintable_char – the character to display when a byte is not printable

  • solve – whether or not to attempt to solve (warning: can be very slow)

  • extra_constraints – extra constraints to pass to the solver is solve is True

  • inspect – whether or not to trigger SimInspect breakpoints for the memory load

  • disable_actions – whether or not to disable SimActions for the memory load

Returns:

hex dump as a string

class angr.storage.memory_mixins.HistoryTrackingMixin(*args, **kwargs)

Bases: RefcountMixin, MemoryMixin

Tracks the history of memory writes.

__init__(*args, **kwargs)
store(addr, data, size=None, **kwargs)
copy(memo)

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:

memo – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

acquire_unique()

Call this function to return a version of this page which can be used for writing, which may or may not be the same object as before. If you use this you must immediately replace the shared reference you previously had with the new unique copy.

parents()
changed_bytes(other, **kwargs)
Return type:

set[int] | None

all_bytes_changed_in_history()
Return type:

SegmentList

class angr.storage.memory_mixins.ISPOMixin(memory_id=None, endness='Iend_BE')

Bases: MemoryMixin

An implementation of the International Stateless Persons Organisation, a mixin which should be applied as a bottom layer for memories which have no state and must redirect certain operations to a parent memory. Main usecase is for memory region classes which are stored within other memories, such as pages.

Parameters:
  • memory_id (str | None)

  • endness (str)

set_state(state)

Sets a new state (for example, if the state has been branched)

class angr.storage.memory_mixins.InspectMixinHigh(memory_id=None, endness='Iend_BE')

Bases: MemoryMixin

Parameters:
  • memory_id (str | None)

  • endness (str)

store(addr, data, size=None, *, condition=None, endness=None, inspect=True, **kwargs)
load(addr, size=None, *, condition=None, endness=None, inspect=True, **kwargs)
class angr.storage.memory_mixins.JavaVmMemory(memory_id='mem', stack=None, heap=None, vm_static_table=None, load_strategies=None, store_strategies=None, max_array_size=1000, **kwargs)

Bases: JavaVmMemoryMixin

class angr.storage.memory_mixins.JavaVmMemoryMixin(memory_id='mem', stack=None, heap=None, vm_static_table=None, load_strategies=None, store_strategies=None, max_array_size=1000, **kwargs)

Bases: MemoryMixin

A memory mixin for JavaVM memory.

__init__(memory_id='mem', stack=None, heap=None, vm_static_table=None, load_strategies=None, store_strategies=None, max_array_size=1000, **kwargs)
static get_new_uuid()

Generate a unique id within the scope of the JavaVM memory. This, for example, is used for distinguishing memory objects of the same type (e.g. multiple instances of the same class).

store(addr, data, frame=0)
load(addr, frame=0, none_if_missing=False)
push_stack_frame()
pop_stack_frame()
property stack
store_array_element(array, idx, value)
store_array_elements(array, start_idx, data)

Stores either a single element or a range of elements in the array.

Parameters:
  • array – Reference to the array.

  • start_idx – Starting index for the store.

  • data – Either a single value or a list of values.

load_array_element(array, idx)
load_array_elements(array, start_idx, no_of_elements)

Loads either a single element or a range of elements from the array.

Parameters:
  • array – Reference to the array.

  • start_idx – Starting index for the load.

  • no_of_elements – Number of elements to load.

concretize_store_idx(idx, strategies=None)

Concretizes a store index.

Parameters:
  • idx – An expression for the index.

  • strategies – A list of concretization strategies (to override the default).

  • min_idx – Minimum value for a concretized index (inclusive).

  • max_idx – Maximum value for a concretized index (exclusive).

Returns:

A list of concrete indexes.

concretize_load_idx(idx, strategies=None)

Concretizes a load index.

Parameters:
  • idx – An expression for the index.

  • strategies – A list of concretization strategies (to override the default).

  • min_idx – Minimum value for a concretized index (inclusive).

  • max_idx – Maximum value for a concretized index (exclusive).

Returns:

A list of concrete indexes.

set_state(state)

Sets a new state (for example, if the state has been branched)

copy(memo: dict[int, Any] | None = None, **kwargs: Any) S_co

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:
  • memo (Optional[dict[int, Any]]) – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

  • kwargs (Any)

Return type:

TypeVar(S_co, covariant=True)

merge(others, merge_conditions, common_ancestor=None)

Should merge the state plugin with the provided others. This will be called by state.merge() after copying the target state, so this should mutate the current instance to merge with the others.

Note that when multiple instances of a single plugin object (for example, a file) are referenced in the state, it is important that merge only ever be called once. This should be solved by designating one of the plugin’s referees as the “real owner”, who should be the one to actually merge it. This technique doesn’t work to resolve the similar issue that arises during copying because merging doesn’t produce a new reference to insert.

There will be n others and n+1 merge conditions, since the first condition corresponds to self. To match elements up to conditions, say zip([self] + others, merge_conditions)

When implementing this, make sure that you “deepen” both others and common_ancestor before calling sub-elements’ merge methods, e.g.

self.foo.merge(
    [o.foo for o in others],
    merge_conditions,
    common_ancestor=common_ancestor.foo if common_ancestor is not None else None
)

During static analysis, merge_conditions can be None, in which case you should use state.solver.union(values). TODO: fish please make this less bullshit

There is a utility claripy.ite_cases which will help with constructing arbitrarily large merged ASTs. Use it like self.bar = claripy.ite_cases(zip(conditions[1:], [o.bar for o in others]), self.bar)

Parameters:
  • others – the other state plugins to merge with

  • merge_conditions – a symbolic condition for each of the plugins

  • common_ancestor – a common ancestor of this plugin and the others being merged

Returns:

True if the state plugins are actually merged.

Return type:

bool

widen(others)

The widening operation for plugins. Widening is a special kind of merging that produces a more general state from several more specific states. It is used only during intensive static analysis. The same behavior regarding copying and mutation from merge should be followed.

Parameters:

others – the other state plugin

Returns:

True if the state plugin is actually widened.

Return type:

bool

class angr.storage.memory_mixins.KeyValueMemory(*args, **kwargs)

Bases: KeyValueMemoryMixin

class angr.storage.memory_mixins.KeyValueMemoryMixin(*args, **kwargs)

Bases: MemoryMixin

KeyValueMemoryMixin is a mixin that provides a simple key-value store for memory.

__init__(*args, **kwargs)
load(addr, size=None, none_if_missing=False, **kwargs)
store(addr, data, type_=None, **kwargs)
copy(memo: dict[int, Any] | None = None, **kwargs: Any) S_co

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:
  • memo (Optional[dict[int, Any]]) – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

  • kwargs (Any)

Return type:

TypeVar(S_co, covariant=True)

class angr.storage.memory_mixins.LabelMergerMixin(*args, **kwargs)

Bases: MemoryMixin

A memory mixin for merging labels. Labels come from SimLabeledMemoryObject.

__init__(*args, **kwargs)
copy(memo=None)

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:

memo – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

class angr.storage.memory_mixins.LabeledMemory(*args, top_func=None, **kwargs)

Bases: SizeNormalizationMixin, ListPagesWithLabelsMixin, DefaultFillerMixin, TopMergerMixin, LabelMergerMixin, PagedMemoryMixin

LabeledMemory is used in static analysis. It allows storing values with labels, such as Definition.

class angr.storage.memory_mixins.ListPage(memory=None, content=None, sinkhole=None, mo_cmp=None, **kwargs)

Bases: MemoryObjectMixin, PageBase

This class implements a page memory mixin with lists as the main content store.

__init__(memory=None, content=None, sinkhole=None, mo_cmp=None, **kwargs)
copy(memo)

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:

memo – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

load(addr, size=None, endness=None, page_addr=None, memory=None, cooperate=False, **kwargs)
store(addr, data, size=None, endness=None, memory=None, cooperate=False, **kwargs)
erase(addr, size=None, **kwargs)

Set [addr:addr+size) to uninitialized. In many cases this will be faster than overwriting those locations with new values. This is commonly used during static data flow analysis.

Parameters:
  • addr – The address to start erasing.

  • size – The number of bytes for erasing.

Return type:

None

Returns:

None

merge(others, merge_conditions, common_ancestor=None, page_addr=None, memory=None, changed_offsets=None)

Should merge the state plugin with the provided others. This will be called by state.merge() after copying the target state, so this should mutate the current instance to merge with the others.

Note that when multiple instances of a single plugin object (for example, a file) are referenced in the state, it is important that merge only ever be called once. This should be solved by designating one of the plugin’s referees as the “real owner”, who should be the one to actually merge it. This technique doesn’t work to resolve the similar issue that arises during copying because merging doesn’t produce a new reference to insert.

There will be n others and n+1 merge conditions, since the first condition corresponds to self. To match elements up to conditions, say zip([self] + others, merge_conditions)

When implementing this, make sure that you “deepen” both others and common_ancestor before calling sub-elements’ merge methods, e.g.

self.foo.merge(
    [o.foo for o in others],
    merge_conditions,
    common_ancestor=common_ancestor.foo if common_ancestor is not None else None
)

During static analysis, merge_conditions can be None, in which case you should use state.solver.union(values). TODO: fish please make this less bullshit

There is a utility claripy.ite_cases which will help with constructing arbitrarily large merged ASTs. Use it like self.bar = claripy.ite_cases(zip(conditions[1:], [o.bar for o in others]), self.bar)

Parameters:
  • others (list[ListPage]) – the other state plugins to merge with

  • merge_conditions – a symbolic condition for each of the plugins

  • common_ancestor – a common ancestor of this plugin and the others being merged

  • page_addr (int | None)

  • changed_offsets (set[int] | None)

Returns:

True if the state plugins are actually merged.

Return type:

bool

changed_bytes(other, page_addr=None)
Parameters:
class angr.storage.memory_mixins.ListPagesMixin(page_size=4096, default_permissions=3, permissions_map=None, page_kwargs=None, **kwargs)

Bases: PagedMemoryMixin

PAGE_TYPE

alias of ListPage

class angr.storage.memory_mixins.ListPagesWithLabelsMixin(page_size=4096, default_permissions=3, permissions_map=None, page_kwargs=None, **kwargs)

Bases: LabeledPagesMixin, ListPagesMixin

class angr.storage.memory_mixins.MVListPage(memory=None, content=None, sinkhole=None, mo_cmp=None, **kwargs)

Bases: MemoryObjectSetMixin, PageBase

MVListPage allows storing multiple values at the same location.

Each store() may take a value or multiple values. Each load() returns an iterator of all values stored at that location.

__init__(memory=None, content=None, sinkhole=None, mo_cmp=None, **kwargs)
copy(memo)

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:

memo – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

Return type:

MVListPage

load(addr, size=None, endness=None, page_addr=None, memory=None, cooperate=False, **kwargs)
Return type:

list[tuple[int, SimMemoryObject | SimLabeledMemoryObject]]

store(addr, data, size=None, endness=None, memory=None, cooperate=False, **kwargs)
erase(addr, size=None, **kwargs)

Set [addr:addr+size) to uninitialized. In many cases this will be faster than overwriting those locations with new values. This is commonly used during static data flow analysis.

Parameters:
  • addr – The address to start erasing.

  • size – The number of bytes for erasing.

Return type:

None

Returns:

None

merge(others, merge_conditions, common_ancestor=None, *, page_addr, memory, changed_offsets=None)

Should merge the state plugin with the provided others. This will be called by state.merge() after copying the target state, so this should mutate the current instance to merge with the others.

Note that when multiple instances of a single plugin object (for example, a file) are referenced in the state, it is important that merge only ever be called once. This should be solved by designating one of the plugin’s referees as the “real owner”, who should be the one to actually merge it. This technique doesn’t work to resolve the similar issue that arises during copying because merging doesn’t produce a new reference to insert.

There will be n others and n+1 merge conditions, since the first condition corresponds to self. To match elements up to conditions, say zip([self] + others, merge_conditions)

When implementing this, make sure that you “deepen” both others and common_ancestor before calling sub-elements’ merge methods, e.g.

self.foo.merge(
    [o.foo for o in others],
    merge_conditions,
    common_ancestor=common_ancestor.foo if common_ancestor is not None else None
)

During static analysis, merge_conditions can be None, in which case you should use state.solver.union(values). TODO: fish please make this less bullshit

There is a utility claripy.ite_cases which will help with constructing arbitrarily large merged ASTs. Use it like self.bar = claripy.ite_cases(zip(conditions[1:], [o.bar for o in others]), self.bar)

Parameters:
  • others (list[MVListPage]) – the other state plugins to merge with

  • merge_conditions – a symbolic condition for each of the plugins

  • common_ancestor – a common ancestor of this plugin and the others being merged

  • page_addr (int)

  • memory (MemoryMixin)

  • changed_offsets (set[int] | None)

Returns:

True if the state plugins are actually merged.

Return type:

bool

compare(other, page_addr=None, memory=None, changed_offsets=None)
Return type:

bool

Parameters:
changed_bytes(other, page_addr=None)
Parameters:
content_gen(index)
class angr.storage.memory_mixins.MVListPagesMixin(*args, skip_missing_values_during_merging=False, **kwargs)

Bases: PagedMemoryMixin

PAGE_TYPE

alias of MVListPage

__init__(*args, skip_missing_values_during_merging=False, **kwargs)
copy(memo: dict[int, Any] | None = None, **kwargs: Any) S_co

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:
  • memo (Optional[dict[int, Any]]) – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

  • kwargs (Any)

Return type:

TypeVar(S_co, covariant=True)

class angr.storage.memory_mixins.MVListPagesWithLabelsMixin(*args, skip_missing_values_during_merging=False, **kwargs)

Bases: LabeledPagesMixin, MVListPagesMixin

class angr.storage.memory_mixins.MemoryObjectMixin

Bases: CooperationBase[SimMemoryObject]

Uses SimMemoryObjects in region storage. With this, load will return a list of tuple (address, MO) and store will take a MO.

class angr.storage.memory_mixins.MemoryRegionMetaMixin(related_function_addr=None, **kwargs)

Bases: MemoryMixin

__init__(related_function_addr=None, **kwargs)
copy(memo: dict[int, Any] | None = None, **kwargs: Any) S_co

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:
  • memo (Optional[dict[int, Any]]) – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

  • kwargs (Any)

Return type:

TypeVar(S_co, covariant=True)

property is_stack
property related_function_addr
get_abstract_locations(addr, size)

Get a list of abstract locations that is within the range of [addr, addr + size]

This implementation is pretty slow. But since this method won’t be called frequently, we can live with the bad implementation for now.

Parameters:
  • addr – Starting address of the memory region.

  • size – Size of the memory region, in bytes.

Returns:

A list of covered AbstractLocation objects, or an empty list if there is none.

store(addr, data, size=None, *, bbl_addr=None, stmt_id=None, ins_addr=None, endness=None, **kwargs)
load(addr, size=None, *, bbl_addr=None, stmt_idx=None, ins_addr=None, **kwargs)
merge(others, merge_conditions, common_ancestor=None)

Should merge the state plugin with the provided others. This will be called by state.merge() after copying the target state, so this should mutate the current instance to merge with the others.

Note that when multiple instances of a single plugin object (for example, a file) are referenced in the state, it is important that merge only ever be called once. This should be solved by designating one of the plugin’s referees as the “real owner”, who should be the one to actually merge it. This technique doesn’t work to resolve the similar issue that arises during copying because merging doesn’t produce a new reference to insert.

There will be n others and n+1 merge conditions, since the first condition corresponds to self. To match elements up to conditions, say zip([self] + others, merge_conditions)

When implementing this, make sure that you “deepen” both others and common_ancestor before calling sub-elements’ merge methods, e.g.

self.foo.merge(
    [o.foo for o in others],
    merge_conditions,
    common_ancestor=common_ancestor.foo if common_ancestor is not None else None
)

During static analysis, merge_conditions can be None, in which case you should use state.solver.union(values). TODO: fish please make this less bullshit

There is a utility claripy.ite_cases which will help with constructing arbitrarily large merged ASTs. Use it like self.bar = claripy.ite_cases(zip(conditions[1:], [o.bar for o in others]), self.bar)

Parameters:
  • others – the other state plugins to merge with

  • merge_conditions – a symbolic condition for each of the plugins

  • common_ancestor – a common ancestor of this plugin and the others being merged

Returns:

True if the state plugins are actually merged.

Return type:

bool

widen(others)

The widening operation for plugins. Widening is a special kind of merging that produces a more general state from several more specific states. It is used only during intensive static analysis. The same behavior regarding copying and mutation from merge should be followed.

Parameters:

others – the other state plugin

Returns:

True if the state plugin is actually widened.

Return type:

bool

dbg_print(indent=0)

Print out debugging information

class angr.storage.memory_mixins.MultiValueMergerMixin(*args, element_limit=5, annotation_limit=256, top_func=None, is_top_func=None, phi_maker=None, merge_into_top=True, **kwargs)

Bases: MemoryMixin

__init__(*args, element_limit=5, annotation_limit=256, top_func=None, is_top_func=None, phi_maker=None, merge_into_top=True, **kwargs)
copy(memo=None)

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:

memo – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

class angr.storage.memory_mixins.MultiValuedMemory(*args, skip_missing_values_during_merging=False, **kwargs)

Bases: SizeNormalizationMixin, MVListPagesMixin, DefaultFillerMixin, MultiValueMergerMixin, PagedMemoryMixin, PagedMemoryMultiValueMixin

class angr.storage.memory_mixins.NameResolutionMixin(memory_id=None, endness='Iend_BE')

Bases: MemoryMixin

This mixin allows you to provide register names as load addresses, and will automatically translate this to an offset and size.

Parameters:
  • memory_id (str | None)

  • endness (str)

store(addr, data, size=None, **kwargs)
load(addr, size=None, **kwargs)
class angr.storage.memory_mixins.PageBase(*args, **kwargs)

Bases: HistoryTrackingMixin, RefcountMixin, CooperationBase, ISPOMixin, PermissionsMixin, MemoryMixin

This is a fairly succinct definition of the contract between PagedMemoryMixin and its constituent pages:

  • Pages must implement the MemoryMixin model for loads, stores, copying, merging, etc

  • However, loading/storing may not necessarily use the same data domain as PagedMemoryMixin. In order to do more efficient loads/stores across pages, we use the CooperationBase interface which allows the page class to determine how to generate and unwrap the objects which are actually stored.

  • To support COW, we use the RefcountMixin and the ISPOMixin (which adds the contract element that memory=self be passed to every method call)

  • Pages have permissions associated with them, stored in the PermissionsMixin.

Read the docstrings for each of the constituent classes to understand the nuances of their functionalities

class angr.storage.memory_mixins.PagedMemoryMixin(page_size=4096, default_permissions=3, permissions_map=None, page_kwargs=None, **kwargs)

Bases: Generic[PageType], MemoryMixin[int | BV | SimActionObject, BV, int | BV | SimActionObject]

A bottom-level storage mechanism. Dispatches reads to individual pages, the type of which is the PAGE_TYPE class variable.

SUPPORTS_CONCRETE_LOAD: bool = True
PAGE_TYPE: type[PageType]
__init__(page_size=4096, default_permissions=3, permissions_map=None, page_kwargs=None, **kwargs)
copy(memo: dict[int, Any] | None = None, **kwargs: Any) S_co

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:
  • memo (Optional[dict[int, Any]]) – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

  • kwargs (Any)

Return type:

TypeVar(S_co, covariant=True)

load(addr, size=None, *, endness=None, **kwargs)
Parameters:
  • addr (int)

  • size (int | None)

store(addr, data, size=None, *, endness=None, **kwargs)
Parameters:
  • addr (int)

  • size (int | None)

erase(addr, size=None, **kwargs)

Set [addr:addr+size) to uninitialized. In many cases this will be faster than overwriting those locations with new values. This is commonly used during static data flow analysis.

Parameters:
  • addr – The address to start erasing.

  • size – The number of bytes for erasing.

Return type:

None

Returns:

None

merge(others, merge_conditions, common_ancestor=None)

Should merge the state plugin with the provided others. This will be called by state.merge() after copying the target state, so this should mutate the current instance to merge with the others.

Note that when multiple instances of a single plugin object (for example, a file) are referenced in the state, it is important that merge only ever be called once. This should be solved by designating one of the plugin’s referees as the “real owner”, who should be the one to actually merge it. This technique doesn’t work to resolve the similar issue that arises during copying because merging doesn’t produce a new reference to insert.

There will be n others and n+1 merge conditions, since the first condition corresponds to self. To match elements up to conditions, say zip([self] + others, merge_conditions)

When implementing this, make sure that you “deepen” both others and common_ancestor before calling sub-elements’ merge methods, e.g.

self.foo.merge(
    [o.foo for o in others],
    merge_conditions,
    common_ancestor=common_ancestor.foo if common_ancestor is not None else None
)

During static analysis, merge_conditions can be None, in which case you should use state.solver.union(values). TODO: fish please make this less bullshit

There is a utility claripy.ite_cases which will help with constructing arbitrarily large merged ASTs. Use it like self.bar = claripy.ite_cases(zip(conditions[1:], [o.bar for o in others]), self.bar)

Parameters:
  • others – the other state plugins to merge with

  • merge_conditions – a symbolic condition for each of the plugins

  • common_ancestor – a common ancestor of this plugin and the others being merged

Returns:

True if the state plugins are actually merged.

Return type:

bool

compare(other)
Return type:

bool

Parameters:

other (PagedMemoryMixin)

permissions(addr, permissions=None, **kwargs)
map_region(addr, length, permissions, *, init_zero=False, **kwargs)
unmap_region(addr, length, **kwargs)
concrete_load(addr, size, writing=False, *, with_bitmap=False, **kwargs)

Set SUPPORTS_CONCRETE_LOAD to True and implement concrete_load if reading concrete bytes is faster in this memory model.

Parameters:
  • addr – The address to load from.

  • size – Size of the memory read.

  • writing

  • with_bitmap (bool)

Returns:

A memoryview into the loaded bytes.

changed_bytes(other)
Return type:

set[int]

changed_pages(other)
Return type:

dict[int, set[int] | None]

copy_contents(dst, src, size, condition=None, **kwargs)

Override this method to provide faster copying of large chunks of data.

Parameters:
  • dst – The destination of copying.

  • src – The source of copying.

  • size – The size of copying.

  • condition – The storing condition.

  • kwargs – Other parameters.

Returns:

None

flush_pages(white_list)

Flush all pages not included in the white_list by removing their pages. Note, this will not wipe them from memory if they were backed by a memory_backer, it will simply reset them to their initial state. Returns the list of pages that were cleared consisting of (addr, length) tuples. :type white_list: :param white_list: white list of regions in the form of (start, end) to exclude from the flush :return: a list of memory page ranges that were flushed :rtype: list

class angr.storage.memory_mixins.PagedMemoryMultiValueMixin(memory_id=None, endness='Iend_BE')

Bases: MemoryMixin

Implement optimizations and fast accessors for the MultiValues-variant of Paged Memory.

Parameters:
  • memory_id (str | None)

  • endness (str)

load_annotations(addr, size, **kwargs)
Parameters:
class angr.storage.memory_mixins.PermissionsMixin(permissions=None, **kwargs)

Bases: MemoryMixin

This mixin adds a permissions_bits field and properties for extracting the read/write/exec permissions. It does NOT add permissions checking.

Parameters:

permissions (int | claripy.ast.BV | None)

__init__(permissions=None, **kwargs)
Parameters:

permissions (int | BV | None)

copy(memo)

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:

memo – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

property perm_read
property perm_write
property perm_exec
class angr.storage.memory_mixins.PrivilegedPagingMixin(page_size=4096, default_permissions=3, permissions_map=None, page_kwargs=None, **kwargs)

Bases: PagedMemoryMixin

A mixin for paged memory models which will raise SimSegfaultExceptions if STRICT_PAGE_ACCESS is enabled and a segfault condition is detected.

Segfault conditions include: - getting a page for reading which is non-readable - getting a page for writing which is non-writable - creating a page

The latter condition means that this should be inserted under any mixins which provide other implementations of _initialize_page.

class angr.storage.memory_mixins.RefcountMixin(**kwargs)

Bases: MemoryMixin

This mixin adds a locked reference counter and methods to manipulate it, to facilitate copy-on-write optimizations.

__init__(**kwargs)
copy(memo)

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:

memo – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

acquire_unique()

Call this function to return a version of this page which can be used for writing, which may or may not be the same object as before. If you use this you must immediately replace the shared reference you previously had with the new unique copy.

acquire_shared()

Call this function to indicate that this page has had a reference added to it and must be copied before it can be acquired uniquely again. Creating the object implicitly starts it with one shared reference.

Return type:

None

release_shared()

Call this function to indicate that this page has had a shared reference to it released

Return type:

None

class angr.storage.memory_mixins.RegionCategoryMixin(memory_id=None, endness='Iend_BE')

Bases: MemoryMixin

Parameters:
  • memory_id (str | None)

  • endness (str)

property category

reg, mem, or file.

Type:

Return the category of this SimMemory instance. It can be one of the three following categories

class angr.storage.memory_mixins.RegionedAddressConcretizationMixin(read_strategies=None, write_strategies=None, **kwargs)

Bases: MemoryMixin

__init__(read_strategies=None, write_strategies=None, **kwargs)
set_state(state)

Sets a new state (for example, if the state has been branched)

copy(memo: dict[int, Any] | None = None, **kwargs: Any) S_co

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:
  • memo (Optional[dict[int, Any]]) – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

  • kwargs (Any)

Return type:

TypeVar(S_co, covariant=True)

merge(others, merge_conditions, common_ancestor=None)

Should merge the state plugin with the provided others. This will be called by state.merge() after copying the target state, so this should mutate the current instance to merge with the others.

Note that when multiple instances of a single plugin object (for example, a file) are referenced in the state, it is important that merge only ever be called once. This should be solved by designating one of the plugin’s referees as the “real owner”, who should be the one to actually merge it. This technique doesn’t work to resolve the similar issue that arises during copying because merging doesn’t produce a new reference to insert.

There will be n others and n+1 merge conditions, since the first condition corresponds to self. To match elements up to conditions, say zip([self] + others, merge_conditions)

When implementing this, make sure that you “deepen” both others and common_ancestor before calling sub-elements’ merge methods, e.g.

self.foo.merge(
    [o.foo for o in others],
    merge_conditions,
    common_ancestor=common_ancestor.foo if common_ancestor is not None else None
)

During static analysis, merge_conditions can be None, in which case you should use state.solver.union(values). TODO: fish please make this less bullshit

There is a utility claripy.ite_cases which will help with constructing arbitrarily large merged ASTs. Use it like self.bar = claripy.ite_cases(zip(conditions[1:], [o.bar for o in others]), self.bar)

Parameters:
  • others – the other state plugins to merge with

  • merge_conditions – a symbolic condition for each of the plugins

  • common_ancestor – a common ancestor of this plugin and the others being merged

Returns:

True if the state plugins are actually merged.

Return type:

bool

class angr.storage.memory_mixins.RegionedMemory(related_function_addr=None, **kwargs)

Bases: RegionCategoryMixin, MemoryRegionMetaMixin, StaticFindMixin, UnwrapperMixin, NameResolutionMixin, DataNormalizationMixin, SimplificationMixin, SizeConcretizationMixin, SizeNormalizationMixin, AddressConcretizationMixin, ConvenientMappingsMixin, DirtyAddrsMixin, ClemoryBackerMixin, DictBackerMixin, UltraPagesMixin, DefaultFillerMixin, AbstractMergerMixin, PagedMemoryMixin

class angr.storage.memory_mixins.RegionedMemoryMixin(write_targets_limit=2048, read_targets_limit=4096, stack_region_map=None, generic_region_map=None, stack_size=65536, cle_memory_backer=None, dict_memory_backer=None, regioned_memory_cls=None, **kwargs)

Bases: MemoryMixin

Regioned memory. This mixin manages multiple memory regions. Each address is represented as a tuple of (region ID, offset into the region), which is called a regioned address.

Converting absolute addresses into regioned addresses: We map an absolute address to a region by looking up which region this address belongs to in the region map. Currently this is only enabled for stack. Heap support has not landed yet.

When start analyzing a function, the user should call set_stack_address_mapping() to create a new region mapping. Likewise, when exiting from a function, the user should cancel the previous mapping by calling unset_stack_address_mapping().

Parameters:
  • write_targets_limit (int)

  • read_targets_limit (int)

  • stack_region_map (RegionMap | None)

  • generic_region_map (RegionMap | None)

  • stack_size (int)

  • cle_memory_backer (Optional | None)

  • dict_memory_backer (dict | None)

  • regioned_memory_cls (type | None)

__init__(write_targets_limit=2048, read_targets_limit=4096, stack_region_map=None, generic_region_map=None, stack_size=65536, cle_memory_backer=None, dict_memory_backer=None, regioned_memory_cls=None, **kwargs)
copy(memo: dict[int, Any] | None = None, **kwargs: Any) S_co

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:
  • memo (Optional[dict[int, Any]]) – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

  • kwargs (Any)

Return type:

TypeVar(S_co, covariant=True)

load(addr, size=None, *, endness=None, condition=None, **kwargs)
Parameters:
  • size (int | BV | None)

  • condition (Bool | None)

store(addr, data, size=None, *, endness=None, **kwargs)
Parameters:

size (int | None)

merge(others, merge_conditions, common_ancestor=None)

Should merge the state plugin with the provided others. This will be called by state.merge() after copying the target state, so this should mutate the current instance to merge with the others.

Note that when multiple instances of a single plugin object (for example, a file) are referenced in the state, it is important that merge only ever be called once. This should be solved by designating one of the plugin’s referees as the “real owner”, who should be the one to actually merge it. This technique doesn’t work to resolve the similar issue that arises during copying because merging doesn’t produce a new reference to insert.

There will be n others and n+1 merge conditions, since the first condition corresponds to self. To match elements up to conditions, say zip([self] + others, merge_conditions)

When implementing this, make sure that you “deepen” both others and common_ancestor before calling sub-elements’ merge methods, e.g.

self.foo.merge(
    [o.foo for o in others],
    merge_conditions,
    common_ancestor=common_ancestor.foo if common_ancestor is not None else None
)

During static analysis, merge_conditions can be None, in which case you should use state.solver.union(values). TODO: fish please make this less bullshit

There is a utility claripy.ite_cases which will help with constructing arbitrarily large merged ASTs. Use it like self.bar = claripy.ite_cases(zip(conditions[1:], [o.bar for o in others]), self.bar)

Parameters:
  • others – the other state plugins to merge with

  • merge_conditions – a symbolic condition for each of the plugins

  • common_ancestor – a common ancestor of this plugin and the others being merged

Returns:

True if the state plugins are actually merged.

Return type:

bool

find(addr, data, max_search, **kwargs)
Parameters:

addr (int | Bits)

set_state(state)

Sets a new state (for example, if the state has been branched)

replace_all(old, new)
Parameters:
set_stack_address_mapping(absolute_address, region_id, related_function_address=None)

Create a new mapping between an absolute address (which is the base address of a specific stack frame) and a region ID.

Parameters:
  • absolute_address (int) – The absolute memory address.

  • region_id (str) – The region ID.

  • related_function_address (Optional[int]) – Related function address.

unset_stack_address_mapping(absolute_address)

Remove a stack mapping.

Parameters:

absolute_address (int) – An absolute memory address that is the base address of the stack frame to destroy.

stack_id(function_address)

Return a memory region ID for a function. If the default region ID exists in the region mapping, an integer will appended to the region name. In this way we can handle recursive function calls, or a function that appears more than once in the call frame.

This also means that stack_id() should only be called when creating a new stack frame for a function. You are not supposed to call this function every time you want to map a function address to a stack ID.

Parameters:

function_address (int) – Address of the function.

Return type:

str

Returns:

ID of the new memory region.

set_stack_size(size)
Parameters:

size (int)

class angr.storage.memory_mixins.SimpleInterfaceMixin(memory_id=None, endness='Iend_BE')

Bases: MemoryMixin

Parameters:
  • memory_id (str | None)

  • endness (str)

load(addr, size=None, *, endness=None, condition=None, fallback=None, **kwargs)
store(addr, data, size=None, *, endness=None, condition=None, **kwargs)
class angr.storage.memory_mixins.SimplificationMixin(memory_id=None, endness='Iend_BE')

Bases: MemoryMixin

Parameters:
  • memory_id (str | None)

  • endness (str)

store(addr, data, size=None, **kwargs)
class angr.storage.memory_mixins.SizeConcretizationMixin(concretize_symbolic_write_size=False, max_concretize_count=256, max_symbolic_size=4194304, raise_memory_limit_error=False, size_limit=257, **kwargs)

Bases: MemoryMixin

This mixin allows memory to process symbolic sizes. It will not touch any sizes which are not ASTs with non-BVV ops. Assumes that the data is a BV.

  • symbolic load sizes will be concretized as their maximum and a warning will be logged

  • symbolic store sizes will be dispatched as several conditional stores with concrete sizes

Parameters:
  • concretize_symbolic_write_size (bool)

  • max_concretize_count (int | None)

  • max_symbolic_size (int)

  • raise_memory_limit_error (bool)

  • size_limit (int)

__init__(concretize_symbolic_write_size=False, max_concretize_count=256, max_symbolic_size=4194304, raise_memory_limit_error=False, size_limit=257, **kwargs)
Parameters:
  • concretize_symbolic_write_size (bool)

  • max_concretize_count (int | None)

  • max_symbolic_size (int)

  • raise_memory_limit_error (bool)

  • size_limit (int)

copy(memo)

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:

memo – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

load(addr, size=None, **kwargs)
store(addr, data, size=None, *, condition=None, **kwargs)
class angr.storage.memory_mixins.SizeNormalizationMixin(memory_id=None, endness='Iend_BE')

Bases: MemoryMixin

Provides basic services related to normalizing sizes. After this mixin, sizes will always be a plain int. Assumes that the data is a BV.

  • load will throw a TypeError if no size is provided

  • store will default to len(data)//byte_width if no size is provided

Parameters:
  • memory_id (str | None)

  • endness (str)

load(addr, size=None, **kwargs)
store(addr, data, size=None, **kwargs)
class angr.storage.memory_mixins.SlottedMemoryMixin(width=None, **kwargs)

Bases: MemoryMixin

__init__(width=None, **kwargs)
set_state(state)

Sets a new state (for example, if the state has been branched)

copy(memo)

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:

memo – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

merge(others, merge_conditions, common_ancestor=None)

Should merge the state plugin with the provided others. This will be called by state.merge() after copying the target state, so this should mutate the current instance to merge with the others.

Note that when multiple instances of a single plugin object (for example, a file) are referenced in the state, it is important that merge only ever be called once. This should be solved by designating one of the plugin’s referees as the “real owner”, who should be the one to actually merge it. This technique doesn’t work to resolve the similar issue that arises during copying because merging doesn’t produce a new reference to insert.

There will be n others and n+1 merge conditions, since the first condition corresponds to self. To match elements up to conditions, say zip([self] + others, merge_conditions)

When implementing this, make sure that you “deepen” both others and common_ancestor before calling sub-elements’ merge methods, e.g.

self.foo.merge(
    [o.foo for o in others],
    merge_conditions,
    common_ancestor=common_ancestor.foo if common_ancestor is not None else None
)

During static analysis, merge_conditions can be None, in which case you should use state.solver.union(values). TODO: fish please make this less bullshit

There is a utility claripy.ite_cases which will help with constructing arbitrarily large merged ASTs. Use it like self.bar = claripy.ite_cases(zip(conditions[1:], [o.bar for o in others]), self.bar)

Parameters:
  • others – the other state plugins to merge with

  • merge_conditions – a symbolic condition for each of the plugins

  • common_ancestor – a common ancestor of this plugin and the others being merged

Returns:

True if the state plugins are actually merged.

Return type:

bool

load(addr, size=None, *, endness=None, **kwargs)
store(addr, data, size=None, *, endness=None, **kwargs)
changed_bytes(other)
class angr.storage.memory_mixins.SmartFindMixin(memory_id=None, endness='Iend_BE')

Bases: MemoryMixin

Memory mixin providing basic searching over concrete and symbolic data.

Parameters:
  • memory_id (str | None)

  • endness (str)

find(addr, data, max_search, *, default=None, endness=None, chunk_size=None, max_symbolic_bytes=None, condition=None, char_size=1, **kwargs)
class angr.storage.memory_mixins.SpecialFillerMixin(special_memory_filler=None, **kwargs)

Bases: MemoryMixin

__init__(special_memory_filler=None, **kwargs)
copy(memo)

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:

memo – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

class angr.storage.memory_mixins.StackAllocationMixin(stack_end=None, stack_size=None, stack_perms=None, **kwargs)

Bases: PagedMemoryMixin

This mixin adds automatic allocation for a stack region based on the stack_end and stack_size parameters.

__init__(stack_end=None, stack_size=None, stack_perms=None, **kwargs)
copy(memo)

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:

memo – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

allocate_stack_pages(addr, size, **kwargs)

Pre-allocates pages for the stack without triggering any logic related to reading from them.

Parameters:
  • addr (int) – The highest address that should be mapped

  • size (int) – The number of bytes to be allocated. byte 1 is the one at addr, byte 2 is the one before that, and so on.

Returns:

A list of the new page objects

class angr.storage.memory_mixins.StaticFindMixin(memory_id=None, endness='Iend_BE')

Bases: SmartFindMixin

Implements data finding for abstract memory.

Parameters:
  • memory_id (str | None)

  • endness (str)

find(addr, data, max_search, *, default=None, endness=None, chunk_size=None, max_symbolic_bytes=None, condition=None, char_size=1, **kwargs)
class angr.storage.memory_mixins.SymbolicMergerMixin(memory_id=None, endness='Iend_BE')

Bases: MemoryMixin

Parameters:
  • memory_id (str | None)

  • endness (str)

class angr.storage.memory_mixins.TopMergerMixin(*args, top_func=None, **kwargs)

Bases: MemoryMixin

A memory mixin for merging values in memory to TOP.

__init__(*args, top_func=None, **kwargs)
copy(memo=None)

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:

memo – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

class angr.storage.memory_mixins.UltraPage(memory=None, init_zero=False, **kwargs)

Bases: MemoryObjectMixin, PageBase

Default page implementation

SUPPORTS_CONCRETE_LOAD: bool = True
__init__(memory=None, init_zero=False, **kwargs)
classmethod new_from_shared(data, memory=None, **kwargs)
copy(memo)

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:

memo – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

load(addr, size=None, page_addr=None, endness=None, memory=None, cooperate=False, **kwargs)
store(addr, data, size=None, endness=None, memory=None, page_addr=None, cooperate=False, **kwargs)
Parameters:
merge(others, merge_conditions, common_ancestor=None, page_addr=None, memory=None, changed_offsets=None)

Should merge the state plugin with the provided others. This will be called by state.merge() after copying the target state, so this should mutate the current instance to merge with the others.

Note that when multiple instances of a single plugin object (for example, a file) are referenced in the state, it is important that merge only ever be called once. This should be solved by designating one of the plugin’s referees as the “real owner”, who should be the one to actually merge it. This technique doesn’t work to resolve the similar issue that arises during copying because merging doesn’t produce a new reference to insert.

There will be n others and n+1 merge conditions, since the first condition corresponds to self. To match elements up to conditions, say zip([self] + others, merge_conditions)

When implementing this, make sure that you “deepen” both others and common_ancestor before calling sub-elements’ merge methods, e.g.

self.foo.merge(
    [o.foo for o in others],
    merge_conditions,
    common_ancestor=common_ancestor.foo if common_ancestor is not None else None
)

During static analysis, merge_conditions can be None, in which case you should use state.solver.union(values). TODO: fish please make this less bullshit

There is a utility claripy.ite_cases which will help with constructing arbitrarily large merged ASTs. Use it like self.bar = claripy.ite_cases(zip(conditions[1:], [o.bar for o in others]), self.bar)

Parameters:
  • others (list[UltraPage]) – the other state plugins to merge with

  • merge_conditions – a symbolic condition for each of the plugins

  • common_ancestor – a common ancestor of this plugin and the others being merged

  • page_addr (int | None)

  • changed_offsets (set[int] | None)

Returns:

True if the state plugins are actually merged.

Return type:

bool

concrete_load(addr, size, writing=False, with_bitmap=False, **kwargs)

Set SUPPORTS_CONCRETE_LOAD to True and implement concrete_load if reading concrete bytes is faster in this memory model.

Parameters:
  • addr – The address to load from.

  • size – Size of the memory read.

  • writing

Returns:

A memoryview into the loaded bytes.

changed_bytes(other, page_addr=None)
Return type:

set[int]

replace_all_with_offsets(offsets, old, new, memory=None)
Parameters:
class angr.storage.memory_mixins.UltraPagesMixin(page_size=4096, default_permissions=3, permissions_map=None, page_kwargs=None, **kwargs)

Bases: PagedMemoryMixin

PAGE_TYPE

alias of UltraPage

class angr.storage.memory_mixins.UnderconstrainedMixin(*args, **kwargs)

Bases: MemoryMixin

__init__(*args, **kwargs)
copy(memo: dict[int, Any] | None = None, **kwargs: Any) S_co

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:
  • memo (Optional[dict[int, Any]]) – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

  • kwargs (Any)

Return type:

TypeVar(S_co, covariant=True)

load(addr, size=None, **kwargs)
store(addr, data, size=None, **kwargs)
class angr.storage.memory_mixins.UnwrapperMixin(memory_id=None, endness='Iend_BE')

Bases: MemoryMixin

This mixin processes SimActionObjects by passing on their .ast field.

Parameters:
  • memory_id (str | None)

  • endness (str)

store(addr, data, size=None, *, condition=None, **kwargs)
load(addr, size=None, *, condition=None, fallback=None, **kwargs)
find(addr, data, max_search, *, default=None, **kwargs)
copy_contents(dst, src, size, condition=None, **kwargs)

Override this method to provide faster copying of large chunks of data.

Parameters:
  • dst – The destination of copying.

  • src – The source of copying.

  • size – The size of copying.

  • condition – The storing condition.

  • kwargs – Other parameters.

Returns:

None

class angr.storage.memory_mixins.name_resolution_mixin.NameResolutionMixin(memory_id=None, endness='Iend_BE')

Bases: MemoryMixin

This mixin allows you to provide register names as load addresses, and will automatically translate this to an offset and size.

Parameters:
  • memory_id (str | None)

  • endness (str)

store(addr, data, size=None, **kwargs)
load(addr, size=None, **kwargs)
class angr.storage.memory_mixins.smart_find_mixin.SmartFindMixin(memory_id=None, endness='Iend_BE')

Bases: MemoryMixin

Memory mixin providing basic searching over concrete and symbolic data.

Parameters:
  • memory_id (str | None)

  • endness (str)

find(addr, data, max_search, *, default=None, endness=None, chunk_size=None, max_symbolic_bytes=None, condition=None, char_size=1, **kwargs)
class angr.storage.memory_mixins.default_filler_mixin.DefaultFillerMixin(memory_id=None, endness='Iend_BE')

Bases: MemoryMixin

Parameters:
  • memory_id (str | None)

  • endness (str)

class angr.storage.memory_mixins.default_filler_mixin.SpecialFillerMixin(special_memory_filler=None, **kwargs)

Bases: MemoryMixin

__init__(special_memory_filler=None, **kwargs)
copy(memo)

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:

memo – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

class angr.storage.memory_mixins.default_filler_mixin.ExplicitFillerMixin(uninitialized_read_handler=None, **kwargs)

Bases: MemoryMixin

__init__(uninitialized_read_handler=None, **kwargs)
copy(memo)

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:

memo – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

class angr.storage.memory_mixins.bvv_conversion_mixin.DataNormalizationMixin(memory_id=None, endness='Iend_BE')

Bases: MemoryMixin

Normalizes the data field for a store and the fallback field for a load to be BVs.

Parameters:
  • memory_id (str | None)

  • endness (str)

store(addr, data, size=None, **kwargs)
load(addr, size=None, *, fallback=None, **kwargs)
class angr.storage.memory_mixins.hex_dumper_mixin.HexDumperMixin(memory_id=None, endness='Iend_BE')

Bases: MemoryMixin

Parameters:
  • memory_id (str | None)

  • endness (str)

hex_dump(start, size, word_size=4, words_per_row=4, endianness='Iend_BE', symbolic_char='?', unprintable_char='.', solve=False, extra_constraints=None, inspect=False, disable_actions=True)

Returns a hex dump as a string. The solver, if enabled, is called once for every byte potentially making this function very slow. It is meant to be used mainly as a “visualization” for debugging.

Warning: May read and display more bytes than size due to rounding. Particularly, if size is less than, or not a multiple of word_size*words_per_line.

Parameters:
  • start – starting address from which to print

  • size – number of bytes to display

  • word_size – number of bytes to group together as one space-delimited unit

  • words_per_row – number of words to display per row of output

  • endianness – endianness to use when displaying each word (ASCII representation is unchanged)

  • symbolic_char – the character to display when a byte is symbolic and has multiple solutions

  • unprintable_char – the character to display when a byte is not printable

  • solve – whether or not to attempt to solve (warning: can be very slow)

  • extra_constraints – extra constraints to pass to the solver is solve is True

  • inspect – whether or not to trigger SimInspect breakpoints for the memory load

  • disable_actions – whether or not to disable SimActions for the memory load

Returns:

hex dump as a string

class angr.storage.memory_mixins.underconstrained_mixin.UnderconstrainedMixin(*args, **kwargs)

Bases: MemoryMixin

__init__(*args, **kwargs)
copy(memo: dict[int, Any] | None = None, **kwargs: Any) S_co

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:
  • memo (Optional[dict[int, Any]]) – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

  • kwargs (Any)

Return type:

TypeVar(S_co, covariant=True)

load(addr, size=None, **kwargs)
store(addr, data, size=None, **kwargs)
class angr.storage.memory_mixins.simple_interface_mixin.SimpleInterfaceMixin(memory_id=None, endness='Iend_BE')

Bases: MemoryMixin

Parameters:
  • memory_id (str | None)

  • endness (str)

load(addr, size=None, *, endness=None, condition=None, fallback=None, **kwargs)
store(addr, data, size=None, *, endness=None, condition=None, **kwargs)
class angr.storage.memory_mixins.actions_mixin.ActionsMixinHigh(memory_id=None, endness='Iend_BE')

Bases: MemoryMixin

Parameters:
  • memory_id (str | None)

  • endness (str)

load(addr, size=None, *, condition=None, fallback=None, disable_actions=False, action=None, **kwargs)
store(addr, data, size=None, *, disable_actions=False, action=None, condition=None, **kwargs)
class angr.storage.memory_mixins.actions_mixin.ActionsMixinLow(memory_id=None, endness='Iend_BE')

Bases: MemoryMixin

Parameters:
  • memory_id (str | None)

  • endness (str)

load(addr, size=None, *, action=None, **kwargs)
store(addr, data, size=None, *, action=None, **kwargs)
Parameters:

action (SimActionData | None)

class angr.storage.memory_mixins.symbolic_merger_mixin.SymbolicMergerMixin(memory_id=None, endness='Iend_BE')

Bases: MemoryMixin

Parameters:
  • memory_id (str | None)

  • endness (str)

class angr.storage.memory_mixins.size_resolution_mixin.SizeNormalizationMixin(memory_id=None, endness='Iend_BE')

Bases: MemoryMixin

Provides basic services related to normalizing sizes. After this mixin, sizes will always be a plain int. Assumes that the data is a BV.

  • load will throw a TypeError if no size is provided

  • store will default to len(data)//byte_width if no size is provided

Parameters:
  • memory_id (str | None)

  • endness (str)

load(addr, size=None, **kwargs)
store(addr, data, size=None, **kwargs)
class angr.storage.memory_mixins.size_resolution_mixin.SizeConcretizationMixin(concretize_symbolic_write_size=False, max_concretize_count=256, max_symbolic_size=4194304, raise_memory_limit_error=False, size_limit=257, **kwargs)

Bases: MemoryMixin

This mixin allows memory to process symbolic sizes. It will not touch any sizes which are not ASTs with non-BVV ops. Assumes that the data is a BV.

  • symbolic load sizes will be concretized as their maximum and a warning will be logged

  • symbolic store sizes will be dispatched as several conditional stores with concrete sizes

Parameters:
  • concretize_symbolic_write_size (bool)

  • max_concretize_count (int | None)

  • max_symbolic_size (int)

  • raise_memory_limit_error (bool)

  • size_limit (int)

__init__(concretize_symbolic_write_size=False, max_concretize_count=256, max_symbolic_size=4194304, raise_memory_limit_error=False, size_limit=257, **kwargs)
Parameters:
  • concretize_symbolic_write_size (bool)

  • max_concretize_count (int | None)

  • max_symbolic_size (int)

  • raise_memory_limit_error (bool)

  • size_limit (int)

copy(memo)

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:

memo – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

load(addr, size=None, **kwargs)
store(addr, data, size=None, *, condition=None, **kwargs)
class angr.storage.memory_mixins.dirty_addrs_mixin.DirtyAddrsMixin(memory_id=None, endness='Iend_BE')

Bases: MemoryMixin

Parameters:
  • memory_id (str | None)

  • endness (str)

store(addr, data, size=None, **kwargs)
class angr.storage.memory_mixins.address_concretization_mixin.MultiwriteAnnotation

Bases: Annotation

property eliminatable

Returns whether this annotation can be eliminated in a simplification.

Returns:

True if eliminatable, False otherwise

property relocateable
class angr.storage.memory_mixins.address_concretization_mixin.AddressConcretizationMixin(read_strategies=None, write_strategies=None, **kwargs)

Bases: MemoryMixin

The address concretization mixin allows symbolic reads and writes to be handled sanely by dispatching them as a number of conditional concrete reads/writes. It provides a “concretization strategies” interface allowing the process of serializing symbolic addresses into concrete ones to be specified.

__init__(read_strategies=None, write_strategies=None, **kwargs)
set_state(state)

Sets a new state (for example, if the state has been branched)

copy(memo: dict[int, Any] | None = None, **kwargs: Any) S_co

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:
  • memo (Optional[dict[int, Any]]) – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

  • kwargs (Any)

Return type:

TypeVar(S_co, covariant=True)

merge(others, merge_conditions, common_ancestor=None)

Should merge the state plugin with the provided others. This will be called by state.merge() after copying the target state, so this should mutate the current instance to merge with the others.

Note that when multiple instances of a single plugin object (for example, a file) are referenced in the state, it is important that merge only ever be called once. This should be solved by designating one of the plugin’s referees as the “real owner”, who should be the one to actually merge it. This technique doesn’t work to resolve the similar issue that arises during copying because merging doesn’t produce a new reference to insert.

There will be n others and n+1 merge conditions, since the first condition corresponds to self. To match elements up to conditions, say zip([self] + others, merge_conditions)

When implementing this, make sure that you “deepen” both others and common_ancestor before calling sub-elements’ merge methods, e.g.

self.foo.merge(
    [o.foo for o in others],
    merge_conditions,
    common_ancestor=common_ancestor.foo if common_ancestor is not None else None
)

During static analysis, merge_conditions can be None, in which case you should use state.solver.union(values). TODO: fish please make this less bullshit

There is a utility claripy.ite_cases which will help with constructing arbitrarily large merged ASTs. Use it like self.bar = claripy.ite_cases(zip(conditions[1:], [o.bar for o in others]), self.bar)

Parameters:
  • others – the other state plugins to merge with

  • merge_conditions – a symbolic condition for each of the plugins

  • common_ancestor – a common ancestor of this plugin and the others being merged

Returns:

True if the state plugins are actually merged.

Return type:

bool

concretize_write_addr(addr, strategies=None, condition=None)

Concretizes an address meant for writing.

Parameters:
  • addr – An expression for the address.

  • strategies – A list of concretization strategies (to override the default).

  • condition – Any extra constraints that should be observed when determining address satisfiability

Returns:

A list of concrete addresses.

concretize_read_addr(addr, strategies=None, condition=None)

Concretizes an address meant for reading.

Parameters:
  • addr – An expression for the address.

  • strategies – A list of concretization strategies (to override the default).

Returns:

A list of concrete addresses.

load(addr, size=None, *, condition=None, **kwargs)
store(addr, data, size=None, *, condition=None, **kwargs)
permissions(addr, permissions=None, **kwargs)
map_region(addr, length, permissions, **kwargs)
unmap_region(addr, length, **kwargs)
concrete_load(addr, size, writing=False, **kwargs)

Set SUPPORTS_CONCRETE_LOAD to True and implement concrete_load if reading concrete bytes is faster in this memory model.

Parameters:
  • addr – The address to load from.

  • size – Size of the memory read.

  • writing

Returns:

A memoryview into the loaded bytes.

class angr.storage.memory_mixins.clouseau_mixin.InspectMixinHigh(memory_id=None, endness='Iend_BE')

Bases: MemoryMixin

Parameters:
  • memory_id (str | None)

  • endness (str)

store(addr, data, size=None, *, condition=None, endness=None, inspect=True, **kwargs)
load(addr, size=None, *, condition=None, endness=None, inspect=True, **kwargs)
class angr.storage.memory_mixins.conditional_store_mixin.ConditionalMixin(memory_id=None, endness='Iend_BE')

Bases: MemoryMixin

Parameters:
  • memory_id (str | None)

  • endness (str)

load(addr, size=None, *, condition=None, fallback=None, **kwargs)
store(addr, data, size=None, *, condition=None, **kwargs)
class angr.storage.memory_mixins.label_merger_mixin.LabelMergerMixin(*args, **kwargs)

Bases: MemoryMixin

A memory mixin for merging labels. Labels come from SimLabeledMemoryObject.

__init__(*args, **kwargs)
copy(memo=None)

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:

memo – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

class angr.storage.memory_mixins.simplification_mixin.SimplificationMixin(memory_id=None, endness='Iend_BE')

Bases: MemoryMixin

Parameters:
  • memory_id (str | None)

  • endness (str)

store(addr, data, size=None, **kwargs)
class angr.storage.memory_mixins.unwrapper_mixin.UnwrapperMixin(memory_id=None, endness='Iend_BE')

Bases: MemoryMixin

This mixin processes SimActionObjects by passing on their .ast field.

Parameters:
  • memory_id (str | None)

  • endness (str)

store(addr, data, size=None, *, condition=None, **kwargs)
load(addr, size=None, *, condition=None, fallback=None, **kwargs)
find(addr, data, max_search, *, default=None, **kwargs)
copy_contents(dst, src, size, condition=None, **kwargs)

Override this method to provide faster copying of large chunks of data.

Parameters:
  • dst – The destination of copying.

  • src – The source of copying.

  • size – The size of copying.

  • condition – The storing condition.

  • kwargs – Other parameters.

Returns:

None

class angr.storage.memory_mixins.convenient_mappings_mixin.ConvenientMappingsMixin(**kwargs)

Bases: MemoryMixin

Implements mappings between names and hashes of symbolic variables and these variables themselves.

__init__(**kwargs)
copy(memo)

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:

memo – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

store(addr, data, size=None, **kwargs)
get_symbolic_addrs()
addrs_for_name(n)

Returns addresses that contain expressions that contain a variable named n.

addrs_for_hash(h)

Returns addresses that contain expressions that contain a variable with the hash of h.

replace_all(old, new)

Replaces all instances of expression old with expression new.

Parameters:
  • old (BV) – A claripy expression. Must contain at least one named variable (to make it possible to use the name index for speedup).

  • new (BV) – The new variable to replace it with.

class angr.storage.memory_mixins.paged_memory.pages.mv_list_page.MVListPage(memory=None, content=None, sinkhole=None, mo_cmp=None, **kwargs)

Bases: MemoryObjectSetMixin, PageBase

MVListPage allows storing multiple values at the same location.

Each store() may take a value or multiple values. Each load() returns an iterator of all values stored at that location.

__init__(memory=None, content=None, sinkhole=None, mo_cmp=None, **kwargs)
copy(memo)

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:

memo – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

Return type:

MVListPage

load(addr, size=None, endness=None, page_addr=None, memory=None, cooperate=False, **kwargs)
Return type:

list[tuple[int, SimMemoryObject | SimLabeledMemoryObject]]

store(addr, data, size=None, endness=None, memory=None, cooperate=False, **kwargs)
erase(addr, size=None, **kwargs)

Set [addr:addr+size) to uninitialized. In many cases this will be faster than overwriting those locations with new values. This is commonly used during static data flow analysis.

Parameters:
  • addr – The address to start erasing.

  • size – The number of bytes for erasing.

Return type:

None

Returns:

None

merge(others, merge_conditions, common_ancestor=None, *, page_addr, memory, changed_offsets=None)

Should merge the state plugin with the provided others. This will be called by state.merge() after copying the target state, so this should mutate the current instance to merge with the others.

Note that when multiple instances of a single plugin object (for example, a file) are referenced in the state, it is important that merge only ever be called once. This should be solved by designating one of the plugin’s referees as the “real owner”, who should be the one to actually merge it. This technique doesn’t work to resolve the similar issue that arises during copying because merging doesn’t produce a new reference to insert.

There will be n others and n+1 merge conditions, since the first condition corresponds to self. To match elements up to conditions, say zip([self] + others, merge_conditions)

When implementing this, make sure that you “deepen” both others and common_ancestor before calling sub-elements’ merge methods, e.g.

self.foo.merge(
    [o.foo for o in others],
    merge_conditions,
    common_ancestor=common_ancestor.foo if common_ancestor is not None else None
)

During static analysis, merge_conditions can be None, in which case you should use state.solver.union(values). TODO: fish please make this less bullshit

There is a utility claripy.ite_cases which will help with constructing arbitrarily large merged ASTs. Use it like self.bar = claripy.ite_cases(zip(conditions[1:], [o.bar for o in others]), self.bar)

Parameters:
  • others (list[MVListPage]) – the other state plugins to merge with

  • merge_conditions – a symbolic condition for each of the plugins

  • common_ancestor – a common ancestor of this plugin and the others being merged

  • page_addr (int)

  • memory (MemoryMixin)

  • changed_offsets (set[int] | None)

Returns:

True if the state plugins are actually merged.

Return type:

bool

compare(other, page_addr=None, memory=None, changed_offsets=None)
Return type:

bool

Parameters:
changed_bytes(other, page_addr=None)
Parameters:
content_gen(index)
class angr.storage.memory_mixins.paged_memory.pages.multi_values.MultiValues(v=None, offset_to_values=None)

Bases: Generic[MVType]

Represents a byte vector where each byte can have one or multiple values.

As an implementation optimization (so that we do not create excessive sets and dicts), self._single_value stores a claripy AST when this MultiValues object represents only one value at offset 0.

Parameters:
__init__(v=None, offset_to_values=None)
Parameters:
add_value(offset, value)
Return type:

None

Parameters:
  • offset (int)

  • value (MVType)

one_value(strip_annotations=False)
Return type:

Optional[TypeVar(MVType, bound= BV | FP)]

Parameters:

strip_annotations (bool)

merge(mv)
Return type:

MultiValues[TypeVar(MVType, bound= BV | FP)]

Parameters:

mv (MultiValues[MVType])

keys()
Return type:

set[int]

values()
Return type:

Iterator[set[TypeVar(MVType, bound= BV | FP)]]

items()
Return type:

Iterator[tuple[int, set[TypeVar(MVType, bound= BV | FP)]]]

count()
Return type:

int

extract(offset, length, endness)
Return type:

MultiValues[BV]

Parameters:
concat(other)
Return type:

MultiValues[BV]

Parameters:
angr.storage.memory_mixins.paged_memory.pages.multi_values.mv_is_bv(mv)
Return type:

TypeGuard[MultiValues[BV]]

Parameters:

mv (MultiValues[Any])

angr.storage.memory_mixins.paged_memory.pages.multi_values.mv_is_fp(mv)
Return type:

TypeGuard[MultiValues[FP]]

Parameters:

mv (MultiValues[Any])

class angr.storage.memory_mixins.top_merger_mixin.TopMergerMixin(*args, top_func=None, **kwargs)

Bases: MemoryMixin

A memory mixin for merging values in memory to TOP.

__init__(*args, top_func=None, **kwargs)
copy(memo=None)

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:

memo – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

class angr.storage.memory_mixins.multi_value_merger_mixin.MultiValueMergerMixin(*args, element_limit=5, annotation_limit=256, top_func=None, is_top_func=None, phi_maker=None, merge_into_top=True, **kwargs)

Bases: MemoryMixin

__init__(*args, element_limit=5, annotation_limit=256, top_func=None, is_top_func=None, phi_maker=None, merge_into_top=True, **kwargs)
copy(memo=None)

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:

memo – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

class angr.storage.memory_mixins.paged_memory.paged_memory_mixin.PagedMemoryMixin(page_size=4096, default_permissions=3, permissions_map=None, page_kwargs=None, **kwargs)

Bases: Generic[PageType], MemoryMixin[int | BV | SimActionObject, BV, int | BV | SimActionObject]

A bottom-level storage mechanism. Dispatches reads to individual pages, the type of which is the PAGE_TYPE class variable.

SUPPORTS_CONCRETE_LOAD: bool = True
PAGE_TYPE: type[PageType]
__init__(page_size=4096, default_permissions=3, permissions_map=None, page_kwargs=None, **kwargs)
copy(memo: dict[int, Any] | None = None, **kwargs: Any) S_co

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:
  • memo (Optional[dict[int, Any]]) – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

  • kwargs (Any)

Return type:

TypeVar(S_co, covariant=True)

load(addr, size=None, *, endness=None, **kwargs)
Parameters:
  • addr (int)

  • size (int | None)

store(addr, data, size=None, *, endness=None, **kwargs)
Parameters:
  • addr (int)

  • size (int | None)

erase(addr, size=None, **kwargs)

Set [addr:addr+size) to uninitialized. In many cases this will be faster than overwriting those locations with new values. This is commonly used during static data flow analysis.

Parameters:
  • addr – The address to start erasing.

  • size – The number of bytes for erasing.

Return type:

None

Returns:

None

merge(others, merge_conditions, common_ancestor=None)

Should merge the state plugin with the provided others. This will be called by state.merge() after copying the target state, so this should mutate the current instance to merge with the others.

Note that when multiple instances of a single plugin object (for example, a file) are referenced in the state, it is important that merge only ever be called once. This should be solved by designating one of the plugin’s referees as the “real owner”, who should be the one to actually merge it. This technique doesn’t work to resolve the similar issue that arises during copying because merging doesn’t produce a new reference to insert.

There will be n others and n+1 merge conditions, since the first condition corresponds to self. To match elements up to conditions, say zip([self] + others, merge_conditions)

When implementing this, make sure that you “deepen” both others and common_ancestor before calling sub-elements’ merge methods, e.g.

self.foo.merge(
    [o.foo for o in others],
    merge_conditions,
    common_ancestor=common_ancestor.foo if common_ancestor is not None else None
)

During static analysis, merge_conditions can be None, in which case you should use state.solver.union(values). TODO: fish please make this less bullshit

There is a utility claripy.ite_cases which will help with constructing arbitrarily large merged ASTs. Use it like self.bar = claripy.ite_cases(zip(conditions[1:], [o.bar for o in others]), self.bar)

Parameters:
  • others – the other state plugins to merge with

  • merge_conditions – a symbolic condition for each of the plugins

  • common_ancestor – a common ancestor of this plugin and the others being merged

Returns:

True if the state plugins are actually merged.

Return type:

bool

compare(other)
Return type:

bool

Parameters:

other (PagedMemoryMixin)

permissions(addr, permissions=None, **kwargs)
map_region(addr, length, permissions, *, init_zero=False, **kwargs)
unmap_region(addr, length, **kwargs)
concrete_load(addr, size, writing=False, *, with_bitmap=False, **kwargs)

Set SUPPORTS_CONCRETE_LOAD to True and implement concrete_load if reading concrete bytes is faster in this memory model.

Parameters:
  • addr – The address to load from.

  • size – Size of the memory read.

  • writing

  • with_bitmap (bool)

Returns:

A memoryview into the loaded bytes.

changed_bytes(other)
Return type:

set[int]

changed_pages(other)
Return type:

dict[int, set[int] | None]

copy_contents(dst, src, size, condition=None, **kwargs)

Override this method to provide faster copying of large chunks of data.

Parameters:
  • dst – The destination of copying.

  • src – The source of copying.

  • size – The size of copying.

  • condition – The storing condition.

  • kwargs – Other parameters.

Returns:

None

flush_pages(white_list)

Flush all pages not included in the white_list by removing their pages. Note, this will not wipe them from memory if they were backed by a memory_backer, it will simply reset them to their initial state. Returns the list of pages that were cleared consisting of (addr, length) tuples. :type white_list: :param white_list: white list of regions in the form of (start, end) to exclude from the flush :return: a list of memory page ranges that were flushed :rtype: list

state: angr.SimState
class angr.storage.memory_mixins.paged_memory.paged_memory_mixin.LabeledPagesMixin(page_size=4096, default_permissions=3, permissions_map=None, page_kwargs=None, **kwargs)

Bases: PagedMemoryMixin

load_with_labels(addr, size=None, endness=None, **kwargs)
Return type:

tuple[Base, tuple[tuple[int, int, int, Any]]]

Parameters:
  • addr (int)

  • size (int | None)

class angr.storage.memory_mixins.paged_memory.paged_memory_mixin.ListPagesMixin(page_size=4096, default_permissions=3, permissions_map=None, page_kwargs=None, **kwargs)

Bases: PagedMemoryMixin

PAGE_TYPE

alias of ListPage

class angr.storage.memory_mixins.paged_memory.paged_memory_mixin.MVListPagesMixin(*args, skip_missing_values_during_merging=False, **kwargs)

Bases: PagedMemoryMixin

PAGE_TYPE

alias of MVListPage

__init__(*args, skip_missing_values_during_merging=False, **kwargs)
copy(memo: dict[int, Any] | None = None, **kwargs: Any) S_co

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:
  • memo (Optional[dict[int, Any]]) – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

  • kwargs (Any)

Return type:

TypeVar(S_co, covariant=True)

class angr.storage.memory_mixins.paged_memory.paged_memory_mixin.ListPagesWithLabelsMixin(page_size=4096, default_permissions=3, permissions_map=None, page_kwargs=None, **kwargs)

Bases: LabeledPagesMixin, ListPagesMixin

class angr.storage.memory_mixins.paged_memory.paged_memory_mixin.MVListPagesWithLabelsMixin(*args, skip_missing_values_during_merging=False, **kwargs)

Bases: LabeledPagesMixin, MVListPagesMixin

class angr.storage.memory_mixins.paged_memory.paged_memory_mixin.UltraPagesMixin(page_size=4096, default_permissions=3, permissions_map=None, page_kwargs=None, **kwargs)

Bases: PagedMemoryMixin

PAGE_TYPE

alias of UltraPage

class angr.storage.memory_mixins.paged_memory.page_backer_mixins.NotMemoryview(obj, offset, size)

Bases: object

__init__(obj, offset, size)
class angr.storage.memory_mixins.paged_memory.page_backer_mixins.ClemoryBackerMixin(cle_memory_backer=None, **kwargs)

Bases: PagedMemoryMixin

Parameters:

cle_memory_backer (None | cle.Loader | cle.Clemory)

__init__(cle_memory_backer=None, **kwargs)
Parameters:

cle_memory_backer (None | Loader | Clemory)

copy(memo)

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:

memo – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

class angr.storage.memory_mixins.paged_memory.page_backer_mixins.ConcreteBackerMixin(cle_memory_backer=None, **kwargs)

Bases: ClemoryBackerMixin

Parameters:

cle_memory_backer (None | cle.Loader | cle.Clemory)

class angr.storage.memory_mixins.paged_memory.page_backer_mixins.DictBackerMixin(dict_memory_backer=None, **kwargs)

Bases: PagedMemoryMixin

__init__(dict_memory_backer=None, **kwargs)
copy(memo)

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:

memo – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

class angr.storage.memory_mixins.paged_memory.stack_allocation_mixin.StackAllocationMixin(stack_end=None, stack_size=None, stack_perms=None, **kwargs)

Bases: PagedMemoryMixin

This mixin adds automatic allocation for a stack region based on the stack_end and stack_size parameters.

__init__(stack_end=None, stack_size=None, stack_perms=None, **kwargs)
copy(memo)

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:

memo – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

allocate_stack_pages(addr, size, **kwargs)

Pre-allocates pages for the stack without triggering any logic related to reading from them.

Parameters:
  • addr (int) – The highest address that should be mapped

  • size (int) – The number of bytes to be allocated. byte 1 is the one at addr, byte 2 is the one before that, and so on.

Returns:

A list of the new page objects

class angr.storage.memory_mixins.paged_memory.privileged_mixin.PrivilegedPagingMixin(page_size=4096, default_permissions=3, permissions_map=None, page_kwargs=None, **kwargs)

Bases: PagedMemoryMixin

A mixin for paged memory models which will raise SimSegfaultExceptions if STRICT_PAGE_ACCESS is enabled and a segfault condition is detected.

Segfault conditions include: - getting a page for reading which is non-readable - getting a page for writing which is non-writable - creating a page

The latter condition means that this should be inserted under any mixins which provide other implementations of _initialize_page.

class angr.storage.memory_mixins.paged_memory.pages.CooperationBase

Bases: Generic[T]

Any given subclass of this class which is not a subclass of MemoryMixin should have the property that any subclass it which is a subclass of MemoryMixin should all work with the same datatypes

class angr.storage.memory_mixins.paged_memory.pages.HistoryTrackingMixin(*args, **kwargs)

Bases: RefcountMixin, MemoryMixin

Tracks the history of memory writes.

__init__(*args, **kwargs)
store(addr, data, size=None, **kwargs)
copy(memo)

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:

memo – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

acquire_unique()

Call this function to return a version of this page which can be used for writing, which may or may not be the same object as before. If you use this you must immediately replace the shared reference you previously had with the new unique copy.

parents()
changed_bytes(other, **kwargs)
Return type:

set[int] | None

all_bytes_changed_in_history()
Return type:

SegmentList

class angr.storage.memory_mixins.paged_memory.pages.ISPOMixin(memory_id=None, endness='Iend_BE')

Bases: MemoryMixin

An implementation of the International Stateless Persons Organisation, a mixin which should be applied as a bottom layer for memories which have no state and must redirect certain operations to a parent memory. Main usecase is for memory region classes which are stored within other memories, such as pages.

Parameters:
  • memory_id (str | None)

  • endness (str)

set_state(state)

Sets a new state (for example, if the state has been branched)

class angr.storage.memory_mixins.paged_memory.pages.ListPage(memory=None, content=None, sinkhole=None, mo_cmp=None, **kwargs)

Bases: MemoryObjectMixin, PageBase

This class implements a page memory mixin with lists as the main content store.

__init__(memory=None, content=None, sinkhole=None, mo_cmp=None, **kwargs)
copy(memo)

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:

memo – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

load(addr, size=None, endness=None, page_addr=None, memory=None, cooperate=False, **kwargs)
store(addr, data, size=None, endness=None, memory=None, cooperate=False, **kwargs)
erase(addr, size=None, **kwargs)

Set [addr:addr+size) to uninitialized. In many cases this will be faster than overwriting those locations with new values. This is commonly used during static data flow analysis.

Parameters:
  • addr – The address to start erasing.

  • size – The number of bytes for erasing.

Return type:

None

Returns:

None

merge(others, merge_conditions, common_ancestor=None, page_addr=None, memory=None, changed_offsets=None)

Should merge the state plugin with the provided others. This will be called by state.merge() after copying the target state, so this should mutate the current instance to merge with the others.

Note that when multiple instances of a single plugin object (for example, a file) are referenced in the state, it is important that merge only ever be called once. This should be solved by designating one of the plugin’s referees as the “real owner”, who should be the one to actually merge it. This technique doesn’t work to resolve the similar issue that arises during copying because merging doesn’t produce a new reference to insert.

There will be n others and n+1 merge conditions, since the first condition corresponds to self. To match elements up to conditions, say zip([self] + others, merge_conditions)

When implementing this, make sure that you “deepen” both others and common_ancestor before calling sub-elements’ merge methods, e.g.

self.foo.merge(
    [o.foo for o in others],
    merge_conditions,
    common_ancestor=common_ancestor.foo if common_ancestor is not None else None
)

During static analysis, merge_conditions can be None, in which case you should use state.solver.union(values). TODO: fish please make this less bullshit

There is a utility claripy.ite_cases which will help with constructing arbitrarily large merged ASTs. Use it like self.bar = claripy.ite_cases(zip(conditions[1:], [o.bar for o in others]), self.bar)

Parameters:
  • others (list[ListPage]) – the other state plugins to merge with

  • merge_conditions – a symbolic condition for each of the plugins

  • common_ancestor – a common ancestor of this plugin and the others being merged

  • page_addr (int | None)

  • changed_offsets (set[int] | None)

Returns:

True if the state plugins are actually merged.

Return type:

bool

changed_bytes(other, page_addr=None)
Parameters:
class angr.storage.memory_mixins.paged_memory.pages.MVListPage(memory=None, content=None, sinkhole=None, mo_cmp=None, **kwargs)

Bases: MemoryObjectSetMixin, PageBase

MVListPage allows storing multiple values at the same location.

Each store() may take a value or multiple values. Each load() returns an iterator of all values stored at that location.

__init__(memory=None, content=None, sinkhole=None, mo_cmp=None, **kwargs)
copy(memo)

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:

memo – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

Return type:

MVListPage

load(addr, size=None, endness=None, page_addr=None, memory=None, cooperate=False, **kwargs)
Return type:

list[tuple[int, SimMemoryObject | SimLabeledMemoryObject]]

store(addr, data, size=None, endness=None, memory=None, cooperate=False, **kwargs)
erase(addr, size=None, **kwargs)

Set [addr:addr+size) to uninitialized. In many cases this will be faster than overwriting those locations with new values. This is commonly used during static data flow analysis.

Parameters:
  • addr – The address to start erasing.

  • size – The number of bytes for erasing.

Return type:

None

Returns:

None

merge(others, merge_conditions, common_ancestor=None, *, page_addr, memory, changed_offsets=None)

Should merge the state plugin with the provided others. This will be called by state.merge() after copying the target state, so this should mutate the current instance to merge with the others.

Note that when multiple instances of a single plugin object (for example, a file) are referenced in the state, it is important that merge only ever be called once. This should be solved by designating one of the plugin’s referees as the “real owner”, who should be the one to actually merge it. This technique doesn’t work to resolve the similar issue that arises during copying because merging doesn’t produce a new reference to insert.

There will be n others and n+1 merge conditions, since the first condition corresponds to self. To match elements up to conditions, say zip([self] + others, merge_conditions)

When implementing this, make sure that you “deepen” both others and common_ancestor before calling sub-elements’ merge methods, e.g.

self.foo.merge(
    [o.foo for o in others],
    merge_conditions,
    common_ancestor=common_ancestor.foo if common_ancestor is not None else None
)

During static analysis, merge_conditions can be None, in which case you should use state.solver.union(values). TODO: fish please make this less bullshit

There is a utility claripy.ite_cases which will help with constructing arbitrarily large merged ASTs. Use it like self.bar = claripy.ite_cases(zip(conditions[1:], [o.bar for o in others]), self.bar)

Parameters:
  • others (list[MVListPage]) – the other state plugins to merge with

  • merge_conditions – a symbolic condition for each of the plugins

  • common_ancestor – a common ancestor of this plugin and the others being merged

  • page_addr (int)

  • memory (MemoryMixin)

  • changed_offsets (set[int] | None)

Returns:

True if the state plugins are actually merged.

Return type:

bool

compare(other, page_addr=None, memory=None, changed_offsets=None)
Return type:

bool

Parameters:
changed_bytes(other, page_addr=None)
Parameters:
content_gen(index)
class angr.storage.memory_mixins.paged_memory.pages.MemoryObjectMixin

Bases: CooperationBase[SimMemoryObject]

Uses SimMemoryObjects in region storage. With this, load will return a list of tuple (address, MO) and store will take a MO.

class angr.storage.memory_mixins.paged_memory.pages.PageBase(*args, **kwargs)

Bases: HistoryTrackingMixin, RefcountMixin, CooperationBase, ISPOMixin, PermissionsMixin, MemoryMixin

This is a fairly succinct definition of the contract between PagedMemoryMixin and its constituent pages:

  • Pages must implement the MemoryMixin model for loads, stores, copying, merging, etc

  • However, loading/storing may not necessarily use the same data domain as PagedMemoryMixin. In order to do more efficient loads/stores across pages, we use the CooperationBase interface which allows the page class to determine how to generate and unwrap the objects which are actually stored.

  • To support COW, we use the RefcountMixin and the ISPOMixin (which adds the contract element that memory=self be passed to every method call)

  • Pages have permissions associated with them, stored in the PermissionsMixin.

Read the docstrings for each of the constituent classes to understand the nuances of their functionalities

class angr.storage.memory_mixins.paged_memory.pages.PermissionsMixin(permissions=None, **kwargs)

Bases: MemoryMixin

This mixin adds a permissions_bits field and properties for extracting the read/write/exec permissions. It does NOT add permissions checking.

Parameters:

permissions (int | claripy.ast.BV | None)

__init__(permissions=None, **kwargs)
Parameters:

permissions (int | BV | None)

copy(memo)

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:

memo – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

property perm_read
property perm_write
property perm_exec
class angr.storage.memory_mixins.paged_memory.pages.RefcountMixin(**kwargs)

Bases: MemoryMixin

This mixin adds a locked reference counter and methods to manipulate it, to facilitate copy-on-write optimizations.

__init__(**kwargs)
copy(memo)

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:

memo – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

acquire_unique()

Call this function to return a version of this page which can be used for writing, which may or may not be the same object as before. If you use this you must immediately replace the shared reference you previously had with the new unique copy.

acquire_shared()

Call this function to indicate that this page has had a reference added to it and must be copied before it can be acquired uniquely again. Creating the object implicitly starts it with one shared reference.

Return type:

None

release_shared()

Call this function to indicate that this page has had a shared reference to it released

Return type:

None

class angr.storage.memory_mixins.paged_memory.pages.UltraPage(memory=None, init_zero=False, **kwargs)

Bases: MemoryObjectMixin, PageBase

Default page implementation

SUPPORTS_CONCRETE_LOAD: bool = True
__init__(memory=None, init_zero=False, **kwargs)
classmethod new_from_shared(data, memory=None, **kwargs)
copy(memo)

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:

memo – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

load(addr, size=None, page_addr=None, endness=None, memory=None, cooperate=False, **kwargs)
store(addr, data, size=None, endness=None, memory=None, page_addr=None, cooperate=False, **kwargs)
Parameters:
merge(others, merge_conditions, common_ancestor=None, page_addr=None, memory=None, changed_offsets=None)

Should merge the state plugin with the provided others. This will be called by state.merge() after copying the target state, so this should mutate the current instance to merge with the others.

Note that when multiple instances of a single plugin object (for example, a file) are referenced in the state, it is important that merge only ever be called once. This should be solved by designating one of the plugin’s referees as the “real owner”, who should be the one to actually merge it. This technique doesn’t work to resolve the similar issue that arises during copying because merging doesn’t produce a new reference to insert.

There will be n others and n+1 merge conditions, since the first condition corresponds to self. To match elements up to conditions, say zip([self] + others, merge_conditions)

When implementing this, make sure that you “deepen” both others and common_ancestor before calling sub-elements’ merge methods, e.g.

self.foo.merge(
    [o.foo for o in others],
    merge_conditions,
    common_ancestor=common_ancestor.foo if common_ancestor is not None else None
)

During static analysis, merge_conditions can be None, in which case you should use state.solver.union(values). TODO: fish please make this less bullshit

There is a utility claripy.ite_cases which will help with constructing arbitrarily large merged ASTs. Use it like self.bar = claripy.ite_cases(zip(conditions[1:], [o.bar for o in others]), self.bar)

Parameters:
  • others (list[UltraPage]) – the other state plugins to merge with

  • merge_conditions – a symbolic condition for each of the plugins

  • common_ancestor – a common ancestor of this plugin and the others being merged

  • page_addr (int | None)

  • changed_offsets (set[int] | None)

Returns:

True if the state plugins are actually merged.

Return type:

bool

concrete_load(addr, size, writing=False, with_bitmap=False, **kwargs)

Set SUPPORTS_CONCRETE_LOAD to True and implement concrete_load if reading concrete bytes is faster in this memory model.

Parameters:
  • addr – The address to load from.

  • size – Size of the memory read.

  • writing

Returns:

A memoryview into the loaded bytes.

changed_bytes(other, page_addr=None)
Return type:

set[int]

state: angr.SimState
replace_all_with_offsets(offsets, old, new, memory=None)
Parameters:
class angr.storage.memory_mixins.paged_memory.pages.refcount_mixin.RefcountMixin(**kwargs)

Bases: MemoryMixin

This mixin adds a locked reference counter and methods to manipulate it, to facilitate copy-on-write optimizations.

__init__(**kwargs)
copy(memo)

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:

memo – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

acquire_unique()

Call this function to return a version of this page which can be used for writing, which may or may not be the same object as before. If you use this you must immediately replace the shared reference you previously had with the new unique copy.

acquire_shared()

Call this function to indicate that this page has had a reference added to it and must be copied before it can be acquired uniquely again. Creating the object implicitly starts it with one shared reference.

Return type:

None

release_shared()

Call this function to indicate that this page has had a shared reference to it released

Return type:

None

class angr.storage.memory_mixins.paged_memory.pages.permissions_mixin.PermissionsMixin(permissions=None, **kwargs)

Bases: MemoryMixin

This mixin adds a permissions_bits field and properties for extracting the read/write/exec permissions. It does NOT add permissions checking.

Parameters:

permissions (int | claripy.ast.BV | None)

__init__(permissions=None, **kwargs)
Parameters:

permissions (int | BV | None)

copy(memo)

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:

memo – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

property perm_read
property perm_write
property perm_exec
class angr.storage.memory_mixins.paged_memory.pages.history_tracking_mixin.HistoryTrackingMixin(*args, **kwargs)

Bases: RefcountMixin, MemoryMixin

Tracks the history of memory writes.

__init__(*args, **kwargs)
store(addr, data, size=None, **kwargs)
copy(memo)

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:

memo – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

acquire_unique()

Call this function to return a version of this page which can be used for writing, which may or may not be the same object as before. If you use this you must immediately replace the shared reference you previously had with the new unique copy.

parents()
changed_bytes(other, **kwargs)
Return type:

set[int] | None

all_bytes_changed_in_history()
Return type:

SegmentList

class angr.storage.memory_mixins.paged_memory.pages.ispo_mixin.ISPOMixin(memory_id=None, endness='Iend_BE')

Bases: MemoryMixin

An implementation of the International Stateless Persons Organisation, a mixin which should be applied as a bottom layer for memories which have no state and must redirect certain operations to a parent memory. Main usecase is for memory region classes which are stored within other memories, such as pages.

Parameters:
  • memory_id (str | None)

  • endness (str)

set_state(state)

Sets a new state (for example, if the state has been branched)

class angr.storage.memory_mixins.paged_memory.pages.cooperation.CooperationBase

Bases: Generic[T]

Any given subclass of this class which is not a subclass of MemoryMixin should have the property that any subclass it which is a subclass of MemoryMixin should all work with the same datatypes

class angr.storage.memory_mixins.paged_memory.pages.cooperation.MemoryObjectMixin

Bases: CooperationBase[SimMemoryObject]

Uses SimMemoryObjects in region storage. With this, load will return a list of tuple (address, MO) and store will take a MO.

class angr.storage.memory_mixins.paged_memory.pages.cooperation.MemoryObjectSetMixin

Bases: CooperationBase

Uses sets of SimMemoryObjects in region storage.

class angr.storage.memory_mixins.paged_memory.pages.cooperation.BasicClaripyCooperation

Bases: CooperationBase

Mix this (along with PageBase) into a storage class which supports loading and storing claripy bitvectors and it will be able to work as a page in the paged memory model.

class angr.storage.memory_mixins.paged_memory.pages.list_page.ListPage(memory=None, content=None, sinkhole=None, mo_cmp=None, **kwargs)

Bases: MemoryObjectMixin, PageBase

This class implements a page memory mixin with lists as the main content store.

__init__(memory=None, content=None, sinkhole=None, mo_cmp=None, **kwargs)
copy(memo)

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:

memo – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

load(addr, size=None, endness=None, page_addr=None, memory=None, cooperate=False, **kwargs)
store(addr, data, size=None, endness=None, memory=None, cooperate=False, **kwargs)
erase(addr, size=None, **kwargs)

Set [addr:addr+size) to uninitialized. In many cases this will be faster than overwriting those locations with new values. This is commonly used during static data flow analysis.

Parameters:
  • addr – The address to start erasing.

  • size – The number of bytes for erasing.

Return type:

None

Returns:

None

merge(others, merge_conditions, common_ancestor=None, page_addr=None, memory=None, changed_offsets=None)

Should merge the state plugin with the provided others. This will be called by state.merge() after copying the target state, so this should mutate the current instance to merge with the others.

Note that when multiple instances of a single plugin object (for example, a file) are referenced in the state, it is important that merge only ever be called once. This should be solved by designating one of the plugin’s referees as the “real owner”, who should be the one to actually merge it. This technique doesn’t work to resolve the similar issue that arises during copying because merging doesn’t produce a new reference to insert.

There will be n others and n+1 merge conditions, since the first condition corresponds to self. To match elements up to conditions, say zip([self] + others, merge_conditions)

When implementing this, make sure that you “deepen” both others and common_ancestor before calling sub-elements’ merge methods, e.g.

self.foo.merge(
    [o.foo for o in others],
    merge_conditions,
    common_ancestor=common_ancestor.foo if common_ancestor is not None else None
)

During static analysis, merge_conditions can be None, in which case you should use state.solver.union(values). TODO: fish please make this less bullshit

There is a utility claripy.ite_cases which will help with constructing arbitrarily large merged ASTs. Use it like self.bar = claripy.ite_cases(zip(conditions[1:], [o.bar for o in others]), self.bar)

Parameters:
  • others (list[ListPage]) – the other state plugins to merge with

  • merge_conditions – a symbolic condition for each of the plugins

  • common_ancestor – a common ancestor of this plugin and the others being merged

  • page_addr (int | None)

  • changed_offsets (set[int] | None)

Returns:

True if the state plugins are actually merged.

Return type:

bool

changed_bytes(other, page_addr=None)
Parameters:
class angr.storage.memory_mixins.paged_memory.pages.ultra_page.UltraPage(memory=None, init_zero=False, **kwargs)

Bases: MemoryObjectMixin, PageBase

Default page implementation

SUPPORTS_CONCRETE_LOAD: bool = True
__init__(memory=None, init_zero=False, **kwargs)
classmethod new_from_shared(data, memory=None, **kwargs)
copy(memo)

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:

memo – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

load(addr, size=None, page_addr=None, endness=None, memory=None, cooperate=False, **kwargs)
store(addr, data, size=None, endness=None, memory=None, page_addr=None, cooperate=False, **kwargs)
Parameters:
merge(others, merge_conditions, common_ancestor=None, page_addr=None, memory=None, changed_offsets=None)

Should merge the state plugin with the provided others. This will be called by state.merge() after copying the target state, so this should mutate the current instance to merge with the others.

Note that when multiple instances of a single plugin object (for example, a file) are referenced in the state, it is important that merge only ever be called once. This should be solved by designating one of the plugin’s referees as the “real owner”, who should be the one to actually merge it. This technique doesn’t work to resolve the similar issue that arises during copying because merging doesn’t produce a new reference to insert.

There will be n others and n+1 merge conditions, since the first condition corresponds to self. To match elements up to conditions, say zip([self] + others, merge_conditions)

When implementing this, make sure that you “deepen” both others and common_ancestor before calling sub-elements’ merge methods, e.g.

self.foo.merge(
    [o.foo for o in others],
    merge_conditions,
    common_ancestor=common_ancestor.foo if common_ancestor is not None else None
)

During static analysis, merge_conditions can be None, in which case you should use state.solver.union(values). TODO: fish please make this less bullshit

There is a utility claripy.ite_cases which will help with constructing arbitrarily large merged ASTs. Use it like self.bar = claripy.ite_cases(zip(conditions[1:], [o.bar for o in others]), self.bar)

Parameters:
  • others (list[UltraPage]) – the other state plugins to merge with

  • merge_conditions – a symbolic condition for each of the plugins

  • common_ancestor – a common ancestor of this plugin and the others being merged

  • page_addr (int | None)

  • changed_offsets (set[int] | None)

Returns:

True if the state plugins are actually merged.

Return type:

bool

concrete_load(addr, size, writing=False, with_bitmap=False, **kwargs)

Set SUPPORTS_CONCRETE_LOAD to True and implement concrete_load if reading concrete bytes is faster in this memory model.

Parameters:
  • addr – The address to load from.

  • size – Size of the memory read.

  • writing

Returns:

A memoryview into the loaded bytes.

changed_bytes(other, page_addr=None)
Return type:

set[int]

state: angr.SimState
replace_all_with_offsets(offsets, old, new, memory=None)
Parameters:
class angr.storage.memory_mixins.regioned_memory.AbstractMergerMixin(memory_id=None, endness='Iend_BE')

Bases: MemoryMixin

AbstractMergerMixin handles merging initialized values.

Parameters:
  • memory_id (str | None)

  • endness (str)

class angr.storage.memory_mixins.regioned_memory.MemoryRegionMetaMixin(related_function_addr=None, **kwargs)

Bases: MemoryMixin

__init__(related_function_addr=None, **kwargs)
copy(memo: dict[int, Any] | None = None, **kwargs: Any) S_co

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:
  • memo (Optional[dict[int, Any]]) – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

  • kwargs (Any)

Return type:

TypeVar(S_co, covariant=True)

property is_stack
property related_function_addr
get_abstract_locations(addr, size)

Get a list of abstract locations that is within the range of [addr, addr + size]

This implementation is pretty slow. But since this method won’t be called frequently, we can live with the bad implementation for now.

Parameters:
  • addr – Starting address of the memory region.

  • size – Size of the memory region, in bytes.

Returns:

A list of covered AbstractLocation objects, or an empty list if there is none.

store(addr, data, size=None, *, bbl_addr=None, stmt_id=None, ins_addr=None, endness=None, **kwargs)
load(addr, size=None, *, bbl_addr=None, stmt_idx=None, ins_addr=None, **kwargs)
merge(others, merge_conditions, common_ancestor=None)

Should merge the state plugin with the provided others. This will be called by state.merge() after copying the target state, so this should mutate the current instance to merge with the others.

Note that when multiple instances of a single plugin object (for example, a file) are referenced in the state, it is important that merge only ever be called once. This should be solved by designating one of the plugin’s referees as the “real owner”, who should be the one to actually merge it. This technique doesn’t work to resolve the similar issue that arises during copying because merging doesn’t produce a new reference to insert.

There will be n others and n+1 merge conditions, since the first condition corresponds to self. To match elements up to conditions, say zip([self] + others, merge_conditions)

When implementing this, make sure that you “deepen” both others and common_ancestor before calling sub-elements’ merge methods, e.g.

self.foo.merge(
    [o.foo for o in others],
    merge_conditions,
    common_ancestor=common_ancestor.foo if common_ancestor is not None else None
)

During static analysis, merge_conditions can be None, in which case you should use state.solver.union(values). TODO: fish please make this less bullshit

There is a utility claripy.ite_cases which will help with constructing arbitrarily large merged ASTs. Use it like self.bar = claripy.ite_cases(zip(conditions[1:], [o.bar for o in others]), self.bar)

Parameters:
  • others – the other state plugins to merge with

  • merge_conditions – a symbolic condition for each of the plugins

  • common_ancestor – a common ancestor of this plugin and the others being merged

Returns:

True if the state plugins are actually merged.

Return type:

bool

widen(others)

The widening operation for plugins. Widening is a special kind of merging that produces a more general state from several more specific states. It is used only during intensive static analysis. The same behavior regarding copying and mutation from merge should be followed.

Parameters:

others – the other state plugin

Returns:

True if the state plugin is actually widened.

Return type:

bool

dbg_print(indent=0)

Print out debugging information

class angr.storage.memory_mixins.regioned_memory.RegionCategoryMixin(memory_id=None, endness='Iend_BE')

Bases: MemoryMixin

Parameters:
  • memory_id (str | None)

  • endness (str)

property category

reg, mem, or file.

Type:

Return the category of this SimMemory instance. It can be one of the three following categories

class angr.storage.memory_mixins.regioned_memory.RegionedAddressConcretizationMixin(read_strategies=None, write_strategies=None, **kwargs)

Bases: MemoryMixin

__init__(read_strategies=None, write_strategies=None, **kwargs)
set_state(state)

Sets a new state (for example, if the state has been branched)

copy(memo: dict[int, Any] | None = None, **kwargs: Any) S_co

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:
  • memo (Optional[dict[int, Any]]) – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

  • kwargs (Any)

Return type:

TypeVar(S_co, covariant=True)

merge(others, merge_conditions, common_ancestor=None)

Should merge the state plugin with the provided others. This will be called by state.merge() after copying the target state, so this should mutate the current instance to merge with the others.

Note that when multiple instances of a single plugin object (for example, a file) are referenced in the state, it is important that merge only ever be called once. This should be solved by designating one of the plugin’s referees as the “real owner”, who should be the one to actually merge it. This technique doesn’t work to resolve the similar issue that arises during copying because merging doesn’t produce a new reference to insert.

There will be n others and n+1 merge conditions, since the first condition corresponds to self. To match elements up to conditions, say zip([self] + others, merge_conditions)

When implementing this, make sure that you “deepen” both others and common_ancestor before calling sub-elements’ merge methods, e.g.

self.foo.merge(
    [o.foo for o in others],
    merge_conditions,
    common_ancestor=common_ancestor.foo if common_ancestor is not None else None
)

During static analysis, merge_conditions can be None, in which case you should use state.solver.union(values). TODO: fish please make this less bullshit

There is a utility claripy.ite_cases which will help with constructing arbitrarily large merged ASTs. Use it like self.bar = claripy.ite_cases(zip(conditions[1:], [o.bar for o in others]), self.bar)

Parameters:
  • others – the other state plugins to merge with

  • merge_conditions – a symbolic condition for each of the plugins

  • common_ancestor – a common ancestor of this plugin and the others being merged

Returns:

True if the state plugins are actually merged.

Return type:

bool

class angr.storage.memory_mixins.regioned_memory.RegionedMemoryMixin(write_targets_limit=2048, read_targets_limit=4096, stack_region_map=None, generic_region_map=None, stack_size=65536, cle_memory_backer=None, dict_memory_backer=None, regioned_memory_cls=None, **kwargs)

Bases: MemoryMixin

Regioned memory. This mixin manages multiple memory regions. Each address is represented as a tuple of (region ID, offset into the region), which is called a regioned address.

Converting absolute addresses into regioned addresses: We map an absolute address to a region by looking up which region this address belongs to in the region map. Currently this is only enabled for stack. Heap support has not landed yet.

When start analyzing a function, the user should call set_stack_address_mapping() to create a new region mapping. Likewise, when exiting from a function, the user should cancel the previous mapping by calling unset_stack_address_mapping().

__init__(write_targets_limit=2048, read_targets_limit=4096, stack_region_map=None, generic_region_map=None, stack_size=65536, cle_memory_backer=None, dict_memory_backer=None, regioned_memory_cls=None, **kwargs)
copy(memo: dict[int, Any] | None = None, **kwargs: Any) S_co

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:
  • memo (Optional[dict[int, Any]]) – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

  • kwargs (Any)

Return type:

TypeVar(S_co, covariant=True)

load(addr, size=None, *, endness=None, condition=None, **kwargs)
Parameters:
  • size (int | BV | None)

  • condition (Bool | None)

store(addr, data, size=None, *, endness=None, **kwargs)
Parameters:

size (int | None)

merge(others, merge_conditions, common_ancestor=None)

Should merge the state plugin with the provided others. This will be called by state.merge() after copying the target state, so this should mutate the current instance to merge with the others.

Note that when multiple instances of a single plugin object (for example, a file) are referenced in the state, it is important that merge only ever be called once. This should be solved by designating one of the plugin’s referees as the “real owner”, who should be the one to actually merge it. This technique doesn’t work to resolve the similar issue that arises during copying because merging doesn’t produce a new reference to insert.

There will be n others and n+1 merge conditions, since the first condition corresponds to self. To match elements up to conditions, say zip([self] + others, merge_conditions)

When implementing this, make sure that you “deepen” both others and common_ancestor before calling sub-elements’ merge methods, e.g.

self.foo.merge(
    [o.foo for o in others],
    merge_conditions,
    common_ancestor=common_ancestor.foo if common_ancestor is not None else None
)

During static analysis, merge_conditions can be None, in which case you should use state.solver.union(values). TODO: fish please make this less bullshit

There is a utility claripy.ite_cases which will help with constructing arbitrarily large merged ASTs. Use it like self.bar = claripy.ite_cases(zip(conditions[1:], [o.bar for o in others]), self.bar)

Parameters:
  • others – the other state plugins to merge with

  • merge_conditions – a symbolic condition for each of the plugins

  • common_ancestor – a common ancestor of this plugin and the others being merged

Returns:

True if the state plugins are actually merged.

Return type:

bool

find(addr, data, max_search, **kwargs)
Parameters:

addr (int | Bits)

set_state(state)

Sets a new state (for example, if the state has been branched)

replace_all(old, new)
Parameters:
set_stack_address_mapping(absolute_address, region_id, related_function_address=None)

Create a new mapping between an absolute address (which is the base address of a specific stack frame) and a region ID.

Parameters:
  • absolute_address (int) – The absolute memory address.

  • region_id (str) – The region ID.

  • related_function_address (Optional[int]) – Related function address.

unset_stack_address_mapping(absolute_address)

Remove a stack mapping.

Parameters:

absolute_address (int) – An absolute memory address that is the base address of the stack frame to destroy.

stack_id(function_address)

Return a memory region ID for a function. If the default region ID exists in the region mapping, an integer will appended to the region name. In this way we can handle recursive function calls, or a function that appears more than once in the call frame.

This also means that stack_id() should only be called when creating a new stack frame for a function. You are not supposed to call this function every time you want to map a function address to a stack ID.

Parameters:

function_address (int) – Address of the function.

Return type:

str

Returns:

ID of the new memory region.

set_stack_size(size)
Parameters:

size (int)

class angr.storage.memory_mixins.regioned_memory.StaticFindMixin(memory_id=None, endness='Iend_BE')

Bases: SmartFindMixin

Implements data finding for abstract memory.

Parameters:
  • memory_id (str | None)

  • endness (str)

find(addr, data, max_search, *, default=None, endness=None, chunk_size=None, max_symbolic_bytes=None, condition=None, char_size=1, **kwargs)
class angr.storage.memory_mixins.regioned_memory.regioned_memory_mixin.RegionedMemoryMixin(write_targets_limit=2048, read_targets_limit=4096, stack_region_map=None, generic_region_map=None, stack_size=65536, cle_memory_backer=None, dict_memory_backer=None, regioned_memory_cls=None, **kwargs)

Bases: MemoryMixin

Regioned memory. This mixin manages multiple memory regions. Each address is represented as a tuple of (region ID, offset into the region), which is called a regioned address.

Converting absolute addresses into regioned addresses: We map an absolute address to a region by looking up which region this address belongs to in the region map. Currently this is only enabled for stack. Heap support has not landed yet.

When start analyzing a function, the user should call set_stack_address_mapping() to create a new region mapping. Likewise, when exiting from a function, the user should cancel the previous mapping by calling unset_stack_address_mapping().

__init__(write_targets_limit=2048, read_targets_limit=4096, stack_region_map=None, generic_region_map=None, stack_size=65536, cle_memory_backer=None, dict_memory_backer=None, regioned_memory_cls=None, **kwargs)
copy(memo: dict[int, Any] | None = None, **kwargs: Any) S_co

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:
  • memo (Optional[dict[int, Any]]) – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

  • kwargs (Any)

Return type:

TypeVar(S_co, covariant=True)

load(addr, size=None, *, endness=None, condition=None, **kwargs)
Parameters:
  • size (int | BV | None)

  • condition (Bool | None)

store(addr, data, size=None, *, endness=None, **kwargs)
Parameters:

size (int | None)

merge(others, merge_conditions, common_ancestor=None)

Should merge the state plugin with the provided others. This will be called by state.merge() after copying the target state, so this should mutate the current instance to merge with the others.

Note that when multiple instances of a single plugin object (for example, a file) are referenced in the state, it is important that merge only ever be called once. This should be solved by designating one of the plugin’s referees as the “real owner”, who should be the one to actually merge it. This technique doesn’t work to resolve the similar issue that arises during copying because merging doesn’t produce a new reference to insert.

There will be n others and n+1 merge conditions, since the first condition corresponds to self. To match elements up to conditions, say zip([self] + others, merge_conditions)

When implementing this, make sure that you “deepen” both others and common_ancestor before calling sub-elements’ merge methods, e.g.

self.foo.merge(
    [o.foo for o in others],
    merge_conditions,
    common_ancestor=common_ancestor.foo if common_ancestor is not None else None
)

During static analysis, merge_conditions can be None, in which case you should use state.solver.union(values). TODO: fish please make this less bullshit

There is a utility claripy.ite_cases which will help with constructing arbitrarily large merged ASTs. Use it like self.bar = claripy.ite_cases(zip(conditions[1:], [o.bar for o in others]), self.bar)

Parameters:
  • others – the other state plugins to merge with

  • merge_conditions – a symbolic condition for each of the plugins

  • common_ancestor – a common ancestor of this plugin and the others being merged

Returns:

True if the state plugins are actually merged.

Return type:

bool

find(addr, data, max_search, **kwargs)
Parameters:

addr (int | Bits)

set_state(state)

Sets a new state (for example, if the state has been branched)

replace_all(old, new)
Parameters:
set_stack_address_mapping(absolute_address, region_id, related_function_address=None)

Create a new mapping between an absolute address (which is the base address of a specific stack frame) and a region ID.

Parameters:
  • absolute_address (int) – The absolute memory address.

  • region_id (str) – The region ID.

  • related_function_address (Optional[int]) – Related function address.

unset_stack_address_mapping(absolute_address)

Remove a stack mapping.

Parameters:

absolute_address (int) – An absolute memory address that is the base address of the stack frame to destroy.

stack_id(function_address)

Return a memory region ID for a function. If the default region ID exists in the region mapping, an integer will appended to the region name. In this way we can handle recursive function calls, or a function that appears more than once in the call frame.

This also means that stack_id() should only be called when creating a new stack frame for a function. You are not supposed to call this function every time you want to map a function address to a stack ID.

Parameters:

function_address (int) – Address of the function.

Return type:

str

Returns:

ID of the new memory region.

set_stack_size(size)
Parameters:

size (int)

class angr.storage.memory_mixins.regioned_memory.region_data.AddressWrapper(region, region_base_addr, address, is_on_stack, function_address)

Bases: object

AddressWrapper is used in SimAbstractMemory, which provides extra meta information for an address (or a ValueSet object) that is normalized from an integer/BVV/StridedInterval.

Parameters:
  • region (str)

  • region_base_addr (int)

  • is_on_stack (bool)

  • function_address (int | None)

__init__(region, region_base_addr, address, is_on_stack, function_address)

Constructor for the class AddressWrapper.

Parameters:
  • region (str) – Name of the memory regions it belongs to.

  • region_base_addr (int) – Base address of the memory region

  • address – An address (not a ValueSet object).

  • is_on_stack (bool) – Whether this address is on a stack region or not.

  • function_address (int | None) – Related function address (if any).

region
region_base_addr
address
is_on_stack
function_address
to_valueset(state)

Convert to a ValueSet instance

Parameters:

state – A state

Returns:

The converted ValueSet instance

class angr.storage.memory_mixins.regioned_memory.region_data.RegionDescriptor(region_id, base_address, related_function_address=None)

Bases: object

Descriptor for a memory region ID.

__init__(region_id, base_address, related_function_address=None)
region_id
base_address
related_function_address
class angr.storage.memory_mixins.regioned_memory.region_data.RegionMap(is_stack)

Bases: object

Mostly used in SimAbstractMemory, RegionMap stores a series of mappings between concrete memory address ranges and memory regions, like stack frames and heap regions.

__init__(is_stack)

Constructor

Parameters:

is_stack – Whether this is a region map for stack frames or not. Different strategies apply for stack regions.

property is_empty
property stack_base
property region_ids
copy(memo: dict[int, Any] | None = None, **kwargs: Any) S_co
Return type:

TypeVar(S_co, covariant=True)

Parameters:
map(absolute_address, region_id, related_function_address=None)

Add a mapping between an absolute address and a region ID. If this is a stack region map, all stack regions beyond (lower than) this newly added regions will be discarded.

Parameters:
  • absolute_address – An absolute memory address.

  • region_id – ID of the memory region.

  • related_function_address – A related function address, mostly used for stack regions.

unmap_by_address(absolute_address)

Removes a mapping based on its absolute address.

Parameters:

absolute_address – An absolute address

absolutize(region_id, relative_address)

Convert a relative address in some memory region to an absolute address.

Parameters:
  • region_id – The memory region ID

  • relative_address – The relative memory offset in that memory region

Returns:

An absolute address if converted, or an exception is raised when region id does not exist.

relativize(absolute_address, target_region_id=None)

Convert an absolute address to the memory offset in a memory region.

Note that if an address belongs to heap region is passed in to a stack region map, it will be converted to an offset included in the closest stack frame, and vice versa for passing a stack address to a heap region. Therefore you should only pass in address that belongs to the same category (stack or non-stack) of this region map.

Parameters:

absolute_address – An absolute memory address

Returns:

A tuple of the closest region ID, the relative offset, and the related function address.

class angr.storage.memory_mixins.regioned_memory.region_category_mixin.RegionCategoryMixin(memory_id=None, endness='Iend_BE')

Bases: MemoryMixin

Parameters:
  • memory_id (str | None)

  • endness (str)

property category

reg, mem, or file.

Type:

Return the category of this SimMemory instance. It can be one of the three following categories

class angr.storage.memory_mixins.regioned_memory.static_find_mixin.StaticFindMixin(memory_id=None, endness='Iend_BE')

Bases: SmartFindMixin

Implements data finding for abstract memory.

Parameters:
  • memory_id (str | None)

  • endness (str)

find(addr, data, max_search, *, default=None, endness=None, chunk_size=None, max_symbolic_bytes=None, condition=None, char_size=1, **kwargs)
class angr.storage.memory_mixins.regioned_memory.abstract_address_descriptor.AbstractAddressDescriptor

Bases: object

AbstractAddressDescriptor describes a list of region+offset tuples. It provides a convenient way for accessing the cardinality (the total number of addresses) without enumerating or creating all addresses in static mode.

__init__()
property cardinality
add_regioned_address(region, addr)
Parameters:
clear()
class angr.storage.memory_mixins.regioned_memory.region_meta_mixin.Segment(offset, size=0)

Bases: object

Segment represents a continuous memory region.

__init__(offset, size=0)
class angr.storage.memory_mixins.regioned_memory.region_meta_mixin.AbstractLocation(bbl_key, stmt_id, region_id, segment_list=None, region_offset=None, size=None)

Bases: object

AbstractLocation represents a location in memory.

__init__(bbl_key, stmt_id, region_id, segment_list=None, region_offset=None, size=None)
property basicblock_key
property statement_id
property region
property segments
update(region_offset, size)
copy()
merge(other)
class angr.storage.memory_mixins.regioned_memory.region_meta_mixin.MemoryRegionMetaMixin(related_function_addr=None, **kwargs)

Bases: MemoryMixin

__init__(related_function_addr=None, **kwargs)
copy(memo: dict[int, Any] | None = None, **kwargs: Any) S_co

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:
  • memo (Optional[dict[int, Any]]) – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

  • kwargs (Any)

Return type:

TypeVar(S_co, covariant=True)

property is_stack
property related_function_addr
get_abstract_locations(addr, size)

Get a list of abstract locations that is within the range of [addr, addr + size]

This implementation is pretty slow. But since this method won’t be called frequently, we can live with the bad implementation for now.

Parameters:
  • addr – Starting address of the memory region.

  • size – Size of the memory region, in bytes.

Returns:

A list of covered AbstractLocation objects, or an empty list if there is none.

store(addr, data, size=None, *, bbl_addr=None, stmt_id=None, ins_addr=None, endness=None, **kwargs)
load(addr, size=None, *, bbl_addr=None, stmt_idx=None, ins_addr=None, **kwargs)
merge(others, merge_conditions, common_ancestor=None)

Should merge the state plugin with the provided others. This will be called by state.merge() after copying the target state, so this should mutate the current instance to merge with the others.

Note that when multiple instances of a single plugin object (for example, a file) are referenced in the state, it is important that merge only ever be called once. This should be solved by designating one of the plugin’s referees as the “real owner”, who should be the one to actually merge it. This technique doesn’t work to resolve the similar issue that arises during copying because merging doesn’t produce a new reference to insert.

There will be n others and n+1 merge conditions, since the first condition corresponds to self. To match elements up to conditions, say zip([self] + others, merge_conditions)

When implementing this, make sure that you “deepen” both others and common_ancestor before calling sub-elements’ merge methods, e.g.

self.foo.merge(
    [o.foo for o in others],
    merge_conditions,
    common_ancestor=common_ancestor.foo if common_ancestor is not None else None
)

During static analysis, merge_conditions can be None, in which case you should use state.solver.union(values). TODO: fish please make this less bullshit

There is a utility claripy.ite_cases which will help with constructing arbitrarily large merged ASTs. Use it like self.bar = claripy.ite_cases(zip(conditions[1:], [o.bar for o in others]), self.bar)

Parameters:
  • others – the other state plugins to merge with

  • merge_conditions – a symbolic condition for each of the plugins

  • common_ancestor – a common ancestor of this plugin and the others being merged

Returns:

True if the state plugins are actually merged.

Return type:

bool

widen(others)

The widening operation for plugins. Widening is a special kind of merging that produces a more general state from several more specific states. It is used only during intensive static analysis. The same behavior regarding copying and mutation from merge should be followed.

Parameters:

others – the other state plugin

Returns:

True if the state plugin is actually widened.

Return type:

bool

dbg_print(indent=0)

Print out debugging information

class angr.storage.memory_mixins.regioned_memory.abstract_merger_mixin.AbstractMergerMixin(memory_id=None, endness='Iend_BE')

Bases: MemoryMixin

AbstractMergerMixin handles merging initialized values.

Parameters:
  • memory_id (str | None)

  • endness (str)

class angr.storage.memory_mixins.regioned_memory.regioned_address_concretization_mixin.RegionedAddressConcretizationMixin(read_strategies=None, write_strategies=None, **kwargs)

Bases: MemoryMixin

__init__(read_strategies=None, write_strategies=None, **kwargs)
set_state(state)

Sets a new state (for example, if the state has been branched)

copy(memo: dict[int, Any] | None = None, **kwargs: Any) S_co

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:
  • memo (Optional[dict[int, Any]]) – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

  • kwargs (Any)

Return type:

TypeVar(S_co, covariant=True)

merge(others, merge_conditions, common_ancestor=None)

Should merge the state plugin with the provided others. This will be called by state.merge() after copying the target state, so this should mutate the current instance to merge with the others.

Note that when multiple instances of a single plugin object (for example, a file) are referenced in the state, it is important that merge only ever be called once. This should be solved by designating one of the plugin’s referees as the “real owner”, who should be the one to actually merge it. This technique doesn’t work to resolve the similar issue that arises during copying because merging doesn’t produce a new reference to insert.

There will be n others and n+1 merge conditions, since the first condition corresponds to self. To match elements up to conditions, say zip([self] + others, merge_conditions)

When implementing this, make sure that you “deepen” both others and common_ancestor before calling sub-elements’ merge methods, e.g.

self.foo.merge(
    [o.foo for o in others],
    merge_conditions,
    common_ancestor=common_ancestor.foo if common_ancestor is not None else None
)

During static analysis, merge_conditions can be None, in which case you should use state.solver.union(values). TODO: fish please make this less bullshit

There is a utility claripy.ite_cases which will help with constructing arbitrarily large merged ASTs. Use it like self.bar = claripy.ite_cases(zip(conditions[1:], [o.bar for o in others]), self.bar)

Parameters:
  • others – the other state plugins to merge with

  • merge_conditions – a symbolic condition for each of the plugins

  • common_ancestor – a common ancestor of this plugin and the others being merged

Returns:

True if the state plugins are actually merged.

Return type:

bool

class angr.storage.memory_mixins.slotted_memory.SlottedMemoryMixin(width=None, **kwargs)

Bases: MemoryMixin

__init__(width=None, **kwargs)
set_state(state)

Sets a new state (for example, if the state has been branched)

copy(memo)

Should return a copy of the plugin without any state attached. Should check the memo first, and add itself to memo if it ends up making a new copy.

In order to simplify using the memo, you should annotate implementations of this function with SimStatePlugin.memo

The base implementation of this function constructs a new instance of the plugin’s class without calling its initializer. If you super-call down to it, make sure you instantiate all the fields in your copy method!

Parameters:

memo – A dictionary mapping object identifiers (id(obj)) to their copied instance. Use this to avoid infinite recursion and diverged copies.

merge(others, merge_conditions, common_ancestor=None)

Should merge the state plugin with the provided others. This will be called by state.merge() after copying the target state, so this should mutate the current instance to merge with the others.

Note that when multiple instances of a single plugin object (for example, a file) are referenced in the state, it is important that merge only ever be called once. This should be solved by designating one of the plugin’s referees as the “real owner”, who should be the one to actually merge it. This technique doesn’t work to resolve the similar issue that arises during copying because merging doesn’t produce a new reference to insert.

There will be n others and n+1 merge conditions, since the first condition corresponds to self. To match elements up to conditions, say zip([self] + others, merge_conditions)

When implementing this, make sure that you “deepen” both others and common_ancestor before calling sub-elements’ merge methods, e.g.

self.foo.merge(
    [o.foo for o in others],
    merge_conditions,
    common_ancestor=common_ancestor.foo if common_ancestor is not None else None
)

During static analysis, merge_conditions can be None, in which case you should use state.solver.union(values). TODO: fish please make this less bullshit

There is a utility claripy.ite_cases which will help with constructing arbitrarily large merged ASTs. Use it like self.bar = claripy.ite_cases(zip(conditions[1:], [o.bar for o in others]), self.bar)

Parameters:
  • others – the other state plugins to merge with

  • merge_conditions – a symbolic condition for each of the plugins

  • common_ancestor – a common ancestor of this plugin and the others being merged

Returns:

True if the state plugins are actually merged.

Return type:

bool

load(addr, size=None, *, endness=None, **kwargs)
store(addr, data, size=None, *, endness=None, **kwargs)
changed_bytes(other)

Concretization Strategies

class angr.concretization_strategies.single.SimConcretizationStrategySingle(filter=None, exact=True)

Bases: SimConcretizationStrategy

Concretization strategy that ensures a single solution for an address.

class angr.concretization_strategies.eval.SimConcretizationStrategyEval(limit, **kwargs)

Bases: SimConcretizationStrategy

Concretization strategy that resolves an address into some limited number of solutions. Always handles the concretization, but only returns a maximum of limit number of solutions. Therefore, should only be used as the fallback strategy.

__init__(limit, **kwargs)

Initializes the base SimConcretizationStrategy.

Parameters:
  • filter – A function, taking arguments of (SimMemory, claripy.AST) that determines if this strategy can handle resolving the provided AST.

  • exact – A flag (default: True) that determines if the convenience resolution functions provided by this class use exact or approximate resolution.

class angr.concretization_strategies.norepeats.SimConcretizationStrategyNorepeats(repeat_expr, repeat_constraints=None, **kwargs)

Bases: SimConcretizationStrategy

Concretization strategy that resolves addresses, without repeating.

__init__(repeat_expr, repeat_constraints=None, **kwargs)

Initializes the base SimConcretizationStrategy.

Parameters:
  • filter – A function, taking arguments of (SimMemory, claripy.AST) that determines if this strategy can handle resolving the provided AST.

  • exact – A flag (default: True) that determines if the convenience resolution functions provided by this class use exact or approximate resolution.

copy()

Returns a copy of the strategy, if there is data that should be kept separate between states. If not, returns self.

merge(others)

Merges this strategy with others (if there is data that should be kept separate between states. If not, is a no-op.

class angr.concretization_strategies.solutions.SimConcretizationStrategySolutions(limit, **kwargs)

Bases: SimConcretizationStrategy

Concretization strategy that resolves an address into some limited number of solutions.

__init__(limit, **kwargs)

Initializes the base SimConcretizationStrategy.

Parameters:
  • filter – A function, taking arguments of (SimMemory, claripy.AST) that determines if this strategy can handle resolving the provided AST.

  • exact – A flag (default: True) that determines if the convenience resolution functions provided by this class use exact or approximate resolution.

class angr.concretization_strategies.nonzero_range.SimConcretizationStrategyNonzeroRange(limit, **kwargs)

Bases: SimConcretizationStrategy

Concretization strategy that resolves a range in a non-zero location.

__init__(limit, **kwargs)

Initializes the base SimConcretizationStrategy.

Parameters:
  • filter – A function, taking arguments of (SimMemory, claripy.AST) that determines if this strategy can handle resolving the provided AST.

  • exact – A flag (default: True) that determines if the convenience resolution functions provided by this class use exact or approximate resolution.

class angr.concretization_strategies.range.SimConcretizationStrategyRange(limit, **kwargs)

Bases: SimConcretizationStrategy

Concretization strategy that resolves addresses to a range.

__init__(limit, **kwargs)

Initializes the base SimConcretizationStrategy.

Parameters:
  • filter – A function, taking arguments of (SimMemory, claripy.AST) that determines if this strategy can handle resolving the provided AST.

  • exact – A flag (default: True) that determines if the convenience resolution functions provided by this class use exact or approximate resolution.

class angr.concretization_strategies.max.SimConcretizationStrategyMax(max_addr=None)

Bases: SimConcretizationStrategy

Concretization strategy that returns the maximum address.

Parameters:

max_addr (int | None)

__init__(max_addr=None)

Initializes the base SimConcretizationStrategy.

Parameters:
  • filter – A function, taking arguments of (SimMemory, claripy.AST) that determines if this strategy can handle resolving the provided AST.

  • exact – A flag (default: True) that determines if the convenience resolution functions provided by this class use exact or approximate resolution.

  • max_addr (int | None)

class angr.concretization_strategies.norepeats_range.SimConcretizationStrategyNorepeatsRange(repeat_expr, min=None, granularity=None, **kwargs)

Bases: SimConcretizationStrategy

Concretization strategy that resolves a range, with no repeats.

__init__(repeat_expr, min=None, granularity=None, **kwargs)

Initializes the base SimConcretizationStrategy.

Parameters:
  • filter – A function, taking arguments of (SimMemory, claripy.AST) that determines if this strategy can handle resolving the provided AST.

  • exact – A flag (default: True) that determines if the convenience resolution functions provided by this class use exact or approximate resolution.

copy()

Returns a copy of the strategy, if there is data that should be kept separate between states. If not, returns self.

merge(others)

Merges this strategy with others (if there is data that should be kept separate between states. If not, is a no-op.

class angr.concretization_strategies.nonzero.SimConcretizationStrategyNonzero(filter=None, exact=True)

Bases: SimConcretizationStrategy

Concretization strategy that returns any non-zero solution.

class angr.concretization_strategies.any.SimConcretizationStrategyAny(filter=None, exact=True)

Bases: SimConcretizationStrategy

Concretization strategy that returns any single solution.

class angr.concretization_strategies.controlled_data.SimConcretizationStrategyControlledData(limit, fixed_addrs, **kwargs)

Bases: SimConcretizationStrategy

Concretization strategy that constraints the address to controlled data. Controlled data consists of symbolic data and the addresses given as arguments. memory.

__init__(limit, fixed_addrs, **kwargs)

Initializes the base SimConcretizationStrategy.

Parameters:
  • filter – A function, taking arguments of (SimMemory, claripy.AST) that determines if this strategy can handle resolving the provided AST.

  • exact – A flag (default: True) that determines if the convenience resolution functions provided by this class use exact or approximate resolution.

class angr.concretization_strategies.unlimited_range.SimConcretizationStrategyUnlimitedRange(limit, **kwargs)

Bases: SimConcretizationStrategy

Concretization strategy that resolves addresses to a range without checking if the number of possible addresses is within the limit.

__init__(limit, **kwargs)

Initializes the base SimConcretizationStrategy.

Parameters:
  • filter – A function, taking arguments of (SimMemory, claripy.AST) that determines if this strategy can handle resolving the provided AST.

  • exact – A flag (default: True) that determines if the convenience resolution functions provided by this class use exact or approximate resolution.

Simulation Manager

class angr.sim_manager.SimulationManager(project, active_states=None, stashes=None, hierarchy=None, resilience=None, save_unsat=False, auto_drop=None, errored=None, completion_mode=<built-in function any>, techniques=None, suggestions=True, **kwargs)

Bases: object

The Simulation Manager is the future future.

Simulation managers allow you to wrangle multiple states in a slick way. States are organized into “stashes”, which you can step forward, filter, merge, and move around as you wish. This allows you to, for example, step two different stashes of states at different rates, then merge them together.

Stashes can be accessed as attributes (i.e. .active). A mulpyplexed stash can be retrieved by prepending the name with mp_, e.g. .mp_active. A single state from the stash can be retrieved by prepending the name with one_, e.g. .one_active.

Note that you shouldn’t usually be constructing SimulationManagers directly - there is a convenient shortcut for creating them in Project.factory: see angr.factory.AngrObjectFactory.

The most important methods you should look at are step, explore, and use_technique.

Parameters:
  • project (angr.project.Project) – A Project instance.

  • stashes – A dictionary to use as the stash store.

  • active_states – Active states to seed the “active” stash with.

  • hierarchy – A StateHierarchy object to use to track the relationships between states.

  • resilience – A set of errors to catch during stepping to put a state in the errore list. You may also provide the values False, None (default), or True to catch, respectively, no errors, all angr-specific errors, and a set of many common errors.

  • save_unsat – Set to True in order to introduce unsatisfiable states into the unsat stash instead of discarding them immediately.

  • auto_drop – A set of stash names which should be treated as garbage chutes.

  • completion_mode – A function describing how multiple exploration techniques with the complete hook set will interact. By default, the builtin function any.

  • techniques – A list of techniques that should be pre-set to use with this manager.

  • suggestions – Whether to automatically install the Suggestions exploration technique. Default True.

Variables:
  • errored – Not a stash, but a list of ErrorRecords. Whenever a step raises an exception that we catch, the state and some information about the error are placed in this list. You can adjust the list of caught exceptions with the resilience parameter.

  • stashes – All the stashes on this instance, as a dictionary.

  • completion_mode – A function describing how multiple exploration techniques with the complete hook set will interact. By default, the builtin function any.

ALL = '_ALL'
DROP = '_DROP'
__init__(project, active_states=None, stashes=None, hierarchy=None, resilience=None, save_unsat=False, auto_drop=None, errored=None, completion_mode=<built-in function any>, techniques=None, suggestions=True, **kwargs)
active: list[SimState]
stashed: list[SimState]
pruned: list[SimState]
unsat: list[SimState]
deadended: list[SimState]
unconstrained: list[SimState]
found: list[SimState]
one_active: SimState
one_stashed: SimState
one_pruned: SimState
one_unsat: SimState
one_deadended: SimState
one_unconstrained: SimState
one_found: SimState
property errored: list[ErrorRecord]
property stashes: defaultdict[str, list[SimState]]
mulpyplex(*stashes)

Mulpyplex across several stashes.

Parameters:

stashes – the stashes to mulpyplex

Returns:

a mulpyplexed list of states from the stashes in question, in the specified order

copy(deep=False)

Make a copy of this simulation manager. Pass deep=True to copy all the states in it as well.

If the current callstack includes hooked methods, the already-called methods will not be included in the copy.

use_technique(tech)

Use an exploration technique with this SimulationManager.

Techniques can be found in angr.exploration_techniques.

Parameters:

tech (ExplorationTechnique) – An ExplorationTechnique object that contains code to modify this SimulationManager’s behavior.

Returns:

The technique that was added, for convenience

remove_technique(tech)

Remove an exploration technique from a list of active techniques.

Parameters:

tech (ExplorationTechnique) – An ExplorationTechnique object.

explore(stash='active', n=None, find=None, avoid=None, find_stash='found', avoid_stash='avoid', cfg=None, num_find=1, avoid_priority=False, **kwargs)

Tick stash “stash” forward (up to “n” times or until “num_find” states are found), looking for condition “find”, avoiding condition “avoid”. Stores found states into “find_stash’ and avoided states into “avoid_stash”.

The “find” and “avoid” parameters may be any of:

  • An address to find

  • A set or list of addresses to find

  • A function that takes a state and returns whether or not it matches.

If an angr CFG is passed in as the “cfg” parameter and “find” is either a number or a list or a set, then any states which cannot possibly reach a success state without going through a failure state will be preemptively avoided.

run(stash='active', n=None, until=None, **kwargs)

Run until the SimulationManager has reached a completed state, according to the current exploration techniques. If no exploration techniques that define a completion state are being used, run until there is nothing left to run.

Parameters:
  • stash – Operate on this stash

  • n – Step at most this many times

  • until – If provided, should be a function that takes a SimulationManager and returns True or False. Stepping will terminate when it is True.

Returns:

The simulation manager, for chaining.

Return type:

SimulationManager

complete()

Returns whether or not this manager has reached a “completed” state.

step(stash='active', target_stash=None, n=None, selector_func=None, step_func=None, error_list=None, successor_func=None, until=None, filter_func=None, **run_args)

Step a stash of states forward and categorize the successors appropriately.

The parameters to this function allow you to control everything about the stepping and categorization process.

Parameters:
  • stash – The name of the stash to step (default: ‘active’)

  • target_stash – The name of the stash to put the results in (default: same as stash)

  • error_list – The list to put ErrorRecord objects in (default: self.errored)

  • selector_func – If provided, should be a function that takes a state and returns a boolean. If True, the state will be stepped. Otherwise, it will be kept as-is.

  • step_func – If provided, should be a function that takes a SimulationManager and returns a SimulationManager. Will be called with the SimulationManager at every step. Note that this function should not actually perform any stepping - it is meant to be a maintenance function called after each step.

  • successor_func – If provided, should be a function that takes a state and return its successors. Otherwise, project.factory.successors will be used.

  • filter_func – If provided, should be a function that takes a state and return the name of the stash, to which the state should be moved.

  • until – (DEPRECATED) If provided, should be a function that takes a SimulationManager and returns True or False. Stepping will terminate when it is True.

  • n – (DEPRECATED) The number of times to step (default: 1 if “until” is not provided)

Additionally, you can pass in any of the following keyword args for project.factory.successors:

Parameters:
  • jumpkind – The jumpkind of the previous exit

  • addr – An address to execute at instead of the state’s ip.

  • stmt_whitelist – A list of stmt indexes to which to confine execution.

  • last_stmt – A statement index at which to stop execution.

  • thumb – Whether the block should be lifted in ARM’s THUMB mode.

  • backup_state – A state to read bytes from instead of using project memory.

  • opt_level – The VEX optimization level to use.

  • insn_bytes – A string of bytes to use for the block instead of the project.

  • size – The maximum size of the block, in bytes.

  • num_inst – The maximum number of instructions.

  • traceflags – traceflags to be passed to VEX. Default: 0

Returns:

The simulation manager, for chaining.

Return type:

SimulationManager

step_state(state, successor_func=None, error_list=None, **run_args)

Don’t use this function manually - it is meant to interface with exploration techniques.

filter(state, filter_func=None)

Don’t use this function manually - it is meant to interface with exploration techniques.

selector(state, selector_func=None)

Don’t use this function manually - it is meant to interface with exploration techniques.

successors(state, successor_func=None, **run_args)

Don’t use this function manually - it is meant to interface with exploration techniques.

prune(filter_func=None, from_stash='active', to_stash='pruned')

Prune unsatisfiable states from a stash.

This function will move all unsatisfiable states in the given stash into a different stash.

Parameters:
  • filter_func – Only prune states that match this filter.

  • from_stash – Prune states from this stash. (default: ‘active’)

  • to_stash – Put pruned states in this stash. (default: ‘pruned’)

Returns:

The simulation manager, for chaining.

Return type:

SimulationManager

populate(stash, states)

Populate a stash with a collection of states.

Parameters:
  • stash – A stash to populate.

  • states – A list of states with which to populate the stash.

absorb(simgr)

Collect all the states from simgr and put them in their corresponding stashes in this manager. This will not modify simgr.

move(from_stash, to_stash, filter_func=None)

Move states from one stash to another.

Parameters:
  • from_stash – Take matching states from this stash.

  • to_stash – Put matching states into this stash.

  • filter_func – Stash states that match this filter. Should be a function that takes a state and returns True or False. (default: stash all states)

Returns:

The simulation manager, for chaining.

Return type:

SimulationManager

stash(filter_func=None, from_stash='active', to_stash='stashed')

Stash some states. This is an alias for move(), with defaults for the stashes.

Parameters:
  • filter_func – Stash states that match this filter. Should be a function that takes a state and returns True or False. (default: stash all states)

  • from_stash – Take matching states from this stash. (default: ‘active’)

  • to_stash – Put matching states into this stash. (default: ‘stashed’)

Returns:

The simulation manager, for chaining.

Return type:

SimulationManager

unstash(filter_func=None, to_stash='active', from_stash='stashed')

Unstash some states. This is an alias for move(), with defaults for the stashes.

Parameters:
  • filter_func – Unstash states that match this filter. Should be a function that takes a state and returns True or False. (default: unstash all states)

  • from_stash – take matching states from this stash. (default: ‘stashed’)

  • to_stash – put matching states into this stash. (default: ‘active’)

Returns:

The simulation manager, for chaining.

Return type:

SimulationManager

drop(filter_func=None, stash='active')

Drops states from a stash. This is an alias for move(), with defaults for the stashes.

Parameters:
  • filter_func – Drop states that match this filter. Should be a function that takes a state and returns True or False. (default: drop all states)

  • stash – Drop matching states from this stash. (default: ‘active’)

Returns:

The simulation manager, for chaining.

Return type:

SimulationManager

apply(state_func=None, stash_func=None, stash='active', to_stash=None)

Applies a given function to a given stash.

Parameters:
  • state_func – A function to apply to every state. Should take a state and return a state. The returned state will take the place of the old state. If the function doesn’t return a state, the old state will be used. If the function returns a list of states, they will replace the original states.

  • stash_func – A function to apply to the whole stash. Should take a list of states and return a list of states. The resulting list will replace the stash. If both state_func and stash_func are provided state_func is applied first, then stash_func is applied on the results.

  • stash – A stash to work with.

  • to_stash – If specified, this stash will be used to store the resulting states instead.

Returns:

The simulation manager, for chaining.

Return type:

SimulationManager

split(stash_splitter=None, stash_ranker=None, state_ranker=None, limit=8, from_stash='active', to_stash='stashed')

Split a stash of states into two stashes depending on the specified options.

The stash from_stash will be split into two stashes depending on the other options passed in. If to_stash is provided, the second stash will be written there.

stash_splitter overrides stash_ranker, which in turn overrides state_ranker. If no functions are provided, the states are simply split according to the limit.

The sort done with state_ranker is ascending.

Parameters:
  • stash_splitter – A function that should take a list of states and return a tuple of two lists (the two resulting stashes).

  • stash_ranker – A function that should take a list of states and return a sorted list of states. This list will then be split according to “limit”.

  • state_ranker – An alternative to stash_splitter. States will be sorted with outputs of this function, which are to be used as a key. The first “limit” of them will be kept, the rest split off.

  • limit – For use with state_ranker. The number of states to keep. Default: 8

  • from_stash – The stash to split (default: ‘active’)

  • to_stash – The stash to write to (default: ‘stashed’)

Returns:

The simulation manager, for chaining.

Return type:

SimulationManager

merge(merge_func=None, merge_key=None, stash='active', prune=True)

Merge the states in a given stash.

Parameters:
  • stash – The stash (default: ‘active’)

  • merge_func – If provided, instead of using state.merge, call this function with the states as the argument. Should return the merged state.

  • merge_key – If provided, should be a function that takes a state and returns a key that will compare equal for all states that are allowed to be merged together, as a first approximation. By default: uses PC, callstack, and open file descriptors.

  • prune – Whether to prune the stash prior to merging it

Returns:

The simulation manager, for chaining.

Return type:

SimulationManager

class angr.sim_manager.ErrorRecord(state, error, traceback)

Bases: object

A container class for a state and an error that was thrown during its execution. You can find these in SimulationManager.errored.

Variables:
  • state – The state that encountered an error, at the point in time just before the erroring step began.

  • error – The error that was thrown.

  • traceback – The traceback for the error that was thrown.

__init__(state, error, traceback)
debug()

Launch a postmortem debug shell at the site of the error.

reraise()
class angr.state_hierarchy.StateHierarchy

Bases: object

The state hierarchy holds weak references to SimStateHistory objects in a directed acyclic graph. It is useful for queries about a state’s ancestry, notably “what is the best ancestor state for a merge among these states” and “what is the most recent unsatisfiable state while using LAZY_SOLVES”

__init__()
get_ref(obj)
dead_ref(ref)
defer_cleanup()
add_state(s)
add_history(h)
simplify()
full_simplify()
lineage(h)

Returns the lineage of histories leading up to h.

all_successors(h)
history_successors(h)
history_predecessors(h)
history_contains(h)
unreachable_state(state)
unreachable_history(h)
most_mergeable(states)

Find the “most mergeable” set of states from those provided.

Parameters:

states – a list of states

Returns:

a tuple of: (list of states to merge, those states’ common history, list of states to not merge yet)

Exploration Techniques

class angr.exploration_techniques.DFS(deferred_stash='deferred')

Bases: ExplorationTechnique

Depth-first search.

Will only keep one path active at a time, any others will be stashed in the ‘deferred’ stash. When we run out of active paths to step, we take the longest one from deferred and continue.

__init__(deferred_stash='deferred')
setup(simgr)

Perform any initialization on this manager you might need to do.

Parameters:

simgr (angr.SimulationManager) – The simulation manager to which you have just been added

step(simgr, stash='active', **kwargs)

Hook the process of stepping a stash forward. Should call simgr.step(stash, **kwargs) in order to do the actual processing.

Parameters:
class angr.exploration_techniques.Bucketizer

Bases: ExplorationTechnique

Loop bucketization: Pick log(n) paths out of n possible paths, and stash (or drop) everything else.

successors(simgr, state, **kwargs)

Perform the process of stepping a state forward, returning a SimSuccessors object.

To defer to the original succession procedure, return the result of simgr.successors(state, **kwargs). Be careful about not calling this method (e.g. calling project.factory.successors manually) as it denies other hooks the opportunity to instrument the step. Instead, you can mutate the kwargs for the step before calling the original, and mutate the result before returning it yourself.

If the user provided a successor_func in their step or run command, it will appear here.

Parameters:
class angr.exploration_techniques.CallFunctionGoal(function, arguments)

Bases: BaseGoal

A goal that prioritizes states reaching certain function, and optionally with specific arguments. Note that constraints on arguments (and on function address as well) have to be identifiable on an accurate CFG. For example, you may have a CallFunctionGoal saying “call printf with the first argument being ‘Hello, world’”, and CFGEmulated must be able to figure our the first argument to printf is in fact “Hello, world”, not some symbolic strings that will be constrained to “Hello, world” during symbolic execution (or simulation, however you put it).

REQUIRE_CFG_STATES = True
__init__(function, arguments)
check(cfg, state, peek_blocks)

Check if the specified function will be reached with certain arguments.

Parameters:
  • cfg

  • state

  • peek_blocks

Returns:

check_state(state)

Check if the specific function is reached with certain arguments

Parameters:

state (angr.SimState) – The state to check

Returns:

True if the function is reached with certain arguments, False otherwise.

Return type:

bool

class angr.exploration_techniques.Director(peek_blocks=100, peek_functions=5, goals=None, cfg_keep_states=False, goal_satisfied_callback=None, num_fallback_states=5)

Bases: ExplorationTechnique

An exploration technique for directed symbolic execution.

A control flow graph (using CFGEmulated) is built and refined during symbolic execution. Each time the execution reaches a block that is outside of the CFG, the CFG recovery will be triggered with that state, with a maximum recovery depth (100 by default). If we see a basic block during state stepping that is not yet in the control flow graph, we go back to control flow graph recovery and “peek” more blocks forward.

When stepping a simulation manager, all states are categorized into three different categories:

  • Might reach the destination within the peek depth. Those states are prioritized.

  • Will not reach the destination within the peek depth. Those states are de-prioritized. However, there is a little chance for those states to be explored as well in order to prevent over-fitting.

__init__(peek_blocks=100, peek_functions=5, goals=None, cfg_keep_states=False, goal_satisfied_callback=None, num_fallback_states=5)

Constructor.

step(simgr, stash='active', **kwargs)
Parameters:
  • simgr

  • stash

  • kwargs

Returns:

add_goal(goal)

Add a goal.

Parameters:

goal (BaseGoal) – The goal to add.

Returns:

None

class angr.exploration_techniques.DrillerCore(trace, fuzz_bitmap=None)

Bases: ExplorationTechnique

An exploration technique that symbolically follows an input looking for new state transitions.

It has to be used with Tracer exploration technique. Results are put in ‘diverted’ stash.

__init__(trace, fuzz_bitmap=None)

:param trace : The basic block trace. :type fuzz_bitmap: :param fuzz_bitmap: AFL’s bitmap of state transitions. Defaults to saying every transition is worth satisfying.

setup(simgr)

Perform any initialization on this manager you might need to do.

Parameters:

simgr (angr.SimulationManager) – The simulation manager to which you have just been added

step(simgr, stash='active', **kwargs)

Hook the process of stepping a stash forward. Should call simgr.step(stash, **kwargs) in order to do the actual processing.

Parameters:
class angr.exploration_techniques.ExecuteAddressGoal(addr)

Bases: BaseGoal

A goal that prioritizes states reaching (or are likely to reach) certain address in some specific steps.

__init__(addr)
check(cfg, state, peek_blocks)

Check if the specified address will be executed

Parameters:
  • cfg

  • state

  • peek_blocks (int)

Returns:

Return type:

bool

check_state(state)

Check if the current address is the target address.

Parameters:

state (angr.SimState) – The state to check.

Returns:

True if the current address is the target address, False otherwise.

Return type:

bool

class angr.exploration_techniques.ExplorationTechnique

Bases: object

An ExplorationTechnique is a set of hooks for a simulation manager that assists in the implementation of new techniques in symbolic exploration.

Any number of these methods may be overridden by a subclass. To use an exploration technique, call simgr.use_technique with an instance of the technique.

__init__()
setup(simgr)

Perform any initialization on this manager you might need to do.

Parameters:

simgr (angr.SimulationManager) – The simulation manager to which you have just been added

step(simgr, stash='active', **kwargs)

Hook the process of stepping a stash forward. Should call simgr.step(stash, **kwargs) in order to do the actual processing.

Parameters:
filter(simgr, state, **kwargs)

Perform filtering on which stash a state should be inserted into.

If the state should be filtered, return the name of the stash to move the state to. If you want to modify the state before filtering it, return a tuple of the stash to move the state to and the modified state. To defer to the original categorization procedure, return the result of simgr.filter(state, **kwargs)

If the user provided a filter_func in their step or run command, it will appear here.

Parameters:
selector(simgr, state, **kwargs)

Determine if a state should participate in the current round of stepping. Return True if the state should be stepped, and False if the state should not be stepped. To defer to the original selection procedure, return the result of simgr.selector(state, **kwargs).

If the user provided a selector_func in their step or run command, it will appear here.

Parameters:
step_state(simgr, state, **kwargs)

Determine the categorization of state successors into stashes. The result should be a dict mapping stash names to the list of successor states that fall into that stash, or None as a stash name to use the original stash name.

If you would like to directly work with a SimSuccessors object, you can obtain it with simgr.successors(state, **kwargs). This is not recommended, as it denies other hooks the opportunity to look at the successors. Therefore, the usual technique is to call simgr.step_state(state, **kwargs) and then mutate the returned dict before returning it yourself.

..note:: This takes precedence over the filter hook - filter is only applied to states returned from here in the None stash.

Parameters:
successors(simgr, state, **kwargs)

Perform the process of stepping a state forward, returning a SimSuccessors object.

To defer to the original succession procedure, return the result of simgr.successors(state, **kwargs). Be careful about not calling this method (e.g. calling project.factory.successors manually) as it denies other hooks the opportunity to instrument the step. Instead, you can mutate the kwargs for the step before calling the original, and mutate the result before returning it yourself.

If the user provided a successor_func in their step or run command, it will appear here.

Parameters:
complete(simgr)

Return whether or not this manager has reached a “completed” state, i.e. SimulationManager.run() should halt.

This is the one hook which is not subject to the nesting rules of hooks. You should not call simgr.complete, you should make your own decision and return True or False. Each of the techniques’ completion checkers will be called and the final result will be compted with simgr.completion_mode.

Parameters:

simgr (angr.SimulationManager)

class angr.exploration_techniques.Explorer(find=None, avoid=None, find_stash='found', avoid_stash='avoid', cfg=None, num_find=1, avoid_priority=False)

Bases: ExplorationTechnique

Search for up to “num_find” paths that satisfy condition “find”, avoiding condition “avoid”. Stashes found paths into “find_stash’ and avoided paths into “avoid_stash”.

The “find” and “avoid” parameters may be any of:

  • An address to find

  • A set or list of addresses to find

  • A function that takes a path and returns whether or not it matches.

If an angr CFG is passed in as the “cfg” parameter and “find” is either a number or a list or a set, then any paths which cannot possibly reach a success state without going through a failure state will be preemptively avoided.

If either the “find” or “avoid” parameter is a function returning a boolean, and a path triggers both conditions, it will be added to the find stash, unless “avoid_priority” is set to True.

__init__(find=None, avoid=None, find_stash='found', avoid_stash='avoid', cfg=None, num_find=1, avoid_priority=False)
setup(simgr)

Perform any initialization on this manager you might need to do.

Parameters:

simgr (angr.SimulationManager) – The simulation manager to which you have just been added

step(simgr, stash='active', **kwargs)

Hook the process of stepping a stash forward. Should call simgr.step(stash, **kwargs) in order to do the actual processing.

Parameters:
filter(simgr, state, **kwargs)

Perform filtering on which stash a state should be inserted into.

If the state should be filtered, return the name of the stash to move the state to. If you want to modify the state before filtering it, return a tuple of the stash to move the state to and the modified state. To defer to the original categorization procedure, return the result of simgr.filter(state, **kwargs)

If the user provided a filter_func in their step or run command, it will appear here.

Parameters:
complete(simgr)

Return whether or not this manager has reached a “completed” state, i.e. SimulationManager.run() should halt.

This is the one hook which is not subject to the nesting rules of hooks. You should not call simgr.complete, you should make your own decision and return True or False. Each of the techniques’ completion checkers will be called and the final result will be compted with simgr.completion_mode.

Parameters:

simgr (angr.SimulationManager)

class angr.exploration_techniques.LengthLimiter(max_length, drop=False)

Bases: ExplorationTechnique

Length limiter on paths.

__init__(max_length, drop=False)
step(simgr, stash='active', **kwargs)

Hook the process of stepping a stash forward. Should call simgr.step(stash, **kwargs) in order to do the actual processing.

Parameters:
class angr.exploration_techniques.LocalLoopSeer(bound=None, bound_reached=None, discard_stash='spinning')

Bases: ExplorationTechnique

LocalLoopSeer monitors exploration and maintains all loop-related data without relying on a control flow graph.

__init__(bound=None, bound_reached=None, discard_stash='spinning')
Parameters:
  • bound – Limit the number of iterations a loop may be executed.

  • bound_reached – If provided, should be a function that takes the LoopSeer and the succ_state. Will be called when loop execution reach the given bound. Default to moving states that exceed the loop limit to a discard stash.

  • discard_stash – Name of the stash containing states exceeding the loop limit.

setup(simgr)

Perform any initialization on this manager you might need to do.

Parameters:

simgr (angr.SimulationManager) – The simulation manager to which you have just been added

filter(simgr, state, **kwargs)

Perform filtering on which stash a state should be inserted into.

If the state should be filtered, return the name of the stash to move the state to. If you want to modify the state before filtering it, return a tuple of the stash to move the state to and the modified state. To defer to the original categorization procedure, return the result of simgr.filter(state, **kwargs)

If the user provided a filter_func in their step or run command, it will appear here.

Parameters:
successors(simgr, state, **kwargs)

Perform the process of stepping a state forward, returning a SimSuccessors object.

To defer to the original succession procedure, return the result of simgr.successors(state, **kwargs). Be careful about not calling this method (e.g. calling project.factory.successors manually) as it denies other hooks the opportunity to instrument the step. Instead, you can mutate the kwargs for the step before calling the original, and mutate the result before returning it yourself.

If the user provided a successor_func in their step or run command, it will appear here.

Parameters:
class angr.exploration_techniques.LoopSeer(cfg=None, functions=None, loops=None, use_header=False, bound=None, bound_reached=None, discard_stash='spinning', limit_concrete_loops=True)

Bases: ExplorationTechnique

This exploration technique monitors exploration and maintains all loop-related data (well, currently it is just the loop trip counts, but feel free to add something else).

__init__(cfg=None, functions=None, loops=None, use_header=False, bound=None, bound_reached=None, discard_stash='spinning', limit_concrete_loops=True)
Parameters:
  • cfg – Normalized CFG is required.

  • functions – Function(s) containing the loop(s) to be analyzed.

  • loops – Specific group of Loop(s) to be analyzed, if this is None we run the LoopFinder analysis.

  • use_header – Whether to use header based trip counter to compare with the bound limit.

  • bound – Limit the number of iterations a loop may be executed.

  • bound_reached – If provided, should be a function that takes the LoopSeer and the succ_state. Will be called when loop execution reach the given bound. Default to moving states that exceed the loop limit to a discard stash.

  • discard_stash – Name of the stash containing states exceeding the loop limit.

  • limit_concrete_loops – If False, do not limit a loop back-edge if it is the only successor (Defaults to True to maintain the original behavior)

setup(simgr)

Perform any initialization on this manager you might need to do.

Parameters:

simgr (angr.SimulationManager) – The simulation manager to which you have just been added

filter(simgr, state, **kwargs)

Perform filtering on which stash a state should be inserted into.

If the state should be filtered, return the name of the stash to move the state to. If you want to modify the state before filtering it, return a tuple of the stash to move the state to and the modified state. To defer to the original categorization procedure, return the result of simgr.filter(state, **kwargs)

If the user provided a filter_func in their step or run command, it will appear here.

Parameters:
successors(simgr, state, **kwargs)

Perform the process of stepping a state forward, returning a SimSuccessors object.

To defer to the original succession procedure, return the result of simgr.successors(state, **kwargs). Be careful about not calling this method (e.g. calling project.factory.successors manually) as it denies other hooks the opportunity to instrument the step. Instead, you can mutate the kwargs for the step before calling the original, and mutate the result before returning it yourself.

If the user provided a successor_func in their step or run command, it will appear here.

Parameters:
class angr.exploration_techniques.ManualMergepoint(address, wait_counter=10, prune=True)

Bases: ExplorationTechnique

__init__(address, wait_counter=10, prune=True)
setup(simgr)

Perform any initialization on this manager you might need to do.

Parameters:

simgr (angr.SimulationManager) – The simulation manager to which you have just been added

mark_nofilter(simgr, stash)
mark_okfilter(simgr, stash)
step(simgr, stash='active', **kwargs)

Hook the process of stepping a stash forward. Should call simgr.step(stash, **kwargs) in order to do the actual processing.

Parameters:
class angr.exploration_techniques.MemoryWatcher(min_memory=512, memory_stash='lowmem')

Bases: ExplorationTechnique

Memory Watcher

Parameters:
  • min_memory (int,optional) – Minimum amount of free memory in MB before stopping execution (default: 95% memory use)

  • memory_stash (str, optional) – What to call the low memory stash (default: ‘lowmem’)

At each step, keep an eye on how much memory is left on the system. Stash off states to effectively stop execution if we’re below a given threshold.

__init__(min_memory=512, memory_stash='lowmem')
setup(simgr)

Perform any initialization on this manager you might need to do.

Parameters:

simgr (angr.SimulationManager) – The simulation manager to which you have just been added

step(simgr, stash='active', **kwargs)

Hook the process of stepping a stash forward. Should call simgr.step(stash, **kwargs) in order to do the actual processing.

Parameters:
class angr.exploration_techniques.Oppologist

Bases: ExplorationTechnique

The Oppologist is an exploration technique that forces uncooperative code through qemu.

__init__()
successors(simgr, state, **kwargs)

Perform the process of stepping a state forward, returning a SimSuccessors object.

To defer to the original succession procedure, return the result of simgr.successors(state, **kwargs). Be careful about not calling this method (e.g. calling project.factory.successors manually) as it denies other hooks the opportunity to instrument the step. Instead, you can mutate the kwargs for the step before calling the original, and mutate the result before returning it yourself.

If the user provided a successor_func in their step or run command, it will appear here.

Parameters:
class angr.exploration_techniques.Slicecutor(annotated_cfg, force_taking_exit=False, force_sat=False)

Bases: ExplorationTechnique

The Slicecutor is an exploration that executes provided code slices.

Parameters:

force_sat (bool)

__init__(annotated_cfg, force_taking_exit=False, force_sat=False)

All parameters except annotated_cfg are optional.

Parameters:
  • annotated_cfg – The AnnotatedCFG that provides the code slice.

  • force_taking_exit – Set to True if you want to create a successor based on our slice in case of unconstrained successors.

  • force_sat (bool) – If a branch specified by the slice is unsatisfiable, set this option to True if you want to force it to be satisfiable and be taken anyway.

setup(simgr)

Perform any initialization on this manager you might need to do.

Parameters:

simgr (angr.SimulationManager) – The simulation manager to which you have just been added

filter(simgr, state, **kwargs)

Perform filtering on which stash a state should be inserted into.

If the state should be filtered, return the name of the stash to move the state to. If you want to modify the state before filtering it, return a tuple of the stash to move the state to and the modified state. To defer to the original categorization procedure, return the result of simgr.filter(state, **kwargs)

If the user provided a filter_func in their step or run command, it will appear here.

Parameters:
step_state(simgr, state, **kwargs)

Determine the categorization of state successors into stashes. The result should be a dict mapping stash names to the list of successor states that fall into that stash, or None as a stash name to use the original stash name.

If you would like to directly work with a SimSuccessors object, you can obtain it with simgr.successors(state, **kwargs). This is not recommended, as it denies other hooks the opportunity to look at the successors. Therefore, the usual technique is to call simgr.step_state(state, **kwargs) and then mutate the returned dict before returning it yourself.

..note:: This takes precedence over the filter hook - filter is only applied to states returned from here in the None stash.

Parameters:
successors(simgr, state, **kwargs)

Perform the process of stepping a state forward, returning a SimSuccessors object.

To defer to the original succession procedure, return the result of simgr.successors(state, **kwargs). Be careful about not calling this method (e.g. calling project.factory.successors manually) as it denies other hooks the opportunity to instrument the step. Instead, you can mutate the kwargs for the step before calling the original, and mutate the result before returning it yourself.

If the user provided a successor_func in their step or run command, it will appear here.

Parameters:
class angr.exploration_techniques.Spiller(src_stash='active', min=5, max=10, staging_stash='spill_stage', staging_min=10, staging_max=20, pickle_callback=None, unpickle_callback=None, post_pickle_callback=None, priority_key=None, vault=None, states_collection=None)

Bases: ExplorationTechnique

Automatically spill states out. It can spill out states to a different stash, spill them out to ANA, or first do the former and then (after enough states) the latter.

__init__(src_stash='active', min=5, max=10, staging_stash='spill_stage', staging_min=10, staging_max=20, pickle_callback=None, unpickle_callback=None, post_pickle_callback=None, priority_key=None, vault=None, states_collection=None)

Initializes the spiller.

Parameters:
  • max – the number of states that are not spilled

  • src_stash – the stash from which to spill states (default: active)

  • staging_stash – the stash to which to spill states (default: “spill_stage”)

  • staging_max – the number of states that can be in the staging stash before things get spilled to ANA (default: None. If staging_stash is set, then this means unlimited, and ANA will not be used).

  • priority_key – a function that takes a state and returns its numerical priority (MAX_INT is lowest priority). By default, self.state_priority will be used, which prioritizes by object ID.

  • vault – an angr.Vault object to handle storing and loading of states. If not provided, an angr.vaults.VaultShelf will be created with a temporary file.

step(simgr, stash='active', **kwargs)

Hook the process of stepping a stash forward. Should call simgr.step(stash, **kwargs) in order to do the actual processing.

Parameters:
static state_priority(state)
class angr.exploration_techniques.StochasticSearch(start_state, restart_prob=0.0001)

Bases: ExplorationTechnique

Stochastic Search.

Will only keep one path active at a time, any others will be discarded. Before each pass through, weights are randomly assigned to each basic block. These weights form a probability distribution for determining which state remains after splits. When we run out of active paths to step, we start again from the start state.

__init__(start_state, restart_prob=0.0001)
Parameters:
  • start_state – The initial state from which exploration stems.

  • restart_prob – The probability of randomly restarting the search (default 0.0001).

step(simgr, stash='active', **kwargs)

Hook the process of stepping a stash forward. Should call simgr.step(stash, **kwargs) in order to do the actual processing.

Parameters:
class angr.exploration_techniques.StubStasher

Bases: ExplorationTechnique

Stash states that reach a stub SimProcedure.

static post_filter(state)
step(simgr, stash='active', **kwargs)

Hook the process of stepping a stash forward. Should call simgr.step(stash, **kwargs) in order to do the actual processing.

Parameters:
class angr.exploration_techniques.Suggestions

Bases: ExplorationTechnique

An exploration technique which analyzes failure cases and logs suggestions for how to mitigate them in future analyses.

__init__()
step(simgr, stash='active', **kwargs)

Hook the process of stepping a stash forward. Should call simgr.step(stash, **kwargs) in order to do the actual processing.

Parameters:
static report(state, event)
class angr.exploration_techniques.TechniqueBuilder(setup=None, step_state=None, step=None, successors=None, filter=None, selector=None, complete=None)

Bases: ExplorationTechnique

This meta technique could be used to hook a couple of simulation manager methods without actually creating a new exploration technique, for example:

class SomeComplexAnalysis(Analysis):

def do_something():

simgr = self.project.factory.simulation_manager() simgr.use_tech(ProxyTechnique(step_state=self._step_state)) simgr.run()

def _step_state(self, state):

# Do stuff! pass

In the above example, the _step_state method can access all the necessary stuff, hidden in the analysis instance, without passing that instance to a one-shot-styled exploration technique.

__init__(setup=None, step_state=None, step=None, successors=None, filter=None, selector=None, complete=None)
class angr.exploration_techniques.Threading(threads=8, local_stash='thread_local')

Bases: ExplorationTechnique

Enable multithreading.

This is only useful in paths where a lot of time is taken inside z3, doing constraint solving. This is because of python’s GIL, which says that only one thread at a time may be executing python code.

__init__(threads=8, local_stash='thread_local')
step(simgr, stash='active', error_list=None, target_stash=None, **kwargs)

Hook the process of stepping a stash forward. Should call simgr.step(stash, **kwargs) in order to do the actual processing.

Parameters:
inner_step(state, simgr, **kwargs)
class angr.exploration_techniques.Timeout(timeout=None)

Bases: ExplorationTechnique

Timeout exploration technique that stops an active exploration if the run time exceeds a predefined timeout

__init__(timeout=None)
setup(simgr)

Perform any initialization on this manager you might need to do.

Parameters:

simgr (angr.SimulationManager) – The simulation manager to which you have just been added

step(simgr, stash='active', **kwargs)

Hook the process of stepping a stash forward. Should call simgr.step(stash, **kwargs) in order to do the actual processing.

Parameters:
class angr.exploration_techniques.Tracer(trace=None, resiliency=False, keep_predecessors=1, crash_addr=None, syscall_data=None, copy_states=False, fast_forward_to_entry=True, mode='strict', aslr=True, follow_unsat=False)

Bases: ExplorationTechnique

An exploration technique that follows an angr path with a concrete input. The tracing result is the state at the last address of the trace, which can be found in the ‘traced’ stash.

If the given concrete input makes the program crash, you should provide crash_addr, and the crashing state will be found in the ‘crashed’ stash.

Parameters:
  • trace – The basic block trace.

  • resiliency – Should we continue to step forward even if qemu and angr disagree?

  • keep_predecessors – Number of states before the final state we should log.

  • crash_addr – If the trace resulted in a crash, provide the crashing instruction pointer here, and the ‘crashed’ stash will be populated with the crashing state.

  • syscall_data – Data related to various syscalls recorded by tracer for replaying

  • copy_states – Whether COPY_STATES should be enabled for the tracing state. It is off by default because most tracing workloads benefit greatly from not performing copying. You want to enable it if you want to see the missed states. It will be re-added for the last 2% of the trace in order to set the predecessors list correctly. If you turn this on you may want to enable the LAZY_SOLVES option.

  • mode – Tracing mode.

  • aslr – Whether there are aslr slides. if not, tracer uses trace address as state address.

  • follow_unsat – Whether unsatisfiable states should be treated as potential successors or not.

Variables:

predecessors – A list of states in the history before the final state.

__init__(trace=None, resiliency=False, keep_predecessors=1, crash_addr=None, syscall_data=None, copy_states=False, fast_forward_to_entry=True, mode='strict', aslr=True, follow_unsat=False)
set_fd_data(fd_data)

Set concrete bytes of various fds read by the program

Parameters:

fd_data (dict[int, bytes])

setup(simgr)

Perform any initialization on this manager you might need to do.

Parameters:

simgr (angr.SimulationManager) – The simulation manager to which you have just been added

complete(simgr)

Return whether or not this manager has reached a “completed” state, i.e. SimulationManager.run() should halt.

This is the one hook which is not subject to the nesting rules of hooks. You should not call simgr.complete, you should make your own decision and return True or False. Each of the techniques’ completion checkers will be called and the final result will be compted with simgr.completion_mode.

Parameters:

simgr (angr.SimulationManager)

filter(simgr, state, **kwargs)

Perform filtering on which stash a state should be inserted into.

If the state should be filtered, return the name of the stash to move the state to. If you want to modify the state before filtering it, return a tuple of the stash to move the state to and the modified state. To defer to the original categorization procedure, return the result of simgr.filter(state, **kwargs)

If the user provided a filter_func in their step or run command, it will appear here.

Parameters:
step(simgr, stash='active', **kwargs)

Hook the process of stepping a stash forward. Should call simgr.step(stash, **kwargs) in order to do the actual processing.

Parameters:
step_state(simgr, state, **kwargs)

Determine the categorization of state successors into stashes. The result should be a dict mapping stash names to the list of successor states that fall into that stash, or None as a stash name to use the original stash name.

If you would like to directly work with a SimSuccessors object, you can obtain it with simgr.successors(state, **kwargs). This is not recommended, as it denies other hooks the opportunity to look at the successors. Therefore, the usual technique is to call simgr.step_state(state, **kwargs) and then mutate the returned dict before returning it yourself.

..note:: This takes precedence over the filter hook - filter is only applied to states returned from here in the None stash.

Parameters:
classmethod crash_windup(state, crash_addr)
class angr.exploration_techniques.UniqueSearch(similarity_func=None, deferred_stash='deferred')

Bases: ExplorationTechnique

Unique Search.

Will only keep one path active at a time, any others will be deferred. The state that is explored depends on how unique it is relative to the other deferred states. A path’s uniqueness is determined by its average similarity between the other (deferred) paths. Similarity is calculated based on the supplied similarity_func, which by default is: The (L2) distance between the counts of the state addresses in the history of the path.

__init__(similarity_func=None, deferred_stash='deferred')
Parameters:
  • similarity_func – How to calculate similarity between two states.

  • deferred_stash – Where to store the deferred states.

setup(simgr)

Perform any initialization on this manager you might need to do.

Parameters:

simgr (angr.SimulationManager) – The simulation manager to which you have just been added

step(simgr, stash='active', **kwargs)

Hook the process of stepping a stash forward. Should call simgr.step(stash, **kwargs) in order to do the actual processing.

Parameters:
static similarity(state_a, state_b)

The (L2) distance between the counts of the state addresses in the history of the path. :type state_a: :param state_a: The first state to compare :type state_b: :param state_b: The second state to compare

static sequence_matcher_similarity(state_a, state_b)

The difflib.SequenceMatcher ratio between the state addresses in the history of the path. :type state_a: :param state_a: The first state to compare :type state_b: :param state_b: The second state to compare

class angr.exploration_techniques.Veritesting(**options)

Bases: ExplorationTechnique

Enable veritesting. This technique, described in a paper[1] from CMU, attempts to address the problem of state explosions in loops by performing smart merging.

[1] https://users.ece.cmu.edu/~aavgerin/papers/veritesting-icse-2014.pdf

__init__(**options)
step_state(simgr, state, successor_func=None, **kwargs)

Determine the categorization of state successors into stashes. The result should be a dict mapping stash names to the list of successor states that fall into that stash, or None as a stash name to use the original stash name.

If you would like to directly work with a SimSuccessors object, you can obtain it with simgr.successors(state, **kwargs). This is not recommended, as it denies other hooks the opportunity to look at the successors. Therefore, the usual technique is to call simgr.step_state(state, **kwargs) and then mutate the returned dict before returning it yourself.

..note:: This takes precedence over the filter hook - filter is only applied to states returned from here in the None stash.

Parameters:
class angr.exploration_techniques.timeout.Timeout(timeout=None)

Bases: ExplorationTechnique

Timeout exploration technique that stops an active exploration if the run time exceeds a predefined timeout

__init__(timeout=None)
setup(simgr)

Perform any initialization on this manager you might need to do.

Parameters:

simgr (angr.SimulationManager) – The simulation manager to which you have just been added

step(simgr, stash='active', **kwargs)

Hook the process of stepping a stash forward. Should call simgr.step(stash, **kwargs) in order to do the actual processing.

Parameters:
class angr.exploration_techniques.dfs.DFS(deferred_stash='deferred')

Bases: ExplorationTechnique

Depth-first search.

Will only keep one path active at a time, any others will be stashed in the ‘deferred’ stash. When we run out of active paths to step, we take the longest one from deferred and continue.

__init__(deferred_stash='deferred')
setup(simgr)

Perform any initialization on this manager you might need to do.

Parameters:

simgr (angr.SimulationManager) – The simulation manager to which you have just been added

step(simgr, stash='active', **kwargs)

Hook the process of stepping a stash forward. Should call simgr.step(stash, **kwargs) in order to do the actual processing.

Parameters:
class angr.exploration_techniques.explorer.Explorer(find=None, avoid=None, find_stash='found', avoid_stash='avoid', cfg=None, num_find=1, avoid_priority=False)

Bases: ExplorationTechnique

Search for up to “num_find” paths that satisfy condition “find”, avoiding condition “avoid”. Stashes found paths into “find_stash’ and avoided paths into “avoid_stash”.

The “find” and “avoid” parameters may be any of:

  • An address to find

  • A set or list of addresses to find

  • A function that takes a path and returns whether or not it matches.

If an angr CFG is passed in as the “cfg” parameter and “find” is either a number or a list or a set, then any paths which cannot possibly reach a success state without going through a failure state will be preemptively avoided.

If either the “find” or “avoid” parameter is a function returning a boolean, and a path triggers both conditions, it will be added to the find stash, unless “avoid_priority” is set to True.

__init__(find=None, avoid=None, find_stash='found', avoid_stash='avoid', cfg=None, num_find=1, avoid_priority=False)
setup(simgr)

Perform any initialization on this manager you might need to do.

Parameters:

simgr (angr.SimulationManager) – The simulation manager to which you have just been added

step(simgr, stash='active', **kwargs)

Hook the process of stepping a stash forward. Should call simgr.step(stash, **kwargs) in order to do the actual processing.

Parameters:
filter(simgr, state, **kwargs)

Perform filtering on which stash a state should be inserted into.

If the state should be filtered, return the name of the stash to move the state to. If you want to modify the state before filtering it, return a tuple of the stash to move the state to and the modified state. To defer to the original categorization procedure, return the result of simgr.filter(state, **kwargs)

If the user provided a filter_func in their step or run command, it will appear here.

Parameters:
complete(simgr)

Return whether or not this manager has reached a “completed” state, i.e. SimulationManager.run() should halt.

This is the one hook which is not subject to the nesting rules of hooks. You should not call simgr.complete, you should make your own decision and return True or False. Each of the techniques’ completion checkers will be called and the final result will be compted with simgr.completion_mode.

Parameters:

simgr (angr.SimulationManager)

class angr.exploration_techniques.lengthlimiter.LengthLimiter(max_length, drop=False)

Bases: ExplorationTechnique

Length limiter on paths.

__init__(max_length, drop=False)
step(simgr, stash='active', **kwargs)

Hook the process of stepping a stash forward. Should call simgr.step(stash, **kwargs) in order to do the actual processing.

Parameters:
class angr.exploration_techniques.manual_mergepoint.ManualMergepoint(address, wait_counter=10, prune=True)

Bases: ExplorationTechnique

__init__(address, wait_counter=10, prune=True)
setup(simgr)

Perform any initialization on this manager you might need to do.

Parameters:

simgr (angr.SimulationManager) – The simulation manager to which you have just been added

mark_nofilter(simgr, stash)
mark_okfilter(simgr, stash)
step(simgr, stash='active', **kwargs)

Hook the process of stepping a stash forward. Should call simgr.step(stash, **kwargs) in order to do the actual processing.

Parameters:
class angr.exploration_techniques.spiller.PickledStatesBase

Bases: object

The base class of pickled states

sort()

Sort pickled states.

add(prio, sid)

Add a newly pickled state.

Parameters:
  • prio (int) – Priority of the state.

  • sid (str) – Persistent ID of the state.

Returns:

None

pop_n(n)

Pop the top N states.

Parameters:

n (int) – Number of states to take.

Returns:

A list of states.

class angr.exploration_techniques.spiller.PickledStatesList

Bases: PickledStatesBase

List-backed pickled state storage.

__init__()
sort()

Sort pickled states.

add(prio, sid)

Add a newly pickled state.

Parameters:
  • prio (int) – Priority of the state.

  • sid (str) – Persistent ID of the state.

Returns:

None

pop_n(n)

Pop the top N states.

Parameters:

n (int) – Number of states to take.

Returns:

A list of states.

class angr.exploration_techniques.spiller.PickledStatesDb(db_str='sqlite:///:memory:')

Bases: PickledStatesBase

Database-backed pickled state storage.

__init__(db_str='sqlite:///:memory:')
sort()

Sort pickled states.

add(prio, sid, taken=False, stash='spilled')

Add a newly pickled state.

Parameters:
  • prio (int) – Priority of the state.

  • sid (str) – Persistent ID of the state.

Returns:

None

pop_n(n, stash='spilled')

Pop the top N states.

Parameters:

n (int) – Number of states to take.

Returns:

A list of states.

get_recent_n(n, stash='spilled')
count()
class angr.exploration_techniques.spiller.Spiller(src_stash='active', min=5, max=10, staging_stash='spill_stage', staging_min=10, staging_max=20, pickle_callback=None, unpickle_callback=None, post_pickle_callback=None, priority_key=None, vault=None, states_collection=None)

Bases: ExplorationTechnique

Automatically spill states out. It can spill out states to a different stash, spill them out to ANA, or first do the former and then (after enough states) the latter.

__init__(src_stash='active', min=5, max=10, staging_stash='spill_stage', staging_min=10, staging_max=20, pickle_callback=None, unpickle_callback=None, post_pickle_callback=None, priority_key=None, vault=None, states_collection=None)

Initializes the spiller.

Parameters:
  • max – the number of states that are not spilled

  • src_stash – the stash from which to spill states (default: active)

  • staging_stash – the stash to which to spill states (default: “spill_stage”)

  • staging_max – the number of states that can be in the staging stash before things get spilled to ANA (default: None. If staging_stash is set, then this means unlimited, and ANA will not be used).

  • priority_key – a function that takes a state and returns its numerical priority (MAX_INT is lowest priority). By default, self.state_priority will be used, which prioritizes by object ID.

  • vault – an angr.Vault object to handle storing and loading of states. If not provided, an angr.vaults.VaultShelf will be created with a temporary file.

step(simgr, stash='active', **kwargs)

Hook the process of stepping a stash forward. Should call simgr.step(stash, **kwargs) in order to do the actual processing.

Parameters:
static state_priority(state)
class angr.exploration_techniques.spiller_db.PickledState(**kwargs)

Bases: Base

id
priority
taken
stash
timestamp
__init__(**kwargs)

A simple constructor that allows initialization from kwargs.

Sets attributes on the constructed instance using the names and values in kwargs.

Only keys that are present as attributes of the instance’s class are allowed. These could be, for example, any mapped columns or relationships.

class angr.exploration_techniques.threading.Threading(threads=8, local_stash='thread_local')

Bases: ExplorationTechnique

Enable multithreading.

This is only useful in paths where a lot of time is taken inside z3, doing constraint solving. This is because of python’s GIL, which says that only one thread at a time may be executing python code.

__init__(threads=8, local_stash='thread_local')
step(simgr, stash='active', error_list=None, target_stash=None, **kwargs)

Hook the process of stepping a stash forward. Should call simgr.step(stash, **kwargs) in order to do the actual processing.

Parameters:
inner_step(state, simgr, **kwargs)
class angr.exploration_techniques.veritesting.Veritesting(**options)

Bases: ExplorationTechnique

Enable veritesting. This technique, described in a paper[1] from CMU, attempts to address the problem of state explosions in loops by performing smart merging.

[1] https://users.ece.cmu.edu/~aavgerin/papers/veritesting-icse-2014.pdf

__init__(**options)
step_state(simgr, state, successor_func=None, **kwargs)

Determine the categorization of state successors into stashes. The result should be a dict mapping stash names to the list of successor states that fall into that stash, or None as a stash name to use the original stash name.

If you would like to directly work with a SimSuccessors object, you can obtain it with simgr.successors(state, **kwargs). This is not recommended, as it denies other hooks the opportunity to look at the successors. Therefore, the usual technique is to call simgr.step_state(state, **kwargs) and then mutate the returned dict before returning it yourself.

..note:: This takes precedence over the filter hook - filter is only applied to states returned from here in the None stash.

Parameters:
class angr.exploration_techniques.tracer.TracingMode

Bases: object

Variables:
  • Strict – Strict mode, the default mode, where an exception is raised immediately if tracer’s path deviates from the provided trace.

  • Permissive – Permissive mode, where tracer attempts to force the path back to the provided trace when a deviation happens. This does not always work, especially when the cause of deviation is related to input that will later be used in exploit generation. But, it might work magically sometimes.

  • CatchDesync – CatchDesync mode, catch desync because of sim_procedures. It might be a sign of something interesting.

Strict = 'strict'
Permissive = 'permissive'
CatchDesync = 'catch_desync'
exception angr.exploration_techniques.tracer.TracerDesyncError(msg, deviating_addr=None, deviating_trace_idx=None)

Bases: AngrTracerError

An error class to report tracing Tracing desyncronization error

__init__(msg, deviating_addr=None, deviating_trace_idx=None)
class angr.exploration_techniques.tracer.RepHook(mnemonic)

Bases: object

Hook rep movs/stos to speed up constraint solving TODO: This should be made an exploration technique later

__init__(mnemonic)
run(state)
class angr.exploration_techniques.tracer.Tracer(trace=None, resiliency=False, keep_predecessors=1, crash_addr=None, syscall_data=None, copy_states=False, fast_forward_to_entry=True, mode='strict', aslr=True, follow_unsat=False)

Bases: ExplorationTechnique

An exploration technique that follows an angr path with a concrete input. The tracing result is the state at the last address of the trace, which can be found in the ‘traced’ stash.

If the given concrete input makes the program crash, you should provide crash_addr, and the crashing state will be found in the ‘crashed’ stash.

Parameters:
  • trace – The basic block trace.

  • resiliency – Should we continue to step forward even if qemu and angr disagree?

  • keep_predecessors – Number of states before the final state we should log.

  • crash_addr – If the trace resulted in a crash, provide the crashing instruction pointer here, and the ‘crashed’ stash will be populated with the crashing state.

  • syscall_data – Data related to various syscalls recorded by tracer for replaying

  • copy_states – Whether COPY_STATES should be enabled for the tracing state. It is off by default because most tracing workloads benefit greatly from not performing copying. You want to enable it if you want to see the missed states. It will be re-added for the last 2% of the trace in order to set the predecessors list correctly. If you turn this on you may want to enable the LAZY_SOLVES option.

  • mode – Tracing mode.

  • aslr – Whether there are aslr slides. if not, tracer uses trace address as state address.

  • follow_unsat – Whether unsatisfiable states should be treated as potential successors or not.

Variables:

predecessors – A list of states in the history before the final state.

__init__(trace=None, resiliency=False, keep_predecessors=1, crash_addr=None, syscall_data=None, copy_states=False, fast_forward_to_entry=True, mode='strict', aslr=True, follow_unsat=False)
set_fd_data(fd_data)

Set concrete bytes of various fds read by the program

Parameters:

fd_data (dict[int, bytes])

setup(simgr)

Perform any initialization on this manager you might need to do.

Parameters:

simgr (angr.SimulationManager) – The simulation manager to which you have just been added

complete(simgr)

Return whether or not this manager has reached a “completed” state, i.e. SimulationManager.run() should halt.

This is the one hook which is not subject to the nesting rules of hooks. You should not call simgr.complete, you should make your own decision and return True or False. Each of the techniques’ completion checkers will be called and the final result will be compted with simgr.completion_mode.

Parameters:

simgr (angr.SimulationManager)

filter(simgr, state, **kwargs)

Perform filtering on which stash a state should be inserted into.

If the state should be filtered, return the name of the stash to move the state to. If you want to modify the state before filtering it, return a tuple of the stash to move the state to and the modified state. To defer to the original categorization procedure, return the result of simgr.filter(state, **kwargs)

If the user provided a filter_func in their step or run command, it will appear here.

Parameters:
step(simgr, stash='active', **kwargs)

Hook the process of stepping a stash forward. Should call simgr.step(stash, **kwargs) in order to do the actual processing.

Parameters:
step_state(simgr, state, **kwargs)

Determine the categorization of state successors into stashes. The result should be a dict mapping stash names to the list of successor states that fall into that stash, or None as a stash name to use the original stash name.

If you would like to directly work with a SimSuccessors object, you can obtain it with simgr.successors(state, **kwargs). This is not recommended, as it denies other hooks the opportunity to look at the successors. Therefore, the usual technique is to call simgr.step_state(state, **kwargs) and then mutate the returned dict before returning it yourself.

..note:: This takes precedence over the filter hook - filter is only applied to states returned from here in the None stash.

Parameters:
classmethod crash_windup(state, crash_addr)
class angr.exploration_techniques.driller_core.DrillerCore(trace, fuzz_bitmap=None)

Bases: ExplorationTechnique

An exploration technique that symbolically follows an input looking for new state transitions.

It has to be used with Tracer exploration technique. Results are put in ‘diverted’ stash.

__init__(trace, fuzz_bitmap=None)

:param trace : The basic block trace. :type fuzz_bitmap: :param fuzz_bitmap: AFL’s bitmap of state transitions. Defaults to saying every transition is worth satisfying.

setup(simgr)

Perform any initialization on this manager you might need to do.

Parameters:

simgr (angr.SimulationManager) – The simulation manager to which you have just been added

step(simgr, stash='active', **kwargs)

Hook the process of stepping a stash forward. Should call simgr.step(stash, **kwargs) in order to do the actual processing.

Parameters:
class angr.exploration_techniques.slicecutor.Slicecutor(annotated_cfg, force_taking_exit=False, force_sat=False)

Bases: ExplorationTechnique

The Slicecutor is an exploration that executes provided code slices.

Parameters:

force_sat (bool)

__init__(annotated_cfg, force_taking_exit=False, force_sat=False)

All parameters except annotated_cfg are optional.

Parameters:
  • annotated_cfg – The AnnotatedCFG that provides the code slice.

  • force_taking_exit – Set to True if you want to create a successor based on our slice in case of unconstrained successors.

  • force_sat (bool) – If a branch specified by the slice is unsatisfiable, set this option to True if you want to force it to be satisfiable and be taken anyway.

setup(simgr)

Perform any initialization on this manager you might need to do.

Parameters:

simgr (angr.SimulationManager) – The simulation manager to which you have just been added

filter(simgr, state, **kwargs)

Perform filtering on which stash a state should be inserted into.

If the state should be filtered, return the name of the stash to move the state to. If you want to modify the state before filtering it, return a tuple of the stash to move the state to and the modified state. To defer to the original categorization procedure, return the result of simgr.filter(state, **kwargs)

If the user provided a filter_func in their step or run command, it will appear here.

Parameters:
step_state(simgr, state, **kwargs)

Determine the categorization of state successors into stashes. The result should be a dict mapping stash names to the list of successor states that fall into that stash, or None as a stash name to use the original stash name.

If you would like to directly work with a SimSuccessors object, you can obtain it with simgr.successors(state, **kwargs). This is not recommended, as it denies other hooks the opportunity to look at the successors. Therefore, the usual technique is to call simgr.step_state(state, **kwargs) and then mutate the returned dict before returning it yourself.

..note:: This takes precedence over the filter hook - filter is only applied to states returned from here in the None stash.

Parameters:
successors(simgr, state, **kwargs)

Perform the process of stepping a state forward, returning a SimSuccessors object.

To defer to the original succession procedure, return the result of simgr.successors(state, **kwargs). Be careful about not calling this method (e.g. calling project.factory.successors manually) as it denies other hooks the opportunity to instrument the step. Instead, you can mutate the kwargs for the step before calling the original, and mutate the result before returning it yourself.

If the user provided a successor_func in their step or run command, it will appear here.

Parameters:
class angr.exploration_techniques.director.BaseGoal(sort)

Bases: object

REQUIRE_CFG_STATES = False
__init__(sort)
check(cfg, state, peek_blocks)
Parameters:
Returns:

True if we can determine that this condition is definitely satisfiable if the path is taken, False otherwise.

Return type:

bool

check_state(state)

Check if the current state satisfies the goal.

Parameters:

state (angr.SimState) – The state to check.

Returns:

True if it satisfies the goal, False otherwise.

Return type:

bool

class angr.exploration_techniques.director.ExecuteAddressGoal(addr)

Bases: BaseGoal

A goal that prioritizes states reaching (or are likely to reach) certain address in some specific steps.

__init__(addr)
check(cfg, state, peek_blocks)

Check if the specified address will be executed

Parameters:
  • cfg

  • state

  • peek_blocks (int)

Returns:

Return type:

bool

check_state(state)

Check if the current address is the target address.

Parameters:

state (angr.SimState) – The state to check.

Returns:

True if the current address is the target address, False otherwise.

Return type:

bool

class angr.exploration_techniques.director.CallFunctionGoal(function, arguments)

Bases: BaseGoal

A goal that prioritizes states reaching certain function, and optionally with specific arguments. Note that constraints on arguments (and on function address as well) have to be identifiable on an accurate CFG. For example, you may have a CallFunctionGoal saying “call printf with the first argument being ‘Hello, world’”, and CFGEmulated must be able to figure our the first argument to printf is in fact “Hello, world”, not some symbolic strings that will be constrained to “Hello, world” during symbolic execution (or simulation, however you put it).

REQUIRE_CFG_STATES = True
__init__(function, arguments)
check(cfg, state, peek_blocks)

Check if the specified function will be reached with certain arguments.

Parameters:
  • cfg

  • state

  • peek_blocks

Returns:

check_state(state)

Check if the specific function is reached with certain arguments

Parameters:

state (angr.SimState) – The state to check

Returns:

True if the function is reached with certain arguments, False otherwise.

Return type:

bool

class angr.exploration_techniques.director.Director(peek_blocks=100, peek_functions=5, goals=None, cfg_keep_states=False, goal_satisfied_callback=None, num_fallback_states=5)

Bases: ExplorationTechnique

An exploration technique for directed symbolic execution.

A control flow graph (using CFGEmulated) is built and refined during symbolic execution. Each time the execution reaches a block that is outside of the CFG, the CFG recovery will be triggered with that state, with a maximum recovery depth (100 by default). If we see a basic block during state stepping that is not yet in the control flow graph, we go back to control flow graph recovery and “peek” more blocks forward.

When stepping a simulation manager, all states are categorized into three different categories:

  • Might reach the destination within the peek depth. Those states are prioritized.

  • Will not reach the destination within the peek depth. Those states are de-prioritized. However, there is a little chance for those states to be explored as well in order to prevent over-fitting.

__init__(peek_blocks=100, peek_functions=5, goals=None, cfg_keep_states=False, goal_satisfied_callback=None, num_fallback_states=5)

Constructor.

step(simgr, stash='active', **kwargs)
Parameters:
  • simgr

  • stash

  • kwargs

Returns:

add_goal(goal)

Add a goal.

Parameters:

goal (BaseGoal) – The goal to add.

Returns:

None

class angr.exploration_techniques.oppologist.Oppologist

Bases: ExplorationTechnique

The Oppologist is an exploration technique that forces uncooperative code through qemu.

__init__()
successors(simgr, state, **kwargs)

Perform the process of stepping a state forward, returning a SimSuccessors object.

To defer to the original succession procedure, return the result of simgr.successors(state, **kwargs). Be careful about not calling this method (e.g. calling project.factory.successors manually) as it denies other hooks the opportunity to instrument the step. Instead, you can mutate the kwargs for the step before calling the original, and mutate the result before returning it yourself.

If the user provided a successor_func in their step or run command, it will appear here.

Parameters:
class angr.exploration_techniques.loop_seer.LoopSeer(cfg=None, functions=None, loops=None, use_header=False, bound=None, bound_reached=None, discard_stash='spinning', limit_concrete_loops=True)

Bases: ExplorationTechnique

This exploration technique monitors exploration and maintains all loop-related data (well, currently it is just the loop trip counts, but feel free to add something else).

__init__(cfg=None, functions=None, loops=None, use_header=False, bound=None, bound_reached=None, discard_stash='spinning', limit_concrete_loops=True)
Parameters:
  • cfg – Normalized CFG is required.

  • functions – Function(s) containing the loop(s) to be analyzed.

  • loops – Specific group of Loop(s) to be analyzed, if this is None we run the LoopFinder analysis.

  • use_header – Whether to use header based trip counter to compare with the bound limit.

  • bound – Limit the number of iterations a loop may be executed.

  • bound_reached – If provided, should be a function that takes the LoopSeer and the succ_state. Will be called when loop execution reach the given bound. Default to moving states that exceed the loop limit to a discard stash.

  • discard_stash – Name of the stash containing states exceeding the loop limit.

  • limit_concrete_loops – If False, do not limit a loop back-edge if it is the only successor (Defaults to True to maintain the original behavior)

setup(simgr)

Perform any initialization on this manager you might need to do.

Parameters:

simgr (angr.SimulationManager) – The simulation manager to which you have just been added

filter(simgr, state, **kwargs)

Perform filtering on which stash a state should be inserted into.

If the state should be filtered, return the name of the stash to move the state to. If you want to modify the state before filtering it, return a tuple of the stash to move the state to and the modified state. To defer to the original categorization procedure, return the result of simgr.filter(state, **kwargs)

If the user provided a filter_func in their step or run command, it will appear here.

Parameters:
successors(simgr, state, **kwargs)

Perform the process of stepping a state forward, returning a SimSuccessors object.

To defer to the original succession procedure, return the result of simgr.successors(state, **kwargs). Be careful about not calling this method (e.g. calling project.factory.successors manually) as it denies other hooks the opportunity to instrument the step. Instead, you can mutate the kwargs for the step before calling the original, and mutate the result before returning it yourself.

If the user provided a successor_func in their step or run command, it will appear here.

Parameters:
class angr.exploration_techniques.local_loop_seer.LocalLoopSeer(bound=None, bound_reached=None, discard_stash='spinning')

Bases: ExplorationTechnique

LocalLoopSeer monitors exploration and maintains all loop-related data without relying on a control flow graph.

__init__(bound=None, bound_reached=None, discard_stash='spinning')
Parameters:
  • bound – Limit the number of iterations a loop may be executed.

  • bound_reached – If provided, should be a function that takes the LoopSeer and the succ_state. Will be called when loop execution reach the given bound. Default to moving states that exceed the loop limit to a discard stash.

  • discard_stash – Name of the stash containing states exceeding the loop limit.

setup(simgr)

Perform any initialization on this manager you might need to do.

Parameters:

simgr (angr.SimulationManager) – The simulation manager to which you have just been added

filter(simgr, state, **kwargs)

Perform filtering on which stash a state should be inserted into.

If the state should be filtered, return the name of the stash to move the state to. If you want to modify the state before filtering it, return a tuple of the stash to move the state to and the modified state. To defer to the original categorization procedure, return the result of simgr.filter(state, **kwargs)

If the user provided a filter_func in their step or run command, it will appear here.

Parameters:
successors(simgr, state, **kwargs)

Perform the process of stepping a state forward, returning a SimSuccessors object.

To defer to the original succession procedure, return the result of simgr.successors(state, **kwargs). Be careful about not calling this method (e.g. calling project.factory.successors manually) as it denies other hooks the opportunity to instrument the step. Instead, you can mutate the kwargs for the step before calling the original, and mutate the result before returning it yourself.

If the user provided a successor_func in their step or run command, it will appear here.

Parameters:
class angr.exploration_techniques.stochastic.StochasticSearch(start_state, restart_prob=0.0001)

Bases: ExplorationTechnique

Stochastic Search.

Will only keep one path active at a time, any others will be discarded. Before each pass through, weights are randomly assigned to each basic block. These weights form a probability distribution for determining which state remains after splits. When we run out of active paths to step, we start again from the start state.

__init__(start_state, restart_prob=0.0001)
Parameters:
  • start_state – The initial state from which exploration stems.

  • restart_prob – The probability of randomly restarting the search (default 0.0001).

step(simgr, stash='active', **kwargs)

Hook the process of stepping a stash forward. Should call simgr.step(stash, **kwargs) in order to do the actual processing.

Parameters:
class angr.exploration_techniques.unique.UniqueSearch(similarity_func=None, deferred_stash='deferred')

Bases: ExplorationTechnique

Unique Search.

Will only keep one path active at a time, any others will be deferred. The state that is explored depends on how unique it is relative to the other deferred states. A path’s uniqueness is determined by its average similarity between the other (deferred) paths. Similarity is calculated based on the supplied similarity_func, which by default is: The (L2) distance between the counts of the state addresses in the history of the path.

__init__(similarity_func=None, deferred_stash='deferred')
Parameters:
  • similarity_func – How to calculate similarity between two states.

  • deferred_stash – Where to store the deferred states.

setup(simgr)

Perform any initialization on this manager you might need to do.

Parameters:

simgr (angr.SimulationManager) – The simulation manager to which you have just been added

step(simgr, stash='active', **kwargs)

Hook the process of stepping a stash forward. Should call simgr.step(stash, **kwargs) in order to do the actual processing.

Parameters:
static similarity(state_a, state_b)

The (L2) distance between the counts of the state addresses in the history of the path. :type state_a: :param state_a: The first state to compare :type state_b: :param state_b: The second state to compare

static sequence_matcher_similarity(state_a, state_b)

The difflib.SequenceMatcher ratio between the state addresses in the history of the path. :type state_a: :param state_a: The first state to compare :type state_b: :param state_b: The second state to compare

class angr.exploration_techniques.tech_builder.TechniqueBuilder(setup=None, step_state=None, step=None, successors=None, filter=None, selector=None, complete=None)

Bases: ExplorationTechnique

This meta technique could be used to hook a couple of simulation manager methods without actually creating a new exploration technique, for example:

class SomeComplexAnalysis(Analysis):

def do_something():

simgr = self.project.factory.simulation_manager() simgr.use_tech(ProxyTechnique(step_state=self._step_state)) simgr.run()

def _step_state(self, state):

# Do stuff! pass

In the above example, the _step_state method can access all the necessary stuff, hidden in the analysis instance, without passing that instance to a one-shot-styled exploration technique.

__init__(setup=None, step_state=None, step=None, successors=None, filter=None, selector=None, complete=None)
angr.exploration_techniques.common.condition_to_lambda(condition, default=False)

Translates an integer, set, list or function into a lambda that checks if state’s current basic block matches some condition.

Parameters:
  • condition – An integer, set, list or lambda to convert to a lambda.

  • default – The default return value of the lambda (in case condition is None). Default: false.

Returns:

A tuple of two items: a lambda that takes a state and returns the set of addresses that it matched from the condition, and a set that contains the normalized set of addresses to stop at, or None if no addresses were provided statically.

class angr.exploration_techniques.memory_watcher.MemoryWatcher(min_memory=512, memory_stash='lowmem')

Bases: ExplorationTechnique

Memory Watcher

Parameters:
  • min_memory (int,optional) – Minimum amount of free memory in MB before stopping execution (default: 95% memory use)

  • memory_stash (str, optional) – What to call the low memory stash (default: ‘lowmem’)

At each step, keep an eye on how much memory is left on the system. Stash off states to effectively stop execution if we’re below a given threshold.

__init__(min_memory=512, memory_stash='lowmem')
setup(simgr)

Perform any initialization on this manager you might need to do.

Parameters:

simgr (angr.SimulationManager) – The simulation manager to which you have just been added

step(simgr, stash='active', **kwargs)

Hook the process of stepping a stash forward. Should call simgr.step(stash, **kwargs) in order to do the actual processing.

Parameters:
class angr.exploration_techniques.bucketizer.Bucketizer

Bases: ExplorationTechnique

Loop bucketization: Pick log(n) paths out of n possible paths, and stash (or drop) everything else.

successors(simgr, state, **kwargs)

Perform the process of stepping a state forward, returning a SimSuccessors object.

To defer to the original succession procedure, return the result of simgr.successors(state, **kwargs). Be careful about not calling this method (e.g. calling project.factory.successors manually) as it denies other hooks the opportunity to instrument the step. Instead, you can mutate the kwargs for the step before calling the original, and mutate the result before returning it yourself.

If the user provided a successor_func in their step or run command, it will appear here.

Parameters:
angr.exploration_techniques.suggestions.ast_weight(ast, memo=None)
class angr.exploration_techniques.suggestions.Suggestions

Bases: ExplorationTechnique

An exploration technique which analyzes failure cases and logs suggestions for how to mitigate them in future analyses.

__init__()
step(simgr, stash='active', **kwargs)

Hook the process of stepping a stash forward. Should call simgr.step(stash, **kwargs) in order to do the actual processing.

Parameters:
static report(state, event)

Simulation Engines

class angr.engines.HeavyResilienceMixin(project, **kwargs)

Bases: VEXResilienceMixin, ClaripyDataMixin

class angr.engines.HeavyVEXMixin(project)

Bases: SuccessorsEngine, ClaripyDataMixin, SimStateStorageMixin, VEXMixin, VEXLifter

Execution engine based on VEX, Valgrind’s IR.

Responds to the following parameters to the step stack:

  • irsb: The PyVEX IRSB object to use for execution. If not provided one will be lifted.

  • skip_stmts: The number of statements to skip in processing

  • last_stmt: Do not execute any statements after this statement

  • whitelist: Only execute statements in this set

  • thumb: Whether the block should be force to be lifted in ARM’s THUMB mode.

  • extra_stop_points:

    An extra set of points at which to break basic blocks

  • opt_level: The VEX optimization level to use.

  • insn_bytes: A string of bytes to use for the block instead of the project.

  • size: The maximum size of the block, in bytes.

  • num_inst: The maximum number of instructions.

  • traceflags: traceflags to be passed to VEX. (default: 0)

Parameters:

project (angr.Project)

process_successors(successors, irsb=None, insn_bytes=None, thumb=False, size=None, num_inst=None, extra_stop_points=None, opt_level=None, strict_block_end=None, **kwargs)

Implement this function to fill out the SimSuccessors object with the results of stepping state.

In order to implement a model where multiple mixins can potentially handle a request, a mixin may implement this method and then perform a super() call if it wants to pass on handling to the next mixin.

Keep in mind python’s method resolution order when composing multiple classes implementing this method. In short: left-to-right, depth-first, but deferring any base classes which are shared by multiple subclasses (the merge point of a diamond pattern in the inheritance graph) until the last point where they would be encountered in this depth-first search. For example, if you have classes A, B(A), C(B), D(A), E(C, D), then the method resolution order will be E, C, B, D, A.

Parameters:
  • state – The state to manipulate

  • successors – The successors object to fill out

  • kwargs – Any extra arguments. Do not fail if you are passed unexpected arguments.

class angr.engines.HooksMixin(project)

Bases: SuccessorsEngine, ProcedureMixin

A SimEngine mixin which adds a SimSuccessors handler which will look into the project’s hooks and run the hook at the current address.

Will respond to the following parameters provided to the step stack:

  • procedure: A SimProcedure instance to force-run instead of consulting the current hooks

  • ret_to: An address to force-return-to at the end of the procedure

Parameters:

project (angr.Project)

process_successors(successors, procedure=None, **kwargs)

Implement this function to fill out the SimSuccessors object with the results of stepping state.

In order to implement a model where multiple mixins can potentially handle a request, a mixin may implement this method and then perform a super() call if it wants to pass on handling to the next mixin.

Keep in mind python’s method resolution order when composing multiple classes implementing this method. In short: left-to-right, depth-first, but deferring any base classes which are shared by multiple subclasses (the merge point of a diamond pattern in the inheritance graph) until the last point where they would be encountered in this depth-first search. For example, if you have classes A, B(A), C(B), D(A), E(C, D), then the method resolution order will be E, C, B, D, A.

Parameters:
  • state – The state to manipulate

  • successors – The successors object to fill out

  • kwargs – Any extra arguments. Do not fail if you are passed unexpected arguments.

class angr.engines.ProcedureEngine(project)

Bases: ProcedureMixin, SuccessorsEngine

A SimEngine that you may use if you only care about processing SimProcedures. Requires the procedure kwarg to be passed to process.

Parameters:

project (angr.Project)

process_successors(successors, procedure=None, **kwargs)

Implement this function to fill out the SimSuccessors object with the results of stepping state.

In order to implement a model where multiple mixins can potentially handle a request, a mixin may implement this method and then perform a super() call if it wants to pass on handling to the next mixin.

Keep in mind python’s method resolution order when composing multiple classes implementing this method. In short: left-to-right, depth-first, but deferring any base classes which are shared by multiple subclasses (the merge point of a diamond pattern in the inheritance graph) until the last point where they would be encountered in this depth-first search. For example, if you have classes A, B(A), C(B), D(A), E(C, D), then the method resolution order will be E, C, B, D, A.

Parameters:
  • state – The state to manipulate

  • successors – The successors object to fill out

  • kwargs – Any extra arguments. Do not fail if you are passed unexpected arguments.

class angr.engines.ProcedureMixin

Bases: object

A mixin for SimEngine which adds the process_procedure method for calling a SimProcedure and adding its results to a SimSuccessors.

process_procedure(state, successors, procedure, ret_to=None, arguments=None, **kwargs)
class angr.engines.SimEngine(project)

Bases: Generic[StateType, ResultType]

A SimEngine is a type which understands how to perform execution on a state.

Parameters:

project (angr.Project)

state: TypeVar(StateType)
__init__(project)
Parameters:

project (Project)

class angr.engines.SimEngineFailure(project)

Bases: SuccessorsEngine, ProcedureMixin

Parameters:

project (angr.Project)

process_successors(successors, **kwargs)

Implement this function to fill out the SimSuccessors object with the results of stepping state.

In order to implement a model where multiple mixins can potentially handle a request, a mixin may implement this method and then perform a super() call if it wants to pass on handling to the next mixin.

Keep in mind python’s method resolution order when composing multiple classes implementing this method. In short: left-to-right, depth-first, but deferring any base classes which are shared by multiple subclasses (the merge point of a diamond pattern in the inheritance graph) until the last point where they would be encountered in this depth-first search. For example, if you have classes A, B(A), C(B), D(A), E(C, D), then the method resolution order will be E, C, B, D, A.

Parameters:
  • state – The state to manipulate

  • successors – The successors object to fill out

  • kwargs – Any extra arguments. Do not fail if you are passed unexpected arguments.

class angr.engines.SimEngineSyscall(project)

Bases: SuccessorsEngine, 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.

Parameters:

project (angr.Project)

process_successors(successors, **kwargs)

Implement this function to fill out the SimSuccessors object with the results of stepping state.

In order to implement a model where multiple mixins can potentially handle a request, a mixin may implement this method and then perform a super() call if it wants to pass on handling to the next mixin.

Keep in mind python’s method resolution order when composing multiple classes implementing this method. In short: left-to-right, depth-first, but deferring any base classes which are shared by multiple subclasses (the merge point of a diamond pattern in the inheritance graph) until the last point where they would be encountered in this depth-first search. For example, if you have classes A, B(A), C(B), D(A), E(C, D), then the method resolution order will be E, C, B, D, A.

Parameters:
  • state – The state to manipulate

  • successors – The successors object to fill out

  • kwargs – Any extra arguments. Do not fail if you are passed unexpected arguments.

class angr.engines.SimEngineUnicorn(project)

Bases: SuccessorsEngine

Concrete execution in the Unicorn Engine, a fork of qemu.

Responds to the following parameters in the step stack:

  • step: How many basic blocks we want to execute

  • extra_stop_points: A collection of addresses at which execution should halt

Parameters:

project (angr.Project)

__init__(project)
Parameters:

project (Project)

process_successors(successors, **kwargs)

Implement this function to fill out the SimSuccessors object with the results of stepping state.

In order to implement a model where multiple mixins can potentially handle a request, a mixin may implement this method and then perform a super() call if it wants to pass on handling to the next mixin.

Keep in mind python’s method resolution order when composing multiple classes implementing this method. In short: left-to-right, depth-first, but deferring any base classes which are shared by multiple subclasses (the merge point of a diamond pattern in the inheritance graph) until the last point where they would be encountered in this depth-first search. For example, if you have classes A, B(A), C(B), D(A), E(C, D), then the method resolution order will be E, C, B, D, A.

Parameters:
  • state – The state to manipulate

  • successors – The successors object to fill out

  • kwargs – Any extra arguments. Do not fail if you are passed unexpected arguments.

class angr.engines.SimInspectMixin(project, **kwargs)

Bases: VEXMixin

handle_vex_block(irsb)
class angr.engines.SimSuccessors(addr, initial_state)

Bases: object

This class serves as a categorization of all the kinds of result states that can come from a SimEngine run.

Variables:
  • addr (int) – The address at which execution is taking place, as a python int

  • initial_state – The initial state for which execution produced these successors

  • engine – The engine that produced these successors

  • sort – A string identifying the type of engine that produced these successors

  • processed (bool) – Whether or not the processing succeeded

  • description (str) – A textual description of the execution step

Parameters:
  • addr (int | SootAddressDescriptor | None)

  • initial_state (HeavyState | None)

The successor states produced by this run are categorized into several lists:

Variables:
  • artifacts (dict) – Any analysis byproducts (for example, an IRSB) that were produced during execution

  • successors – The “normal” successors. IP may be symbolic, but must have reasonable number of solutions

  • unsat_successors – Any successor which is unsatisfiable after its guard condition is added.

  • all_successors – successors + unsat_successors

  • flat_successors – The normal successors, but any symbolic IPs have been concretized. There is one state in this list for each possible value an IP may be concretized to for each successor state.

  • unconstrained_successors – Any state for which during the flattening process we find too many solutions.

Parameters:
  • addr (int | SootAddressDescriptor | None)

  • initial_state (HeavyState | None)

A more detailed description of the successor lists may be found here: https://docs.angr.io/core-concepts/simulation#simsuccessors

__init__(addr, initial_state)
Parameters:
property is_empty
add_successor(state, target, guard, jumpkind, add_guard=True, exit_stmt_idx=None, exit_ins_addr=None, source=None)

Add a successor state of the SimRun. This procedure stores method parameters into state.scratch, does some housekeeping, and calls out to helper functions to prepare the state and categorize it into the appropriate successor lists.

Parameters:
  • state (SimState) – The successor state.

  • target – The target (of the jump/call/ret).

  • guard – The guard expression.

  • jumpkind (str) – The jumpkind (call, ret, jump, or whatnot).

  • add_guard (bool) – Whether to add the guard constraint (default: True).

  • exit_stmt_idx (int) – The ID of the exit statement, an integer by default. ‘default’ stands for the default exit, and None means it’s not from a statement (for example, from a SimProcedure).

  • exit_ins_addr (int) – The instruction pointer of this exit, which is an integer by default.

  • source (int) – The source of the jump (i.e., the address of the basic block).

class angr.engines.SootMixin(project)

Bases: SuccessorsEngine, ProcedureMixin

Execution engine based on Soot.

Parameters:

project (angr.Project)

lift_soot(addr=None, the_binary=None, **kwargs)
process_successors(successors, **kwargs)

Implement this function to fill out the SimSuccessors object with the results of stepping state.

In order to implement a model where multiple mixins can potentially handle a request, a mixin may implement this method and then perform a super() call if it wants to pass on handling to the next mixin.

Keep in mind python’s method resolution order when composing multiple classes implementing this method. In short: left-to-right, depth-first, but deferring any base classes which are shared by multiple subclasses (the merge point of a diamond pattern in the inheritance graph) until the last point where they would be encountered in this depth-first search. For example, if you have classes A, B(A), C(B), D(A), E(C, D), then the method resolution order will be E, C, B, D, A.

Parameters:
  • state – The state to manipulate

  • successors – The successors object to fill out

  • kwargs – Any extra arguments. Do not fail if you are passed unexpected arguments.

get_unconstrained_simprocedure()
classmethod setup_callsite(state, args, ret_addr, ret_var=None)
static setup_arguments(state, args)
static prepare_return_state(state, ret_value=None)
static terminate_execution(statement, state, successors)
static prepare_native_return_state(native_state)

Hook target for native function call returns.

Recovers and stores the return value from native memory and toggles the state, s.t. execution continues in the Soot engine.

class angr.engines.SuccessorsEngine(project)

Bases: SimEngine[SimState[int | SootAddressDescriptor, BV | SootAddressDescriptor], SimSuccessors]

A mixin for SimEngine which implements process to perform common operations related to symbolic execution and dispatches to a process_successors method to fill a SimSuccessors object with the results.

Parameters:

project (angr.Project)

__init__(project)
Parameters:

project (Project)

process(state, **kwargs)

Perform execution with a state.

You should only override this method in a subclass in order to provide the correct method signature and docstring. You should override the _process method to do your actual execution.

Parameters:
  • state (SimState[int | SootAddressDescriptor, BV | SootAddressDescriptor]) – The state with which to execute. This state will be copied before modification.

  • inline – This is an inline execution. Do not bother copying the state.

  • force_addr – Force execution to pretend that we’re working at this concrete address

Return type:

SimSuccessors

Returns:

A SimSuccessors object categorizing the execution’s successor states

process_successors(successors, **kwargs)

Implement this function to fill out the SimSuccessors object with the results of stepping state.

In order to implement a model where multiple mixins can potentially handle a request, a mixin may implement this method and then perform a super() call if it wants to pass on handling to the next mixin.

Keep in mind python’s method resolution order when composing multiple classes implementing this method. In short: left-to-right, depth-first, but deferring any base classes which are shared by multiple subclasses (the merge point of a diamond pattern in the inheritance graph) until the last point where they would be encountered in this depth-first search. For example, if you have classes A, B(A), C(B), D(A), E(C, D), then the method resolution order will be E, C, B, D, A.

Parameters:
  • state – The state to manipulate

  • successors – The successors object to fill out

  • kwargs – Any extra arguments. Do not fail if you are passed unexpected arguments.

class angr.engines.SuperFastpathMixin(*args, **kwargs)

Bases: VEXSlicingMixin

This mixin implements the superfastpath execution mode, which skips all but the last four instructions.

handle_vex_block(irsb)
class angr.engines.TrackActionsMixin(*args, **kwargs)

Bases: HeavyVEXMixin

__init__(*args, **kwargs)
handle_vex_block(irsb)
class angr.engines.UberEngine(project)

Bases: SimEngineFailure, SimEngineSyscall, HooksMixin, SimEngineUnicorn, SuperFastpathMixin, TrackActionsMixin, SimInspectMixin, HeavyResilienceMixin, SootMixin, HeavyVEXMixin

The default execution engine for angr. This engine includes mixins for most common functionality in angr, including VEX IR, unicorn, syscall handling, and simprocedure handling.

For some performance-sensitive applications, you may want to create a custom engine with only the necessary mixins.

Parameters:

project (angr.Project)

class angr.engines.UberEnginePcode(*args, **kwargs)

Bases: SimEngineFailure, SimEngineSyscall, HooksMixin, HeavyPcodeMixin

class angr.engines.engine.SimEngine(project)

Bases: Generic[StateType, ResultType]

A SimEngine is a type which understands how to perform execution on a state.

Parameters:

project (angr.Project)

state: TypeVar(StateType)
__init__(project)
Parameters:

project (Project)

class angr.engines.successors.SimSuccessors(addr, initial_state)

Bases: object

This class serves as a categorization of all the kinds of result states that can come from a SimEngine run.

Variables:
  • addr (int) – The address at which execution is taking place, as a python int

  • initial_state – The initial state for which execution produced these successors

  • engine – The engine that produced these successors

  • sort – A string identifying the type of engine that produced these successors

  • processed (bool) – Whether or not the processing succeeded

  • description (str) – A textual description of the execution step

Parameters:
  • addr (int | SootAddressDescriptor | None)

  • initial_state (HeavyState | None)

The successor states produced by this run are categorized into several lists:

Variables:
  • artifacts (dict) – Any analysis byproducts (for example, an IRSB) that were produced during execution

  • successors – The “normal” successors. IP may be symbolic, but must have reasonable number of solutions

  • unsat_successors – Any successor which is unsatisfiable after its guard condition is added.

  • all_successors – successors + unsat_successors

  • flat_successors – The normal successors, but any symbolic IPs have been concretized. There is one state in this list for each possible value an IP may be concretized to for each successor state.

  • unconstrained_successors – Any state for which during the flattening process we find too many solutions.

Parameters:
  • addr (int | SootAddressDescriptor | None)

  • initial_state (HeavyState | None)

A more detailed description of the successor lists may be found here: https://docs.angr.io/core-concepts/simulation#simsuccessors

__init__(addr, initial_state)
Parameters:
property is_empty
add_successor(state, target, guard, jumpkind, add_guard=True, exit_stmt_idx=None, exit_ins_addr=None, source=None)

Add a successor state of the SimRun. This procedure stores method parameters into state.scratch, does some housekeeping, and calls out to helper functions to prepare the state and categorize it into the appropriate successor lists.

Parameters:
  • state (SimState) – The successor state.

  • target – The target (of the jump/call/ret).

  • guard – The guard expression.

  • jumpkind (str) – The jumpkind (call, ret, jump, or whatnot).

  • add_guard (bool) – Whether to add the guard constraint (default: True).

  • exit_stmt_idx (int) – The ID of the exit statement, an integer by default. ‘default’ stands for the default exit, and None means it’s not from a statement (for example, from a SimProcedure).

  • exit_ins_addr (int) – The instruction pointer of this exit, which is an integer by default.

  • source (int) – The source of the jump (i.e., the address of the basic block).

class angr.engines.successors.SuccessorsEngine(project)

Bases: SimEngine[SimState[int | SootAddressDescriptor, BV | SootAddressDescriptor], SimSuccessors]

A mixin for SimEngine which implements process to perform common operations related to symbolic execution and dispatches to a process_successors method to fill a SimSuccessors object with the results.

Parameters:

project (angr.Project)

__init__(project)
Parameters:

project (Project)

process(state, **kwargs)

Perform execution with a state.

You should only override this method in a subclass in order to provide the correct method signature and docstring. You should override the _process method to do your actual execution.

Parameters:
  • state (SimState[int | SootAddressDescriptor, BV | SootAddressDescriptor]) – The state with which to execute. This state will be copied before modification.

  • inline – This is an inline execution. Do not bother copying the state.

  • force_addr – Force execution to pretend that we’re working at this concrete address

Return type:

SimSuccessors

Returns:

A SimSuccessors object categorizing the execution’s successor states

process_successors(successors, **kwargs)

Implement this function to fill out the SimSuccessors object with the results of stepping state.

In order to implement a model where multiple mixins can potentially handle a request, a mixin may implement this method and then perform a super() call if it wants to pass on handling to the next mixin.

Keep in mind python’s method resolution order when composing multiple classes implementing this method. In short: left-to-right, depth-first, but deferring any base classes which are shared by multiple subclasses (the merge point of a diamond pattern in the inheritance graph) until the last point where they would be encountered in this depth-first search. For example, if you have classes A, B(A), C(B), D(A), E(C, D), then the method resolution order will be E, C, B, D, A.

Parameters:
  • state – The state to manipulate

  • successors – The successors object to fill out

  • kwargs – Any extra arguments. Do not fail if you are passed unexpected arguments.

class angr.engines.procedure.ProcedureMixin

Bases: object

A mixin for SimEngine which adds the process_procedure method for calling a SimProcedure and adding its results to a SimSuccessors.

process_procedure(state, successors, procedure, ret_to=None, arguments=None, **kwargs)
class angr.engines.procedure.ProcedureEngine(project)

Bases: ProcedureMixin, SuccessorsEngine

A SimEngine that you may use if you only care about processing SimProcedures. Requires the procedure kwarg to be passed to process.

Parameters:

project (angr.Project)

process_successors(successors, procedure=None, **kwargs)

Implement this function to fill out the SimSuccessors object with the results of stepping state.

In order to implement a model where multiple mixins can potentially handle a request, a mixin may implement this method and then perform a super() call if it wants to pass on handling to the next mixin.

Keep in mind python’s method resolution order when composing multiple classes implementing this method. In short: left-to-right, depth-first, but deferring any base classes which are shared by multiple subclasses (the merge point of a diamond pattern in the inheritance graph) until the last point where they would be encountered in this depth-first search. For example, if you have classes A, B(A), C(B), D(A), E(C, D), then the method resolution order will be E, C, B, D, A.

Parameters:
  • state – The state to manipulate

  • successors – The successors object to fill out

  • kwargs – Any extra arguments. Do not fail if you are passed unexpected arguments.

class angr.engines.hook.HooksMixin(project)

Bases: SuccessorsEngine, ProcedureMixin

A SimEngine mixin which adds a SimSuccessors handler which will look into the project’s hooks and run the hook at the current address.

Will respond to the following parameters provided to the step stack:

  • procedure: A SimProcedure instance to force-run instead of consulting the current hooks

  • ret_to: An address to force-return-to at the end of the procedure

Parameters:

project (angr.Project)

process_successors(successors, procedure=None, **kwargs)

Implement this function to fill out the SimSuccessors object with the results of stepping state.

In order to implement a model where multiple mixins can potentially handle a request, a mixin may implement this method and then perform a super() call if it wants to pass on handling to the next mixin.

Keep in mind python’s method resolution order when composing multiple classes implementing this method. In short: left-to-right, depth-first, but deferring any base classes which are shared by multiple subclasses (the merge point of a diamond pattern in the inheritance graph) until the last point where they would be encountered in this depth-first search. For example, if you have classes A, B(A), C(B), D(A), E(C, D), then the method resolution order will be E, C, B, D, A.

Parameters:
  • state – The state to manipulate

  • successors – The successors object to fill out

  • kwargs – Any extra arguments. Do not fail if you are passed unexpected arguments.

class angr.engines.syscall.SimEngineSyscall(project)

Bases: SuccessorsEngine, 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.

Parameters:

project (angr.Project)

process_successors(successors, **kwargs)

Implement this function to fill out the SimSuccessors object with the results of stepping state.

In order to implement a model where multiple mixins can potentially handle a request, a mixin may implement this method and then perform a super() call if it wants to pass on handling to the next mixin.

Keep in mind python’s method resolution order when composing multiple classes implementing this method. In short: left-to-right, depth-first, but deferring any base classes which are shared by multiple subclasses (the merge point of a diamond pattern in the inheritance graph) until the last point where they would be encountered in this depth-first search. For example, if you have classes A, B(A), C(B), D(A), E(C, D), then the method resolution order will be E, C, B, D, A.

Parameters:
  • state – The state to manipulate

  • successors – The successors object to fill out

  • kwargs – Any extra arguments. Do not fail if you are passed unexpected arguments.

class angr.engines.failure.SimEngineFailure(project)

Bases: SuccessorsEngine, ProcedureMixin

Parameters:

project (angr.Project)

process_successors(successors, **kwargs)

Implement this function to fill out the SimSuccessors object with the results of stepping state.

In order to implement a model where multiple mixins can potentially handle a request, a mixin may implement this method and then perform a super() call if it wants to pass on handling to the next mixin.

Keep in mind python’s method resolution order when composing multiple classes implementing this method. In short: left-to-right, depth-first, but deferring any base classes which are shared by multiple subclasses (the merge point of a diamond pattern in the inheritance graph) until the last point where they would be encountered in this depth-first search. For example, if you have classes A, B(A), C(B), D(A), E(C, D), then the method resolution order will be E, C, B, D, A.

Parameters:
  • state – The state to manipulate

  • successors – The successors object to fill out

  • kwargs – Any extra arguments. Do not fail if you are passed unexpected arguments.

class angr.engines.vex.ClaripyDataMixin(project, **kwargs)

Bases: VEXMixin

This mixin provides methods that makes the vex engine process guest code using claripy ASTs as the data domain.

class angr.engines.vex.HeavyResilienceMixin(project, **kwargs)

Bases: VEXResilienceMixin, ClaripyDataMixin

class angr.engines.vex.HeavyVEXMixin(project)

Bases: SuccessorsEngine, ClaripyDataMixin, SimStateStorageMixin, VEXMixin, VEXLifter

Execution engine based on VEX, Valgrind’s IR.

Responds to the following parameters to the step stack:

  • irsb: The PyVEX IRSB object to use for execution. If not provided one will be lifted.

  • skip_stmts: The number of statements to skip in processing

  • last_stmt: Do not execute any statements after this statement

  • whitelist: Only execute statements in this set

  • thumb: Whether the block should be force to be lifted in ARM’s THUMB mode.

  • extra_stop_points:

    An extra set of points at which to break basic blocks

  • opt_level: The VEX optimization level to use.

  • insn_bytes: A string of bytes to use for the block instead of the project.

  • size: The maximum size of the block, in bytes.

  • num_inst: The maximum number of instructions.

  • traceflags: traceflags to be passed to VEX. (default: 0)

Parameters:

project (angr.Project)

process_successors(successors, irsb=None, insn_bytes=None, thumb=False, size=None, num_inst=None, extra_stop_points=None, opt_level=None, strict_block_end=None, **kwargs)

Implement this function to fill out the SimSuccessors object with the results of stepping state.

In order to implement a model where multiple mixins can potentially handle a request, a mixin may implement this method and then perform a super() call if it wants to pass on handling to the next mixin.

Keep in mind python’s method resolution order when composing multiple classes implementing this method. In short: left-to-right, depth-first, but deferring any base classes which are shared by multiple subclasses (the merge point of a diamond pattern in the inheritance graph) until the last point where they would be encountered in this depth-first search. For example, if you have classes A, B(A), C(B), D(A), E(C, D), then the method resolution order will be E, C, B, D, A.

Parameters:
  • state – The state to manipulate

  • successors – The successors object to fill out

  • kwargs – Any extra arguments. Do not fail if you are passed unexpected arguments.

class angr.engines.vex.SimInspectMixin(project, **kwargs)

Bases: VEXMixin

handle_vex_block(irsb)
class angr.engines.vex.SuperFastpathMixin(*args, **kwargs)

Bases: VEXSlicingMixin

This mixin implements the superfastpath execution mode, which skips all but the last four instructions.

handle_vex_block(irsb)
class angr.engines.vex.TrackActionsMixin(*args, **kwargs)

Bases: HeavyVEXMixin

__init__(*args, **kwargs)
handle_vex_block(irsb)
class angr.engines.vex.VEXLifter(project, use_cache=None, cache_size=50000, default_opt_level=1, selfmodifying_code=None, single_step=False, default_strict_block_end=False, **kwargs)

Bases: SimEngine

Implements the VEX lifter engine mixin.

__init__(project, use_cache=None, cache_size=50000, default_opt_level=1, selfmodifying_code=None, single_step=False, default_strict_block_end=False, **kwargs)
clear_cache()
lift_vex(addr=None, state=None, clemory=None, insn_bytes=None, offset=None, arch=None, size=None, num_inst=None, traceflags=0, thumb=False, extra_stop_points=None, opt_level=None, strict_block_end=None, skip_stmts=False, collect_data_refs=False, cross_insn_opt=None, load_from_ro_regions=False, const_prop=False)

Lift an IRSB.

There are many possible valid sets of parameters. You at the very least must pass some source of data, some source of an architecture, and some source of an address.

Sources of data in order of priority: insn_bytes, clemory, state

Sources of an address, in order of priority: addr, state

Sources of an architecture, in order of priority: arch, clemory, state

Parameters:
  • state – A state to use as a data source.

  • clemory (Union[Clemory, ClemoryReadOnlyView, None]) – A cle.memory.Clemory object to use as a data source.

  • addr – The address at which to start the block.

  • thumb – Whether the block should be lifted in ARM’s THUMB mode.

  • opt_level – The VEX optimization level to use. The final IR optimization level is determined by (ordered by priority): - Argument opt_level - opt_level is set to 1 if OPTIMIZE_IR exists in state options - self._default_opt_level

  • insn_bytes (Optional[bytes]) – A string of bytes to use as a data source.

  • offset – If using insn_bytes, the number of bytes in it to skip over.

  • size – The maximum size of the block, in bytes.

  • num_inst – The maximum number of instructions.

  • traceflags – traceflags to be passed to VEX. (default: 0)

  • strict_block_end – Whether to force blocks to end at all conditional branches (default: false)

Return type:

IRSB

class angr.engines.vex.VEXMixin(project, **kwargs)

Bases: SimEngine

__init__(project, **kwargs)
handle_vex_block(irsb)
Parameters:

irsb (IRSB)

class angr.engines.vex.VEXResilienceMixin(project, **kwargs)

Bases: VEXMixin

class angr.engines.vex.VEXSlicingMixin(*args, **kwargs)

Bases: VEXMixin

__init__(*args, **kwargs)
process(state, block=None, skip_stmts=0, last_stmt=None, whitelist=None, **kwargs)
handle_vex_block(irsb)
class angr.engines.soot.SootMixin(project)

Bases: SuccessorsEngine, ProcedureMixin

Execution engine based on Soot.

Parameters:

project (angr.Project)

lift_soot(addr=None, the_binary=None, **kwargs)
process_successors(successors, **kwargs)

Implement this function to fill out the SimSuccessors object with the results of stepping state.

In order to implement a model where multiple mixins can potentially handle a request, a mixin may implement this method and then perform a super() call if it wants to pass on handling to the next mixin.

Keep in mind python’s method resolution order when composing multiple classes implementing this method. In short: left-to-right, depth-first, but deferring any base classes which are shared by multiple subclasses (the merge point of a diamond pattern in the inheritance graph) until the last point where they would be encountered in this depth-first search. For example, if you have classes A, B(A), C(B), D(A), E(C, D), then the method resolution order will be E, C, B, D, A.

Parameters:
  • state – The state to manipulate

  • successors – The successors object to fill out

  • kwargs – Any extra arguments. Do not fail if you are passed unexpected arguments.

get_unconstrained_simprocedure()
classmethod setup_callsite(state, args, ret_addr, ret_var=None)
static setup_arguments(state, args)
static prepare_return_state(state, ret_value=None)
static terminate_execution(statement, state, successors)
static prepare_native_return_state(native_state)

Hook target for native function call returns.

Recovers and stores the return value from native memory and toggles the state, s.t. execution continues in the Soot engine.

class angr.engines.soot.engine.SootMixin(project)

Bases: SuccessorsEngine, ProcedureMixin

Execution engine based on Soot.

Parameters:

project (angr.Project)

lift_soot(addr=None, the_binary=None, **kwargs)
process_successors(successors, **kwargs)

Implement this function to fill out the SimSuccessors object with the results of stepping state.

In order to implement a model where multiple mixins can potentially handle a request, a mixin may implement this method and then perform a super() call if it wants to pass on handling to the next mixin.

Keep in mind python’s method resolution order when composing multiple classes implementing this method. In short: left-to-right, depth-first, but deferring any base classes which are shared by multiple subclasses (the merge point of a diamond pattern in the inheritance graph) until the last point where they would be encountered in this depth-first search. For example, if you have classes A, B(A), C(B), D(A), E(C, D), then the method resolution order will be E, C, B, D, A.

Parameters:
  • state – The state to manipulate

  • successors – The successors object to fill out

  • kwargs – Any extra arguments. Do not fail if you are passed unexpected arguments.

get_unconstrained_simprocedure()
classmethod setup_callsite(state, args, ret_addr, ret_var=None)
static setup_arguments(state, args)
static prepare_return_state(state, ret_value=None)
static terminate_execution(statement, state, successors)
static prepare_native_return_state(native_state)

Hook target for native function call returns.

Recovers and stores the return value from native memory and toggles the state, s.t. execution continues in the Soot engine.

class angr.engines.unicorn.SimEngineUnicorn(project)

Bases: SuccessorsEngine

Concrete execution in the Unicorn Engine, a fork of qemu.

Responds to the following parameters in the step stack:

  • step: How many basic blocks we want to execute

  • extra_stop_points: A collection of addresses at which execution should halt

Parameters:

project (angr.Project)

__init__(project)
Parameters:

project (Project)

process_successors(successors, **kwargs)

Implement this function to fill out the SimSuccessors object with the results of stepping state.

In order to implement a model where multiple mixins can potentially handle a request, a mixin may implement this method and then perform a super() call if it wants to pass on handling to the next mixin.

Keep in mind python’s method resolution order when composing multiple classes implementing this method. In short: left-to-right, depth-first, but deferring any base classes which are shared by multiple subclasses (the merge point of a diamond pattern in the inheritance graph) until the last point where they would be encountered in this depth-first search. For example, if you have classes A, B(A), C(B), D(A), E(C, D), then the method resolution order will be E, C, B, D, A.

Parameters:
  • state – The state to manipulate

  • successors – The successors object to fill out

  • kwargs – Any extra arguments. Do not fail if you are passed unexpected arguments.

class angr.engines.pcode.HeavyPcodeMixin(*args, **kwargs)

Bases: SuccessorsEngine, PcodeLifterEngineMixin, PcodeEmulatorMixin

Execution engine based on P-code, Ghidra’s IR.

Responds to the following parameters to the step stack:

  • irsb: The P-Code IRSB object to use for execution. If not provided one will be lifted.

  • skip_stmts: The number of statements to skip in processing

  • last_stmt: Do not execute any statements after this statement

  • thumb: Whether the block should be force to be lifted in ARM’s THUMB mode. (FIXME)

  • extra_stop_points:

    An extra set of points at which to break basic blocks

  • insn_bytes: A string of bytes to use for the block instead of the project.

  • size: The maximum size of the block, in bytes.

  • num_inst: The maximum number of instructions.

__init__(*args, **kwargs)
process_successors(successors, irsb=None, insn_bytes=None, thumb=False, size=None, num_inst=None, extra_stop_points=None, **kwargs)

Implement this function to fill out the SimSuccessors object with the results of stepping state.

In order to implement a model where multiple mixins can potentially handle a request, a mixin may implement this method and then perform a super() call if it wants to pass on handling to the next mixin.

Keep in mind python’s method resolution order when composing multiple classes implementing this method. In short: left-to-right, depth-first, but deferring any base classes which are shared by multiple subclasses (the merge point of a diamond pattern in the inheritance graph) until the last point where they would be encountered in this depth-first search. For example, if you have classes A, B(A), C(B), D(A), E(C, D), then the method resolution order will be E, C, B, D, A.

Parameters:
  • state – The state to manipulate

  • successors (SimSuccessors) – The successors object to fill out

  • kwargs – Any extra arguments. Do not fail if you are passed unexpected arguments.

  • irsb (IRSB | None)

  • insn_bytes (bytes | None)

  • thumb (bool)

  • size (int | None)

  • num_inst (int | None)

  • extra_stop_points (Iterable[int] | None)

Return type:

None

angr.engines.pcode.register_pcode_arch_default_cc(arch)
Parameters:

arch (ArchPcode)

class angr.engines.pcode.engine.HeavyPcodeMixin(*args, **kwargs)

Bases: SuccessorsEngine, PcodeLifterEngineMixin, PcodeEmulatorMixin

Execution engine based on P-code, Ghidra’s IR.

Responds to the following parameters to the step stack:

  • irsb: The P-Code IRSB object to use for execution. If not provided one will be lifted.

  • skip_stmts: The number of statements to skip in processing

  • last_stmt: Do not execute any statements after this statement

  • thumb: Whether the block should be force to be lifted in ARM’s THUMB mode. (FIXME)

  • extra_stop_points:

    An extra set of points at which to break basic blocks

  • insn_bytes: A string of bytes to use for the block instead of the project.

  • size: The maximum size of the block, in bytes.

  • num_inst: The maximum number of instructions.

__init__(*args, **kwargs)
process_successors(successors, irsb=None, insn_bytes=None, thumb=False, size=None, num_inst=None, extra_stop_points=None, **kwargs)

Implement this function to fill out the SimSuccessors object with the results of stepping state.

In order to implement a model where multiple mixins can potentially handle a request, a mixin may implement this method and then perform a super() call if it wants to pass on handling to the next mixin.

Keep in mind python’s method resolution order when composing multiple classes implementing this method. In short: left-to-right, depth-first, but deferring any base classes which are shared by multiple subclasses (the merge point of a diamond pattern in the inheritance graph) until the last point where they would be encountered in this depth-first search. For example, if you have classes A, B(A), C(B), D(A), E(C, D), then the method resolution order will be E, C, B, D, A.

Parameters:
  • state – The state to manipulate

  • successors (SimSuccessors) – The successors object to fill out

  • kwargs – Any extra arguments. Do not fail if you are passed unexpected arguments.

  • irsb (IRSB | None)

  • insn_bytes (bytes | None)

  • thumb (bool)

  • size (int | None)

  • num_inst (int | None)

  • extra_stop_points (Iterable[int] | None)

Return type:

None

class angr.engines.pcode.lifter.ExitStatement(dst, jumpkind)

Bases: object

This class exists to ease compatibility with CFGFast’s processing of exit_statements. See _scan_irsb method.

Parameters:
  • dst (int | None)

  • jumpkind (str)

__init__(dst, jumpkind)
Parameters:
  • dst (int | None)

  • jumpkind (str)

dst: int | None
jumpkind: str
class angr.engines.pcode.lifter.PcodeDisassemblerBlock(addr, insns, thumb, arch)

Bases: DisassemblerBlock

Helper class to represent a block of disassembled target architecture instructions

addr
arch
insns
thumb
class angr.engines.pcode.lifter.PcodeDisassemblerInsn(pcode_insn)

Bases: DisassemblerInsn

Helper class to represent a disassembled target architecture instruction

__init__(pcode_insn)
property size: int
property address: int
property mnemonic: str
property op_str: str
class angr.engines.pcode.lifter.IRSB(data, mem_addr, arch, max_inst=None, max_bytes=None, bytes_offset=0, traceflags=0, opt_level=1, num_inst=None, num_bytes=None, strict_block_end=False, skip_stmts=False, collect_data_refs=False)

Bases: object

IRSB stands for Intermediate Representation Super-Block. An IRSB in is a single-entry, multiple-exit code block.

Variables:
  • arch (archinfo.Arch) – The architecture this block is lifted under

  • statements (list of IRStmt) – The statements in this block

  • next (IRExpr) – The expression for the default exit target of this block

  • offsIP (int) – The offset of the instruction pointer in the VEX guest state

  • stmts_used (int) – The number of statements in this IRSB

  • jumpkind (str) – The type of this block’s default jump (call, boring, syscall, etc) as a VEX enum string

  • direct_next (bool) – Whether this block ends with a direct (not indirect) jump or branch

  • size (int) – The size of this block in bytes

  • addr (int) – The address of this basic block, i.e. the address in the first IMark

Parameters:
  • data (str | bytes | None)

  • mem_addr (int)

  • arch (Arch)

  • max_inst (int | None)

  • max_bytes (int | None)

  • bytes_offset (int)

  • traceflags (int)

  • opt_level (int)

  • num_inst (int | None)

  • num_bytes (int | None)

  • strict_block_end (bool)

  • skip_stmts (bool)

  • collect_data_refs (bool)

MAX_EXITS = 400
MAX_DATA_REFS = 2000
__init__(data, mem_addr, arch, max_inst=None, max_bytes=None, bytes_offset=0, traceflags=0, opt_level=1, num_inst=None, num_bytes=None, strict_block_end=False, skip_stmts=False, collect_data_refs=False)
Parameters:
  • data (str | bytes | None) – The bytes to lift. Can be either a string of bytes or a cffi buffer object. You may also pass None to initialize an empty IRSB.

  • mem_addr (int) – The address to lift the data at.

  • arch (Arch) – The architecture to lift the data as.

  • max_inst (Optional[int]) – The maximum number of instructions to lift. (See note below)

  • max_bytes (Optional[int]) – The maximum number of bytes to use.

  • num_inst (Optional[int]) – Replaces max_inst if max_inst is None. If set to None as well, no instruction limit is used.

  • num_bytes (Optional[int]) – Replaces max_bytes if max_bytes is None. If set to None as well, no byte limit is used.

  • bytes_offset (int) – The offset into data to start lifting at. Note that for ARM THUMB mode, both mem_addr and bytes_offset must be odd (typically bytes_offset is set to 1).

  • traceflags (int) – Unused by P-Code lifter

  • opt_level (int) – Unused by P-Code lifter

  • strict_block_end (bool) – Unused by P-Code lifter

  • skip_stmts (bool)

  • collect_data_refs (bool)

Return type:

None

Note

Explicitly specifying the number of instructions to lift (max_inst) may not always work exactly as expected. For example, on MIPS, it is meaningless to lift a branch or jump instruction without its delay slot. VEX attempts to Do The Right Thing by possibly decoding fewer instructions than requested. Specifically, this means that lifting a branch or jump on MIPS as a single instruction (max_inst=1) will result in an empty IRSB, and subsequent attempts to run this block will raise SimIRSBError(‘Empty IRSB passed to SimIRSB.’).

Note

If no instruction and byte limit is used, the lifter will continue lifting the block until the block ends properly or until it runs out of data to lift.

addr: int
arch: Arch
behaviors: BehaviorFactory | None
data_refs: Sequence
const_vals: Sequence
default_exit_target: Any
jumpkind: str | None
next: int | None
static empty_block(arch, addr, statements=None, nxt=None, tyenv=None, jumpkind=None, direct_next=None, size=None)
Return type:

IRSB

Parameters:
property has_statements: bool
property exit_statements: Sequence[tuple[int, int, ExitStatement]]
copy()

Copy by creating an empty IRSB and then filling in the leftover attributes. Copy is made as deep as possible

Return type:

IRSB

extend(extendwith)

Appends an irsb to the current irsb. The irsb that is appended is invalidated. The appended irsb’s jumpkind and default exit are used. :type extendwith: IRSB :param extendwith: The IRSB to append to this IRSB

Return type:

IRSB

Parameters:

extendwith (IRSB)

invalidate_direct_next()
Return type:

None

pp()

Pretty-print the IRSB to stdout.

Return type:

None

property tyenv
property stmts_used: int
property offsIP: int | None
property direct_next: bool
property expressions

Return an iterator of all expressions contained in the IRSB.

property instructions: int

The number of instructions in this block

property instruction_addresses: Sequence[int]

Addresses of instructions in this block.

property size: int

The size of this block, in bytes

property operations

A list of all operations done by the IRSB, as libVEX enum names

property all_constants

Returns all constants in the block (including incrementing of the program counter) as pyvex.const.IRConst.

property constants

The constants (excluding updates of the program counter) in the IRSB as pyvex.const.IRConst.

property constant_jump_targets

A set of the static jump targets of the basic block.

property constant_jump_targets_and_jumpkinds

A dict of the static jump targets of the basic block to their jumpkind.

property is_noop_block: bool

Returns True if this block is a no-op block (i.e. it has no instructions and no jumps).

property statements: list
property disassembly: PcodeDisassemblerBlock
class angr.engines.pcode.lifter.Lifter(arch, addr)

Bases: object

A lifter is a class of methods for processing a block.

Variables:
  • data – The bytes to lift as either a python string of bytes or a cffi buffer object.

  • bytes_offset – The offset into data to start lifting at.

  • max_bytes – The maximum number of bytes to lift. If set to None, no byte limit is used.

  • max_inst – The maximum number of instructions to lift. If set to None, no instruction limit is used.

  • opt_level – Unused by P-Code lifter

  • traceflags – Unused by P-Code lifter

  • allow_arch_optimizations – Unused by P-Code lifter

  • strict_block_end – Unused by P-Code lifter

  • skip_stmts – Unused by P-Code lifter

Parameters:
REQUIRE_DATA_C = False
REQUIRE_DATA_PY = False
__init__(arch, addr)
Parameters:
arch: Arch
addr: int
data: str | bytes | None
bytes_offset: int | None
opt_level: int
traceflags: int | None
allow_arch_optimizations: bool | None
strict_block_end: bool | None
collect_data_refs: bool
max_inst: int | None
max_bytes: int | None
skip_stmts: bool
irsb: IRSB
lift()

Lifts the data using the information passed into _lift. Should be overridden in child classes.

Should set the lifted IRSB to self.irsb. If a lifter raises a LiftingException on the data, this signals that the lifter cannot lift this data and arch and the lifter is skipped. If a lifter can lift any amount of data, it should lift it and return the lifted block with a jumpkind of Ijk_NoDecode, signalling to pyvex that other lifters should be used on the undecodable data.

Return type:

None

angr.engines.pcode.lifter.lift(data, addr, arch, max_bytes=None, max_inst=None, bytes_offset=0, opt_level=1, traceflags=0, strict_block_end=True, inner=False, skip_stmts=False, collect_data_refs=False)

Lift machine code in data to a P-code IRSB.

If a lifter raises a LiftingException on the data, it is skipped. If it succeeds and returns a block with a jumpkind of Ijk_NoDecode, all of the lifters are tried on the rest of the data and if they work, their output is appended to the first block.

Parameters:
  • arch (Arch) – The arch to lift the data as.

  • addr (int) – The starting address of the block. Effects the IMarks.

  • data (str | bytes | None) – The bytes to lift as either a python string of bytes or a cffi buffer object.

  • max_bytes (Optional[int]) – The maximum number of bytes to lift. If set to None, no byte limit is used.

  • max_inst (Optional[int]) – The maximum number of instructions to lift. If set to None, no instruction limit is used.

  • bytes_offset (int) – The offset into data to start lifting at.

  • opt_level (int) – Unused by P-Code lifter

  • traceflags (int) – Unused by P-Code lifter

  • strict_block_end (bool)

  • inner (bool)

  • skip_stmts (bool)

  • collect_data_refs (bool)

Return type:

IRSB

Note

Explicitly specifying the number of instructions to lift (max_inst) may not always work exactly as expected. For example, on MIPS, it is meaningless to lift a branch or jump instruction without its delay slot. VEX attempts to Do The Right Thing by possibly decoding fewer instructions than requested. Specifically, this means that lifting a branch or jump on MIPS as a single instruction (max_inst=1) will result in an empty IRSB, and subsequent attempts to run this block will raise SimIRSBError(‘Empty IRSB passed to SimIRSB.’).

Note

If no instruction and byte limit is used, the lifter will continue lifting the block until the block ends properly or until it runs out of data to lift.

class angr.engines.pcode.lifter.PcodeBasicBlockLifter(arch)

Bases: object

Lifts basic blocks to P-code

Parameters:

arch (archinfo.Arch)

__init__(arch)
Parameters:

arch (Arch)

context: Context
behaviors: BehaviorFactory
lift(irsb, baseaddr, data, bytes_offset=0, max_bytes=None, max_inst=None, branch_delay_slot=False, is_sparc32=False)
Return type:

None

Parameters:
class angr.engines.pcode.lifter.PcodeLifter(arch, addr)

Bases: Lifter

Handles calling into pypcode to lift a block

Parameters:
addr: int
allow_arch_optimizations: bool | None
arch: Arch
bytes_offset: int | None
collect_data_refs: bool
data: str | bytes | None
irsb: IRSB
max_bytes: int | None
max_inst: int | None
opt_level: int
skip_stmts: bool
strict_block_end: bool | None
traceflags: int | None
lift()

Lifts the data using the information passed into _lift. Should be overridden in child classes.

Should set the lifted IRSB to self.irsb. If a lifter raises a LiftingException on the data, this signals that the lifter cannot lift this data and arch and the lifter is skipped. If a lifter can lift any amount of data, it should lift it and return the lifted block with a jumpkind of Ijk_NoDecode, signalling to pyvex that other lifters should be used on the undecodable data.

Return type:

None

class angr.engines.pcode.lifter.PcodeLifterEngineMixin(project=None, use_cache=None, cache_size=50000, default_opt_level=1, selfmodifying_code=None, single_step=False, default_strict_block_end=False, **kwargs)

Bases: SimEngine

Lifter mixin to lift from machine code to P-Code.

Parameters:
  • use_cache (bool | None)

  • cache_size (int)

  • default_opt_level (int)

  • selfmodifying_code (bool | None)

  • single_step (bool)

  • default_strict_block_end (bool)

__init__(project=None, use_cache=None, cache_size=50000, default_opt_level=1, selfmodifying_code=None, single_step=False, default_strict_block_end=False, **kwargs)
Parameters:
  • use_cache (bool | None)

  • cache_size (int)

  • default_opt_level (int)

  • selfmodifying_code (bool | None)

  • single_step (bool)

  • default_strict_block_end (bool)

clear_cache()
Return type:

None

lift_vex(addr=None, state=None, clemory=None, insn_bytes=None, arch=None, size=None, num_inst=None, traceflags=0, thumb=False, extra_stop_points=None, opt_level=None, strict_block_end=None, skip_stmts=False, collect_data_refs=False, load_from_ro_regions=False, cross_insn_opt=None, const_prop=None)

Temporary compatibility interface for integration with block code.

Return type:

IRSB

Parameters:
  • addr (int | None)

  • state (SimState | None)

  • clemory (Clemory | ClemoryReadOnlyView | None)

  • insn_bytes (bytes | None)

  • arch (Arch | None)

  • size (int | None)

  • num_inst (int | None)

  • traceflags (int)

  • thumb (bool)

  • extra_stop_points (Iterable[int] | None)

  • opt_level (int | None)

  • strict_block_end (bool | None)

  • skip_stmts (bool)

  • collect_data_refs (bool)

  • load_from_ro_regions (bool)

  • cross_insn_opt (bool | None)

  • const_prop (bool | None)

lift_pcode(addr=None, state=None, clemory=None, insn_bytes=None, arch=None, size=None, num_inst=None, traceflags=0, thumb=False, extra_stop_points=None, opt_level=None, strict_block_end=None, skip_stmts=False, collect_data_refs=False, load_from_ro_regions=False, cross_insn_opt=None, const_prop=None)

Lift an IRSB.

There are many possible valid sets of parameters. You at the very least must pass some source of data, some source of an architecture, and some source of an address.

Sources of data in order of priority: insn_bytes, clemory, state

Sources of an address, in order of priority: addr, state

Sources of an architecture, in order of priority: arch, clemory, state

Parameters:
  • state (Optional[SimState]) – A state to use as a data source.

  • clemory (Union[Clemory, ClemoryReadOnlyView, None]) – A cle.memory.Clemory object to use as a data source.

  • addr (Optional[int]) – The address at which to start the block.

  • thumb (bool) – Whether the block should be lifted in ARM’s THUMB mode.

  • opt_level (Optional[int]) – Unused for P-Code lifter

  • insn_bytes (Optional[bytes]) – A string of bytes to use as a data source.

  • size (Optional[int]) – The maximum size of the block, in bytes.

  • num_inst (Optional[int]) – The maximum number of instructions.

  • traceflags (int) – Unused by P-Code lifter

  • strict_block_end (Optional[bool]) – Unused by P-Code lifter

  • load_from_ro_regions (bool) – Unused by P-Code lifter

  • arch (Arch | None)

  • extra_stop_points (Iterable[int] | None)

  • skip_stmts (bool)

  • collect_data_refs (bool)

  • cross_insn_opt (bool | None)

  • const_prop (bool | None)

Return type:

IRSB

class angr.engines.pcode.emulate.PcodeEmulatorMixin(*args, **kwargs)

Bases: SimEngine

Mixin for p-code execution.

__init__(*args, **kwargs)
handle_pcode_block(irsb)

Execute a single P-Code IRSB.

Parameters:

irsb (IRSB) – Block to be executed.

Return type:

None

angr.engines.pcode.behavior.make_bv_sizes_equal(bv1, bv2)

Makes two BVs equal in length through sign extension.

Return type:

tuple[BV, BV]

Parameters:
class angr.engines.pcode.behavior.OpBehavior(opcode, is_unary, is_special=False)

Bases: object

Base class for all operation behaviors.

Parameters:
__init__(opcode, is_unary, is_special=False)
Parameters:
Return type:

None

opcode: int
is_unary: bool
is_special: bool
evaluate_unary(size_out, size_in, in1)
Return type:

BV

Parameters:
evaluate_binary(size_out, size_in, in1, in2)
Return type:

BV

Parameters:
static generic_compare(args, comparison)
Return type:

BV

Parameters:
classmethod booleanize(in1)

Reduce input BV to a single bit of truth: out <- 1 if (in1 != 0) else 0.

Return type:

BV

Parameters:

in1 (BV)

class angr.engines.pcode.behavior.OpBehaviorCopy

Bases: OpBehavior

Behavior for the COPY operation.

__init__()
evaluate_unary(size_out, size_in, in1)
Return type:

BV

Parameters:
is_special: bool
is_unary: bool
opcode: int
class angr.engines.pcode.behavior.OpBehaviorEqual

Bases: OpBehavior

Behavior for the INT_EQUAL operation.

__init__()
evaluate_binary(size_out, size_in, in1, in2)
Return type:

BV

Parameters:
is_special: bool
is_unary: bool
opcode: int
class angr.engines.pcode.behavior.OpBehaviorNotEqual

Bases: OpBehavior

Behavior for the INT_NOTEQUAL operation.

__init__()
evaluate_binary(size_out, size_in, in1, in2)
Return type:

BV

Parameters:
is_special: bool
is_unary: bool
opcode: int
class angr.engines.pcode.behavior.OpBehaviorIntSless

Bases: OpBehavior

Behavior for the INT_SLESS operation.

__init__()
evaluate_binary(size_out, size_in, in1, in2)
Return type:

BV

Parameters:
is_special: bool
is_unary: bool
opcode: int
class angr.engines.pcode.behavior.OpBehaviorIntSlessEqual

Bases: OpBehavior

Behavior for the INT_SLESSEQUAL operation.

__init__()
evaluate_binary(size_out, size_in, in1, in2)
Return type:

BV

Parameters:
is_special: bool
is_unary: bool
opcode: int
class angr.engines.pcode.behavior.OpBehaviorIntLess

Bases: OpBehavior

Behavior for the INT_LESS operation.

__init__()
evaluate_binary(size_out, size_in, in1, in2)
Return type:

BV

Parameters:
is_special: bool
is_unary: bool
opcode: int
class angr.engines.pcode.behavior.OpBehaviorIntLessEqual

Bases: OpBehavior

Behavior for the INT_LESSEQUAL operation.

__init__()
evaluate_binary(size_out, size_in, in1, in2)
Return type:

BV

Parameters:
is_special: bool
is_unary: bool
opcode: int
class angr.engines.pcode.behavior.OpBehaviorIntZext

Bases: OpBehavior

Behavior for the INT_ZEXT operation.

__init__()
evaluate_unary(size_out, size_in, in1)
Return type:

BV

Parameters:
is_special: bool
is_unary: bool
opcode: int
class angr.engines.pcode.behavior.OpBehaviorIntSext

Bases: OpBehavior

Behavior for the INT_SEXT operation.

__init__()
evaluate_unary(size_out, size_in, in1)
Return type:

BV

Parameters:
is_special: bool
is_unary: bool
opcode: int
class angr.engines.pcode.behavior.OpBehaviorIntAdd

Bases: OpBehavior

Behavior for the INT_ADD operation.

__init__()
evaluate_binary(size_out, size_in, in1, in2)
Return type:

BV

Parameters:
is_special: bool
is_unary: bool
opcode: int
class angr.engines.pcode.behavior.OpBehaviorIntSub

Bases: OpBehavior

Behavior for the INT_SUB operation.

__init__()
evaluate_binary(size_out, size_in, in1, in2)
Return type:

BV

Parameters:
is_special: bool
is_unary: bool
opcode: int
class angr.engines.pcode.behavior.OpBehaviorIntCarry

Bases: OpBehavior

Behavior for the INT_CARRY operation.

__init__()
evaluate_binary(size_out, size_in, in1, in2)
Return type:

BV

Parameters:
is_special: bool
is_unary: bool
opcode: int
class angr.engines.pcode.behavior.OpBehaviorIntScarry

Bases: OpBehavior

Behavior for the INT_SCARRY operation.

__init__()
evaluate_binary(size_out, size_in, in1, in2)
Return type:

BV

Parameters:
is_special: bool
is_unary: bool
opcode: int
class angr.engines.pcode.behavior.OpBehaviorIntSborrow

Bases: OpBehavior

Behavior for the INT_SBORROW operation.

__init__()
evaluate_binary(size_out, size_in, in1, in2)
Return type:

BV

Parameters:
is_special: bool
is_unary: bool
opcode: int
class angr.engines.pcode.behavior.OpBehaviorInt2Comp

Bases: OpBehavior

Behavior for the INT_2COMP operation.

__init__()
evaluate_unary(size_out, size_in, in1)
Return type:

BV

Parameters:
is_special: bool
is_unary: bool
opcode: int
class angr.engines.pcode.behavior.OpBehaviorIntNegate

Bases: OpBehavior

Behavior for the INT_NEGATE operation.

__init__()
evaluate_unary(size_out, size_in, in1)
Return type:

BV

Parameters:
is_special: bool
is_unary: bool
opcode: int
class angr.engines.pcode.behavior.OpBehaviorIntXor

Bases: OpBehavior

Behavior for the INT_XOR operation.

__init__()
evaluate_binary(size_out, size_in, in1, in2)
Return type:

BV

Parameters:
is_special: bool
is_unary: bool
opcode: int
class angr.engines.pcode.behavior.OpBehaviorIntAnd

Bases: OpBehavior

Behavior for the INT_AND operation.

__init__()
evaluate_binary(size_out, size_in, in1, in2)
Return type:

BV

Parameters:
is_special: bool
is_unary: bool
opcode: int
class angr.engines.pcode.behavior.OpBehaviorIntOr

Bases: OpBehavior

Behavior for the INT_OR operation.

__init__()
evaluate_binary(size_out, size_in, in1, in2)
Return type:

BV

Parameters:
is_special: bool
is_unary: bool
opcode: int
class angr.engines.pcode.behavior.OpBehaviorIntLeft

Bases: OpBehavior

Behavior for the INT_LEFT operation.

__init__()
evaluate_binary(size_out, size_in, in1, in2)
Return type:

BV

Parameters:
is_special: bool
is_unary: bool
opcode: int
class angr.engines.pcode.behavior.OpBehaviorIntRight

Bases: OpBehavior

Behavior for the INT_RIGHT operation.

__init__()
evaluate_binary(size_out, size_in, in1, in2)
Return type:

BV

Parameters:
is_special: bool
is_unary: bool
opcode: int
class angr.engines.pcode.behavior.OpBehaviorIntSright

Bases: OpBehavior

Behavior for the INT_SRIGHT operation.

__init__()
evaluate_binary(size_out, size_in, in1, in2)
Return type:

BV

Parameters:
is_special: bool
is_unary: bool
opcode: int
class angr.engines.pcode.behavior.OpBehaviorIntMult

Bases: OpBehavior

Behavior for the INT_MULT operation.

__init__()
evaluate_binary(size_out, size_in, in1, in2)
Return type:

BV

Parameters:
is_special: bool
is_unary: bool
opcode: int
class angr.engines.pcode.behavior.OpBehaviorIntDiv

Bases: OpBehavior

Behavior for the INT_DIV operation.

__init__()
evaluate_binary(size_out, size_in, in1, in2)
Return type:

BV

Parameters:
is_special: bool
is_unary: bool
opcode: int
class angr.engines.pcode.behavior.OpBehaviorIntSdiv

Bases: OpBehavior

Behavior for the INT_SDIV operation.

__init__()
evaluate_binary(size_out, size_in, in1, in2)
Return type:

BV

Parameters:
is_special: bool
is_unary: bool
opcode: int
class angr.engines.pcode.behavior.OpBehaviorIntRem

Bases: OpBehavior

Behavior for the INT_REM operation.

__init__()
evaluate_binary(size_out, size_in, in1, in2)
Return type:

BV

Parameters:
is_special: bool
is_unary: bool
opcode: int
class angr.engines.pcode.behavior.OpBehaviorIntSrem

Bases: OpBehavior

Behavior for the INT_SREM operation.

__init__()
evaluate_binary(size_out, size_in, in1, in2)
Return type:

BV

Parameters:
is_special: bool
is_unary: bool
opcode: int
class angr.engines.pcode.behavior.OpBehaviorBoolNegate

Bases: OpBehavior

Behavior for the BOOL_NEGATE operation.

__init__()
evaluate_unary(size_out, size_in, in1)
Return type:

BV

Parameters:
is_special: bool
is_unary: bool
opcode: int
class angr.engines.pcode.behavior.OpBehaviorBoolXor

Bases: OpBehavior

Behavior for the BOOL_XOR operation.

__init__()
evaluate_binary(size_out, size_in, in1, in2)
Return type:

BV

Parameters:
is_special: bool
is_unary: bool
opcode: int
class angr.engines.pcode.behavior.OpBehaviorBoolAnd

Bases: OpBehavior

Behavior for the BOOL_AND operation.

__init__()
evaluate_binary(size_out, size_in, in1, in2)
Return type:

BV

Parameters:
is_special: bool
is_unary: bool
opcode: int
class angr.engines.pcode.behavior.OpBehaviorBoolOr

Bases: OpBehavior

Behavior for the BOOL_OR operation.

__init__()
evaluate_binary(size_out, size_in, in1, in2)
Return type:

BV

Parameters:
is_special: bool
is_unary: bool
opcode: int
class angr.engines.pcode.behavior.OpBehaviorFloatEqual

Bases: OpBehavior

Behavior for the FLOAT_EQUAL operation.

__init__()
is_special: bool
is_unary: bool
opcode: int
class angr.engines.pcode.behavior.OpBehaviorFloatNotEqual

Bases: OpBehavior

Behavior for the FLOAT_NOTEQUAL operation.

__init__()
is_special: bool
is_unary: bool
opcode: int
class angr.engines.pcode.behavior.OpBehaviorFloatLess

Bases: OpBehavior

Behavior for the FLOAT_LESS operation.

__init__()
is_special: bool
is_unary: bool
opcode: int
class angr.engines.pcode.behavior.OpBehaviorFloatLessEqual

Bases: OpBehavior

Behavior for the FLOAT_LESSEQUAL operation.

__init__()
is_special: bool
is_unary: bool
opcode: int
class angr.engines.pcode.behavior.OpBehaviorFloatNan

Bases: OpBehavior

Behavior for the FLOAT_NAN operation.

__init__()
is_special: bool
is_unary: bool
opcode: int
class angr.engines.pcode.behavior.OpBehaviorFloatAdd

Bases: OpBehavior

Behavior for the FLOAT_ADD operation.

__init__()
is_special: bool
is_unary: bool
opcode: int
class angr.engines.pcode.behavior.OpBehaviorFloatDiv

Bases: OpBehavior

Behavior for the FLOAT_DIV operation.

__init__()
is_special: bool
is_unary: bool
opcode: int
class angr.engines.pcode.behavior.OpBehaviorFloatMult

Bases: OpBehavior

Behavior for the FLOAT_MULT operation.

__init__()
is_special: bool
is_unary: bool
opcode: int
class angr.engines.pcode.behavior.OpBehaviorFloatSub

Bases: OpBehavior

Behavior for the FLOAT_SUB operation.

__init__()
is_special: bool
is_unary: bool
opcode: int
class angr.engines.pcode.behavior.OpBehaviorFloatNeg

Bases: OpBehavior

Behavior for the FLOAT_NEG operation.

__init__()
is_special: bool
is_unary: bool
opcode: int
class angr.engines.pcode.behavior.OpBehaviorFloatAbs

Bases: OpBehavior

Behavior for the FLOAT_ABS operation.

__init__()
is_special: bool
is_unary: bool
opcode: int
class angr.engines.pcode.behavior.OpBehaviorFloatSqrt

Bases: OpBehavior

Behavior for the FLOAT_SQRT operation.

__init__()
is_special: bool
is_unary: bool
opcode: int
class angr.engines.pcode.behavior.OpBehaviorFloatInt2Float

Bases: OpBehavior

Behavior for the FLOAT_INT2FLOAT operation.

__init__()
is_special: bool
is_unary: bool
opcode: int
class angr.engines.pcode.behavior.OpBehaviorFloatFloat2Float

Bases: OpBehavior

Behavior for the FLOAT_FLOAT2FLOAT operation.

__init__()
is_special: bool
is_unary: bool
opcode: int
class angr.engines.pcode.behavior.OpBehaviorFloatTrunc

Bases: OpBehavior

Behavior for the FLOAT_TRUNC operation.

__init__()
is_special: bool
is_unary: bool
opcode: int
class angr.engines.pcode.behavior.OpBehaviorFloatCeil

Bases: OpBehavior

Behavior for the FLOAT_CEIL operation.

__init__()
is_special: bool
is_unary: bool
opcode: int
class angr.engines.pcode.behavior.OpBehaviorFloatFloor

Bases: OpBehavior

Behavior for the FLOAT_FLOOR operation.

__init__()
is_special: bool
is_unary: bool
opcode: int
class angr.engines.pcode.behavior.OpBehaviorFloatRound

Bases: OpBehavior

Behavior for the FLOAT_ROUND operation.

__init__()
is_special: bool
is_unary: bool
opcode: int
class angr.engines.pcode.behavior.OpBehaviorPiece

Bases: OpBehavior

Behavior for the PIECE operation.

__init__()
is_special: bool
is_unary: bool
opcode: int
class angr.engines.pcode.behavior.OpBehaviorSubpiece

Bases: OpBehavior

Behavior for the SUBPIECE operation.

__init__()
evaluate_binary(size_out, size_in, in1, in2)
Return type:

BV

Parameters:
is_special: bool
is_unary: bool
opcode: int
class angr.engines.pcode.behavior.OpBehaviorPopcount

Bases: OpBehavior

Behavior for the POPCOUNT operation.

__init__()
evaluate_unary(size_out, size_in, in1)
Return type:

BV

Parameters:
is_special: bool
is_unary: bool
opcode: int
class angr.engines.pcode.behavior.OpBehaviorLzcount

Bases: OpBehavior

Behavior for the LZCOUNT operation.

__init__()
evaluate_unary(size_out, size_in, in1)
Return type:

BV

Parameters:
is_special: bool
is_unary: bool
opcode: int
class angr.engines.pcode.behavior.BehaviorFactory

Bases: object

Returns the behavior object for a given opcode.

__init__()
get_behavior_for_opcode(opcode)
Return type:

OpBehavior

Parameters:

opcode (int)

class angr.engines.pcode.cc.SimCCM68k(arch)

Bases: SimCC

Default CC for M68k

Parameters:

arch (archinfo.Arch)

ARG_REGS: list[str] = []
FP_ARG_REGS: list[str] = []
STACKARG_SP_DIFF = 4
RETURN_VAL: SimFunctionArgument | None = <d0>
RETURN_ADDR: SimFunctionArgument | None = [0x0]
class angr.engines.pcode.cc.SimCCRISCV(arch)

Bases: SimCC

Default CC for RISCV

Parameters:

arch (archinfo.Arch)

ARG_REGS: list[str] = ['a0', 'a1', 'a2', 'a3', 'a4', 'a5', 'a6', 'a7']
RETURN_ADDR: SimFunctionArgument | None = <ra>
RETURN_VAL: SimFunctionArgument | None = <a0>
class angr.engines.pcode.cc.SimCCSPARC(arch)

Bases: SimCC

Default CC for SPARC

Parameters:

arch (archinfo.Arch)

ARG_REGS: list[str] = ['o0', 'o1', 'o2', 'o3', 'o4', 'o5']
RETURN_VAL: SimFunctionArgument | None = <o0>
RETURN_ADDR: SimFunctionArgument | None = <o7>
class angr.engines.pcode.cc.SimCCSH4(arch)

Bases: SimCC

Default CC for SH4

Parameters:

arch (archinfo.Arch)

ARG_REGS: list[str] = ['r4', 'r5']
RETURN_VAL: SimFunctionArgument | None = <r0>
RETURN_ADDR: SimFunctionArgument | None = <pr>
class angr.engines.pcode.cc.SimCCPARISC(arch)

Bases: SimCC

Default CC for PARISC

Parameters:

arch (archinfo.Arch)

ARG_REGS: list[str] = ['r26', 'r25']
RETURN_VAL: SimFunctionArgument | None = <r28>
RETURN_ADDR: SimFunctionArgument | None = <rp>
class angr.engines.pcode.cc.SimCCPowerPC(arch)

Bases: SimCC

Default CC for PowerPC

Parameters:

arch (archinfo.Arch)

ARG_REGS: list[str] = ['r3', 'r4', 'r5', 'r6', 'r7', 'r8', 'r9', 'r10']
FP_ARG_REGS: list[str] = []
STACKARG_SP_BUFF = 8
RETURN_ADDR: SimFunctionArgument | None = <lr>
RETURN_VAL: SimFunctionArgument | None = <r3>
class angr.engines.pcode.cc.SimCCXtensa(arch)

Bases: SimCC

Default CC for Xtensa

Parameters:

arch (archinfo.Arch)

ARG_REGS: list[str] = ['i2', 'i3', 'i4', 'i5', 'i6', 'i7']
FP_ARG_REGS: list[str] = []
RETURN_ADDR: SimFunctionArgument | None = <a0>
RETURN_VAL: SimFunctionArgument | None = <o2>
angr.engines.pcode.cc.register_pcode_arch_default_cc(arch)
Parameters:

arch (ArchPcode)

Simulation Logging

class angr.state_plugins.sim_action.SimAction(state, region_type)

Bases: SimEvent

A SimAction represents a semantic action that an analyzed program performs.

TMP = 'tmp'
REG = 'reg'
MEM = 'mem'
__init__(state, region_type)

Initializes the SimAction.

Parameters:

state – the state that’s the SimAction is taking place in.

property all_objects
property is_symbolic
property tmp_deps
property reg_deps
copy()
downsize()

Clears some low-level details (that take up memory) out of the SimAction.

class angr.state_plugins.sim_action.SimActionExit(state, target, condition=None, exit_type=None)

Bases: SimAction

An Exit action represents a (possibly conditional) jump.

CONDITIONAL = 'conditional'
DEFAULT = 'default'
__init__(state, target, condition=None, exit_type=None)

Initializes the SimAction.

Parameters:

state – the state that’s the SimAction is taking place in.

property all_objects
property is_symbolic
class angr.state_plugins.sim_action.SimActionConstraint(state, constraint, condition=None)

Bases: SimAction

A constraint action represents an extra constraint added during execution of a path.

__init__(state, constraint, condition=None)

Initializes the SimAction.

Parameters:

state – the state that’s the SimAction is taking place in.

property all_objects
property is_symbolic
class angr.state_plugins.sim_action.SimActionOperation(state, op, exprs, result)

Bases: SimAction

An action representing an operation between variables and/or constants.

__init__(state, op, exprs, result)

Initializes the SimAction.

Parameters:

state – the state that’s the SimAction is taking place in.

property all_objects
property is_symbolic
class angr.state_plugins.sim_action.SimActionData(state, region_type, action, tmp=None, addr=None, size=None, data=None, condition=None, fallback=None, fd=None)

Bases: SimAction

A Data action represents a read or a write from memory, registers or a file.

READ = 'read'
WRITE = 'write'
OPERATE = 'operate'
__init__(state, region_type, action, tmp=None, addr=None, size=None, data=None, condition=None, fallback=None, fd=None)

Initializes the SimAction.

Parameters:

state – the state that’s the SimAction is taking place in.

downsize()

Clears some low-level details (that take up memory) out of the SimAction.

property all_objects
property is_symbolic
property tmp_deps
property reg_deps
property storage
angr.state_plugins.sim_action_object.ast_preserving_op(f, *args)
angr.state_plugins.sim_action_object.ast_stripping_decorator(f)
class angr.state_plugins.sim_action_object.SimActionObject(ast, reg_deps=frozenset({}), tmp_deps=frozenset({}), deps=frozenset({}), state=None)

Bases: object

A SimActionObject tracks an AST and its dependencies.

Parameters:
__init__(ast, reg_deps=frozenset({}), tmp_deps=frozenset({}), deps=frozenset({}), state=None)
Parameters:
ast: Base
reg_deps: frozenset[SimActionData | SimActionOperation]
tmp_deps: frozenset[SimActionData | SimActionOperation]
to_claripy()
Return type:

Base

copy()
Return type:

SimActionObject

is_leaf()
Return type:

bool

property op: str
property args: tuple[ArgType, ...]
property length: int | None
property variables: frozenset[str]
property symbolic: bool
property annotations: tuple[Annotation, ...]
property depth: int
SDiv(other)
Return type:

SimActionObject

SMod(other)
Return type:

SimActionObject

union(other)
Return type:

SimActionObject

intersection(other)
Return type:

SimActionObject

widen(other)
Return type:

SimActionObject

raw_to_bv()
Return type:

SimActionObject

bv_to_fp()
Return type:

SimActionObject

class angr.state_plugins.sim_event.SimEvent(state, event_type, **kwargs)

Bases: object

A SimEvent is a log entry for some notable event during symbolic execution. It logs the location it was generated (ins_addr, bbl_addr, stmt_idx, and sim_procedure) as well as arbitrary tags (objects).

You may also be interested in SimAction, which is a specialization of SimEvent for CPU events.

__init__(state, event_type, **kwargs)
angr.state_plugins.sim_event.resource_event(state, exception)

Procedures

class angr.sim_procedure.SimProcedure(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)

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:

The following parameters are optional:

Parameters:
  • 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 – 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

  • project (Project)

  • prototype (SimTypeFunction)

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.

Parameters:

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

Parameters:

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 – 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.

Parameters:
__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)
project: Project
arch: Arch
cc: SimCC
prototype: SimTypeFunction
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.

ty_ptr(ty)
property is_java
property argument_types
property return_type
class angr.procedures.stubs.format_parser.FormatString(parser, components)

Bases: object

Describes a format string.

SCANF_DELIMITERS = [b'\t', b'\n', b'\x0b', b'\r', b' ']
__init__(parser, components)

Takes a list of components which are either just strings or a FormatSpecifier.

property state
replace(va_arg)

Implement printf - based on the stored format specifier information, format the values from the arg getter function args into a string.

Parameters:

va_arg – A function which takes a type and returns the next argument of that type

Returns:

The result formatted string

interpret(va_arg, addr=None, simfd=None)

implement scanf - extract formatted data from memory or a file according to the stored format specifiers and store them into the pointers extracted from args.

Parameters:
  • va_arg – A function which, given a type, returns the next argument of that type

  • addr – The address in the memory to extract data from, or…

  • simfd – A file descriptor to use for reading data from

Returns:

The number of arguments parsed

class angr.procedures.stubs.format_parser.FormatSpecifier(string, length_spec, pad_chr, size, signed)

Bases: object

Describes a format specifier within a format string.

__init__(string, length_spec, pad_chr, size, signed)
string
size
signed
length_spec
pad_chr
property spec_type
class angr.procedures.stubs.format_parser.FormatParser(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)

Bases: SimProcedure

For SimProcedures relying on printf-style format strings.

Parameters:
ARGS_MISMATCH = True
basic_spec = {b'A': double, b'E': double, b'F': double, b'G': double, b'X': unsigned int, b'a': double, b'c': char, b'd': int, b'e': double, b'f': double, b'g': double, b'i': int, b'n': unsigned int*, b'o': unsigned int, b'p': unsigned int*, b's': char*, b'u': unsigned int, b'x': unsigned int}
int_sign = {'signed': [b'd', b'i'], 'unsigned': [b'o', b'u', b'x', b'X']}
int_len_mod = {b'h': (short, unsigned short), b'hh': (char, char), b'j': (long long, unsigned long long), b'l': (long, unsigned long), b'll': (long long, unsigned long long), b't': (long, long), b'z': (size_t, size_t)}
other_types = {('string',): <function FormatParser.<lambda>>}
flags = ['#', '0', '\\-', ' ', '\\+', "\\'", 'I']
extract_components(fmt)

Extract the actual formats from the format string fmt.

Parameters:

fmt (list) – A list of format chars.

Return type:

list

Returns:

a FormatString object

class angr.procedures.stubs.format_parser.ScanfFormatParser(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)

Bases: FormatParser

For SimProcedures relying on scanf-style format strings.

basic_spec = {b'A': float, b'E': float, b'F': float, b'G': float, b'X': unsigned int, b'a': float, b'c': char, b'd': int, b'e': float, b'f': float, b'g': float, b'i': int, b'n': unsigned int*, b'o': unsigned int, b'p': unsigned int*, b's': char*, b'u': unsigned int, b'x': unsigned int}
float_spec = [b'e', b'E', b'f', b'F', b'g', b'G', b'a', b'A']
float_len_mod = {b'l': <class 'angr.sim_type.SimTypeDouble'>, b'll': <class 'angr.sim_type.SimTypeDouble'>}
class angr.procedures.definitions.SimTypeCollection

Bases: object

A type collection is the mechanism for describing types. Types in a type collection can be referenced using

__init__()
set_names(*names)
Parameters:

names (str)

add(name, t)

Add a type to the collection.

Parameters:
  • name (str) – Name of the type to add.

  • t (SimType) – The SimType object to add to the collection.

Return type:

None

get(name, bottom_on_missing=False)

Get a SimType object from the collection as identified by the name.

Parameters:
  • name (str) – Name of the type to get.

  • bottom_on_missing (bool) – Return a SimTypeBottom object if the required type does not exist.

Return type:

SimType

Returns:

The SimType object.

init_str()
Return type:

str

class angr.procedures.definitions.SimLibrary

Bases: object

A SimLibrary is the mechanism for describing a dynamic library’s API, its functions and metadata.

Any instance of this class (or its subclasses) found in the angr.procedures.definitions package will be automatically picked up and added to angr.SIM_LIBRARIES via all its names.

Variables:
  • fallback_cc – A mapping from architecture to the default calling convention that should be used if no other information is present. Contains some sane defaults for linux.

  • fallback_proc – A SimProcedure class that should be used to provide stub procedures. By default, ReturnUnconstrained.

__init__()
copy()

Make a copy of this SimLibrary, allowing it to be mutated without affecting the global version.

Returns:

A new SimLibrary object with the same library references but different dict/list references

update(other)

Augment this SimLibrary with the information from another SimLibrary

Parameters:

other (SimLibrary) – The other SimLibrary

property name

The first common name of this library, e.g. libc.so.6, or ‘??????’ if none are known.

set_library_names(*names)

Set some common names of this library by which it may be referred during linking

Parameters:

names – Any number of string library names may be passed as varargs.

set_default_cc(arch_name, cc_cls)

Set the default calling convention used for this library under a given architecture

Parameters:

arch_name – The string name of the architecture, i.e. the .name field from archinfo.

Parm cc_cls:

The SimCC class (not an instance!) to use

set_non_returning(*names)

Mark some functions in this class as never returning, i.e. loops forever or terminates execution

Parameters:

names – Any number of string function names may be passed as varargs

set_prototype(name, proto)

Set the prototype of a function in the form of a SimTypeFunction containing argument and return types

Parameters:
  • name – The name of the function as a string

  • proto – The prototype of the function as a SimTypeFunction

set_prototypes(protos)

Set the prototypes of many functions

Parameters:

protos – Dictionary mapping function names to SimTypeFunction objects

set_c_prototype(c_decl)

Set the prototype of a function in the form of a C-style function declaration.

Parameters:

c_decl (str) – The C-style declaration of the function.

Returns:

A tuple of (function name, function prototype)

Return type:

tuple

add(name, proc_cls, **kwargs)

Add a function implementation to the library.

Parameters:
  • name – The name of the function as a string

  • proc_cls – The implementation of the function as a SimProcedure _class_, not instance

  • kwargs – Any additional parameters to the procedure class constructor may be passed as kwargs

add_all_from_dict(dictionary, **kwargs)

Batch-add function implementations to the library.

Parameters:
  • dictionary – A mapping from name to procedure class, i.e. the first two arguments to add()

  • kwargs – Any additional kwargs will be passed to the constructors of _each_ procedure class

add_alias(name, *alt_names)

Add some duplicate names for a given function. The original function’s implementation must already be registered.

Parameters:
  • name – The name of the function for which an implementation is already present

  • alt_names – Any number of alternate names may be passed as varargs

get(name, arch)

Get an implementation of the given function specialized for the given arch, or a stub procedure if none exists.

Parameters:
  • name – The name of the function as a string

  • arch – The architecure to use, as either a string or an archinfo.Arch instance

Returns:

A SimProcedure instance representing the function as found in the library

get_stub(name, arch)

Get a stub procedure for the given function, regardless of if a real implementation is available. This will apply any metadata, such as a default calling convention or a function prototype.

By stub, we pretty much always mean a ReturnUnconstrained SimProcedure with the appropriate display name and metadata set. This will appear in state.history.descriptions as <SimProcedure display_name (stub)>

Parameters:
  • name – The name of the function as a string

  • arch – The architecture to use, as either a string or an archinfo.Arch instance

Returns:

A SimProcedure instance representing a plausable stub as could be found in the library.

get_prototype(name, arch=None)

Get a prototype of the given function name, optionally specialize the prototype to a given architecture.

Parameters:
  • name (str) – Name of the function.

  • arch – The architecture to specialize to.

Return type:

SimTypeFunction | None

Returns:

Prototype of the function, or None if the prototype does not exist.

has_metadata(name)

Check if a function has either an implementation or any metadata associated with it

Parameters:

name – The name of the function as a string

Returns:

A bool indicating if anything is known about the function

has_implementation(name)

Check if a function has an implementation associated with it

Parameters:

name – The name of the function as a string

Returns:

A bool indicating if an implementation of the function is available

has_prototype(func_name)

Check if a function has a prototype associated with it.

Parameters:

func_name (str) – The name of the function.

Returns:

A bool indicating if a prototype of the function is available.

Return type:

bool

class angr.procedures.definitions.SimCppLibrary

Bases: SimLibrary

SimCppLibrary is a specialized version of SimLibrary that will demangle C++ function names before looking for an implementation or prototype for it.

get(name, arch)

Get an implementation of the given function specialized for the given arch, or a stub procedure if none exists. Demangle the function name if it is a mangled C++ name.

Parameters:
  • name (str) – The name of the function as a string

  • arch – The architecure to use, as either a string or an archinfo.Arch instance

Returns:

A SimProcedure instance representing the function as found in the library

get_stub(name, arch)

Get a stub procedure for the given function, regardless of if a real implementation is available. This will apply any metadata, such as a default calling convention or a function prototype. Demangle the function name if it is a mangled C++ name.

Parameters:
  • name (str) – The name of the function as a string

  • arch – The architecture to use, as either a string or an archinfo.Arch instance

Returns:

A SimProcedure instance representing a plausable stub as could be found in the library.

get_prototype(name, arch=None)

Get a prototype of the given function name, optionally specialize the prototype to a given architecture. The function name will be demangled first.

Parameters:
  • name (str) – Name of the function.

  • arch – The architecture to specialize to.

Return type:

SimTypeFunction | None

Returns:

Prototype of the function, or None if the prototype does not exist.

has_metadata(name)

Check if a function has either an implementation or any metadata associated with it. Demangle the function name if it is a mangled C++ name.

Parameters:

name – The name of the function as a string

Returns:

A bool indicating if anything is known about the function

has_implementation(name)

Check if a function has an implementation associated with it. Demangle the function name if it is a mangled C++ name.

Parameters:

name (str) – A mangled function name.

Returns:

bool

has_prototype(func_name)

Check if a function has a prototype associated with it. Demangle the function name if it is a mangled C++ name.

Parameters:

name (str) – A mangled function name.

Returns:

bool

class angr.procedures.definitions.SimSyscallLibrary

Bases: SimLibrary

SimSyscallLibrary is a specialized version of SimLibrary for dealing not with a dynamic library’s API but rather an operating system’s syscall API. Because this interface is inherently lower-level than a dynamic library, many parts of this class has been changed to store data based on an “ABI name” (ABI = application binary interface, like an API but for when there’s no programming language) instead of an architecture. An ABI name is just an arbitrary string with which a calling convention and a syscall numbering is associated.

All the SimLibrary methods for adding functions still work, but now there’s an additional layer on top that associates them with numbers.

__init__()
copy()

Make a copy of this SimLibrary, allowing it to be mutated without affecting the global version.

Returns:

A new SimLibrary object with the same library references but different dict/list references

update(other)

Augment this SimLibrary with the information from another SimLibrary

Parameters:

other – The other SimLibrary

minimum_syscall_number(abi)
Parameters:

abi – The abi to evaluate

Returns:

The smallest syscall number known for the given abi

maximum_syscall_number(abi)
Parameters:

abi – The abi to evaluate

Returns:

The largest syscall number known for the given abi

add_number_mapping(abi, number, name)

Associate a syscall number with the name of a function present in the underlying SimLibrary

Parameters:
  • abi – The abi for which this mapping applies

  • number – The syscall number

  • name – The name of the function

add_number_mapping_from_dict(abi, mapping)

Batch-associate syscall numbers with names of functions present in the underlying SimLibrary

Parameters:
  • abi – The abi for which this mapping applies

  • mapping – A dict mapping syscall numbers to function names

set_abi_cc(abi, cc_cls)

Set the default calling convention for an abi

Parameters:
  • abi – The name of the abi

  • cc_cls – A SimCC _class_, not an instance, that should be used for syscalls using the abi

set_prototype(abi, name, proto)

Set the prototype of a function in the form of a SimTypeFunction containing argument and return types

Parameters:
  • abi (str) – ABI of the syscall.

  • name (str) – The name of the syscall as a string

  • proto (SimTypeFunction) – The prototype of the syscall as a SimTypeFunction

Return type:

None

set_prototypes(abi, protos)

Set the prototypes of many syscalls.

Parameters:
  • abi (str) – ABI of the syscalls.

  • protos (dict[str, SimTypeFunction]) – Dictionary mapping syscall names to SimTypeFunction objects

Return type:

None

get(number, arch, abi_list=())

The get() function for SimSyscallLibrary looks a little different from its original version.

Instead of providing a name, you provide a number, and you additionally provide a list of abi names that are applicable. The first abi for which the number is present in the mapping will be chosen. This allows for the easy abstractions of architectures like ARM or MIPS linux for which there are many ABIs that can be used at any time by using syscall numbers from various ranges. If no abi knows about the number, the stub procedure with the name “sys_%d” will be used.

Parameters:
  • number – The syscall number

  • arch – The architecture being worked with, as either a string name or an archinfo.Arch

  • abi_list – A list of ABI names that could be used

Returns:

A SimProcedure representing the implementation of the given syscall, or a stub if no implementation is available

get_stub(number, arch, abi_list=())

Pretty much the intersection of SimLibrary.get_stub() and SimSyscallLibrary.get().

Parameters:
  • number – The syscall number

  • arch – The architecture being worked with, as either a string name or an archinfo.Arch

  • abi_list – A list of ABI names that could be used

Returns:

A SimProcedure representing a plausable stub that could model the syscall

get_prototype(abi, name, arch=None)

Get a prototype of the given syscall name and its ABI, optionally specialize the prototype to a given architecture.

Parameters:
  • abi (str) – ABI of the prototype to get.

  • name (str) – Name of the syscall.

  • arch – The architecture to specialize to.

Return type:

SimTypeFunction | None

Returns:

Prototype of the syscall, or None if the prototype does not exist.

has_metadata(number, arch, abi_list=())

Pretty much the intersection of SimLibrary.has_metadata() and SimSyscallLibrary.get().

Parameters:
  • number – The syscall number

  • arch – The architecture being worked with, as either a string name or an archinfo.Arch

  • abi_list – A list of ABI names that could be used

Returns:

A bool of whether or not any implementation or metadata is known about the given syscall

has_implementation(number, arch, abi_list=())

Pretty much the intersection of SimLibrary.has_implementation() and SimSyscallLibrary.get().

Parameters:
  • number – The syscall number

  • arch – The architecture being worked with, as either a string name or an archinfo.Arch

  • abi_list – A list of ABI names that could be used

Returns:

A bool of whether or not an implementation of the syscall is available

has_prototype(abi, name)

Check if a function has a prototype associated with it. Demangle the function name if it is a mangled C++ name.

Parameters:
  • abi (str) – Name of the ABI.

  • name (str) – The syscall name.

Return type:

bool

Returns:

bool

angr.procedures.definitions.load_type_collections(skip=None)
Return type:

None

angr.procedures.definitions.load_win32_type_collections()
Return type:

None

angr.procedures.definitions.load_external_definitions()

Load library definitions from specific directories. By default it parses ANGR_EXTERNAL_DEFINITIONS_DIRS as a semicolon separated list of directory paths. Then it loads all .py files in each directory. These .py files should declare SimLibrary() objects and call .set_library_names() to register themselves in angr.SIM_LIBRARIES.

angr.procedures.definitions.load_win32api_definitions()
angr.procedures.definitions.load_all_definitions()

Calling Conventions and Types

class angr.calling_conventions.PointerWrapper(value, buffer=False)

Bases: object

__init__(value, buffer=False)
class angr.calling_conventions.AllocHelper(ptrsize)

Bases: object

__init__(ptrsize)
alloc(size)
dump(val, state, loc=None)
translate(val, base)
apply(state, base)
size()
classmethod calc_size(val, arch)
classmethod stack_loc(val, arch, offset=0)
angr.calling_conventions.refine_locs_with_struct_type(arch, locs, arg_type, offset=0, treat_bot_as_int=True)
Parameters:
class angr.calling_conventions.SerializableIterator

Bases: object

getstate()
setstate(state)
class angr.calling_conventions.SerializableListIterator(lst)

Bases: SerializableIterator

__init__(lst)
getstate()
setstate(state)
class angr.calling_conventions.SerializableCounter(start, stride, mapping=<function SerializableCounter.<lambda>>)

Bases: SerializableIterator

__init__(start, stride, mapping=<function SerializableCounter.<lambda>>)
getstate()
setstate(state)
class angr.calling_conventions.SimFunctionArgument(size, is_fp=False)

Bases: object

Represent a generic function argument.

Variables:
  • size (int) – The size of the argument, in number of bytes.

  • is_fp (bool) – Whether loads from this location should return a floating point bitvector

Parameters:
__init__(size, is_fp=False)
Parameters:
check_value_set(value, arch)
check_value_get(value)
set_value(state, value, **kwargs)
get_value(state, **kwargs)
refine(size, arch=None, offset=None, is_fp=None)
get_footprint()

Return a list of SimRegArg and SimStackArgs that are the base components used for this location

Return type:

Iterable[SimRegArg | SimStackArg]

class angr.calling_conventions.SimRegArg(reg_name, size, reg_offset=0, is_fp=False, clear_entire_reg=False)

Bases: SimFunctionArgument

Represents a function argument that has been passed in a register.

Variables:
  • reg_name (string) – The name of the represented register.

  • size (int) – The size of the data to store, in number of bytes.

  • reg_offset – The offset into the register to start storing data.

  • clear_entire_reg – Whether a store to this register should zero the unused parts of the register.

  • is_fp (bool) – Whether loads from this location should return a floating point bitvector

Parameters:
  • reg_name (RegisterName)

  • size (int)

__init__(reg_name, size, reg_offset=0, is_fp=False, clear_entire_reg=False)
Parameters:
get_footprint()

Return a list of SimRegArg and SimStackArgs that are the base components used for this location

check_offset(arch)
Return type:

int

set_value(state, value, **kwargs)
get_value(state, **kwargs)
refine(size, arch=None, offset=None, is_fp=None)
sse_extend()
class angr.calling_conventions.SimStackArg(stack_offset, size, is_fp=False)

Bases: SimFunctionArgument

Represents a function argument that has been passed on the stack.

Variables:
  • stack_offset (int) – The position of the argument relative to the stack pointer after the function prelude.

  • size (int) – The size of the argument, in number of bytes.

  • is_fp (bool) – Whether loads from this location should return a floating point bitvector

Parameters:
__init__(stack_offset, size, is_fp=False)
Parameters:
get_footprint()

Return a list of SimRegArg and SimStackArgs that are the base components used for this location

set_value(state, value, stack_base=None, **kwargs)
get_value(state, stack_base=None, **kwargs)
refine(size, arch=None, offset=None, is_fp=None)
class angr.calling_conventions.SimComboArg(locations, is_fp=False)

Bases: SimFunctionArgument, Generic[T]

An argument which spans multiple storage locations. Locations should be given least-significant first.

Parameters:

locations (list[T])

__init__(locations, is_fp=False)
Parameters:

locations (list[T])

get_footprint()

Return a list of SimRegArg and SimStackArgs that are the base components used for this location

set_value(state, value, **kwargs)
get_value(state, **kwargs)
class angr.calling_conventions.SimStructArg(struct, locs)

Bases: SimFunctionArgument

An argument which de/serializes a struct from a list of storage locations

Variables:
  • struct – The simtype describing the structure

  • locs – The storage locations to use

Parameters:
__init__(struct, locs)
Parameters:
get_footprint()

Return a list of SimRegArg and SimStackArgs that are the base components used for this location

get_single_footprint()
Return type:

SimStackArg | SimRegArg | SimComboArg

get_value(state, **kwargs)
set_value(state, value, **kwargs)
class angr.calling_conventions.SimArrayArg(locs)

Bases: SimFunctionArgument

__init__(locs)
get_footprint()

Return a list of SimRegArg and SimStackArgs that are the base components used for this location

get_value(state, **kwargs)
set_value(state, value, **kwargs)
class angr.calling_conventions.SimReferenceArgument(ptr_loc, main_loc)

Bases: SimFunctionArgument

A function argument which is passed by reference.

Variables:
  • ptr_loc – The location the reference’s pointer is stored

  • main_loc – A SimStackArgument describing how to load the argument’s value as if it were stored at offset zero on the stack. It will be passed stack_base=ptr_loc.get_value(state)

Parameters:
__init__(ptr_loc, main_loc)
Parameters:
get_footprint()

Return a list of SimRegArg and SimStackArgs that are the base components used for this location

get_value(state, **kwargs)
set_value(state, value, **kwargs)
class angr.calling_conventions.ArgSession(cc)

Bases: object

A class to keep track of the state accumulated in laying parameters out into memory

__init__(cc)
cc
fp_iter
int_iter
both_iter
getstate()
setstate(state)
class angr.calling_conventions.UsercallArgSession(cc)

Bases: object

An argsession for use with SimCCUsercall

__init__(cc)
cc
real_args
getstate()
setstate(state)
class angr.calling_conventions.SimCC(arch)

Bases: object

A calling convention allows you to extract from a state the data passed from function to function by calls and returns. Most of the methods provided by SimCC that operate on a state assume that the program is just after a call but just before stack frame allocation, though this may be overridden with the stack_base parameter to each individual method.

This is the base class for all calling conventions.

Parameters:

arch (archinfo.Arch)

__init__(arch)
Parameters:

arch (Arch) – The Archinfo arch for this CC

ARG_REGS: list[str] = []
FP_ARG_REGS: list[str] = []
STACKARG_SP_BUFF = 0
STACKARG_SP_DIFF = 0
CALLER_SAVED_REGS: list[str] = []
RETURN_ADDR: SimFunctionArgument | None = None
RETURN_VAL: SimFunctionArgument | None = None
OVERFLOW_RETURN_VAL: SimFunctionArgument | None = None
FP_RETURN_VAL: SimFunctionArgument | None = None
ARCH: type[Arch] | None = None
EXTRA_ARCHES: tuple[type[Arch], ...] = ()
CALLEE_CLEANUP = False
STACK_ALIGNMENT = 1
property int_args

Iterate through all the possible arg positions that can only be used to store integer or pointer values.

Returns an iterator of SimFunctionArguments

property memory_args

Iterate through all the possible arg positions that can be used to store any kind of argument.

Returns an iterator of SimFunctionArguments

property fp_args

Iterate through all the possible arg positions that can only be used to store floating point values.

Returns an iterator of SimFunctionArguments

is_fp_arg(arg)

This should take a SimFunctionArgument instance and return whether or not that argument is a floating-point argument.

Returns True for MUST be a floating point arg,

False for MUST NOT be a floating point arg, None for when it can be either.

class ArgSession(cc)

Bases: object

A class to keep track of the state accumulated in laying parameters out into memory

both_iter
cc
fp_iter
int_iter
__init__(cc)
getstate()
setstate(state)
arg_session(ret_ty)

Return an arg session.

A session provides the control interface necessary to describe how integral and floating-point arguments are laid out into memory. The default behavior is that there are a finite list of int-only and fp-only argument slots, and an infinite number of generic slots, and when an argument of a given type is requested, the most slot available is used. If you need different behavior, subclass ArgSession.

You need to provide the return type of the function in order to kick off an arg layout session.

Parameters:

ret_ty (SimType | None)

return_in_implicit_outparam(ty)
stack_space(args)
Parameters:

args – A list of SimFunctionArguments

Returns:

The number of bytes that should be allocated on the stack to store all these args, NOT INCLUDING the return address.

return_val(ty, perspective_returned=False)

The location the return value is stored, based on its type.

property return_addr

The location the return address is stored.

next_arg(session, arg_type)
Parameters:
static is_fp_value(val)
static guess_prototype(args, prototype=None)

Come up with a plausible SimTypeFunction for the given args (as would be passed to e.g. setup_callsite).

You can pass a variadic function prototype in the base_type parameter and all its arguments will be used, only guessing types for the variadic arguments.

arg_locs(prototype)
Return type:

list[SimFunctionArgument]

get_args(state, prototype, stack_base=None)
set_return_val(state, val, ty, stack_base=None, perspective_returned=False)
setup_callsite(state, ret_addr, args, prototype, stack_base=None, alloc_base=None, grow_like_stack=True)

This function performs the actions of the caller getting ready to jump into a function.

Parameters:
  • state – The SimState to operate on

  • ret_addr – The address to return to when the called function finishes

  • args – The list of arguments that that the called function will see

  • prototype – The signature of the call you’re making. Should include variadic args concretely.

  • stack_base – An optional pointer to use as the top of the stack, circa the function entry point

  • alloc_base – An optional pointer to use as the place to put excess argument data

  • grow_like_stack – When allocating data at alloc_base, whether to allocate at decreasing addresses

The idea here is that you can provide almost any kind of python type in args and it’ll be translated to a binary format to be placed into simulated memory. Lists (representing arrays) must be entirely elements of the same type and size, while tuples (representing structs) can be elements of any type and size. If you’d like there to be a pointer to a given value, wrap the value in a PointerWrapper.

If stack_base is not provided, the current stack pointer will be used, and it will be updated. If alloc_base is not provided, the stack base will be used and grow_like_stack will implicitly be True.

grow_like_stack controls the behavior of allocating data at alloc_base. When data from args needs to be wrapped in a pointer, the pointer needs to point somewhere, so that data is dumped into memory at alloc_base. If you set alloc_base to point to somewhere other than the stack, set grow_like_stack to False so that sequential allocations happen at increasing addresses.

teardown_callsite(state, return_val=None, prototype=None, force_callee_cleanup=False)

This function performs the actions of the callee as it’s getting ready to return. It returns the address to return to.

Parameters:
  • state – The state to mutate

  • return_val – The value to return

  • prototype – The prototype of the given function

  • force_callee_cleanup – If we should clean up the stack allocation for the arguments even if it’s not the callee’s job to do so

TODO: support the stack_base parameter from setup_callsite…? Does that make sense in this context? Maybe it could make sense by saying that you pass it in as something like the “saved base pointer” value?

static find_cc(arch, args, sp_delta, platform='Linux')

Pinpoint the best-fit calling convention and return the corresponding SimCC instance, or None if no fit is found.

Parameters:
  • arch (Arch) – An ArchX instance. Can be obtained from archinfo.

  • args (list[SimRegArg | SimStackArg]) – A list of arguments. It may be updated by the first matched calling convention to remove non-argument arguments.

  • sp_delta (int) – The change of stack pointer before and after the call is made.

  • platform (str | None)

Return type:

SimCC | None

Returns:

A calling convention instance, or None if none of the SimCC subclasses seems to fit the arguments provided.

classmethod arches()
Return type:

tuple[type[Arch], ...]

get_arg_info(state, prototype)

This is just a simple wrapper that collects the information from various locations prototype is as passed to self.arg_locs and self.get_args :param angr.SimState state: The state to evaluate and extract the values from :return: A list of tuples, where the nth tuple is (type, name, location, value) of the nth argument

class angr.calling_conventions.SimLyingRegArg(name, size=8)

Bases: SimRegArg

A register that LIES about the types it holds

__init__(name, size=8)
get_value(state, **kwargs)
set_value(state, value, **kwargs)
refine(size, arch=None, offset=None, is_fp=None)
class angr.calling_conventions.SimCCUsercall(arch, args, ret_loc)

Bases: SimCC

__init__(arch, args, ret_loc)
Parameters:

arch – The Archinfo arch for this CC

ArgSession

alias of UsercallArgSession

next_arg(session, arg_type)
return_val(ty, **kwargs)

The location the return value is stored, based on its type.

class angr.calling_conventions.SimCCCdecl(arch)

Bases: SimCC

Parameters:

arch (archinfo.Arch)

ARG_REGS: list[str] = []
FP_ARG_REGS: list[str] = []
STACKARG_SP_DIFF = 4
CALLER_SAVED_REGS: list[str] = ['eax', 'ecx', 'edx']
RETURN_VAL: SimFunctionArgument | None = <eax>
OVERFLOW_RETURN_VAL: SimFunctionArgument | None = <edx>
FP_RETURN_VAL: SimFunctionArgument | None = <st0>
RETURN_ADDR: SimFunctionArgument | None = [0x0]
ARCH

alias of ArchX86

next_arg(session, arg_type)
STRUCT_RETURN_THRESHOLD = 32
return_val(ty, perspective_returned=False)

The location the return value is stored, based on its type.

return_in_implicit_outparam(ty)
class angr.calling_conventions.SimCCMicrosoftCdecl(arch)

Bases: SimCCCdecl

Parameters:

arch (archinfo.Arch)

STRUCT_RETURN_THRESHOLD = 64
class angr.calling_conventions.SimCCMicrosoftThiscall(arch)

Bases: SimCCCdecl

Parameters:

arch (archinfo.Arch)

CALLEE_CLEANUP = True
ARG_REGS: list[str] = ['ecx']
CALLER_SAVED_REGS: list[str] = ['eax', 'ecx', 'edx']
STRUCT_RETURN_THRESHOLD = 64
arg_locs(prototype)
Return type:

list[SimFunctionArgument]

class angr.calling_conventions.SimCCStdcall(arch)

Bases: SimCCMicrosoftCdecl

Parameters:

arch (archinfo.Arch)

CALLEE_CLEANUP = True
class angr.calling_conventions.SimCCMicrosoftFastcall(arch)

Bases: SimCC

Parameters:

arch (archinfo.Arch)

ARG_REGS: list[str] = ['ecx', 'edx']
STACKARG_SP_DIFF = 4
RETURN_VAL: SimFunctionArgument | None = <eax>
RETURN_ADDR: SimFunctionArgument | None = [0x0]
ARCH

alias of ArchX86

class angr.calling_conventions.MicrosoftAMD64ArgSession(cc)

Bases: object

__init__(cc)
class angr.calling_conventions.SimCCMicrosoftAMD64(arch)

Bases: SimCC

Parameters:

arch (archinfo.Arch)

ARG_REGS: list[str] = ['rcx', 'rdx', 'r8', 'r9']
FP_ARG_REGS: list[str] = ['xmm0', 'xmm1', 'xmm2', 'xmm3']
STACKARG_SP_DIFF = 8
STACKARG_SP_BUFF = 32
RETURN_VAL: SimFunctionArgument | None = <rax>
OVERFLOW_RETURN_VAL: SimFunctionArgument | None = <rdx>
FP_RETURN_VAL: SimFunctionArgument | None = <xmm0>
RETURN_ADDR: SimFunctionArgument | None = [0x0]
ARCH

alias of ArchAMD64

STACK_ALIGNMENT = 16
ArgSession

alias of MicrosoftAMD64ArgSession

STRUCT_RETURN_THRESHOLD = 64
next_arg(session, arg_type)
return_in_implicit_outparam(ty)
return_val(ty, perspective_returned=False)

The location the return value is stored, based on its type.

class angr.calling_conventions.SimCCSyscall(arch)

Bases: SimCC

The base class of all syscall CCs.

Parameters:

arch (archinfo.Arch)

ERROR_REG: SimRegArg = None
SYSCALL_ERRNO_START = None
static syscall_num(state)
Return type:

int

linux_syscall_update_error_reg(state, expr)
set_return_val(state, val, ty, **kwargs)
class angr.calling_conventions.SimCCX86LinuxSyscall(arch)

Bases: SimCCSyscall

Parameters:

arch (archinfo.Arch)

ARG_REGS: list[str] = ['ebx', 'ecx', 'edx', 'esi', 'edi', 'ebp']
FP_ARG_REGS: list[str] = []
RETURN_VAL: SimFunctionArgument | None = <eax>
RETURN_ADDR: SimFunctionArgument | None = <ip_at_syscall>
ARCH

alias of ArchX86

static syscall_num(state)
class angr.calling_conventions.SimCCX86WindowsSyscall(arch)

Bases: SimCCSyscall

Parameters:

arch (archinfo.Arch)

ARG_REGS: list[str] = ['ecx']
FP_ARG_REGS: list[str] = []
RETURN_VAL: SimFunctionArgument | None = <eax>
RETURN_ADDR: SimFunctionArgument | None = <ip_at_syscall>
ARCH

alias of ArchX86

static syscall_num(state)
class angr.calling_conventions.SimCCSystemVAMD64(arch)

Bases: SimCC

Parameters:

arch (archinfo.Arch)

ARG_REGS: list[str] = ['rdi', 'rsi', 'rdx', 'rcx', 'r8', 'r9']
FP_ARG_REGS: list[str] = ['xmm0', 'xmm1', 'xmm2', 'xmm3', 'xmm4', 'xmm5', 'xmm6', 'xmm7']
STACKARG_SP_DIFF = 8
CALLER_SAVED_REGS: list[str] = ['rdi', 'rsi', 'rdx', 'rcx', 'r8', 'r9', 'r10', 'r11', 'rax']
RETURN_ADDR: SimFunctionArgument | None = [0x0]
RETURN_VAL: SimFunctionArgument | None = <rax>
OVERFLOW_RETURN_VAL: SimFunctionArgument | None = <rdx>
FP_RETURN_VAL: SimFunctionArgument | None = <xmm0>
OVERFLOW_FP_RETURN_VAL = <xmm1>
ARCH

alias of ArchAMD64

STACK_ALIGNMENT = 16
next_arg(session, arg_type)
return_val(ty, perspective_returned=False)

The location the return value is stored, based on its type.

Parameters:

ty (SimType | None)

return_in_implicit_outparam(ty)
class angr.calling_conventions.SimCCAMD64LinuxSyscall(arch)

Bases: SimCCSyscall

Parameters:

arch (archinfo.Arch)

ARG_REGS: list[str] = ['rdi', 'rsi', 'rdx', 'r10', 'r8', 'r9']
RETURN_VAL: SimFunctionArgument | None = <rax>
RETURN_ADDR: SimFunctionArgument | None = <ip_at_syscall>
ARCH

alias of ArchAMD64

CALLER_SAVED_REGS: list[str] = ['rax', 'rcx', 'r11']
static syscall_num(state)
class angr.calling_conventions.SimCCAMD64WindowsSyscall(arch)

Bases: SimCCSyscall

Parameters:

arch (archinfo.Arch)

ARG_REGS: list[str] = ['rcx']
FP_ARG_REGS: list[str] = []
RETURN_VAL: SimFunctionArgument | None = <rax>
RETURN_ADDR: SimFunctionArgument | None = <ip_at_syscall>
ARCH

alias of ArchAMD64

static syscall_num(state)
class angr.calling_conventions.SimCCARM(arch)

Bases: SimCC

Parameters:

arch (archinfo.Arch)

ARG_REGS: list[str] = ['r0', 'r1', 'r2', 'r3']
FP_ARG_REGS: list[str] = []
CALLER_SAVED_REGS: list[str] = ['r0', 'r1', 'r2', 'r3']
RETURN_ADDR: SimFunctionArgument | None = <lr>
RETURN_VAL: SimFunctionArgument | None = <r0>
OVERFLOW_RETURN_VAL: SimFunctionArgument | None = <r1>
ARCH

alias of ArchARM

next_arg(session, arg_type)
class angr.calling_conventions.SimCCARMHF(arch)

Bases: SimCCARM

Parameters:

arch (archinfo.Arch)

ARG_REGS: list[str] = ['r0', 'r1', 'r2', 'r3']
FP_ARG_REGS: list[str] = ['s0', 's1', 's2', 's3', 's4', 's5', 's6', 's7', 's8', 's9', 's10', 's11', 's12', 's13', 's14', 's15']
FP_RETURN_VAL: SimFunctionArgument | None = <s0>
CALLER_SAVED_REGS: list[str] = []
RETURN_ADDR: SimFunctionArgument | None = <lr>
RETURN_VAL: SimFunctionArgument | None = <r0>
OVERFLOW_RETURN_VAL: SimFunctionArgument | None = <r1>
ARCH

alias of ArchARMHF

EXTRA_ARCHES: tuple[type[Arch], ...] = (<class 'archinfo.arch_arm.ArchARMCortexM'>,)
next_arg(session, arg_type)
class angr.calling_conventions.SimCCARMLinuxSyscall(arch)

Bases: SimCCSyscall

Parameters:

arch (archinfo.Arch)

ARG_REGS: list[str] = ['r0', 'r1', 'r2', 'r3']
FP_ARG_REGS: list[str] = []
RETURN_ADDR: SimFunctionArgument | None = <ip_at_syscall>
RETURN_VAL: SimFunctionArgument | None = <r0>
ARCH

alias of ArchARM

static syscall_num(state)
class angr.calling_conventions.SimCCAArch64(arch)

Bases: SimCC

Parameters:

arch (archinfo.Arch)

ARG_REGS: list[str] = ['x0', 'x1', 'x2', 'x3', 'x4', 'x5', 'x6', 'x7']
FP_ARG_REGS: list[str] = []
RETURN_ADDR: SimFunctionArgument | None = <lr>
RETURN_VAL: SimFunctionArgument | None = <x0>
ARCH

alias of ArchAArch64

class angr.calling_conventions.SimCCAArch64LinuxSyscall(arch)

Bases: SimCCSyscall

Parameters:

arch (archinfo.Arch)

ARG_REGS: list[str] = ['x0', 'x1', 'x2', 'x3', 'x4', 'x5', 'x6', 'x7']
FP_ARG_REGS: list[str] = []
RETURN_VAL: SimFunctionArgument | None = <x0>
RETURN_ADDR: SimFunctionArgument | None = <ip_at_syscall>
ARCH

alias of ArchAArch64

static syscall_num(state)
class angr.calling_conventions.SimCCRISCV64LinuxSyscall(arch)

Bases: SimCCSyscall

Parameters:

arch (archinfo.Arch)

ARG_REGS: list[str] = ['a0', 'a1', 'a2', 'a3', 'a4', 'a5', 'a6', 'a7']
FP_ARG_REGS: list[str] = []
RETURN_VAL: SimFunctionArgument | None = <a0>
RETURN_ADDR: SimFunctionArgument | None = <ip_at_syscall>
ARCH

alias of ArchRISCV64

static syscall_num(state)
class angr.calling_conventions.SimCCO32(arch)

Bases: SimCC

Parameters:

arch (archinfo.Arch)

ARG_REGS: list[str] = ['a0', 'a1', 'a2', 'a3']
FP_ARG_REGS: list[str] = ['f12', 'f13', 'f14', 'f15']
STACKARG_SP_BUFF = 16
CALLER_SAVED_REGS: list[str] = ['t9', 'gp']
RETURN_ADDR: SimFunctionArgument | None = <ra>
RETURN_VAL: SimFunctionArgument | None = <v0>
OVERFLOW_RETURN_VAL: SimFunctionArgument | None = <v1>
ARCH

alias of ArchMIPS32

next_arg(session, arg_type)
class angr.calling_conventions.SimCCO32LinuxSyscall(arch)

Bases: SimCCSyscall

Parameters:

arch (archinfo.Arch)

ARG_REGS: list[str] = ['a0', 'a1', 'a2', 'a3']
FP_ARG_REGS: list[str] = []
RETURN_VAL: SimFunctionArgument | None = <v0>
RETURN_ADDR: SimFunctionArgument | None = <ip_at_syscall>
ARCH

alias of ArchMIPS32

ERROR_REG: SimRegArg = <a3>
SYSCALL_ERRNO_START = -1133
static syscall_num(state)
class angr.calling_conventions.SimCCN64(arch)

Bases: SimCC

Parameters:

arch (archinfo.Arch)

ARG_REGS: list[str] = ['a0', 'a1', 'a2', 'a3', 'a4', 'a5', 'a6', 'a7']
CALLER_SAVED_REGS: list[str] = ['t9', 'gp']
FP_ARG_REGS: list[str] = []
STACKARG_SP_BUFF = 32
RETURN_ADDR: SimFunctionArgument | None = <ra>
RETURN_VAL: SimFunctionArgument | None = <v0>
ARCH

alias of ArchMIPS64

angr.calling_conventions.SimCCO64

alias of SimCCN64

class angr.calling_conventions.SimCCN64LinuxSyscall(arch)

Bases: SimCCSyscall

Parameters:

arch (archinfo.Arch)

ARG_REGS: list[str] = ['a0', 'a1', 'a2', 'a3', 'a4', 'a5', 'a6', 'a7']
FP_ARG_REGS: list[str] = []
RETURN_VAL: SimFunctionArgument | None = <v0>
RETURN_ADDR: SimFunctionArgument | None = <ip_at_syscall>
ARCH

alias of ArchMIPS64

ERROR_REG: SimRegArg = <a3>
SYSCALL_ERRNO_START = -1133
static syscall_num(state)
class angr.calling_conventions.SimCCPowerPC(arch)

Bases: SimCC

Parameters:

arch (archinfo.Arch)

ARG_REGS: list[str] = ['r3', 'r4', 'r5', 'r6', 'r7', 'r8', 'r9', 'r10']
FP_ARG_REGS: list[str] = []
STACKARG_SP_BUFF = 8
RETURN_ADDR: SimFunctionArgument | None = <lr>
RETURN_VAL: SimFunctionArgument | None = <r3>
OVERFLOW_RETURN_VAL: SimFunctionArgument | None = <r4>
ARCH

alias of ArchPPC32

class angr.calling_conventions.SimCCPowerPCLinuxSyscall(arch)

Bases: SimCCSyscall

Parameters:

arch (archinfo.Arch)

ARG_REGS: list[str] = ['r3', 'r4', 'r5', 'r6', 'r7', 'r8', 'r9', 'r10']
FP_ARG_REGS: list[str] = []
RETURN_VAL: SimFunctionArgument | None = <r3>
RETURN_ADDR: SimFunctionArgument | None = <ip_at_syscall>
ARCH

alias of ArchPPC32

ERROR_REG: SimRegArg = <cr0_0>
SYSCALL_ERRNO_START = -515
static syscall_num(state)
class angr.calling_conventions.SimCCPowerPC64(arch)

Bases: SimCC

Parameters:

arch (archinfo.Arch)

ARG_REGS: list[str] = ['r3', 'r4', 'r5', 'r6', 'r7', 'r8', 'r9', 'r10']
FP_ARG_REGS: list[str] = []
STACKARG_SP_BUFF = 112
RETURN_ADDR: SimFunctionArgument | None = <lr>
RETURN_VAL: SimFunctionArgument | None = <r3>
ARCH

alias of ArchPPC64

class angr.calling_conventions.SimCCPowerPC64LinuxSyscall(arch)

Bases: SimCCSyscall

Parameters:

arch (archinfo.Arch)

ARG_REGS: list[str] = ['r3', 'r4', 'r5', 'r6', 'r7', 'r8', 'r9', 'r10']
FP_ARG_REGS: list[str] = []