angr.analyses.decompiler.clinic

class angr.analyses.decompiler.clinic.BlockCache

Bases: tuple

BlockCache(prop,)

static __new__(_cls, prop)

Create new instance of BlockCache(prop,)

prop

Alias for field number 0

class angr.analyses.decompiler.clinic.ClinicMode

Bases: Enum

Analysis mode for Clinic.

DECOMPILE = 1
COLLECT_DATA_REFS = 2
class angr.analyses.decompiler.clinic.DataRefDesc

Bases: object

The fields of this class is compatible with items inside IRSB.data_refs.

data_addr: int
data_size: int
block_addr: int
stmt_idx: int
ins_addr: int
data_type_str: str
__init__(data_addr, data_size, block_addr, stmt_idx, ins_addr, data_type_str)
Parameters:
  • data_addr (int)

  • data_size (int)

  • block_addr (int)

  • stmt_idx (int)

  • ins_addr (int)

  • data_type_str (str)

Return type:

None

class angr.analyses.decompiler.clinic.ClinicStage

Bases: IntEnum

Different stages of treating an ailment.

INITIALIZATION = 0
AIL_GRAPH_CONVERSION = 1
MAKE_RETURN_SITES = 2
MAKE_ARGUMENT_LIST = 3
TRACK_STACK_POINTERS = 4
CONSTANT_PROPAGATION = 5
MAKE_CALLSITES = 6
POST_CALLSITES = 7
PRE_SSA_LEVEL0_FIXUPS = 8
SSA_LEVEL0_TRANSFORMATION = 9
PRE_SSA_LEVEL1_SIMPLIFICATIONS = 10
SSA_LEVEL1_TRANSFORMATION = 11
POST_SSA_LEVEL1_SIMPLIFICATIONS = 12
RECOVER_VARIABLES = 13
SEMANTIC_VARIABLE_NAMING = 14
COLLECT_EXTERNS = 15
__new__(value)
class angr.analyses.decompiler.clinic.ComboRegReferenceWalker

Bases: AILBlockRewriter

Rewrite references to combo registers to load from the combo register.

__init__(project, ail_manager)
class angr.analyses.decompiler.clinic.Clinic

Bases: Analysis, Serializable

A Clinic deals with AILments: it lifts a function to AIL and runs the decompiler’s simplification pipeline on it.

AIL graphs exposed after a DECOMPILE-mode run:

  • cc_graph: the graph at the end of Clinic’s own simplification, frozen as a copy before region identification. Serialized; available on both live and cached-and-reloaded clinics.

  • graph: cc_graph further transformed by the decompiler’s graph-simplification passes, region identification, and region-simplification passes — the final graph. Serialized; available on both live and cached-and-reloaded clinics.

  • unoptimized_graph: a copy taken before the first structure-altering optimization pass; use it for an exact instruction-to-AIL mapping. Only built (and serialized) with Decompiler(save_unoptimized_graph=True); otherwise it is None on both live and cached-and-reloaded clinics.

  • _ail_graph / _init_ail_graph: pipeline internals; never serialized.

CROSS_INSN_OPT_MIN_BLOCK_SIZE = 99

lift a block with cross-insn-opt only when it contains at least this many bytes

CROSS_INSN_OPT_MIN_LARGE_BLOCK_COUNT = 400

…and only in functions with at least this many such blocks

CROSS_INSN_OPT_MAX_BINOP_COUNT = 3

…and it has fewer BinOps than this in total

CROSS_INSN_OPT_MIN_STRIDE_REPEATS = 30

…and only when the block contains this many consecutive repeating byte strides

CROSS_INSN_OPT_MAX_STRIDE = 4

longest byte stride when looking for repeating patterns

__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, 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, force_single_loop_entry=False, typehoon_cls=<class 'angr.analyses.typehoon.typehoon.Typehoon'>, max_ail_statements=1000000, 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=Flavors.DEFAULT_FLAVOR, variable_map=None, save_unoptimized_graph=False, known_patterns=None, recognize_known_patterns=True)
Parameters:
cc_graph: DiGraph | None
unoptimized_graph: DiGraph | None
arg_vvars: dict[int, tuple[VirtualVariable, SimVariable]] | None
variable_map: VariableMap
externs: set[SimMemoryVariable]
data_refs: dict[int, list[DataRefDesc]]
entry_node_addr: Address
unresolvable_peephole_optimizations: list[str]
reaching_definitions: SRDAModel | None
vvar_to_vvar: dict[int, int] | None
secondary_stackvars: set[int]
edges_to_remove: list[tuple[Address, Address]]
copied_var_ids: set[int]
typehoon: Typehoon | None
stack_items: dict[int, StackItem]
go_sigs_version: int | None
go_sigs_deps: dict[str, int]
go_sigs_updated: bool
go_sigs_stale: bool
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

MAX_CALLEE_CLEANUP_SUBSET_CANDIDATES = 4
block_lifted_with_cross_insn_opt(block_addr, block_size)
Return type:

bool

Parameters:
  • block_addr (int)

  • block_size (int)

static repeating_stride_run(data, max_stride)

The longest run of consecutive repetitions of up to max_stride bytes in data.

Return type:

int

Parameters:
static binop_count(block)

The number of binary operations across all statements of block.

Return type:

int

Parameters:

block (Block)

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.

resolve_peephole_optimizations()

Retry resolving peephole-optimization names that were unresolvable at parse time (their defining module may have been imported since). Resolved classes move into peephole_optimizations; names that still do not resolve stay in unresolvable_peephole_optimizations.

Return type:

None

classmethod parse_from_cmessage(cmsg, *, project=None, kb=None, function=None, cfg=None, **kwargs)

Bypasses Clinic.__init__() (which runs the analysis) and reconstructs the instance directly. Runtime back-references — project / kb / function / _cfg — come from kwargs.

Only the state consumed by the decompiler’s cache-reuse path and by post-decompilation consumers (cc_graph, graph, optionally unoptimized_graph) is serialized; regenerable and runtime-only state is restored to its default here. If function is None and kb is provided, the function is resolved by address from the cmessage.