angr.knowledge_plugins.functions.function_manager

class angr.knowledge_plugins.functions.function_manager.FunctionDictBase

Bases: Generic

Base class for FunctionDict and SpillingFunctionDict.

__init__(backref, key_types=<class 'int'>)
Parameters:
floor_addr(addr)
Parameters:

addr (K)

ceiling_addr(addr)
items()
get(addr, default=<object object>, /, meta_only=False)
Overloads:
  • self, key (K), default (None), meta_only (bool) → Function

  • self, key (K), default (Function), meta_only (bool) → Function

  • self, key (K), default (T), meta_only (bool) → Function | T

Parameters:
  • addr (K)

  • meta_only (bool)

irange(minimum=None, maximum=None, inclusive=(True, True), reverse=False)
class angr.knowledge_plugins.functions.function_manager.FunctionDict

Bases: SortedDict[K, Function], FunctionDictBase[K]

FunctionDict is a dict where the keys are function starting addresses and map to the associated Function.

floor_addr(addr)
Parameters:

addr (K)

ceiling_addr(addr)
class angr.knowledge_plugins.functions.function_manager.SpillingFunctionDict

Bases: UserDict[K, Function], FunctionDictBase[K]

SpillingFunctionDict extends FunctionDict with LRU caching and LMDB spilling. This class keeps only the most recently accessed N functions in memory, spilling others to an LMDB database on disk.

SpillingFunctionDict also keeps a cache of meta-only Function objects that do not have graph or block information. These meta-only Function objects are read-only and may become stale if the full Function is later loaded and updated. Therefore, please be extremely cautious when using these meta-only Function objects.

SpillingFunctionDict._load_from_lmdb() does not support reentry. If a function being loaded from LMDB triggers another load from LMDB, the inner load will raise a RuntimeError.

A Function instance becomes “dirty” (Function.dirty) if it has been modified since being loaded from LMDB. Dirty functions are always saved back to LMDB when evicted, while clean functions are skipped during eviction.

A Function instance becomes “evicted” (Function.evicted) and stale if it has been spilled to LMDB. An evicted Function instance may not reflect the most recent state of the function, and any changes to an evicted Function instance will not be saved to LMDB. Therefore, if SpillingFunctionDict is in use, it is advised not to hold a Function instance for too long before using it.

Variables:
  • cache_limit – The maximum number of functions to keep in memory.

  • rtdb – A reference to the RuntimeDb knowledge base plugin.

  • _lru_order – An OrderedDict tracking the eviction order of cached functions.

  • _spilled_keys – A set of function addresses that have been spilled to LMDB.

  • _db_batch_size – The number of functions that are evicted in a single batch.

  • _meta_func_cache – An LRU cache for meta-only Function objects.

  • _eviction_enabled – A flag indicating whether eviction is currently enabled or not.

__init__(backref, rtdb, /, key_types=<class 'int'>, cache_limit=1000, db_batch_size=100, **kwargs)
Parameters:
copy()
Return type:

SpillingFunctionDict[TypeVar(K, int, SootMethodDescriptor)]

clear()

Clear all functions from memory and spilled storage.

Return type:

None

property cached_keys: Generator[K]
property cache_limit: int

Get the maximum number of functions to keep in memory.

property cached_count: int

Return the number of functions currently in memory.

property spilled_count: int

Return the number of functions currently spilled to LMDB.

property total_count: int

Return the total number of functions (in memory + spilled).

is_cached(addr)
Return type:

bool

Parameters:

addr (K)

bulk_import_serialized(items)

Bulk-import already-serialized functions directly into the LMDB backing store and register them as spilled, without deserializing them. The serialized bytes must be serialized function_pb2.Function messages, i.e., the exact format that _save_to_lmdb() writes.

Imported functions are deserialized lazily upon first access, through the regular _load_from_lmdb() path.

Parameters:

items (list[tuple[TypeVar(K, int, SootMethodDescriptor), bytes]]) – A list of (address, serialized function bytes) tuples.

Return type:

None

export_serialized()

Export all functions as serialized bytes, e.g., for dumping into an angr database.

Functions whose LMDB records are guaranteed to be current are copied directly from the LMDB backing store (in a single read transaction) without being deserialized and re-serialized. This applies to all spilled functions and to cached functions that are clean: a Function instance is only ever clean if it was deserialized from serialized bytes and has not been modified since (eviction relies on the same invariant to skip writing clean functions back to LMDB). Dirty functions, and functions whose LMDB record is missing, are serialized from their in-memory objects through the regular path.

Return type:

list[tuple[TypeVar(K, int, SootMethodDescriptor), bytes, bool]]

Returns:

A list of (address, serialized function bytes, copied_from_lmdb) tuples, ordered by address.

load_all_spilled()

Load all spilled functions back into memory (disables eviction temporarily).

Return type:

None

evict_all_cached()

Evict all cached functions to LMDB.

Return type:

None

class angr.knowledge_plugins.functions.function_manager.FunctionManager

Bases: KnowledgeBasePlugin, Mapping[K, Function], Generic

When cache_limit is set, the FunctionManager uses a SpillingFunctionDict that implements an LRU cache keeping only the most recently accessed N functions in memory, spilling others to an LMDB database on disk. This allows working with binaries that have more functions than can fit in memory.

Parameters:

cache_limit (int | None) – Maximum number of functions to keep in memory. None means unlimited (no eviction). Default is None.

__init__(kb, cache_limit=None)
Parameters:
copy()
clear()
get_default_cache_limit(max_limit=5000)

Get the default function cache limit based on the size of the binary.

Return type:

int | None

Returns:

The default cache limit; None means unlimited.

Parameters:

max_limit (int)

is_plt_cached(addr)
Return type:

bool

Parameters:

addr (int)

get_binary_name_cached(addr)
Return type:

str | None

Parameters:

addr (int)

function_name_changed(addr, old_name, new_name)

Notify the FunctionManager that a function’s name has changed.

Parameters:
  • addr (TypeVar(K, int, SootMethodDescriptor)) – Address of the function.

  • old_name (str | None) – Old name of the function, or None if there is no old name.

  • new_name (str) – New name of the function.

Return type:

None

get_by_addr(addr, meta_only=False)
Return type:

Function

Parameters:

meta_only (bool)

get_by_name(name, check_previous_names=False)
Return type:

Generator[Function]

Parameters:
  • name (str)

  • check_previous_names (bool)

get_addrs_by_name(name, check_previous_names=False)
Return type:

set[int]

Parameters:
  • name (str)

  • check_previous_names (bool)

contains_addr(addr)

Decide if an address is handled by the function manager.

Note: this function is non-conformant with python programming idioms, but its needed for performance reasons.

Parameters:

addr (int) – Address of the function.

ceiling_addr(addr)

Return the function who has the least address that is greater than or equal to addr.

Parameters:

addr (TypeVar(K, int, SootMethodDescriptor)) – The address to query.

Return type:

Optional[TypeVar(K, int, SootMethodDescriptor)]

Returns:

A Function instance, or None if there is no other function after addr.

ceiling_func(addr)

Return the function who has the least address that is greater than or equal to addr.

Parameters:

addr (int) – The address to query.

Return type:

Function | None

Returns:

A Function instance, or None if there is no other function after addr.

floor_addr(addr)

Return the function who has the greatest address that is less than or equal to addr.

Parameters:

addr (TypeVar(K, int, SootMethodDescriptor)) – The address to query.

Return type:

Optional[TypeVar(K, int, SootMethodDescriptor)]

Returns:

An address, or None if there is no other function before addr.

floor_func(addr)

Return the function who has the greatest address that is less than or equal to addr.

Parameters:

addr (int) – The address to query.

Returns:

A Function instance, or None if there is no other function before addr.

Return type:

Function or None

query(query, check_previous_names=False)

Query for a function using selectors to disambiguate. Supported variations:

::<name> Function <name> in the main object ::<addr>::<name> Function <name> at <addr> ::<obj>::<name> Function <name> in <obj>

Return type:

Function | None

Parameters:
  • query (str)

  • check_previous_names (bool)

function(addr=None, name=None, check_previous_names=False, create=False, syscall=False, plt=None)

Get a function object from the function manager.

Pass either addr or name with the appropriate values.

Parameters:
  • addr (Optional[TypeVar(K, int, SootMethodDescriptor)]) – Address of the function.

  • name (str | None) – Name of the function.

  • create (bool) – Whether to create the function or not if the function does not exist.

  • syscall (bool) – True to create the function as a syscall, False otherwise.

  • plt (bool | None) – True to find the PLT stub, False to find a non-PLT stub, None to disable this restriction.

  • check_previous_names (bool)

Returns:

The Function instance, or None if the function is not found and create is False.

Return type:

Function | None

dbg_draw(prefix='dbg_function_')
rebuild_callgraph()
set_function_returning(addr, v)
Return type:

None

Parameters:
  • addr (K)

  • v (bool | None)

nonreturning_func_addrs()

Yield all non-returning function addresses.

Return type:

Generator[int]

unknown_returning_func_addrs()

Yield all function addresses with unknown returning status.

Return type:

Generator[int]

is_func_nonreturning(addr)

Check if a function is non-returning.

Parameters:

addr (TypeVar(K, int, SootMethodDescriptor)) – Address of the function.

Return type:

bool

Returns:

True if non-returning, False if returning or unknown.

is_func_returning_unknown(addr)

Check if a function’s returning status is unknown.

Parameters:

addr (TypeVar(K, int, SootMethodDescriptor)) – Address of the function.

Return type:

bool

Returns:

True if returning status is unknown, False otherwise.

get_func_block_count(addr)

Get the number of blocks in a function.

Parameters:

addr (TypeVar(K, int, SootMethodDescriptor)) – Address of the function.

Return type:

int | None

Returns:

Number of blocks, or None if unknown.

set_func_block_count(addr, count)

Set the number of blocks in a function.

Parameters:
Return type:

None

Returns:

None

get_func_addr_with_block_count(block_count)

Get the addresses of all functions that have exactly block_count blocks.

Parameters:

block_count (int) – The number of blocks to match.

Return type:

set[TypeVar(K, int, SootMethodDescriptor)]

Returns:

The set of matching function addresses.

get_func_name(addr)

Get the name of a function without loading the (possibly spilled) Function object.

Parameters:

addr (TypeVar(K, int, SootMethodDescriptor)) – Address of the function.

Return type:

str | None

Returns:

The function’s name, or None if unknown.

get_from_signature(addr)

Get the from_signature value of a function without loading the (possibly spilled) Function object.

Parameters:

addr (TypeVar(K, int, SootMethodDescriptor)) – Address of the function.

Return type:

str | None

Returns:

The function’s from_signature value (e.g. "flirt"), or None.

set_from_signature(addr, from_signature)

Update the cached from_signature value for a function. Called by Function.from_signature’s setter.

Parameters:
Return type:

None

Returns:

None

get_all_funcaddrs_from_signature(from_signature='flirt')

Get the addresses of all functions whose from_signature matches, without loading any Function object.

Parameters:

from_signature (str) – The from_signature value to match (default "flirt").

Return type:

set[TypeVar(K, int, SootMethodDescriptor)]

Returns:

The set of matching function addresses.

get_key_func_addrs(func_type)
Return type:

set[TypeVar(K, int, SootMethodDescriptor)]

Parameters:

func_type (str)

get_key_func_type_and_addrs()

Get all cached key functions grouped by key-function type (e.g. "alloca_probe", "jmp_rax").

Return type:

dict[str, set[TypeVar(K, int, SootMethodDescriptor)]]

Returns:

A mapping from key-function type to the set of function addresses of that type.

add_key_func_addr(func_type, addr)
Return type:

None

Parameters:
  • func_type (str)

  • addr (K)

property cache_limit: int | None

Get the maximum number of functions to keep in memory. None means unlimited (no eviction).

property cached_function_count: int

Return the number of functions currently in memory.

property spilled_function_count: int

Return the number of functions currently spilled to LMDB.

property total_function_count: int

Return the total number of functions (in memory + spilled).