ailment — angr Intermediate Language#

class ailment.Block(addr, original_size, statements=None, idx=None)[source]#

Bases: object

Describes an AIL block.

__init__(addr, original_size, statements=None, idx=None)[source]#
addr#
original_size#
statements: List[Statement]#
idx#
copy(statements=None)[source]#
dbg_repr(indent=0)[source]#
likes(other)[source]#
class ailment.Assignment(*args, **kwargs)[source]#

Bases: Statement

Assignment statement: expr_a = expr_b

__init__(idx, dst, src, **kwargs)[source]#
dst#
src#
likes(other)[source]#
replace(old_expr, new_expr)[source]#
copy()[source]#
Return type:

Assignment

class ailment.Expression(*args, **kwargs)[source]#

Bases: TaggedObject

The base class of all AIL expressions.

__init__(idx, depth, **kwargs)[source]#
depth#
has_atom(atom, identity=True)[source]#
likes(atom)[source]#
replace(old_expr, new_expr)[source]#
class ailment.Const(*args, **kwargs)[source]#

Bases: Atom

__init__(idx, variable, value, bits, **kwargs)[source]#
value#
bits#
property size#
likes(other)[source]#
property sign_bit#
copy()[source]#
Return type:

Const

class ailment.Tmp(*args, **kwargs)[source]#

Bases: Atom

__init__(idx, variable, tmp_idx, bits, **kwargs)[source]#
tmp_idx#
bits#
property size#
likes(other)[source]#
copy()[source]#
Return type:

Tmp

class ailment.Register(*args, **kwargs)[source]#

Bases: Atom

__init__(idx, variable, reg_offset, bits, **kwargs)[source]#
reg_offset#
bits#
property size#
likes(atom)[source]#
copy()[source]#
Return type:

Register

class ailment.UnaryOp(*args, **kwargs)[source]#

Bases: Op

__init__(idx, op, operand, variable=None, variable_offset=None, **kwargs)[source]#
operand#
bits#
variable#
variable_offset#
likes(other)[source]#
replace(old_expr, new_expr)[source]#
property operands#
property size#
copy()[source]#
Return type:

UnaryOp

has_atom(atom, identity=True)[source]#
class ailment.BinaryOp(*args, **kwargs)[source]#

Bases: Op

OPSTR_MAP = {'Add': '+', 'AddF': '+', 'AddV': '+', 'And': '&', 'Carry': 'CARRY', 'CmpEQ': '==', 'CmpF': 'CmpF', 'CmpGE': '>=', 'CmpGEs': '>=s', 'CmpGT': '>', 'CmpGTs': '>s', 'CmpLE': '<=', 'CmpLEs': '<=s', 'CmpLT': '<', 'CmpLTs': '<s', 'CmpNE': '!=', 'Concat': 'CONCAT', 'Div': '/', 'DivF': '/', 'DivMod': '/m', 'LogicalAnd': '&&', 'LogicalOr': '||', 'Mod': '%', 'Mul': '*', 'MulF': '*', 'MulV': '*', 'Or': '|', 'Rol': 'ROL', 'Ror': 'ROR', 'SBorrow': 'SBORROW', 'SCarry': 'SCARRY', 'Sar': '>>a', 'Shl': '<<', 'Shr': '>>', 'Sub': '-', 'SubF': '-', 'Xor': '^'}#
COMPARISON_NEGATION = {'CmpEQ': 'CmpNE', 'CmpGE': 'CmpLT', 'CmpGEs': 'CmpLTs', 'CmpGT': 'CmpLE', 'CmpGTs': 'CmpLEs', 'CmpLE': 'CmpGT', 'CmpLEs': 'CmpGTs', 'CmpLT': 'CmpGE', 'CmpLTs': 'CmpGEs', 'CmpNE': 'CmpEQ'}#
__init__(idx, op, operands, signed, variable=None, variable_offset=None, bits=None, floating_point=False, rounding_mode=None, from_bits=None, to_bits=None, **kwargs)[source]#
operands#
bits#
signed#
variable#
variable_offset#
floating_point#
rounding_mode#
from_bits#
to_bits#
likes(other)[source]#
has_atom(atom, identity=True)[source]#
replace(old_expr, new_expr)[source]#
property verbose_op#
property size#
copy()[source]#
Return type:

BinaryOp

class ailment.Manager(name=None, arch=None)[source]#

Bases: object

Parameters:

name (str | None) –

__init__(name=None, arch=None)[source]#
Parameters:

name (str | None) –

next_atom()[source]#
reset()[source]#
property ins_addr: int | None#
class ailment.IRSBConverter[source]#

Bases: Converter

static convert(irsb, manager)[source]#

Convert the given IRSB to an AIL block

Parameters:
  • irsb – The IRSB to convert

  • manager – The manager to use

Returns:

Returns the converted block

class ailment.AILBlockWalkerBase(stmt_handlers=None, expr_handlers=None)[source]#

Bases: object

Walks all statements and expressions of an AIL node and do nothing.

__init__(stmt_handlers=None, expr_handlers=None)[source]#
walk(block)[source]#
Parameters:

block (Block) –

walk_statement(stmt)[source]#
Parameters:

stmt (Statement) –

walk_expression(expr, stmt_idx=None, stmt=None, block=None)[source]#
Parameters:
  • expr (Expression) –

  • stmt_idx (int | None) –

  • stmt (int | None) –

  • block (Block | None) –

class ailment.AILBlockWalker(stmt_handlers=None, expr_handlers=None)[source]#

Bases: AILBlockWalkerBase

Walks all statements and expressions of an AIL node, and rebuilds expressions, statements, or blocks if needed.

If you need a pure walker without rebuilding, use AILBlockWalkerBase instead.

__init__(stmt_handlers=None, expr_handlers=None)[source]#

Converter#

exception ailment.converter_common.SkipConversionNotice[source]#

Bases: Exception

class ailment.converter_common.Converter[source]#

Bases: object

static convert(thing)[source]#

Expressions#

class ailment.expression.Expression(*args, **kwargs)[source]#

Bases: TaggedObject

The base class of all AIL expressions.

__init__(idx, depth, **kwargs)[source]#
depth#
has_atom(atom, identity=True)[source]#
likes(atom)[source]#
replace(old_expr, new_expr)[source]#
class ailment.expression.Atom(*args, **kwargs)[source]#

Bases: Expression

__init__(idx, variable, variable_offset=0, **kwargs)[source]#
variable#
variable_offset#
copy()[source]#
class ailment.expression.Const(*args, **kwargs)[source]#

Bases: Atom

__init__(idx, variable, value, bits, **kwargs)[source]#
value#
bits#
property size#
likes(other)[source]#
property sign_bit#
copy()[source]#
Return type:

Const

class ailment.expression.Tmp(*args, **kwargs)[source]#

Bases: Atom

__init__(idx, variable, tmp_idx, bits, **kwargs)[source]#
tmp_idx#
bits#
property size#
likes(other)[source]#
copy()[source]#
Return type:

Tmp

class ailment.expression.Register(*args, **kwargs)[source]#

Bases: Atom

__init__(idx, variable, reg_offset, bits, **kwargs)[source]#
reg_offset#
bits#
property size#
likes(atom)[source]#
copy()[source]#
Return type:

Register

class ailment.expression.Op(*args, **kwargs)[source]#

Bases: Expression

__init__(idx, depth, op, **kwargs)[source]#
op#
property verbose_op#
class ailment.expression.UnaryOp(*args, **kwargs)[source]#

Bases: Op

__init__(idx, op, operand, variable=None, variable_offset=None, **kwargs)[source]#
operand#
bits#
variable#
variable_offset#
likes(other)[source]#
replace(old_expr, new_expr)[source]#
property operands#
property size#
copy()[source]#
Return type:

UnaryOp

has_atom(atom, identity=True)[source]#
class ailment.expression.Convert(*args, **kwargs)[source]#

Bases: UnaryOp

TYPE_INT = 0#
TYPE_FP = 1#
__init__(idx, from_bits, to_bits, is_signed, operand, from_type=0, to_type=0, rounding_mode=None, **kwargs)[source]#
from_bits#
to_bits#
is_signed#
from_type#
to_type#
rounding_mode#
likes(other)[source]#
replace(old_expr, new_expr)[source]#
copy()[source]#
Return type:

Convert

class ailment.expression.Reinterpret(idx, from_bits, from_type, to_bits, to_type, operand, **kwargs)[source]#

Bases: UnaryOp

__init__(idx, from_bits, from_type, to_bits, to_type, operand, **kwargs)[source]#
Parameters:
  • from_bits (int) –

  • from_type (str) –

  • to_bits (int) –

  • to_type (str) –

from_bits#
from_type#
to_bits#
to_type#
likes(other)[source]#
replace(old_expr, new_expr)[source]#
copy()[source]#
Return type:

Reinterpret

class ailment.expression.BinaryOp(*args, **kwargs)[source]#

Bases: Op

OPSTR_MAP = {'Add': '+', 'AddF': '+', 'AddV': '+', 'And': '&', 'Carry': 'CARRY', 'CmpEQ': '==', 'CmpF': 'CmpF', 'CmpGE': '>=', 'CmpGEs': '>=s', 'CmpGT': '>', 'CmpGTs': '>s', 'CmpLE': '<=', 'CmpLEs': '<=s', 'CmpLT': '<', 'CmpLTs': '<s', 'CmpNE': '!=', 'Concat': 'CONCAT', 'Div': '/', 'DivF': '/', 'DivMod': '/m', 'LogicalAnd': '&&', 'LogicalOr': '||', 'Mod': '%', 'Mul': '*', 'MulF': '*', 'MulV': '*', 'Or': '|', 'Rol': 'ROL', 'Ror': 'ROR', 'SBorrow': 'SBORROW', 'SCarry': 'SCARRY', 'Sar': '>>a', 'Shl': '<<', 'Shr': '>>', 'Sub': '-', 'SubF': '-', 'Xor': '^'}#
COMPARISON_NEGATION = {'CmpEQ': 'CmpNE', 'CmpGE': 'CmpLT', 'CmpGEs': 'CmpLTs', 'CmpGT': 'CmpLE', 'CmpGTs': 'CmpLEs', 'CmpLE': 'CmpGT', 'CmpLEs': 'CmpGTs', 'CmpLT': 'CmpGE', 'CmpLTs': 'CmpGEs', 'CmpNE': 'CmpEQ'}#
__init__(idx, op, operands, signed, variable=None, variable_offset=None, bits=None, floating_point=False, rounding_mode=None, from_bits=None, to_bits=None, **kwargs)[source]#
operands#
bits#
signed#
variable#
variable_offset#
floating_point#
rounding_mode#
from_bits#
to_bits#
likes(other)[source]#
has_atom(atom, identity=True)[source]#
replace(old_expr, new_expr)[source]#
property verbose_op#
property size#
copy()[source]#
Return type:

BinaryOp

class ailment.expression.TernaryOp(*args, **kwargs)[source]#

Bases: Op

OPSTR_MAP = {}#
__init__(idx, op, operands, bits=None, **kwargs)[source]#
operands#
bits#
likes(other)[source]#
has_atom(atom, identity=True)[source]#
replace(old_expr, new_expr)[source]#
property verbose_op#
property size#
copy()[source]#
Return type:

TernaryOp

class ailment.expression.Load(*args, **kwargs)[source]#

Bases: Expression

__init__(idx, addr, size, endness, variable=None, variable_offset=None, guard=None, alt=None, **kwargs)[source]#
addr#
size#
endness#
guard#
alt#
variable#
variable_offset#
property bits#
has_atom(atom, identity=True)[source]#
replace(old_expr, new_expr)[source]#
likes(other)[source]#
copy()[source]#
Return type:

Load

class ailment.expression.ITE(*args, **kwargs)[source]#

Bases: Expression

__init__(idx, cond, iffalse, iftrue, variable=None, variable_offset=None, **kwargs)[source]#
cond#
iffalse#
iftrue#
bits#
variable#
variable_offset#
likes(atom)[source]#
has_atom(atom, identity=True)[source]#
replace(old_expr, new_expr)[source]#
property size#
copy()[source]#
Return type:

ITE

class ailment.expression.DirtyExpression(*args, **kwargs)[source]#

Bases: Expression

__init__(idx, dirty_expr, bits=None, **kwargs)[source]#
dirty_expr#
bits#
likes(other)[source]#
copy()[source]#
Return type:

DirtyExpression

replace(old_expr, new_expr)[source]#
property size#
class ailment.expression.VEXCCallExpression(*args, **kwargs)[source]#

Bases: Expression

__init__(idx, cee_name, operands, bits=None, **kwargs)[source]#
cee_name#
operands#
bits#
likes(other)[source]#
copy()[source]#
Return type:

VEXCCallExpression

replace(old_expr, new_expr)[source]#
property size#
class ailment.expression.MultiStatementExpression(idx, stmts, expr, **kwargs)[source]#

Bases: Expression

For representing comma-separated statements and expression in C.

__init__(idx, stmts, expr, **kwargs)[source]#
Parameters:
stmts#
expr#
likes(other)[source]#
property bits#
property size#
replace(old_expr, new_expr)[source]#
copy()[source]#
Return type:

MultiStatementExpression

class ailment.expression.BasePointerOffset(*args, **kwargs)[source]#

Bases: Expression

__init__(idx, bits, base, offset, variable=None, variable_offset=None, **kwargs)[source]#
bits#
base#
offset#
variable#
variable_offset#
property size#
likes(other)[source]#
replace(old_expr, new_expr)[source]#
copy()[source]#
Return type:

BasePointerOffset

class ailment.expression.StackBaseOffset(*args, **kwargs)[source]#

Bases: BasePointerOffset

__init__(idx, bits, offset, **kwargs)[source]#
copy()[source]#
Return type:

StackBaseOffset

ailment.expression.negate(expr)[source]#
Return type:

Expression

Parameters:

expr (Expression) –

Statement#

class ailment.statement.Statement(*args, **kwargs)[source]#

Bases: TaggedObject

The base class of all AIL statements.

replace(old_expr, new_expr)[source]#
eq(expr0, expr1)[source]#
class ailment.statement.Assignment(*args, **kwargs)[source]#

Bases: Statement

Assignment statement: expr_a = expr_b

__init__(idx, dst, src, **kwargs)[source]#
dst#
src#
likes(other)[source]#
replace(old_expr, new_expr)[source]#
copy()[source]#
Return type:

Assignment

class ailment.statement.Store(*args, **kwargs)[source]#

Bases: Statement

Store statement: *addr = data

__init__(idx, addr, data, size, endness, guard=None, variable=None, offset=None, **kwargs)[source]#
addr#
data#
size#
endness#
variable#
guard#
offset#
likes(other)[source]#
replace(old_expr, new_expr)[source]#
copy()[source]#
Return type:

Store

class ailment.statement.Jump(idx, target, target_idx=None, **kwargs)[source]#

Bases: Statement

Jump statement: goto target

__init__(idx, target, target_idx=None, **kwargs)[source]#
Parameters:

target_idx (int | None) –

target#
target_idx#
likes(other)[source]#
property depth#
replace(old_expr, new_expr)[source]#
copy()[source]#
class ailment.statement.ConditionalJump(idx, condition, true_target, false_target, true_target_idx=None, false_target_idx=None, **kwargs)[source]#

Bases: Statement

if (cond) {true_target} else {false_target}

__init__(idx, condition, true_target, false_target, true_target_idx=None, false_target_idx=None, **kwargs)[source]#
Parameters:
  • true_target_idx (int | None) –

  • false_target_idx (int | None) –

condition#
true_target#
false_target#
true_target_idx#
false_target_idx#
likes(other)[source]#
replace(old_expr, new_expr)[source]#
copy()[source]#
Return type:

ConditionalJump

class ailment.statement.Call(idx, target, calling_convention=None, prototype=None, args=None, ret_expr=None, fp_ret_expr=None, **kwargs)[source]#

Bases: Expression, Statement

Call is both an expression and a statement. The return expression of a call is defined as the ret_expr if and only if the callee function has one return expression.

__init__(idx, target, calling_convention=None, prototype=None, args=None, ret_expr=None, fp_ret_expr=None, **kwargs)[source]#
Parameters:

calling_convention (SimCC | None) –

target#
calling_convention#
prototype#
args#
ret_expr#
fp_ret_expr#
likes(other)[source]#
property bits#
property size#
property verbose_op#
property op#
replace(old_expr, new_expr)[source]#
copy()[source]#
class ailment.statement.Return(*args, **kwargs)[source]#

Bases: Statement

Return statement: (return expr_a), (return)

__init__(idx, ret_exprs, **kwargs)[source]#
ret_exprs#
likes(other)[source]#
replace(old_expr, new_expr)[source]#
copy()[source]#
class ailment.statement.DirtyStatement(*args, **kwargs)[source]#

Bases: Statement

Wrapper around the original statement, which is usually not convertible (temporarily).

__init__(idx, dirty_stmt, **kwargs)[source]#
dirty_stmt#
copy()[source]#
Return type:

DirtyStatement

class ailment.statement.Label(idx, name, ins_addr, block_idx=None, **kwargs)[source]#

Bases: Statement

A dummy statement that indicates a label with a name.

__init__(idx, name, ins_addr, block_idx=None, **kwargs)[source]#
Parameters:
  • name (str) –

  • ins_addr (int) –

  • block_idx (int | None) –

name#
ins_addr#
block_idx#
likes(other)[source]#
Parameters:

other (Label) –

copy()[source]#
Return type:

Label

Misc. Things#

class ailment.block.Block(addr, original_size, statements=None, idx=None)[source]#

Bases: object

Describes an AIL block.

Parameters:

statements (List[Statement]) –

__init__(addr, original_size, statements=None, idx=None)[source]#
addr#
original_size#
statements: List[Statement]#
idx#
copy(statements=None)[source]#
dbg_repr(indent=0)[source]#
likes(other)[source]#
class ailment.manager.Manager(name=None, arch=None)[source]#

Bases: object

Parameters:

name (str | None) –

__init__(name=None, arch=None)[source]#
Parameters:

name (str | None) –

next_atom()[source]#
reset()[source]#
property ins_addr: int | None#
class ailment.tagged_object.TaggedObject(*args, **kwargs)[source]#

Bases: object

A class that takes arbitrary tags.

__init__(idx, **kwargs)[source]#
idx#
initialize_tags(tags)[source]#
property tags: Dict#
ailment.utils.get_bits(expr)[source]#
Return type:

Optional[int]

Parameters:

expr (int | Expression) –

ailment.utils.stable_hash(t)[source]#
Return type:

int

Parameters:

t (Tuple) –

ailment.utils.is_none_or_likeable(arg1, arg2, is_list=False)[source]#

Returns whether two things are both None or can like each other