angr.analyses.decompiler.structured_codegen.c

type angr.analyses.decompiler.structured_codegen.c.RenderResult = tuple[str, PositionMapping, PositionMapping, InstructionMapping, dict[Any, set[Any]]]
angr.analyses.decompiler.structured_codegen.c.qualifies_for_simple_cast(ty1, ty2)
angr.analyses.decompiler.structured_codegen.c.qualifies_for_width_cast(ty)
angr.analyses.decompiler.structured_codegen.c.int_width_and_signedness(ty)

The (bits, signed) of an integer-like C type, or None when the type is not an integer or has no size.

Return type:

tuple[int, bool] | None

Parameters:

ty (SimType | None)

angr.analyses.decompiler.structured_codegen.c.int_operand_signedness(expr)

The signedness of an integer expression as C reads it. Constants are neutral (None): an int literal does not make (int)a - 1 unsigned, even though the common type the codegen computes for it is.

Return type:

bool | None

Parameters:

expr (CExpression)

angr.analyses.decompiler.structured_codegen.c.is_sign_fixing_cast(cast)

A same-width integer cast whose operand C reads with the other signedness, e.g. (long long)x for unsigned x.

Return type:

bool

Parameters:

cast (CTypeCast)

angr.analyses.decompiler.structured_codegen.c.qualifies_for_implicit_cast(ty1, ty2)
angr.analyses.decompiler.structured_codegen.c.c_return_type(returnty)

Convert a return type to a C-compatible type. - Arrays are converted to pointers to their element type.

Return type:

SimType

Parameters:

returnty (SimType)

angr.analyses.decompiler.structured_codegen.c.extract_terms(expr)
Return type:

tuple[int, list[tuple[int, CExpression]]]

Parameters:

expr (CExpression)

angr.analyses.decompiler.structured_codegen.c.is_machine_word_size_type(type_, arch)
Return type:

bool

Parameters:
angr.analyses.decompiler.structured_codegen.c.guess_value_type(value, project)
Return type:

SimType | None

Parameters:
angr.analyses.decompiler.structured_codegen.c.type_equals(t0, t1)
Return type:

bool

Parameters:
angr.analyses.decompiler.structured_codegen.c.type_layout_key(ty, memo=None)

A structural sort key for a type, derived purely from its memory layout (sizes, field offsets, and the layouts of field/element/pointee types) and not from any user-renamable struct or field name. This lets the code generator order type definitions stably without their order changing when the user renames a struct or a field.

The key covers the type down to TYPE_LAYOUT_KEY_DEPTH levels of struct nesting. The key summarizes the member of each struct level in a hash.

Return type:

str

Parameters:

memo (_LayoutKeyMemo | None)

angr.analyses.decompiler.structured_codegen.c.cextern_sort_key(cextern)

A stable sort key for extern variables, based on the variable’s address. Unlike the variable name, the address does not change when the user renames the variable, so the ordering of extern definitions stays put across renames.

Return type:

tuple

angr.analyses.decompiler.structured_codegen.c.type_to_c_repr_chunks(ty, name=None, name_type=None, full=False, indent_str='', indent_delta=4, memo=None)

Helper generator function to turn a SimType into generated tuples of (C-string, AST node).

Parameters:
  • indent_delta (int) – Number of space characters used to indent each struct field one level deeper.

  • memo (set[int] | None) – IDs of the aggregates currently being rendered further up the stack, so that a self-referential type is elided instead of recursed into. An aggregate is added before its members are rendered and removed once they are done.

  • ty (SimType)

class angr.analyses.decompiler.structured_codegen.c.CConstruct

Bases: object

Represents a program construct in C. Acts as the base class for all other representation constructions.

__init__(codegen, tags=None)
tags
codegen: CStructuredCodeGenerator
ident: str
idx: int
c_repr(initial_pos=0, indent=0, pos_to_node=None, pos_to_addr=None, addr_to_pos=None)

Creates the C representation of the code and displays it by constructing a large string. This function is called by each program function that needs to be decompiled. The map_pos_to_node and map_pos_to_addr act as position maps for the location of each variable and statement to be tracked for later GUI operations. The map_pos_to_addr also contains expressions that are nested inside of statements.

c_repr_chunks(indent=0, asexpr=False)
static indent_str(indent=0)
class angr.analyses.decompiler.structured_codegen.c.CFunction

Bases: CConstruct, FunctionNode

Represents a function in C.

__init__(addr, name, functy, arg_list, statements, variables_in_use, variable_manager, demangled_name=None, show_demangled_name=True, omit_header=False, **kwargs)
Parameters:
addr
name
functy
arg_list
statements
variables_in_use
variable_manager: VariableManagerInternal
demangled_name
unified_local_vars: dict[SimVariable, list[tuple[CVariable, SimType]]]
show_demangled_name
omit_header
refresh()
get_unified_local_vars()
Return type:

dict[SimVariable, list[tuple[CVariable, SimType]]]

variable_list_repr_chunks(indent=0)
c_repr_chunks(indent=0, asexpr=False)
headerless_c_repr_chunks(indent=0)
full_c_repr_chunks(indent=0, asexpr=False)
static sort_local_vars(local_vars)
Return type:

list[SimVariable]

Parameters:

local_vars (Iterable[SimVariable])

class angr.analyses.decompiler.structured_codegen.c.CStatement

Bases: CConstruct

Represents a statement in C.

__init__(tags=None, *, codegen)
codegen: CStructuredCodeGenerator
ident: str
idx: int
tags
class angr.analyses.decompiler.structured_codegen.c.CExpression

Bases: CConstruct, ExpressionNode

Base class for C expressions.

__init__(collapsed=False, tags=None, *, codegen)
collapsed
property type: SimType | None
set_type(v)
class angr.analyses.decompiler.structured_codegen.c.CStatements

Bases: CStatement

Represents a sequence of statements in C.

__init__(statements, addr=None, **kwargs)
statements
addr
c_repr_chunks(indent=0, asexpr=False)
class angr.analyses.decompiler.structured_codegen.c.CAILBlock

Bases: CStatement

Represents a block of AIL statements.

__init__(block, **kwargs)
block
c_repr_chunks(indent=0, asexpr=False)
class angr.analyses.decompiler.structured_codegen.c.CLoop

Bases: CStatement

Represents a loop in C.

class angr.analyses.decompiler.structured_codegen.c.CWhileLoop

Bases: CLoop

Represents a while loop in C.

__init__(condition, body, **kwargs)
condition
body
c_repr_chunks(indent=0, asexpr=False)
class angr.analyses.decompiler.structured_codegen.c.CDoWhileLoop

Bases: CLoop

Represents a do-while loop in C.

__init__(condition, body, **kwargs)
condition
body
c_repr_chunks(indent=0, asexpr=False)
class angr.analyses.decompiler.structured_codegen.c.CForLoop

Bases: CStatement

Represents a for-loop in C.

__init__(initializer, condition, iterator, body, **kwargs)
initializer
condition
iterator
body
c_repr_chunks(indent=0, asexpr=False)
class angr.analyses.decompiler.structured_codegen.c.CIfElse

Bases: CStatement

Represents an if-else construct in C.

__init__(condition_and_nodes, else_node=None, simplify_else_scope=False, cstyle_ifs=True, **kwargs)
Parameters:

condition_and_nodes (list[tuple[CExpression, CStatement | None]])

condition_and_nodes
else_node
simplify_else_scope
cstyle_ifs
c_repr_chunks(indent=0, asexpr=False)
class angr.analyses.decompiler.structured_codegen.c.CIfBreak

Bases: CStatement

Represents an if-break statement in C.

__init__(condition, cstyle_ifs=True, **kwargs)
condition
cstyle_ifs
c_repr_chunks(indent=0, asexpr=False)
class angr.analyses.decompiler.structured_codegen.c.CBreak

Bases: CStatement

Represents a break statement in C.

__init__(**kwargs)
c_repr_chunks(indent=0, asexpr=False)
class angr.analyses.decompiler.structured_codegen.c.CContinue

Bases: CStatement

Represents a continue statement in C.

__init__(**kwargs)
c_repr_chunks(indent=0, asexpr=False)
class angr.analyses.decompiler.structured_codegen.c.CSwitchCase

Bases: CStatement

Represents a switch-case statement in C.

__init__(switch, cases, default, **kwargs)
switch
cases: list[tuple[int | tuple[int], CStatements]]
default
c_repr_chunks(indent=0, asexpr=False)
class angr.analyses.decompiler.structured_codegen.c.CIncompleteSwitchCase

Bases: CStatement

Represents an incomplete switch-case construct; this only appear in the decompilation output when switch-case structuring fails (for whatever reason).

__init__(head, cases, **kwargs)
head
cases: list[tuple[int, CStatements]]
c_repr_chunks(indent=0, asexpr=False)
class angr.analyses.decompiler.structured_codegen.c.CAssignment

Bases: CStatement

a = b

__init__(lhs, rhs, **kwargs)
lhs
rhs
c_repr_chunks(indent=0, asexpr=False)
class angr.analyses.decompiler.structured_codegen.c.CExpressionStatement

Bases: CStatement

Wraps a CExpression so it can be used as a standalone statement.

expr;

__init__(expr, returning=True, **kwargs)
Parameters:
expr
returning
c_repr_chunks(indent=0, asexpr=False)
class angr.analyses.decompiler.structured_codegen.c.CFunctionCall

Bases: CExpression, FunctionCallNode

func(arg0, arg1)

Variables:

callee_func (Function) – The function getting called.

__init__(callee_target, callee_func, args, show_demangled_name=True, show_disambiguated_name=True, tags=None, *, codegen, callsite_prototype=None, **kwargs)
Parameters:
callee_target
callee_func: Function | None
callsite_prototype
args
show_demangled_name
show_disambiguated_name
property prettify_thiscall: bool
property prototype: SimTypeFunction | None
property prototype_returnty: SimType

Returns returnty and avoids creating the SimTypeFunction instance if the function prototype is not available. Instead of self.prototype.returnty, you should use self.prototype_returnty for better performance.

property type
c_repr_chunks(indent=0, asexpr=False)
class angr.analyses.decompiler.structured_codegen.c.CReturn

Bases: CStatement

__init__(retval, **kwargs)
retval
c_repr_chunks(indent=0, asexpr=False)
class angr.analyses.decompiler.structured_codegen.c.CGoto

Bases: CStatement

__init__(target, target_idx, **kwargs)
target: int | CExpression
target_idx
c_repr_chunks(indent=0, asexpr=False)
class angr.analyses.decompiler.structured_codegen.c.CUnsupportedStatement

Bases: CStatement

A wrapper for unsupported AIL statement.

__init__(stmt, **kwargs)
stmt
c_repr_chunks(indent=0, asexpr=False)
class angr.analyses.decompiler.structured_codegen.c.CDirtyStatement

Bases: CExpression

__init__(dirty, **kwargs)
Parameters:

dirty (CDirtyExpression)

dirty
property type
c_repr_chunks(indent=0, asexpr=False)
class angr.analyses.decompiler.structured_codegen.c.CLabel

Bases: CStatement, LabelNode

Represents a label in C code.

__init__(name, **kwargs)
Parameters:

name (str)

name
c_repr_chunks(indent=0, asexpr=False)
class angr.analyses.decompiler.structured_codegen.c.CStructField

Bases: CExpression, StructFieldNode

__init__(struct_type, offset, field, **kwargs)
Parameters:
struct_type
offset
field
property type
c_repr_chunks(indent=0, asexpr=False)
class angr.analyses.decompiler.structured_codegen.c.CFakeVariable

Bases: CExpression

An uninterpreted name to display in the decompilation output. Pretty much always represents an error?

__init__(name, ty, **kwargs)
Parameters:
name
property type
c_repr_chunks(indent=0, asexpr=False)
class angr.analyses.decompiler.structured_codegen.c.CVariable

Bases: CExpression, VariableNode

CVariable represents access to a variable with the specified type (variable_type).

variable must be a SimVariable.

__init__(variable, unified_variable=None, variable_type=None, vvar_id=None, **kwargs)
Parameters:

variable (SimVariable)

variable: SimVariable
unified_variable: SimVariable | None
variable_type: SimType | None
vvar_id
property type
property name
c_repr_chunks(indent=0, asexpr=False)
class angr.analyses.decompiler.structured_codegen.c.CIndexedVariable

Bases: CExpression, IndexedVariableNode

Represent a variable (an array) that is indexed.

__init__(variable, index, variable_type=None, **kwargs)
Parameters:
index: CExpression
property type
c_repr_chunks(indent=0, asexpr=False)
collapsed
class angr.analyses.decompiler.structured_codegen.c.CVariableField

Bases: CExpression, VariableFieldNode

Represent a field of a variable.

stl_accessor: str | None = None
__init__(variable, field, var_is_ptr=False, **kwargs)
Parameters:
property type
c_repr_chunks(indent=0, asexpr=False)
collapsed
class angr.analyses.decompiler.structured_codegen.c.CUnaryOp

Bases: CExpression, UnaryOpNode

Unary operations.

__init__(op, operand, **kwargs)
Parameters:

operand (CExpression)

op
operand
property type
c_repr_chunks(indent=0, asexpr=False)
class angr.analyses.decompiler.structured_codegen.c.CBinaryOp

Bases: CExpression, BinaryOpNode

Binary operations.

__init__(op, lhs, rhs, signed=None, **kwargs)
Parameters:

signed (bool | None)

op
lhs
rhs
signed
common_type
static compute_common_type(op, lhs_ty, rhs_ty)
Return type:

SimType

Parameters:
property type
property op_precedence
c_repr_chunks(indent=0, asexpr=False)
class angr.analyses.decompiler.structured_codegen.c.CTypeCast

Bases: CExpression

__init__(src_type, dst_type, expr, **kwargs)
Parameters:
src_type
dst_type
expr
property type
c_repr_chunks(indent=0, asexpr=False)
angr.analyses.decompiler.structured_codegen.c.prefix_unary_operand_needs_parens(operand, op)

Whether the operand of the prefix unary operator op must be parenthesized.

Skip operand parentheses after * in the following cases: - **p - *p->q - *a[i] - *(char *)p - !!x

-(-x) and ~(~x) keep their parentheses. Everything else (binops or an expression class with no known precedence) keeps parentheses.

Return type:

bool

Parameters:
angr.analyses.decompiler.structured_codegen.c.is_addressable_lvalue(cexpr)

Whether the expression names memory: a stack or global variable, an array element, a dereference, or a field of one of those. Register variables and register-held parameters are not.

Return type:

bool

Parameters:

cexpr (CExpression)

class angr.analyses.decompiler.structured_codegen.c.CReinterpret

Bases: CExpression

A bit-pattern view of an expression as another type of the same width: *(T *)&x for a memory-backed lvalue, __double_as_longlong(x) (the CUDA intrinsic names) for register variables and other values.

INTRINSICS: dict[tuple[str, int | None, str, int | None], str] = {('F', 32, 'I', 32): '__float_as_int', ('F', 64, 'I', 64): '__double_as_longlong', ('I', 32, 'F', 32): '__int_as_float', ('I', 64, 'F', 64): '__longlong_as_double'}
__init__(src_type, dst_type, expr, **kwargs)
Parameters:
src_type
dst_type
expr
property type
c_repr_chunks(indent=0, asexpr=False)
class angr.analyses.decompiler.structured_codegen.c.CConstant

Bases: CExpression, ConstantNode

__init__(value, type_, reference_values=None, **kwargs)
Parameters:
value: int | float | str
reference_values
property fmt
property fmt_hex
property fmt_neg
property fmt_char
property fmt_float
property fmt_double
property type
static str_to_c_str(_str, prefix='', maxlen=None)
Return type:

str

Parameters:
  • prefix (str)

  • maxlen (int | None)

c_repr_chunks(indent=0, asexpr=False)
fmt_int(value)

Format an integer using the format setup of the current node.

Parameters:

value (int) – The integer value to format.

Return type:

str

Returns:

The formatted string.

class angr.analyses.decompiler.structured_codegen.c.CRegister

Bases: CExpression

__init__(reg, **kwargs)
Parameters:

reg (str)

reg
property type
c_repr_chunks(indent=0, asexpr=False)
class angr.analyses.decompiler.structured_codegen.c.CITE

Bases: CExpression

__init__(cond, iftrue, iffalse, **kwargs)
cond
iftrue
iffalse
property type
c_repr_chunks(indent=0, asexpr=False)
class angr.analyses.decompiler.structured_codegen.c.CMultiStatementExpression

Bases: CExpression

(stmt0, stmt1, stmt2, expr)

__init__(stmts, expr, **kwargs)
Parameters:
stmts
expr
property type
c_repr_chunks(indent=0, asexpr=False)
class angr.analyses.decompiler.structured_codegen.c.CVEXCCallExpression

Bases: CExpression

ccall_name(arg0, arg1, …)

__init__(callee, operands, **kwargs)
Parameters:
callee
operands
property type
c_repr_chunks(indent=0, asexpr=False)
class angr.analyses.decompiler.structured_codegen.c.CVectorConvert

Bases: CExpression

A lane-wise conversion (an AIL Convert with vector_count), rendered as an intrinsic-style call because C has no vector cast syntax.

__init__(expr, operand, **kwargs)
Parameters:
expr
operand
property type
c_repr_chunks(indent=0, asexpr=False)
class angr.analyses.decompiler.structured_codegen.c.CDirtyExpression

Bases: CExpression

Ideally all dirty expressions should be handled and converted to proper conversions during conversion from VEX to AIL. Eventually this class should not be used at all.

__init__(dirty, operands=None, **kwargs)
Parameters:

operands (list[CExpression] | None)

dirty
operands
property type
intrinsic_name()

Return the dirty callee if it is a clean C identifier, else None.

Return type:

str | None

c_repr_chunks(indent=0, asexpr=False)
class angr.analyses.decompiler.structured_codegen.c.CClosingObject

Bases: ClosingObjectNode

A class to represent all objects that can be closed by it’s correspodning character. Examples: (), {}, []

__init__(opening_symbol)
opening_symbol
class angr.analyses.decompiler.structured_codegen.c.CArrayTypeLength

Bases: object

A class to represent the type information of fixed-size array lengths. Examples: In “char foo[20]”, this would be the “[20]”.

__init__(text)
text
class angr.analyses.decompiler.structured_codegen.c.CStructFieldNameDef

Bases: object

A class to represent the name of a defined field in a struct. Needed because it’s not a CVariable or a CStructField (because CStructField is the access of a CStructField). Example: In “struct foo { int bar; }, this would be “bar”.

__init__(name)
name
class angr.analyses.decompiler.structured_codegen.c.CStructuredCodeGenerator

Bases: BaseStructuredCodeGenerator, Analysis, Serializable

__init__(func, sequence, indent=0, cfg=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, indent_size=4, variable_map=None, stl_accessor_calls=False)
Parameters:
ailexpr2cnode: dict[tuple[Expression, bool], CExpression] | None
cnode2ailexpr: dict[CExpression, Expression] | None
map_ast_to_pos: dict[SimVariable, set[PositionMappingElement]] | None
map_addr_to_label: dict[tuple[int, int | None], CLabel]
cfunc: CFunction | None
cexterns: set[CVariable] | None
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:

RenderResult

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:
ERRNO_LOCATION_FUNCS = frozenset({'__errno', '__errno_location', '__error', '_errno'})

The libc functions that return &errno. errno is a macro that dereferences one of them, so it never survives into a binary as a symbol; what reaches decompilation is *(__errno_location()), which is both correct and unreadable.

class angr.analyses.decompiler.structured_codegen.c.CStructuredCodeWalker

Bases: object

handle(obj)
handle_default(obj)
handle_CFunction(obj)
handle_CStatements(obj)
handle_CWhileLoop(obj)
handle_CDoWhileLoop(obj)
handle_CForLoop(obj)
handle_CIfElse(obj)
handle_CIfBreak(obj)
handle_CSwitchCase(obj)
handle_CAssignment(obj)
handle_CExpressionStatement(obj)
handle_CFunctionCall(obj)
handle_CReturn(obj)
handle_CGoto(obj)
handle_CIndexedVariable(obj)
handle_CVariableField(obj)
handle_CUnaryOp(obj)
handle_CBinaryOp(obj)
handle_CTypeCast(obj)
handle_CITE(obj)
handle_CMultiStatementExpression(obj)
handle_CVectorConvert(obj)
handle_CVEXCCallExpression(obj)
handle_CDirtyExpression(obj)
class angr.analyses.decompiler.structured_codegen.c.MakeTypecastsImplicit

Bases: CStructuredCodeWalker

classmethod collapse(dst_ty, child)
Return type:

CExpression

Parameters:
handle_CAssignment(obj)
handle_CFunctionCall(obj)
Parameters:

obj (CFunctionCall)

handle_CReturn(obj)
Parameters:

obj (CReturn)

handle_CBinaryOp(obj)
Parameters:

obj (CBinaryOp)

handle_CTypeCast(obj)
Parameters:

obj (CTypeCast)

class angr.analyses.decompiler.structured_codegen.c.FieldReferenceCleanup

Bases: CStructuredCodeWalker

handle_CTypeCast(obj)
class angr.analyses.decompiler.structured_codegen.c.PointerArithmeticFixer

Bases: CStructuredCodeWalker

Before calling this fixer class, pointer arithmetics are purely integer-based and ignoring the pointer type.

For example, in the following case:

struct A* a_ptr; // assume struct A is 24 bytes in size a_ptr = a_ptr + 24;

It means adding 24 to the address of a_ptr, without considering the size of struct A. This fixer class will make pointer arithmetics aware of the pointer type. In this case, the fixer class will convert the code to a_ptr = a_ptr + 1.

handle_CAssignment(obj)
Parameters:

obj (CAssignment)

handle_CBinaryOp(obj)
Parameters:

obj (CBinaryOp)