angr.exploration_techniques¶
- class angr.exploration_techniques.DFS
Bases:
ExplorationTechniqueDepth-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')
- class angr.exploration_techniques.Bucketizer
Bases:
ExplorationTechniqueLoop bucketization: Pick log(n) paths out of n possible paths, and stash (or drop) everything else.
- class angr.exploration_techniques.CallFunctionGoal
Bases:
BaseGoalA 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:
- class angr.exploration_techniques.Director
Bases:
ExplorationTechniqueAn 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
Bases:
ExplorationTechniqueAn 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.
- class angr.exploration_techniques.ExecuteAddressGoal
Bases:
BaseGoalA 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
- 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:
- class angr.exploration_techniques.ExplorationTechnique
Bases:
objectAn 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_techniquewith 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:
simgr (angr.SimulationManager)
stash (str)
- 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_funcin their step or run command, it will appear here.- Parameters:
simgr (angr.SimulationManager)
state (angr.SimState)
- 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_funcin their step or run command, it will appear here.- Parameters:
simgr (angr.SimulationManager)
state (angr.SimState)
- 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 callsimgr.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:
simgr (angr.SimulationManager)
state (angr.SimState)
- 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. callingproject.factory.successorsmanually) 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_funcin their step or run command, it will appear here.- Parameters:
simgr (angr.SimulationManager)
state (angr.SimState)
- 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 withsimgr.completion_mode.- Parameters:
simgr (angr.SimulationManager)
- class angr.exploration_techniques.Explorer
Bases:
ExplorationTechniqueSearch 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)
- class angr.exploration_techniques.LengthLimiter
Bases:
ExplorationTechniqueLength limiter on paths.
- __init__(max_length, drop=False)
- class angr.exploration_techniques.LocalLoopSeer
Bases:
ExplorationTechniqueLocalLoopSeer 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.
- class angr.exploration_techniques.LoopSeer
Bases:
ExplorationTechniqueThis 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)
- class angr.exploration_techniques.ManualMergepoint
Bases:
ExplorationTechnique- __init__(address, wait_counter=10, prune=True)
- mark_nofilter(simgr, stash)
- mark_okfilter(simgr, stash)
- class angr.exploration_techniques.MemoryWatcher
Bases:
ExplorationTechniqueMemory Watcher
- Parameters:
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')
- class angr.exploration_techniques.Oppologist
Bases:
ExplorationTechniqueThe Oppologist is an exploration technique that forces uncooperative code through qemu.
- __init__()
- class angr.exploration_techniques.Slicecutor
Bases:
ExplorationTechniqueThe Slicecutor is an exploration that executes provided code slices.
- __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.
- class angr.exploration_techniques.Spiller
Bases:
ExplorationTechniqueAutomatically 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.
- static state_priority(state)
- class angr.exploration_techniques.StochasticSearch
Bases:
ExplorationTechniqueStochastic 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).
- class angr.exploration_techniques.StubStasher
Bases:
ExplorationTechniqueStash states that reach a stub SimProcedure.
- static post_filter(state)
- class angr.exploration_techniques.Suggestions
Bases:
ExplorationTechniqueAn exploration technique which analyzes failure cases and logs suggestions for how to mitigate them in future analyses.
- __init__()
- static report(state, event)
- class angr.exploration_techniques.TechniqueBuilder
Bases:
ExplorationTechniqueThis 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
Bases:
ExplorationTechniqueEnable 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')
- inner_step(state, simgr, **kwargs)
- class angr.exploration_techniques.Timeout
Bases:
ExplorationTechniqueTimeout exploration technique that stops an active exploration if the run time exceeds a predefined timeout
- __init__(timeout=None)
- class angr.exploration_techniques.Tracer
Bases:
ExplorationTechniqueAn 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 (list[SimState]) – 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
- classmethod crash_windup(state, crash_addr)
- class angr.exploration_techniques.UniqueSearch
Bases:
ExplorationTechniqueUnique 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.
- 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
Bases:
ExplorationTechniqueEnable 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)
Submodules