angr.knowledge_plugins.functions.function

angr.knowledge_plugins.functions.function.dirty_func(func)
class angr.knowledge_plugins.functions.function.PrototypeSource

Bases: int, Enum

An enumeration to represent the source of a function prototype. The values are ordered by certainty, with higher values indicating more certainty.

NONE = 0
GUESSED = 1
CCA_LOW = 2
CALLSITE_LOW = 3
CALLSITE_DECOMPILER = 6
CCA_DECOMPILER = 20
SIMPROC = 21
SIGNATURES = 25
USER = 100
__new__(value)
class angr.knowledge_plugins.functions.function.FunctionInfo

Bases: UserDict

A dictionary that updates the .dirty field of the Function object when modified.

__init__(func)
Parameters:

func (Function)

copy(owner)
Return type:

FunctionInfo

Parameters:

owner (Function)

to_json()
Return type:

str

classmethod from_json(json_str, owner)
Return type:

FunctionInfo

Parameters:
class angr.knowledge_plugins.functions.function.Function

Bases: Serializable

A representation of a function and various information about it.

Variables:
  • meta_only – Whether this function only contains meta-information and in read-only mode.

  • _dirty – Whether this function has been modified since last serialization.

  • evicted – Whether this function has been evicted from FunctionManager to external storage.

__init__(function_manager, addr, name=None, syscall=None, is_simprocedure=None, binary_name=None, is_plt=None, returning=None, alignment=False, calling_convention=None, prototype=None, prototype_libname=None, prototype_source=None, is_prototype_guessed=True)

Function constructor. If the optional parameters are not provided, they will be automatically determined upon the creation of a Function object.

Parameters:
  • addr (int) – The address of the function.

  • name (str) – The name of the function.

  • syscall (bool) – Whether this function is a syscall or not.

  • is_simprocedure (bool | None) – Whether this function is a SimProcedure or not.

  • binary_name (str) – Name of the binary where this function is.

  • is_plt (bool | None) – If this function is a PLT entry.

  • returning (bool) – If this function returns.

  • alignment (bool) – If this function acts as an alignment filler. Such functions usually only contain nops.

  • function_manager (FunctionManager | None)

  • calling_convention (SimCC | None)

  • prototype (SimTypeFunction | None)

  • prototype_libname (str | None)

  • prototype_source (PrototypeSource | None)

  • is_prototype_guessed (bool)

is_default_name
binary_name
property name
property from_signature: str | None
property project: Project | None
property returning
property calling_convention: SimCC | None
property prototypes: dict[str, SimTypeFunction | None]

A snapshot of every flavor’s prototype, keyed by decompilation flavor. Write through set_prototype(); the default-flavor entry is also exposed as .prototype.

property prototype_sources: dict[str, PrototypeSource]

A snapshot of every flavor’s prototype source; the default-flavor entry is also exposed as .prototype_source.

property prototype: SimTypeFunction | None
get_prototype(flavor)

The prototype a decompilation of the given flavor should use: the flavor’s own entry, or the C prototype when the flavor has none. The C flavor never falls back to another flavor.

Return type:

SimTypeFunction | None

Parameters:

flavor (str | None)

has_prototype_for_flavor(flavor)

Whether the flavor has its own entry (as opposed to falling back to the C prototype).

Return type:

bool

Parameters:

flavor (str | None)

uses_default_prototype_for(flavor)

Whether get_prototype(flavor) is the default flavor’s (C) prototype, e.g., to dereference it by library.

Return type:

bool

Parameters:

flavor (str | None)

get_prototype_source(flavor)

The source of the prototype get_prototype(flavor) returns.

Return type:

PrototypeSource

Parameters:

flavor (str | None)

set_prototype(flavor, proto, source=None)

Set the prototype of a flavor. A flavor’s first entry starts with the source of the prototype it used to fall back to (the C one) unless source is given.

Return type:

None

Parameters:
set_prototype_source(flavor, source)

Set the source of a flavor’s prototype; a flavor without an entry gets one that falls back to C’s.

Return type:

None

Parameters:
clear_prototype(flavor)

Drop a flavor’s own entry so that it falls back to the C prototype; clearing C sets it to None.

Return type:

None

Parameters:

flavor (str | None)

property prototype_libname
Setter accepts:

str | None

property is_prototype_guessed: bool
is_prototype_guessed_for(flavor)
Return type:

bool

Parameters:

flavor (str | None)

property is_prototype_groundtruth: bool

True if the prototype comes from outside of the decompiler (SimProcedures, signatures, or the user) and may be fed back into type inference as ground truth. Prototypes inferred by the decompiler itself are excluded so that re-decompiling a function does not freeze its own earlier guess.

is_prototype_groundtruth_for(flavor)

is_prototype_groundtruth for the prototype get_prototype(flavor) returns.

Return type:

bool

Parameters:

flavor (str | None)

property prototype_source: PrototypeSource
property info: FunctionInfo
Setter accepts:

FunctionInfo | dict

property is_plt: bool
property is_simprocedure: bool
property is_syscall: bool
property is_alignment: bool
transition_out_edges(node)

(successor, edge data) pairs of a node, in the order of transition_graph.out_edges(node, data=True), without building the networkx transition graph when it does not exist yet.

Return type:

list[tuple[CodeNode, Mapping[str, Any]]]

Parameters:

node (CodeNode)

transition_in_edges(node)

(predecessor, edge data) pairs of a node, in the order of transition_graph.in_edges(node, data=True), without building the networkx transition graph when it does not exist yet.

Return type:

list[tuple[CodeNode, Mapping[str, Any]]]

Parameters:

node (CodeNode)

has_node(node)
Return type:

bool

Parameters:

node (CodeNode)

set_edge_outside(src, dst, outside)
Return type:

None

Parameters:
add_graph_node(node)

Add a node to the transition graph without registering it as a local block.

Return type:

None

Parameters:

node (CodeNode)

add_graph_edge(src, dst, type=None, outside=None, ins_addr=<object object>, stmt_idx=<object object>, confirmed=None)

Add or update an edge of the transition graph.

Return type:

None

Parameters:
remove_graph_node(node)

Remove a node and its edges from the transition graph.

Return type:

None

Parameters:

node (CodeNode)

set_edge_confirmed(src, dst, confirmed)
Return type:

None

Parameters:
property transition_graph: TransitionGraph

A read-only networkx view of the transition graph, created on-demand and kept in sync with the Function’s updates.

property startpoint: CodeNode | None
property blocks

An iterator of all local blocks in the current function.

Returns:

angr.lifter.Block instances.

property code_nodes: dict[int, CodeNode]
property cyclomatic_complexity

The cyclomatic complexity of the function.

Cyclomatic complexity is a software metric used to indicate the complexity of a program. It is a quantitative measure of the number of linearly independent paths through a program’s source code. It is computed using the formula: M = E - N + 2P, where E = the number of edges in the graph, N = the number of nodes in the graph, P = the number of connected components.

The cyclomatic complexity value is lazily computed and cached for future use. Initially this value is None until it is computed for the first time

Returns:

The cyclomatic complexity of the function.

Return type:

int

property xrefs: Iterator[XRef]

An iterator of all xrefs of the current function.

Returns:

angr.knowledge_plugins.xrefs.xref.XRef instances.

property block_addrs

An iterator of all local block addresses in the current function.

Returns:

block addresses.

property block_addrs_set

Return a set of block addresses for a better performance of inclusion tests.

Returns:

A set of block addresses.

Return type:

set

get_block(addr, size=None, byte_string=None)

Getting a block out of the current function.

Parameters:
  • addr (int) – The address of the block.

  • size (int | None) – The size of the block. This is optional. If not provided, angr will load

  • byte_string (bytes | None)

Returns:

get_block_size(addr)
Return type:

int | None

Parameters:

addr (int)

property nodes: Iterable[CodeNode]
get_node(addr)
Return type:

BlockNode | None

property has_unresolved_jumps
property has_unresolved_calls
property operations

All of the operations that are done by this functions.

property code_constants

All of the constants that are used by this functions’s code.

classmethod parse_from_cmessage(cmsg, **kwargs)
Parameters:

cmsg

Return Function:

The function instantiated out of the cmsg data.

string_references(minimum_length=2)

All of the constant string references used by this function.

Parameters:

minimum_length – The minimum length of strings to find (default is 1)

Returns:

A generator yielding tuples of (address, string) where is address is the location of the string in memory.

property local_runtime_values

Tries to find all runtime values of this function which do not come from inputs. These values are generated by starting from a blank state and reanalyzing the basic blocks once each. Function calls are skipped, and back edges are never taken so these values are often unreliable, This function is good at finding simple constant addresses which the function will use or calculate.

Returns:

a set of constants

property num_arguments
property endpoints: list[CodeNode]
property endpoints_with_type: defaultdict[str, set[CodeNode]]
property ret_sites: list[CodeNode]
property jumpout_sites: list[CodeNode]
property retout_sites: list[CodeNode]
property callout_sites: list[CodeNode]
property size
property binary

Get the object this function belongs to. :return: The object this function belongs to.

property offset: int

the function’s binary offset (i.e., non-rebased address)

Type:

return

property symbol: Symbol | None

the function’s Symbol, if any

Type:

return

property pseudocode: str | None

the function’s pseudocode

Type:

return

property dirty: bool
mark_dirty()
Return type:

None

add_jumpout_site(node)

Add a custom jumpout site.

Parameters:

node (CodeNode) – The address of the basic block that control flow leaves during this transition.

Returns:

None

add_retout_site(node)

Add a custom retout site.

Retout (returning to outside of the function) sites are very rare. It mostly occurs during CFG recovery when we incorrectly identify the beginning of a function in the first iteration, and then correctly identify that function later in the same iteration (function alignments can lead to this bizarre case). We will mark all edges going out of the header of that function as a outside edge, because all successors now belong to the incorrectly-identified function. This identification error will be fixed in the second iteration of CFG recovery. However, we still want to keep track of jumpouts/retouts during the first iteration so other logic in CFG recovery still work.

Parameters:

node (CodeNode) – The address of the basic block that control flow leaves the current function after a call.

Returns:

None

clear_transition_graph()
confirm_fakeret(src, dst)
transit_to(from_node, to_node, outside=False, ins_addr=None, stmt_idx=None, is_exception=False, update_func_block_count=True)

Registers an edge between basic blocks in this function’s transition graph. Arguments are CodeNode objects.

Parameters:
  • from_node (CodeNode) – The address of the basic block that control flow leaves during this transition.

  • to_node – The address of the basic block that control flow enters during this transition.

  • outside (bool) – If this is a transition to another function, e.g. tail call optimization

  • update_func_block_count (bool)

Returns:

None

call_to(from_node, to_func, ret_node, stmt_idx=None, ins_addr=None, return_to_outside=False, syscall=False, update_func_block_count=True)

Registers an edge between the caller basic block and callee function.

Parameters:
  • from_node (angr.knowledge.CodeNode) – The basic block that control flow leaves during the transition.

  • to_func (FuncNode | HookNode) – The function that we are calling, represented as a FuncNode.

  • ret_node (angr.knowledge.CodeNode or None) – The basic block that control flow should return to after the function call.

  • stmt_idx (int, str or None) – Statement ID of this call.

  • ins_addr (int or None) – Instruction address of this call.

  • syscall (bool)

  • update_func_block_count (bool)

fakeret_to(from_node, to_node, confirmed=None, to_outside=False, update_func_block_count=True)
Parameters:

update_func_block_count (bool)

remove_fakeret(from_node, to_node)
remove_edge(from_node, to_node)
Return type:

None

Parameters:
return_from_call(from_func, to_node, to_outside=False, confirm_fakeret=True)
Parameters:
update_func_block_count()

Update the cached block count of this function in the function manager.

Return type:

None

register(is_local, node, update_func_block_count=True)

Register a node with the function and return its ID. The first object that is registered for a fresh ID becomes the ID’s canonical CodeNode object.

Return type:

int

Parameters:
register_node(is_local, node, update_func_block_count=True)
Return type:

CodeNode

Parameters:
add_return_site(return_site)

Registers a basic block as a site for control flow to return from this function.

Parameters:

return_site (CodeNode) – The block node that ends with a return.

add_call_site(call_site_addr, call_target_addr, retn_addr)

Registers a basic block as calling a function and returning somewhere.

Parameters:
  • call_site_addr – The address of a basic block that ends in a call.

  • call_target_addr – The address of the target of said call.

  • retn_addr – The address that said call will return to.

add_endpoint(endpoint_node, sort)

Registers an endpoint with a type of sort. The type can be one of the following: - call: calling a function that does not return - return: returning from the current function - transition: a jump/branch targeting a different function

It is possible for a block to act as two different sorts of endpoints. For example, consider the following block:

.text:0000000000024350 mov eax, 1 .text:0000000000024355 lock xadd [rdi+4], eax .text:000000000002435A retn

VEX code:

00 | —— IMark(0x424350, 5, 0) —— 01 | PUT(rax) = 0x0000000000000001 02 | PUT(rip) = 0x0000000000424355 03 | —— IMark(0x424355, 5, 0) —— 04 | t11 = GET:I64(rdi) 05 | t10 = Add64(t11,0x0000000000000004) 06 | t0 = LDle:I32(t10) 07 | t2 = Add32(t0,0x00000001) 08 | t(4,4294967295) = CASle(t10 :: (t0,None)->(t2,None)) 09 | t14 = CasCmpNE32(t4,t0) 10 | if (t14) { PUT(rip) = 0x424355; Ijk_Boring } 11 | PUT(cc_op) = 0x0000000000000003 12 | t15 = 32Uto64(t0) 13 | PUT(cc_dep1) = t15 14 | PUT(cc_dep2) = 0x0000000000000001 15 | t17 = 32Uto64(t0) 16 | PUT(rax) = t17 17 | PUT(rip) = 0x000000000042435a 18 | —— IMark(0x42435a, 1, 0) —— 19 | t6 = GET:I64(rsp) 20 | t7 = LDle:I64(t6) 21 | t8 = Add64(t6,0x0000000000000008) 22 | PUT(rsp) = t8 23 | t18 = Sub64(t8,0x0000000000000080) 24 | ====== AbiHint(0xt18, 128, t7) ====== NEXT: PUT(rip) = t7; Ijk_Ret

This block acts as both a return endpoint and a transition endpoint (transitioning to 0x424355).

Parameters:
  • endpoint_node – The endpoint node.

  • sort – Type of the endpoint.

Returns:

None

mark_nonreturning_calls_endpoints()

Iterate through all call edges in transition graph. For each call a non-returning function, mark the source basic block as an endpoint.

This method should only be executed once all functions are recovered and analyzed by CFG recovery, so we know whether each function returns or not.

Returns:

None

property call_sites: dict[int, tuple[int | None, int | None]]
call_edge_addrs()

(call-site block address, callee address) of every call edge, in transition-graph order. Unlike call_sites, a block with several call targets contributes one pair per target.

Return type:

list[tuple[int, int]]

jumpout_targets()

(jump-out site block address, target address, branch instruction address) of every transition that leaves this function, such as a tail jump. The instruction address is None when the CFG did not record it.

Return type:

list[tuple[int, int, int | None]]

unconfirmed_fakeret_edges()

Fake-return edges that have not been confirmed by a return of the callee, in transition-graph order.

Return type:

list[tuple[CodeNode, CodeNode]]

outgoing_function_targets()

Addresses of the functions this function calls or jumps out to.

Return type:

list[int]

get_call_sites()

Gets a list of all the basic blocks that end in calls.

Return type:

Iterable[int]

Returns:

A view of the addresses of the blocks that end in calls.

get_call_target(callsite_addr)

Get the target of a call.

Parameters:

callsite_addr – The address of a basic block that ends in a call.

Returns:

The target of said call, or None if callsite_addr is not a callsite.

get_call_return(callsite_addr)

Get the hypothetical return address of a call.

Parameters:

callsite_addr – The address of the basic block that ends in a call.

Returns:

The likely return target of said call, or None if callsite_addr is not a callsite.

property graph: TransitionGraph

Get a local transition graph. A local transition graph is a transition graph that only contains nodes that belong to the current function. All edges, except for the edges going out from the current function or coming from outside the current function, are included.

The generated graph is a read-only view cached in self._local_transition_graph.

Returns:

A local transition graph.

graph_ex(exception_edges=True)

Get a local transition graph with a custom configuration. A local transition graph is a transition graph that only contains nodes that belong to the current function. This method allows user to include certain types of edges and nodes, such as exception edges.

The generated graph is not cached. It is a mutable copy.

Parameters:

exception_edges (bool) – Should exception edges and the nodes that are only reachable through exception edges be kept.

Return type:

networkx.DiGraph[CodeNode]

Returns:

A local transition graph with a special configuration.

transition_graph_ex(exception_edges=True)

Get a transition graph with a custom configuration. This method allows user to exclude certain types of edges together with the nodes that are only reachable through such edges, such as exception edges.

The generated graph is not cached.

Parameters:

exception_edges (bool) – Should exception edges and the nodes that are only reachable through exception edges be kept.

Returns:

A local transition graph with a special configuration.

Return type:

networkx.DiGraph

subgraph(ins_addrs)

Generate a sub control flow graph of instruction addresses based on self.graph

Parameters:

ins_addrs (iterable) – A collection of instruction addresses that should be included in the subgraph.

Return networkx.DiGraph:

A subgraph.

instruction_size(insn_addr)

Get the size of the instruction specified by insn_addr.

Parameters:

insn_addr (int) – Address of the instruction

Return int:

Size of the instruction in bytes, or None if the instruction is not found.

addr
bp_on_stack
evicted
meta_only
normalized
previous_names
ran_cca
retaddr_on_stack
sp_delta
tags
addr_to_instruction_addr(addr)

Obtain the address of the instruction that covers @addr.

Parameters:

addr (int) – An address.

Returns:

Address of the instruction that covers @addr, or None if this addr is not covered by any instruction of this function.

Return type:

int or None

dbg_print()

Returns a representation of the list of basic blocks in this function.

dbg_draw(filename)

Draw the graph and save it to a PNG file.

property arguments
property has_return
property callable
normalize()

Make sure all basic blocks in the transition graph of this function do not overlap. You will end up with a CFG that IDA Pro generates.

This method does not touch the CFG result. You may call CFG{Emulated, Fast}.normalize() for that matter.

Returns:

None

find_declaration(ignore_binary_name=False, binary_name_hint=None)

Find the most likely function declaration from the embedded collection of prototypes, set it to self.prototype, and update self.calling_convention with the declaration.

Parameters:
  • ignore_binary_name (bool) – Do not rely on the executable or library where the function belongs to determine its source library. This is useful when working on statically linked binaries (because all functions will belong to the main executable). We will search for all libraries in angr to find the first declaration match.

  • binary_name_hint (str | None) – Substring of the library name where this function might be originally coming from. Useful for FLIRT-identified functions in statically linked binaries.

Return type:

bool

Returns:

True if a declaration is found and self.prototype and self.calling_convention are updated. False if we fail to find a matching function declaration, in which case self.prototype or self.calling_convention will be kept untouched.

is_rust_function()

Determines if the function name follows Rust mangling conventions.

property demangled_name
property short_name
get_unambiguous_name(display_name=None)

Get a disambiguated function name.

Parameters:

display_name (str | None) – Name to display, otherwise the function name.

Return type:

str

Returns:

The function name in one of the following forms:

  • ::<name> when the function binary is the main object.

  • ::<obj>::<name> when the function binary is not the main object.

  • ::<addr>::<name> when the function binary is an unnamed non-main object, or when multiple functions with the same name are defined in the function binary.

apply_definition(definition, calling_convention=None)
Return type:

None

Parameters:
functions_reachable()
Return type:

set[Function]

Returns:

The set of all functions that can be reached from the function represented by self.

holes(min_size=8)

Find the number of non-consecutive areas in the function that are at least min_size bytes large.

Return type:

int

Parameters:

min_size (int)

copy()
pp(**kwargs)

Pretty-print the function disassembly.