Source code for angr.exploration_techniques.common
from .. import engines
from ..errors import SimError, AngrError, AngrExplorationTechniqueError
[docs]def 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.
:param condition: An integer, set, list or lambda to convert to a lambda.
:param 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.
"""
if condition is None:
def condition_function(state):
return default
static_addrs = set()
elif isinstance(condition, int):
return condition_to_lambda((condition,))
elif isinstance(condition, (tuple, set, list)):
static_addrs = set(condition)
def condition_function(state):
if state.addr in static_addrs:
# returning {state.addr} instead of True to properly handle find/avoid conflicts
return {state.addr}
if not isinstance(state.project.factory.default_engine, engines.vex.VEXLifter):
return False
try:
# If the address is not in the set (which could mean it is
# not at the top of a block), check directly in the blocks
# (Blocks are repeatedly created for every check, but with
# the IRSB cache in angr lifter it should be OK.)
return static_addrs.intersection(set(state.block().instruction_addrs))
except (AngrError, SimError):
return False
elif hasattr(condition, "__call__"):
condition_function = condition
static_addrs = None
else:
raise AngrExplorationTechniqueError(
"ExplorationTechnique is unable to convert given type (%s) to a callable condition function."
% condition.__class__
)
return condition_function, static_addrs