angr.analyses.decompiler

class angr.analyses.decompiler.AILSimplifier

Bases: Analysis

Perform function-level simplifications.

__init__(func, func_graph, ail_manager, remove_dead_memdefs=False, stack_arg_offsets=None, unify_variables=False, gp=None, narrow_expressions=False, fold_expressions=True, only_consts=False, fold_callexprs_into_conditions=False, use_callee_saved_regs_at_return=True, rewrite_ccalls=True, rename_ccalls=True, rewrite_dirty=True, removed_vvar_ids=None, arg_vvars=None, avoid_vvar_ids=None)
class angr.analyses.decompiler.BaseStructuredCodeGenerator

Bases: object

__init__(flavor=None, notes=None, expr_comments=None, stmt_comments=None, const_formats=None)
static adjust_mapping_positions(offset, pos_to_node, pos_to_addr, addr_to_pos)

Adjust positions in the mappings to account for the notes that are prepended to the text.

Parameters:
  • offset (int) – The length of the notes to prepend.

  • pos_to_node (PositionMapping) – The position to node mapping.

  • pos_to_addr (PositionMapping) – The position to address mapping.

  • addr_to_pos (InstructionMapping) – The address to position mapping.

Return type:

tuple[PositionMapping, PositionMapping, InstructionMapping]

Returns:

Adjusted mappings.

reapply_options(options)
regenerate_text()
Return type:

None

reload_variable_types()
Return type:

None

next_idx(key)
Return type:

str

Parameters:

key (str)

reset_idx_counters()
Return type:

None

class angr.analyses.decompiler.BlockSimplifier

Bases: Analysis

Simplify an AIL block.

__init__(block, ail_manager, func_addr=None, stack_pointer_tracker=None, peephole_optimizations=None, preserve_vvar_ids=None, type_hints=None, cached_reaching_definitions=None, cached_propagator=None)
Parameters:
class angr.analyses.decompiler.CStructuredCodeGenerator

Bases: BaseStructuredCodeGenerator, Analysis

__init__(func, sequence, indent=0, cfg=None, variable_kb=None, func_args=None, binop_depth_cutoff=16, show_casts=True, braces_on_own_lines=True, use_compound_assignments=True, show_local_types=True, comment_gotos=False, cstyle_null_cmp=True, flavor=None, stmt_comments=None, expr_comments=None, show_externs=True, externs=None, const_formats=None, show_demangled_name=True, show_disambiguated_name=True, ail_graph=None, simplify_else_scope=True, cstyle_ifs=True, omit_func_header=False, display_block_addrs=False, display_vvar_ids=False, min_data_addr=4194304, notes=None, display_notes=True, max_str_len=None, prettify_thiscall=False, cstyle_void_param=True, variable_map=None)
Parameters:
reapply_options(options)
cleanup()

Remove existing rendering results.

regenerate_text()

Re-render text and re-generate all sorts of mapping information.

Return type:

None

render_text(cfunc)
Return type:

tuple[str, PositionMapping, PositionMapping, InstructionMapping, dict[Any, set[Any]]]

Parameters:

cfunc (CFunction)

render_notes()

Render decompilation notes.

Return type:

str

Returns:

A string containing all notes.

reload_variable_types()
Return type:

None

default_simtype_from_bits(n, signed=True)
Return type:

SimType

Parameters:
variables_unify(v1, v2)
Return type:

bool

Parameters:
class angr.analyses.decompiler.CallSiteMaker

Bases: Analysis

Add calling convention, declaration, and args to a call site.

__init__(block, *, ail_manager, reaching_definitions=None, stack_pointer_tracker=None)
Parameters:

ail_manager (Manager)

class angr.analyses.decompiler.Clinic

Bases: Analysis

A Clinic deals with AILments.

__init__(func, remove_dead_memdefs=False, exception_edges=False, sp_tracker_track_memory=True, fold_expressions=True, fold_callexprs_into_conditions=False, insert_labels=True, optimization_passes=None, cfg=None, peephole_optimizations=None, must_struct=None, variable_kb=None, reset_variable_names=False, rewrite_ites_to_diamonds=True, rewrite_ites_to_diamond_max_cases=15, cache=None, mode=ClinicMode.DECOMPILE, sp_shift=0, inline_functions=None, inlined_counts=None, inlining_parents=None, vvar_id_start=0, optimization_scratch=None, desired_variables=None, force_loop_single_exit=True, refine_loops_with_single_successor=False, expose_loop_head_backedges=False, typehoon_cls=<class 'angr.analyses.typehoon.typehoon.Typehoon'>, max_type_constraints=100000, type_constraint_set_degradation_threshold=150, ail_graph=None, arg_vvars=None, start_stage=ClinicStage.INITIALIZATION, end_stage=None, skip_stages=(), notes=None, static_vvars=None, static_buffers=None, flatten_args=False, constrain_callee_prototypes=False, semvar_naming=True, flavor='pseudocode', variable_map=None)
Parameters:
block(addr, size)

Get the converted block at the given specific address with the given size.

Parameters:
Returns:

dbg_repr()
Returns:

calculate_stack_depth()
copy_graph(graph=None)
Return type:

DiGraph

parse_variable_addr(addr)
Return type:

tuple[Any, Any]

Parameters:

addr (Expression)

new_block_addr()

Return a block address that does not conflict with any existing blocks.

Return type:

int

Returns:

The block address.

static remove_empty_nodes(graph)
Return type:

DiGraph

Parameters:

graph (DiGraph)

constrain_callee_prototypes()

Constrain the types of callee function arguments based on facts that are observed at call sites. Note that this function will change the prototypes of (callee) functions in the knowledge base, which means it may affect the decompilation output of the current function if it is decompiled again.

class angr.analyses.decompiler.ClinicMode

Bases: Enum

Analysis mode for Clinic.

DECOMPILE = 1
COLLECT_DATA_REFS = 2
class angr.analyses.decompiler.DecompilationCache

Bases: object

Caches key data structures that can be used later for refining decompilation results, such as retyping variables.

__init__(addr)
parameters: dict[str, Any]
addr
type_constraints: dict[TypeVariable, set[TypeConstraint]] | None
arg_vvars: dict | None
func_typevar: TypeVariable | None
var_to_typevar: dict | None
stackvar_max_sizes: dict | None
stack_offset_typevars: dict | None
codegen: BaseStructuredCodeGenerator | None
clinic: Clinic | None
variable_map: VariableMap | None
ite_exprs: set[tuple[int, Any]] | None
binop_operators: dict[OpDescriptor, str] | None
errors: list[str]
function_summary: str | None
notes: dict[str, str]
max_tv_id: int
property local_types
class angr.analyses.decompiler.Decompiler

Bases: Analysis

The decompiler analysis.

Run this on a Function object for which a normalized CFG has been constructed. The fully processed output can be found in result.codegen.text

__init__(func, cfg=None, options=None, preset=None, optimization_passes=None, sp_tracker_track_memory=True, variable_kb=None, peephole_optimizations=None, vars_must_struct=None, flavor='pseudocode', expr_comments=None, stmt_comments=None, ite_exprs=None, binop_operators=None, decompile=True, regen_clinic=True, inline_functions=None, desired_variables=None, update_memory_data=True, want_full_graph=False, generate_code=True, use_cache=True, update_cache=True, expr_collapse_depth=16, clinic_graph=None, clinic_arg_vvars=None, clinic_start_stage=None, clinic_end_stage=None, clinic_skip_stages=(), static_vvars=None, static_buffers=None, codegen_cls=<class 'angr.analyses.decompiler.structured_codegen.c.CStructuredCodeGenerator'>)
Parameters:
reflow_variable_types(cache)

Re-run type inference on an existing variable recovery result, then rerun codegen to generate new results.

Returns:

Parameters:

cache (DecompilationCache)

find_data_references_and_update_memory_data(seq_node)
Parameters:

seq_node (SequenceNode)

transform_graph_from_ssa(ail_graph)

Translate an SSA AIL graph out of SSA form. This is useful for producing a non-SSA AIL graph for displaying in angr management.

Parameters:

ail_graph (DiGraph) – The AIL graph to transform out of SSA form.

Return type:

DiGraph

Returns:

The translated AIL graph.

transform_seqnode_from_ssa(seq_node)
Return type:

SequenceNode

Parameters:

seq_node (SequenceNode)

llm_refine()

Use the configured LLM to suggest improved variable names, function names, and variable types. Returns True if any changes were made.

Return type:

bool

llm_suggest_variable_names(llm_client=None, code_text=None, raise_exc=False)

Ask the LLM to suggest better variable names for the decompiled code. Returns True if any variables were renamed.

Parameters:
  • raise_exc (bool) – If True, exceptions from the LLM call are propagated to the caller. If False (default), exceptions are caught and the method returns False.

  • code_text (str | None)

Return type:

bool

llm_suggest_function_name(llm_client=None, code_text=None, raise_exc=False)

Ask the LLM to suggest a better function name. Only suggests rename for auto-generated names (starting with sub_ or fcn.). Returns True if the function was renamed.

Parameters:
  • raise_exc (bool) – If True, exceptions from the LLM call are propagated to the caller.

  • code_text (str | None)

Return type:

bool

llm_suggest_variable_types(llm_client=None, code_text=None, raise_exc=False)

Ask the LLM to suggest better C types for variables. Returns True if any variable types were changed.

Parameters:
  • raise_exc (bool) – If True, exceptions from the LLM call are propagated to the caller.

  • code_text (str | None)

Return type:

bool

llm_summarize_function(llm_client=None, code_text=None, raise_exc=False)

Ask the LLM to produce a natural-language summary of what the decompiled function does. The summary is stored in the DecompilationCache and returned.

Returns the summary string, or None if summarization failed.

Parameters:
  • raise_exc (bool) – If True, exceptions from the LLM call are propagated to the caller.

  • code_text (str | None)

Return type:

str | None

static options_to_params(options)

Convert decompilation options to a dict of params.

Parameters:

options (list[tuple[DecompilationOption, Any]]) – The decompilation options.

Return type:

dict[str, Any]

Returns:

A dict of keyword arguments.

class angr.analyses.decompiler.GraphDephication

Bases: DephicationBase

GraphDephication removes phi expressions from an AIL graph, essentially transforms a partial-SSA form of AIL graph to a normal AIL graph.

__init__(func, ail_graph, vvar_to_vvar_mapping=None, rewrite=False, variable_kb=None, variable_map=None)
Parameters:
  • func (Function | str) – The subject of the analysis: a function, or a single basic block

  • ail_graph – The AIL graph to transform.

  • vvar_to_vvar_mapping (dict[int, int] | None)

  • rewrite (bool)

  • variable_kb (KnowledgeBase | None)

  • variable_map (VariableMap | None)

class angr.analyses.decompiler.ImportSourceCode

Bases: BaseStructuredCodeGenerator, Analysis

__init__(function, flavor='source', source_root=None, encoding='utf-8')
regenerate_text()
class angr.analyses.decompiler.RegionIdentifier

Bases: Analysis

A region is a single-entry-single-exit subgraph of control flow. The region identifier recursively identifies the smallest possible regions within a function graph and creates a RegionOverlay object whose nodes are either Blocks or RegionOverlays.

Note, that the analysis may modify the graph in-place. If you want to keep the original graph, set the update_graph parameter to False.

__init__(func, cond_proc=None, graph=None, ail_manager=None, update_graph=True, largest_successor_tree_outside_loop=True, force_loop_single_exit=True, refine_loops_with_single_successor=False, expose_loop_head_backedges=False, entry_node_addr=None)
static slice_graph(graph, node, frontier, include_frontier=False)

Generate a slice of the graph from the head node to the given frontier.

Parameters:
  • graph (networkx.DiGraph) – The graph to work on.

  • node – The starting node in the graph.

  • frontier – A list of frontier nodes.

  • include_frontier (bool) – Whether the frontier nodes are included in the slice or not.

Returns:

A subgraph.

Return type:

networkx.DiGraph[TNode]

test_reducibility()
Return type:

bool

class angr.analyses.decompiler.RegionOverlay

Bases: object

A single-entry region marked over the shared graph held by an OverlayManager. The region tree is built out of RegionOverlay objects (RegionIdentifier emits them) and they are the only region type the decompiler uses.

Overlays form a tree (nested, never overlapping). An overlay’s members are either shared-graph nodes it owns directly or child overlays. The region graph and the region graph-with-successors are derived on demand from the shared graph by quotienting child overlays into single nodes; successors are likewise derived from edges that cross the region boundary, so they can never go stale.

Read-only API (head, graph, graph_with_successors, successors, cyclic, addr) mirrors the region container consumers expect; graph/graph_with_successors/successors are lazy zero-copy views.

Mutation verbs:

  • true structural changes (add_node, remove_node, add_edge, detach_edge, replace_nodes) pass through to the shared graph, so the effects are immediately visible to all enclosing regions;

  • hide_edge removes an edge from this overlay’s views only (the old “remove it from region graphs but keep the parent edge” pattern);

  • finalize(result_node) collapses a fully-structured region into a single node of its parent;

  • dissolve() merges an unsuccessfully-structured region back into its parent.

__init__(mgr, head, cyclic, cyclic_ancestor=False, parent=None)
Parameters:
head
cyclic
cyclic_ancestor
parent
children: list[RegionOverlay]
edge_marks: defaultdict[str, set[tuple[Any, Any]]]
replacement
property addr
property manager: OverlayManager
property members: set
ancestors()

All overlays enclosing this one, including this one itself.

Return type:

set[RegionOverlay]

underlying_nodes()

All shared-graph nodes inside this region (including nodes of nested regions).

Return type:

set

create_subregion(head, members, cyclic, cyclic_ancestor=False)

Carve a new child overlay out of this overlay. members must be a subset of this overlay’s members (shared-graph nodes owned by this overlay and/or existing child overlays); head must be one of them.

Return type:

RegionOverlay

Parameters:
successor_nodes()

The derived successor set of this region: representatives of all shared-graph nodes targeted by edges leaving the region.

Return type:

set

view_graph(full=False, include_marked=False, blacklisted_edges=frozenset({}))

A zero-copy, networkx-compatible view of this region (see RegionOverlayGraph).

Return type:

RegionOverlayGraph

Parameters:
view()

The region graph (members only): a zero-copy networkx-compatible view; treat it as read-only.

Return type:

RegionOverlayGraph

view_with_successors()

The region graph including successor nodes: a zero-copy view; treat it as read-only.

Return type:

RegionOverlayGraph

property raw_graph: RegionOverlayGraph

The member view including marked edges (the old graph with cyclic_refinement_outgoing attrs present).

property raw_graph_with_successors: RegionOverlayGraph

The with-successors view including marked edges.

property graph: DiGraph
property graph_with_successors: DiGraph
property successors: set
property full_graph: None
add_node(node)

Insert a new node into the shared graph as a direct member of this region.

Return type:

None

remove_node(node, absorbed_into=None, absorb_out_edges=True)

Remove a node. If node is a member (or a member overlay’s node), it is removed from the shared graph for real. If it is a successor of this region, the removal is interpreted as hiding all edges from this region to it (the successor belongs to an enclosing region and must survive).

When the node’s content has been absorbed into another node during structuring, pass that node as absorbed_into: in-edges from outside this region (e.g. abnormal loop entries) are then rewired to it instead of being dropped, so enclosing regions keep their entry edges. With absorb_out_edges (the default), out-edges crossing the region boundary (e.g. loop exits) are rewired to it as well, so the shared graph never loses the region’s exit flow; pass False only when the caller re-establishes every successor edge explicitly.

Return type:

None

Parameters:

absorb_out_edges (bool)

hide_edge_to_successor(succ)
Return type:

None

underlying_edge_pairs(src, dst)
Return type:

list[tuple[Any, Any]]

add_edge(src, dst, **data)

Add a real edge to the shared graph. Overlay endpoints are resolved to underlying nodes: the destination resolves to its entry (head chain); overlay sources are not supported. Endpoints that are not in the shared graph yet become members of this region (mirroring networkx’s implicit node creation).

Return type:

None

detach_edge(src, dst)

Remove an edge from the shared graph for real (e.g., when the edge has been virtualized into a goto). Overlay endpoints remove all underlying edges between the two node sets.

Return type:

None

mark_edge(src, dst, **attrs)

Mark a view-level edge (e.g. cyclic_refinement_outgoing) so RegionOverlayGraph hides it by default. Marks live in overlay state, never reach the shared graph, and are remapped/cleared with the region.

Return type:

None

absorb_successor_into(succ, new_node)

Absorb a successor node into a structured member node in this region’s with-successors view only (the successor still belongs to an enclosing region): the successor’s view out-edges are re-attached to the member node as view-only extra edges, then the successor disappears from this region’s views.

Return type:

None

drop_edge_marks_from(node, key)

Clear marks on all out-edges of a node (the new_node after a replace), undoably.

Return type:

None

remove_edge_with_successors_only(src, dst)

Hide an edge from the with-successors view only, leaving the member view and the shared graph alone (a rare asymmetric bookkeeping pattern in Phoenix’s switch-case structuring).

Return type:

None

hide_edge(src, dst)

Remove an edge from this overlay’s views only. Enclosing regions still see the underlying edge(s).

Return type:

None

replace_nodes(old_node_0, new_node, old_node_1=None, self_loop=True)

Replace one or two member nodes with a new node, preserving and rewiring all underlying edges (including edges from/to nodes outside this region, which is how results become visible to enclosing regions).

Mirrors StructurerBase.replace_nodes, with one deliberate difference: in-edges of old_node_1 from outside this region are rewired to new_node instead of being dropped (they are entry edges owned by enclosing regions, e.g. abnormal loop entries).

Return type:

None

Parameters:

self_loop (bool)

snapshot_successors()

Capture this region’s structural successors and how many member edges reach each, taken before the region is structured. finalize() uses it to re-establish the region-to-successor edges that structuring removes when it virtualizes/refines the corresponding control-flow edges into gotos or breaks.

Return type:

set

finalize(result_node=None, succ_snapshot=None)

Collapse this fully-structured region into its parent: the region must consist of a single member node (the structuring result), which takes the region’s place among the parent’s members. Returns that node.

succ_snapshot (from snapshot_successors() before structuring) is used to re-establish the edges from result_node to the region’s successors: structuring may have removed the live control-flow edges (refining them into breaks/gotos), but the structured region still flows to those successors and enclosing regions must see that. A successor whose every member edge was virtualized is a pure goto target and is not reconnected.

collapse_to(result_node)

Collapse this region into its parent by replacing all of its member nodes with a single external result node (the structuring result). Used by structurers that compute their result without destructively reducing the shared graph (e.g. DreamStructurer): the region’s members are still present, so their crossing in/out edges are rewired onto result_node and the members are removed. Returns result_node.

This is the non-self-collapsing counterpart of finalize(); the legacy GraphRegion path called replace_region() for the same purpose.

dissolve()

Merge this region back into its parent (the failure path of structuring): members are reparented, and edges hidden in this region stay hidden in the parent (matching how partially-structured region graphs were merged back before).

Return type:

None

class angr.analyses.decompiler.RegionSimplifier

Bases: Analysis

Simplifies a given region.

__init__(func, region, ail_manager, arg_vvars=None, simplify_switches=True, simplify_ifelse=True, variable_manager=None, loopctr_naming=True)
Parameters:
class angr.analyses.decompiler.SeqNodeDephication

Bases: DephicationBase

SeqNodeDephication removes phi expressions from a SequenceNode and its children. It also removes redundant variable assignments, e.g., vvar_2 = vvar_1 where both vvar_1 and vvar_2 are mapped to the same variable.

__init__(func, seq_node, vvar_to_vvar_mapping=None, rewrite=False, variable_kb=None, variable_map=None)
Parameters:
class angr.analyses.decompiler.Ssailification

Bases: Analysis

Ssailification (SSA-AIL-ification) transforms an AIL graph to its partial-SSA form.

__init__(func, ail_graph, entry=None, canonical_size=8, stack_pointer_tracker=None, func_addr=None, ail_manager=None, ssa_stackvars=False, ssa_tmps=False, func_args=None, rewrite_vvars=None, vvar_id_start=0)
Parameters:
  • func – The subject of the analysis: a function, or a single basic block

  • ail_graph – The AIL graph to transform.

  • canonical_size – The sizes (in bytes) that objects with an UNKNOWN_SIZE are treated as for operations where sizes are necessary.

angr.analyses.decompiler.StructuredCodeGenerator

alias of CStructuredCodeGenerator

class angr.analyses.decompiler.VariableMap

Bases: object

A side container that maps the .idx of AIL Statement and Expression objects to variable-related information.

The following pieces of information are tracked:

  • variable (a SimVariable) and variable_offset (an int): the variable that an AIL atom resolves to, and the offset into that variable.

  • custom_string (a bool): whether a Const expression refers to a custom string.

  • reference_values (a dict mapping SimType to a value): reference values associated with a Const expression (e.g., custom strings).

  • reference_variable (a SimVariable) and reference_variable_offset (an int): the variable that a constant expression references, and the offset into it. These are siblings of variable / variable_offset that are specifically used for constants that reference global/extern variables.

  • prototype (a SimTypeFunction) and calling_convention (a SimCC): the call-site prototype and calling convention associated with an AIL Call expression. These used to live directly on the Call object; they are heavy, non-serializable Python references, so they are tracked here instead.

  • variant (an EnumVariant): the enum variant that a Rust Let expression binds.

  • returnty (a SimType): the return type of a Rust FunctionLikeMacro call.

Keys are the integer .idx values of AIL Statement/Expression objects. Because Clinic builds one ailment.Manager per invocation, .idx values are unique within a single Clinic. So a VariableMap is scoped to one Clinic instance and is stored in the corresponding DecompilationCache.

__init__()
variable(obj)
Return type:

SimVariable | None

Parameters:

obj (TaggedObject | int)

variable_offset(obj)
Return type:

int

Parameters:

obj (TaggedObject | int)

custom_string(obj)
Return type:

bool

Parameters:

obj (TaggedObject | int)

reference_values(obj)
Return type:

dict[SimType, Any] | None

Parameters:

obj (TaggedObject | int)

reference_variable(obj)
Return type:

SimVariable | None

Parameters:

obj (TaggedObject | int)

reference_variable_offset(obj)
Return type:

int

Parameters:

obj (TaggedObject | int)

has_variable(obj)
Return type:

bool

Parameters:

obj (TaggedObject | int)

prototype(obj)
Return type:

SimTypeFunction | None

Parameters:

obj (TaggedObject | int)

calling_convention(obj)
Return type:

SimCC | None

Parameters:

obj (TaggedObject | int)

variant(obj)
Return type:

Any

Parameters:

obj (TaggedObject | int)

returnty(obj)
Return type:

SimType | None

Parameters:

obj (TaggedObject | int)

set_variable(obj, variable, offset=0)

Set the variable information for an AIL atom. If variable is None, the variable information for this atom is cleared.

Return type:

None

Parameters:
set_variable_offset(obj, offset)
Return type:

None

Parameters:
set_custom_string(obj, value=True)
Return type:

None

Parameters:
set_reference_values(obj, reference_values)
Return type:

None

Parameters:
set_reference_variable(obj, variable, offset=0)

Set the reference variable information for an AIL atom. If variable is None, the reference variable information for this atom is cleared.

Return type:

None

Parameters:
set_prototype(obj, prototype)

Set the call-site prototype for an AIL Call. If prototype is None, the prototype information for this atom is cleared.

Return type:

None

Parameters:
set_calling_convention(obj, cc)

Set the calling convention for an AIL Call. If cc is None, the calling-convention information for this atom is cleared.

Return type:

None

Parameters:
set_variant(obj, variant)

Set the enum variant for a Rust Let expression. If variant is None, the variant information for this atom is cleared.

Return type:

None

Parameters:
set_returnty(obj, returnty)

Set the return type for a Rust FunctionLikeMacro call. If returnty is None, the return-type information for this atom is cleared.

Return type:

None

Parameters:
transfer(src, dst)

Copy all variable information associated with src to dst. Used when an AIL atom is deep-copied to a new .idx (e.g. during structuring/duplication) so that the new atom keeps the same variable association.

Return type:

None

Parameters:
to_json()

Serialize this VariableMap to a JSON-compatible object.

Variables are referenced by their .ident (reference-by-ident); they must be resolved back to SimVariable objects via a resolver in from_json().

Return type:

dict[str, Any]

classmethod from_json(data, resolve_variable)

Deserialize a VariableMap from a JSON-compatible object produced by to_json().

Parameters:
  • data (dict[str, Any]) – The JSON object.

  • resolve_variable (Callable[[str], SimVariable | None]) – A callable that maps a variable ident (str) to a SimVariable (or None if it cannot be resolved).

Return type:

VariableMap

Submodules