# Copyright (c) 2015-2024 Vector 35 Inc
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to
# deal in the Software without restriction, including without limitation the
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
# sell copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
# IN THE SOFTWARE.
import ctypes
import struct
from typing import Generator, List, Optional, Dict, Union, Tuple, NewType, ClassVar, Set, Callable, Any, Iterator, overload
from dataclasses import dataclass
# Binary Ninja components
from .enums import LowLevelILOperation, LowLevelILFlagCondition, DataFlowQueryOption, FunctionGraphType, ILInstructionAttribute
from . import _binaryninjacore as core
from . import basicblock #required for LowLevelILBasicBlock
from . import function
from . import mediumlevelil
from . import highlevelil
from . import flowgraph
from . import variable
from . import binaryview
from . import architecture
from . import types
from . import deprecation
from .interaction import show_graph_report
from .commonil import (
BaseILInstruction, Constant, BinaryOperation, Tailcall, UnaryOperation, Comparison, SSA, Phi, FloatingPoint,
ControlFlow, Terminal, Syscall, Localcall, StackOperation, Return, Signed, Arithmetic, Carry, DoublePrecision,
Memory, Load, Store, RegisterStack, SetReg, Intrinsic
)
ExpressionIndex = NewType('ExpressionIndex', int)
InstructionIndex = NewType('InstructionIndex', int)
Index = Union[ExpressionIndex, InstructionIndex]
TokenList = List['function.InstructionTextToken']
InstructionOrExpression = Union['LowLevelILInstruction', Index]
ILRegisterType = Union[str, 'ILRegister', int]
LLILInstructionsType = Generator['LowLevelILInstruction', None, None]
OperandsType = Tuple[ExpressionIndex, ExpressionIndex, ExpressionIndex, ExpressionIndex]
LowLevelILOperandType = Union['LowLevelILOperationAndSize', 'ILRegister', 'ILFlag', 'ILIntrinsic', 'ILRegisterStack',
int, Dict[int, int], float, 'LowLevelILInstruction',
Dict['architecture.RegisterStackName', int], 'SSAFlag', 'SSARegister', 'SSARegisterStack',
'ILSemanticFlagClass', 'ILSemanticFlagGroup', 'LowLevelILFlagCondition', List[int],
List['LowLevelILInstruction'], List[Union['ILFlag', 'ILRegister']], List['SSARegister'],
List['SSARegisterStack'], List['SSAFlag'], List['SSARegisterOrFlag'], None]
ILInstructionAttributeSet = Union[Set[ILInstructionAttribute], List[ILInstructionAttribute]]
LowLevelILVisitorCallback = Callable[[str, LowLevelILOperandType, str, Optional['LowLevelILInstruction']], bool]
[docs]
class LowLevelILLabel:
def __init__(self, handle: Optional[core.BNLowLevelILLabel] = None):
if handle is None:
self.handle = (core.BNLowLevelILLabel * 1)()
core.BNLowLevelILInitLabel(self.handle)
else:
self.handle = handle
@property
def ref(self) -> bool:
return self.handle[0].ref
@ref.setter
def ref(self, value):
self.handle[0].ref = value
@property
def resolved(self) -> bool:
return self.handle[0].resolved
@property
def operand(self) -> InstructionIndex:
return InstructionIndex(self.handle[0].operand)
@operand.setter
def operand(self, value: InstructionIndex):
self.handle[0].operand = int(value)
[docs]
@dataclass(frozen=True)
class ILRegister:
arch: 'architecture.Architecture'
index: 'architecture.RegisterIndex'
def __repr__(self):
return f"<ILRegister: {self.name}>"
def __str__(self):
return self.name
def __int__(self):
return self.index
def __eq__(self, other: Union[str, 'ILRegister']):
if isinstance(other, str) and other in self.arch.regs:
index = self.arch.regs[architecture.RegisterName(other)].index
assert index is not None
other = ILRegister(self.arch, index)
elif not isinstance(other, self.__class__):
return NotImplemented
return (self.arch, self.index) == (other.arch, other.index)
@property
def info(self) -> 'architecture.RegisterInfo':
return self.arch.regs[self.name]
@property
def temp(self) -> bool:
return (self.index & 0x80000000) != 0
@property
def name(self) -> 'architecture.RegisterName':
if self.temp:
return architecture.RegisterName(f"temp{self.index & 0x7fffffff}")
else:
return architecture.RegisterName(self.arch.get_reg_name(self.index))
[docs]
@dataclass(frozen=True)
class ILRegisterStack:
arch: 'architecture.Architecture'
index: 'architecture.RegisterStackIndex'
def __repr__(self):
return f"<ILRegisterStack: {self.name}>"
def __str__(self):
return self.name
def __int__(self):
return self.index
@property
def info(self) -> 'architecture.RegisterStackInfo':
return self.arch.reg_stacks[self.name]
@property
def name(self) -> 'architecture.RegisterStackName':
return self.arch.get_reg_stack_name(self.index)
[docs]
@dataclass(frozen=True)
class ILFlag:
arch: 'architecture.Architecture'
index: 'architecture.FlagIndex'
def __repr__(self):
return f"<ILFlag: {self.name}>"
def __str__(self):
return self.name
def __int__(self):
return self.index
@property
def temp(self) -> bool:
return (self.index & 0x80000000) != 0
@property
def name(self) -> 'architecture.FlagName':
if self.temp:
return architecture.FlagName(f"cond:{(self.index & 0x7fffffff)}")
else:
return architecture.FlagName(self.arch.get_flag_name(self.index))
[docs]
@dataclass(frozen=True)
class ILSemanticFlagClass:
arch: 'architecture.Architecture'
index: 'architecture.SemanticClassIndex'
def __repr__(self):
return f"<ILSemanticFlagClass: {self.name}>"
def __str__(self):
return self.name
def __int__(self):
return self.index
@property
def name(self) -> 'architecture.SemanticClassName':
return self.arch.get_semantic_flag_class_name(self.index)
[docs]
@dataclass(frozen=True)
class ILSemanticFlagGroup:
arch: 'architecture.Architecture'
index: 'architecture.SemanticGroupIndex'
def __repr__(self):
return f"<ILSemanticFlagGroup: {self.name}>"
def __str__(self):
return self.name
def __int__(self):
return self.index
@property
def name(self) -> 'architecture.SemanticGroupName':
return self.arch.get_semantic_flag_group_name(self.index)
[docs]
@dataclass(frozen=True)
class ILIntrinsic:
arch: 'architecture.Architecture'
index: 'architecture.IntrinsicIndex'
def __repr__(self):
return f"<ILIntrinsic: {self.name} - {self.arch}>"
def __str__(self):
return self.name
@property
def name(self) -> 'architecture.IntrinsicName':
return self.arch.get_intrinsic_name(self.index)
@property
def inputs(self) -> List['architecture.IntrinsicInput']:
"""``inputs`` is only available if the IL intrinsic is an Architecture intrinsic """
return self.arch.intrinsics[self.name].inputs
@property
def outputs(self) -> List['types.Type']:
"""``outputs`` is only available if the IL intrinsic is an Architecture intrinsic """
return self.arch.intrinsics[self.name].outputs
[docs]
@dataclass(frozen=True)
class SSARegister:
reg: ILRegister
version: int
def __repr__(self):
return f"<SSARegister: {self.reg} version {self.version}>"
[docs]
@dataclass(frozen=True)
class SSARegisterStack:
reg_stack: ILRegisterStack
version: int
def __repr__(self):
return f"<SSARegisterStack: {self.reg_stack} version {self.version}>"
[docs]
@dataclass(frozen=True)
class SSAFlag:
flag: ILFlag
version: int
def __repr__(self):
return f"<SSAFlag {self.flag} version {self.version}>"
[docs]
@dataclass(frozen=True)
class SSARegisterOrFlag:
reg_or_flag: Union[ILRegister, ILFlag]
version: int
def __repr__(self):
return f"<SSARegisterOrFlag: {self.reg_or_flag} version {self.version}>"
[docs]
@dataclass(frozen=True)
class LowLevelILOperationAndSize:
operation: 'LowLevelILOperation'
size: int
def __repr__(self):
if self.size == 0:
return f"<LowLevelILOperationAndSize: {self.operation.name}>"
return f"<LowLevelILOperationAndSize: {self.operation.name} {self.size}>"
[docs]
@dataclass(frozen=True)
class CoreLowLevelILInstruction:
operation: LowLevelILOperation
attributes: int
size: int
flags: int
source_operand: ExpressionIndex
operands: OperandsType
address: int
[docs]
@classmethod
def from_BNLowLevelILInstruction(cls, instr: core.BNLowLevelILInstruction) -> 'CoreLowLevelILInstruction':
operands: OperandsType = (
ExpressionIndex(instr.operands[0]), ExpressionIndex(instr.operands[1]), ExpressionIndex(instr.operands[2]),
ExpressionIndex(instr.operands[3])
)
return cls(
LowLevelILOperation(instr.operation), instr.attributes, instr.size, instr.flags, instr.sourceOperand, operands, instr.address
)
[docs]
@dataclass(frozen=True)
class LowLevelILInstruction(BaseILInstruction):
"""
``class LowLevelILInstruction`` Low Level Intermediate Language Instructions are infinite length tree-based
instructions. Tree-based instructions use infix notation with the left hand operand being the destination operand.
Infix notation is thus more natural to read than other notations (e.g. x86 ``mov eax, 0`` vs. LLIL ``eax = 0``).
"""
function: 'LowLevelILFunction'
expr_index: ExpressionIndex
instr: CoreLowLevelILInstruction
instr_index: Optional[InstructionIndex]
# ILOperations is deprecated and will be removed in a future version once BNIL Graph no longer uses it
# Use the visit methods visit, visit_all, and visit_operands
ILOperations: ClassVar[Dict[LowLevelILOperation, List[Tuple[str, str]]]] = {
LowLevelILOperation.LLIL_NOP: [], LowLevelILOperation.LLIL_SET_REG: [("dest", "reg"), ("src", "expr")],
LowLevelILOperation.LLIL_SET_REG_SPLIT: [("hi", "reg"), ("lo", "reg"),
("src", "expr")], LowLevelILOperation.LLIL_SET_REG_STACK_REL: [
("stack", "reg_stack"), ("dest", "expr"), ("src", "expr")
], LowLevelILOperation.LLIL_REG_STACK_PUSH: [("stack", "reg_stack"),
("src", "expr")],
LowLevelILOperation.LLIL_SET_FLAG: [("dest", "flag"), ("src", "expr")], LowLevelILOperation.LLIL_LOAD: [
("src", "expr")
], LowLevelILOperation.LLIL_STORE: [("dest", "expr"),
("src", "expr")], LowLevelILOperation.LLIL_PUSH: [("src", "expr")],
LowLevelILOperation.LLIL_POP: [], LowLevelILOperation.LLIL_REG: [("src", "reg")],
LowLevelILOperation.LLIL_REG_SPLIT: [("hi", "reg"), ("lo", "reg")], LowLevelILOperation.LLIL_REG_STACK_REL: [
("stack", "reg_stack"), ("src", "expr")
], LowLevelILOperation.LLIL_REG_STACK_POP: [("stack", "reg_stack")],
LowLevelILOperation.LLIL_REG_STACK_FREE_REG: [("dest", "reg")], LowLevelILOperation.LLIL_REG_STACK_FREE_REL: [
("stack", "reg_stack"), ("dest", "expr")
], LowLevelILOperation.LLIL_CONST: [("constant", "int")], LowLevelILOperation.LLIL_CONST_PTR: [
("constant", "int")
], LowLevelILOperation.LLIL_EXTERN_PTR: [
("constant", "int"), ("offset", "int")
], LowLevelILOperation.LLIL_FLOAT_CONST: [("constant", "float")], LowLevelILOperation.LLIL_FLAG: [
("src", "flag")
], LowLevelILOperation.LLIL_FLAG_BIT: [("src", "flag"), ("bit", "int")], LowLevelILOperation.LLIL_ADD: [
("left", "expr"), ("right", "expr")
], LowLevelILOperation.LLIL_ADC: [
("left", "expr"), ("right", "expr"), ("carry", "expr")
], LowLevelILOperation.LLIL_SUB: [("left", "expr"), ("right", "expr")], LowLevelILOperation.LLIL_SBB: [
("left", "expr"), ("right", "expr"), ("carry", "expr")
], LowLevelILOperation.LLIL_AND: [("left", "expr"), ("right", "expr")], LowLevelILOperation.LLIL_OR: [
("left", "expr"), ("right", "expr")
], LowLevelILOperation.LLIL_XOR: [("left", "expr"), ("right", "expr")], LowLevelILOperation.LLIL_LSL: [
("left", "expr"), ("right", "expr")
], LowLevelILOperation.LLIL_LSR: [("left", "expr"), ("right", "expr")], LowLevelILOperation.LLIL_ASR: [
("left", "expr"), ("right", "expr")
], LowLevelILOperation.LLIL_ROL: [("left", "expr"), ("right", "expr")], LowLevelILOperation.LLIL_RLC: [
("left", "expr"), ("right", "expr"), ("carry", "expr")
], LowLevelILOperation.LLIL_ROR: [("left", "expr"), ("right", "expr")], LowLevelILOperation.LLIL_RRC: [
("left", "expr"), ("right", "expr"), ("carry", "expr")
], LowLevelILOperation.LLIL_MUL: [("left", "expr"), ("right", "expr")], LowLevelILOperation.LLIL_MULU_DP: [
("left", "expr"), ("right", "expr")
], LowLevelILOperation.LLIL_MULS_DP: [("left", "expr"), ("right", "expr")], LowLevelILOperation.LLIL_DIVU: [
("left", "expr"), ("right", "expr")
], LowLevelILOperation.LLIL_DIVU_DP: [("left", "expr"), ("right", "expr")], LowLevelILOperation.LLIL_DIVS: [
("left", "expr"), ("right", "expr")
], LowLevelILOperation.LLIL_DIVS_DP: [("left", "expr"), ("right", "expr")], LowLevelILOperation.LLIL_MODU: [
("left", "expr"), ("right", "expr")
], LowLevelILOperation.LLIL_MODU_DP: [("left", "expr"), ("right", "expr")], LowLevelILOperation.LLIL_MODS: [
("left", "expr"), ("right", "expr")
], LowLevelILOperation.LLIL_MODS_DP: [("left", "expr"), ("right", "expr")], LowLevelILOperation.LLIL_NEG: [
("src", "expr")
], LowLevelILOperation.LLIL_NOT: [("src", "expr")], LowLevelILOperation.LLIL_SX: [
("src", "expr")
], LowLevelILOperation.LLIL_ZX: [("src", "expr")], LowLevelILOperation.LLIL_LOW_PART: [
("src", "expr")
], LowLevelILOperation.LLIL_JUMP: [("dest", "expr")], LowLevelILOperation.LLIL_JUMP_TO: [
("dest", "expr"), ("targets", "target_map")
], LowLevelILOperation.LLIL_CALL: [("dest", "expr")], LowLevelILOperation.LLIL_CALL_STACK_ADJUST: [
("dest", "expr"), ("stack_adjustment", "int"), ("reg_stack_adjustments", "reg_stack_adjust")
], LowLevelILOperation.LLIL_TAILCALL: [("dest", "expr")], LowLevelILOperation.LLIL_RET: [
("dest", "expr")
], LowLevelILOperation.LLIL_NORET: [], LowLevelILOperation.LLIL_IF: [
("condition", "expr"), ("true", "int"), ("false", "int")
], LowLevelILOperation.LLIL_GOTO: [("dest", "int")], LowLevelILOperation.LLIL_FLAG_COND: [
("condition", "cond"), ("semantic_class", "sem_class")
], LowLevelILOperation.LLIL_FLAG_GROUP: [("semantic_group", "sem_group")], LowLevelILOperation.LLIL_CMP_E: [
("left", "expr"), ("right", "expr")
], LowLevelILOperation.LLIL_CMP_NE: [("left", "expr"), ("right", "expr")], LowLevelILOperation.LLIL_CMP_SLT: [
("left", "expr"), ("right", "expr")
], LowLevelILOperation.LLIL_CMP_ULT: [("left", "expr"), ("right", "expr")], LowLevelILOperation.LLIL_CMP_SLE: [
("left", "expr"), ("right", "expr")
], LowLevelILOperation.LLIL_CMP_ULE: [("left", "expr"), ("right", "expr")], LowLevelILOperation.LLIL_CMP_SGE: [
("left", "expr"), ("right", "expr")
], LowLevelILOperation.LLIL_CMP_UGE: [("left", "expr"), ("right", "expr")], LowLevelILOperation.LLIL_CMP_SGT: [
("left", "expr"), ("right", "expr")
], LowLevelILOperation.LLIL_CMP_UGT: [("left", "expr"), ("right", "expr")], LowLevelILOperation.LLIL_TEST_BIT: [
("left", "expr"), ("right", "expr")
], LowLevelILOperation.LLIL_BOOL_TO_INT: [("src", "expr")], LowLevelILOperation.LLIL_ADD_OVERFLOW: [
("left", "expr"), ("right", "expr")
], LowLevelILOperation.LLIL_SYSCALL: [], LowLevelILOperation.LLIL_INTRINSIC: [
("output", "reg_or_flag_list"), ("intrinsic", "intrinsic"), ("param", "expr")
], LowLevelILOperation.LLIL_INTRINSIC_SSA: [
("output", "reg_or_flag_ssa_list"), ("intrinsic", "intrinsic"), ("param", "expr")
], LowLevelILOperation.LLIL_MEMORY_INTRINSIC_OUTPUT_SSA: [
("dest_memory", "int"), ("output", "reg_ssa_list")
], LowLevelILOperation.LLIL_MEMORY_INTRINSIC_SSA: [
("output", "expr"), ("intrinsic", "intrinsic"), ("params", "expr_list"), ("src_memory", "int")
], LowLevelILOperation.LLIL_BP: [], LowLevelILOperation.LLIL_TRAP: [("vector", "int")],
LowLevelILOperation.LLIL_UNDEF: [], LowLevelILOperation.LLIL_UNIMPL: [], LowLevelILOperation.LLIL_UNIMPL_MEM: [
("src", "expr")
], LowLevelILOperation.LLIL_FADD: [("left", "expr"), ("right", "expr")], LowLevelILOperation.LLIL_FSUB: [
("left", "expr"), ("right", "expr")
], LowLevelILOperation.LLIL_FMUL: [("left", "expr"), ("right", "expr")], LowLevelILOperation.LLIL_FDIV: [
("left", "expr"), ("right", "expr")
], LowLevelILOperation.LLIL_FSQRT: [("src", "expr")], LowLevelILOperation.LLIL_FNEG: [
("src", "expr")
], LowLevelILOperation.LLIL_FABS: [("src", "expr")], LowLevelILOperation.LLIL_FLOAT_TO_INT: [
("src", "expr")
], LowLevelILOperation.LLIL_INT_TO_FLOAT: [("src", "expr")], LowLevelILOperation.LLIL_FLOAT_CONV: [
("src", "expr")
], LowLevelILOperation.LLIL_ROUND_TO_INT: [("src", "expr")], LowLevelILOperation.LLIL_FLOOR: [
("src", "expr")
], LowLevelILOperation.LLIL_CEIL: [("src", "expr")], LowLevelILOperation.LLIL_FTRUNC: [
("src", "expr")
], LowLevelILOperation.LLIL_FCMP_E: [("left", "expr"), ("right", "expr")], LowLevelILOperation.LLIL_FCMP_NE: [
("left", "expr"), ("right", "expr")
], LowLevelILOperation.LLIL_FCMP_LT: [("left", "expr"), ("right", "expr")], LowLevelILOperation.LLIL_FCMP_LE: [
("left", "expr"), ("right", "expr")
], LowLevelILOperation.LLIL_FCMP_GE: [("left", "expr"), ("right", "expr")], LowLevelILOperation.LLIL_FCMP_GT: [
("left", "expr"), ("right", "expr")
], LowLevelILOperation.LLIL_FCMP_O: [("left", "expr"), ("right", "expr")], LowLevelILOperation.LLIL_FCMP_UO: [
("left", "expr"), ("right", "expr")
], LowLevelILOperation.LLIL_SET_REG_SSA: [("dest", "reg_ssa"),
("src", "expr")], LowLevelILOperation.LLIL_SET_REG_SSA_PARTIAL: [
("full_reg", "reg_ssa"), ("dest", "reg"), ("src", "expr")
], LowLevelILOperation.LLIL_SET_REG_SPLIT_SSA: [
("hi", "expr"), ("lo", "expr"), ("src", "expr")
], LowLevelILOperation.LLIL_SET_REG_STACK_REL_SSA: [
("stack", "expr"), ("dest", "expr"), ("top", "expr"),
("src", "expr")
], LowLevelILOperation.LLIL_SET_REG_STACK_ABS_SSA: [
("stack", "expr"), ("dest", "reg"), ("src", "expr")
], LowLevelILOperation.LLIL_REG_SPLIT_DEST_SSA: [("dest", "reg_ssa")],
LowLevelILOperation.LLIL_REG_STACK_DEST_SSA: [
("src", "reg_stack_ssa_dest_and_src")
], LowLevelILOperation.LLIL_REG_SSA: [("src", "reg_ssa")], LowLevelILOperation.LLIL_REG_SSA_PARTIAL: [
("full_reg", "reg_ssa"), ("src", "reg")
], LowLevelILOperation.LLIL_REG_SPLIT_SSA: [("hi", "reg_ssa"),
("lo", "reg_ssa")], LowLevelILOperation.LLIL_REG_STACK_REL_SSA: [
("stack", "reg_stack_ssa"), ("src", "expr"), ("top", "expr")
], LowLevelILOperation.LLIL_REG_STACK_ABS_SSA: [
("stack", "reg_stack_ssa"), ("src", "reg")
], LowLevelILOperation.LLIL_REG_STACK_FREE_REL_SSA: [
("stack", "expr"), ("dest", "expr"), ("top", "expr")
], LowLevelILOperation.LLIL_REG_STACK_FREE_ABS_SSA: [
("stack", "expr"), ("dest", "reg")
], LowLevelILOperation.LLIL_SET_FLAG_SSA: [("dest", "flag_ssa"),
("src", "expr")],
LowLevelILOperation.LLIL_FLAG_SSA: [("src", "flag_ssa")], LowLevelILOperation.LLIL_FLAG_BIT_SSA: [
("src", "flag_ssa"), ("bit", "int")
], LowLevelILOperation.LLIL_CALL_SSA: [("output", "expr"), ("dest", "expr"), ("stack", "expr"),
("param", "expr")], LowLevelILOperation.LLIL_SYSCALL_SSA: [
("output", "expr"), ("stack", "expr"), ("param", "expr")
], LowLevelILOperation.LLIL_TAILCALL_SSA: [
("output", "expr"), ("dest", "expr"), ("stack", "expr"),
("param", "expr")
], LowLevelILOperation.LLIL_CALL_OUTPUT_SSA: [
("dest_memory", "int"), ("dest", "reg_ssa_list")
], LowLevelILOperation.LLIL_CALL_STACK_SSA: [("src", "reg_ssa"),
("src_memory", "int")],
LowLevelILOperation.LLIL_CALL_PARAM: [("src", "expr_list")],
LowLevelILOperation.LLIL_SEPARATE_PARAM_LIST_SSA: [("src", "expr_list")],
LowLevelILOperation.LLIL_SHARED_PARAM_SLOT_SSA: [("src", "expr_list")], LowLevelILOperation.LLIL_LOAD_SSA: [
("src", "expr"), ("src_memory", "int")
], LowLevelILOperation.LLIL_STORE_SSA: [("dest", "expr"), ("dest_memory", "int"), ("src_memory", "int"),
("src", "expr")], LowLevelILOperation.LLIL_REG_PHI: [
("dest", "reg_ssa"), ("src", "reg_ssa_list")
], LowLevelILOperation.LLIL_REG_STACK_PHI: [
("dest", "reg_stack_ssa"), ("src", "reg_stack_ssa_list")
], LowLevelILOperation.LLIL_FLAG_PHI: [
("dest", "flag_ssa"), ("src", "flag_ssa_list")
], LowLevelILOperation.LLIL_MEM_PHI: [("dest_memory", "int"),
("src_memory", "int_list")]
}
[docs]
@staticmethod
def show_llil_hierarchy():
"""
Opens a new tab showing the LLIL hierarchy which includes classes which can
easily be used with isinstance to match multiple types of IL instructions.
"""
graph = flowgraph.FlowGraph()
nodes = {}
for instruction in ILInstruction.values():
instruction.add_subgraph(graph, nodes)
show_graph_report("LLIL Class Hierarchy Graph", graph)
[docs]
@classmethod
def create(
cls, func: 'LowLevelILFunction', expr_index: ExpressionIndex, instr_index: Optional[InstructionIndex] = None
) -> 'LowLevelILInstruction':
assert func.arch is not None, "Attempted to create IL instruction with function missing an Architecture"
inst = core.BNGetLowLevelILByIndex(func.handle, expr_index)
assert inst is not None, "core.BNGetLowLevelILByIndex returned None"
core_inst = CoreLowLevelILInstruction.from_BNLowLevelILInstruction(inst)
return ILInstruction[core_inst.operation](func, expr_index, core_inst, instr_index) # type: ignore
def __str__(self):
tokens = self.tokens
if tokens is None:
return "invalid"
result = ""
for token in tokens:
result += token.text
return result
def __repr__(self):
return f"<{self.__class__.__name__}: {self}>"
def __eq__(self, other: 'LowLevelILInstruction') -> bool:
if not isinstance(other, LowLevelILInstruction):
return NotImplemented
return self.function == other.function and self.expr_index == other.expr_index
def __ne__(self, other: 'LowLevelILInstruction') -> bool:
if not isinstance(other, LowLevelILInstruction):
return NotImplemented
return not (self == other)
def __lt__(self, other: 'LowLevelILInstruction') -> bool:
if not isinstance(other, LowLevelILInstruction):
return NotImplemented
return self.function == other.function and self.expr_index < other.expr_index
def __le__(self, other: 'LowLevelILInstruction') -> bool:
if not isinstance(other, LowLevelILInstruction):
return NotImplemented
return self.function == other.function and self.expr_index <= other.expr_index
def __gt__(self, other: 'LowLevelILInstruction') -> bool:
if not isinstance(other, LowLevelILInstruction):
return NotImplemented
return self.function == other.function and self.expr_index > other.expr_index
def __ge__(self, other: 'LowLevelILInstruction') -> bool:
if not isinstance(other, LowLevelILInstruction):
return NotImplemented
return self.function == other.function and self.expr_index >= other.expr_index
def __hash__(self):
return hash((self.function, self.expr_index))
@property
def size(self) -> int:
return self.instr.size
@property
def address(self) -> int:
return self.instr.address
@property
def operation(self) -> LowLevelILOperation:
return self.instr.operation
@property
def source_operand(self) -> Optional[ExpressionIndex]:
return self.instr.source_operand
@property
def tokens(self) -> TokenList:
"""LLIL tokens (read-only)"""
# special case for those instructions that don't have tokens
if isinstance(self, (LowLevelILCallOutputSsa, LowLevelILCallParam, LowLevelILCallStackSsa, LowLevelILMemoryIntrinsicOutputSsa)):
return []
count = ctypes.c_ulonglong()
assert self.function.arch is not None, f"self.function.arch is None"
tokens = ctypes.POINTER(core.BNInstructionTextToken)()
result = core.BNGetLowLevelILExprText(
self.function.handle, self.function.arch.handle, self.expr_index, None, tokens, count
)
assert result, "core.BNGetLowLevelILExprText returned False"
try:
return function.InstructionTextToken._from_core_struct(tokens, count.value)
finally:
core.BNFreeInstructionText(tokens, count.value)
@property
def il_basic_block(self) -> 'LowLevelILBasicBlock':
"""IL basic block object containing this expression (read-only) (only available on finalized functions)"""
assert self.function.source_function is not None
view = self.function.source_function.view
core_block = core.BNGetLowLevelILBasicBlockForInstruction(self.function.handle, self.instr_index)
assert core_block is not None, "BNGetLowLevelILBasicBlockForInstruction returned None"
return LowLevelILBasicBlock(core_block, self.function, view)
@property
def ssa_form(self) -> 'LowLevelILInstruction':
"""SSA form of expression (read-only)"""
ssa_func = self.function.ssa_form
assert ssa_func is not None
return LowLevelILInstruction.create(
ssa_func, ExpressionIndex(core.BNGetLowLevelILSSAExprIndex(self.function.handle, self.expr_index)),
core.BNGetLowLevelILSSAInstructionIndex(self.function.handle, self.instr_index)
if self.instr_index is not None else None
)
@property
def non_ssa_form(self) -> 'LowLevelILInstruction':
"""Non-SSA form of expression (read-only)"""
non_ssa_function = self.function.non_ssa_form
assert non_ssa_function is not None
return LowLevelILInstruction.create(
non_ssa_function,
ExpressionIndex(core.BNGetLowLevelILNonSSAExprIndex(self.function.handle, self.expr_index)),
core.BNGetLowLevelILNonSSAInstructionIndex(self.function.handle, self.instr_index)
if self.instr_index is not None else None
)
@property
def medium_level_il(self) -> Optional['mediumlevelil.MediumLevelILInstruction']:
"""Gets the medium level IL expression corresponding to this expression (may be None for eliminated instructions)"""
expr = self.function.get_medium_level_il_expr_index(self.expr_index)
if expr is None:
return None
mlil_func = self.function.medium_level_il
assert mlil_func is not None, "self.function.medium_level_il is None"
return mediumlevelil.MediumLevelILInstruction.create(mlil_func, expr)
@property
def mlil(self) -> Optional['mediumlevelil.MediumLevelILInstruction']:
return self.medium_level_il
@property
def mlils(self) -> List['mediumlevelil.MediumLevelILInstruction']:
result = []
for expr in self.function.get_medium_level_il_expr_indexes(self.expr_index):
result.append(mediumlevelil.MediumLevelILInstruction.create(self.function.medium_level_il, expr))
return result
@property
def mapped_medium_level_il(self) -> Optional['mediumlevelil.MediumLevelILInstruction']:
"""Gets the mapped medium level IL expression corresponding to this expression"""
expr = self.function.get_mapped_medium_level_il_expr_index(self.expr_index)
if expr is None:
return None
return mediumlevelil.MediumLevelILInstruction.create(self.function.mapped_medium_level_il, expr)
@property
def mmlil(self) -> Optional['mediumlevelil.MediumLevelILInstruction']:
return self.mapped_medium_level_il
@property
def high_level_il(self) -> Optional['highlevelil.HighLevelILInstruction']:
"""Gets the high level IL expression corresponding to this expression (may be None for eliminated instructions)"""
if self.mlil is None:
return None
return self.mlil.hlil
@property
def hlil(self) -> Optional['highlevelil.HighLevelILInstruction']:
return self.high_level_il
@property
def hlils(self) -> List['highlevelil.HighLevelILInstruction']:
result = set()
for mlil_expr in self.mlils:
for hlil_expr in mlil_expr.hlils:
try:
result.add(hlil_expr)
except:
assert False, f"mlil_expr.hlils returned list of lists: {hlil_expr} {type(hlil_expr)}"
return list(result)
@property
def value(self) -> 'variable.RegisterValue':
"""Value of expression if constant or a known value (read-only)"""
value = core.BNGetLowLevelILExprValue(self.function.handle, self.expr_index)
return variable.RegisterValue.from_BNRegisterValue(value, self.function.arch)
@property
def possible_values(self) -> 'variable.PossibleValueSet':
"""Possible values of expression using path-sensitive static data flow analysis (read-only)"""
value = core.BNGetLowLevelILPossibleExprValues(self.function.handle, self.expr_index, None, 0)
result = variable.PossibleValueSet(self.function.arch, value)
core.BNFreePossibleValueSet(value)
return result
@property
def raw_operands(self) -> OperandsType:
"""Raw operand expression indices as specified by the core structure (read-only)"""
return self.instr.operands
@property
def operands(self) -> List[LowLevelILOperandType]:
"""
Operands for the instruction
Consider using more specific APIs for ``src``, ``dest``, ``params``, etc where appropriate.
"""
return list(map(lambda x: x[1], self.detailed_operands))
@property
def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
"""
Returns a list of tuples containing the name of the operand, the operand, and the type of the operand.
Useful for iterating over all operands of an instruction and sub-instructions.
"""
return []
[docs]
def traverse(self, cb: Callable[['LowLevelILInstruction', Any], Any], *args: Any, **kwargs: Any) -> Iterator[Any]:
"""
``traverse`` is a generator that allows you to traverse the LowLevelILInstruction in a depth-first manner. It will yield the
result of the callback function for each node in the tree. Arguments can be passed to the callback function using
``args`` and ``kwargs``. See the `Developer Docs <https://docs.binary.ninja/dev/concepts.html#walking-ils>`_ for more examples.
:param Callable[[LowLevelILInstruction, Any], Any] cb: The callback function to call for each node in the LowLevelILInstruction
:param Any args: Custom user-defined arguments
:param Any kwargs: Custom user-defined keyword arguments
:return: An iterator of the results of the callback function
:rtype: Iterator[Any]
:Example:
>>> def get_constant_less_than_value(inst: LowLevelILInstruction, value: int) -> int:
>>> if isinstance(inst, Constant) and inst.constant < value:
>>> return inst.constant
>>>
>>> list(inst.traverse(get_constant_less_than_value, 10))
"""
if (result := cb(self, *args, **kwargs)) is not None:
yield result
for _, op, _ in self.detailed_operands:
if isinstance(op, LowLevelILInstruction):
yield from op.traverse(cb, *args, **kwargs)
elif isinstance(op, list) and all(isinstance(i, LowLevelILInstruction) for i in op):
for i in op:
yield from i.traverse(cb, *args, **kwargs) # type: ignore
[docs]
@deprecation.deprecated(deprecated_in="4.0.4907", details="Use :py:func:`LowLevelILInstruction.traverse` instead.")
def visit_all(self, cb: LowLevelILVisitorCallback,
name: str = "root", parent: Optional['LowLevelILInstruction'] = None) -> bool:
"""
Visits all operands of this instruction and all operands of any sub-instructions.
Using pre-order traversal.
:param LowLevelILVisitorCallback cb: Callback function that takes the name of the operand, the operand, operand type, and parent instruction
:return: True if all instructions were visited, False if the callback returned False
"""
if cb(name, self, "LowLevelILInstruction", parent) == False:
return False
for name, op, opType in self.detailed_operands:
if isinstance(op, LowLevelILInstruction):
if not op.visit_all(cb, name, self):
return False
elif isinstance(op, list) and all(isinstance(i, LowLevelILInstruction) for i in op):
for i in op:
if not i.visit_all(cb, name, self): # type: ignore
return False
elif cb(name, op, opType, self) == False:
return False
return True
[docs]
@deprecation.deprecated(deprecated_in="4.0.4907", details="Use :py:func:`LowLevelILInstruction.traverse` instead.")
def visit_operands(self, cb: LowLevelILVisitorCallback,
name: str = "root", parent: Optional['LowLevelILInstruction'] = None) -> bool:
"""
Visits all leaf operands of this instruction and any sub-instructions.
:param LowLevelILVisitorCallback cb: Callback function that takes the name of the operand, the operand, operand type, and parent instruction
:return: True if all instructions were visited, False if the callback returned False
"""
for name, op, opType in self.detailed_operands:
if isinstance(op, LowLevelILInstruction):
if not op.visit_operands(cb, name, self):
return False
elif isinstance(op, list) and all(isinstance(i, LowLevelILInstruction) for i in op):
for i in op:
if not i.visit_operands(cb, name, self): # type: ignore
return False
elif cb(name, op, opType, self) == False:
return False
return True
[docs]
@deprecation.deprecated(deprecated_in="4.0.4907", details="Use :py:func:`LowLevelILInstruction.traverse` instead.")
def visit(self, cb: LowLevelILVisitorCallback,
name: str = "root", parent: Optional['LowLevelILInstruction'] = None) -> bool:
"""
Visits all LowLevelILInstructions in the operands of this instruction and any sub-instructions.
:param LowLevelILVisitorCallback cb: Callback function that takes the name of the operand, the operand, operand type, and parent instruction
:return: True if all instructions were visited, False if the callback returned False
"""
if cb(name, self, "LowLevelILInstruction", parent) == False:
return False
for name, op, opType in self.detailed_operands:
if isinstance(op, LowLevelILInstruction):
if not op.visit(cb, name, self):
return False
elif isinstance(op, list) and all(isinstance(i, LowLevelILInstruction) for i in op):
for i in op:
if not i.visit(cb, name, self): # type: ignore
return False
return True
@property
def prefix_operands(self) -> List[LowLevelILOperandType]:
"""All operands in the expression tree in prefix order"""
result: List[LowLevelILOperandType] = [LowLevelILOperationAndSize(self.instr.operation, self.instr.size)]
for operand in self.operands:
if isinstance(operand, LowLevelILInstruction):
assert id(self) != id(operand), f"circular reference {operand}({repr(operand)}) is {self}({repr(self)})"
result.extend(operand.prefix_operands)
else:
result.append(operand)
return result
@property
def postfix_operands(self) -> List[LowLevelILOperandType]:
"""All operands in the expression tree in postfix order"""
result: List[LowLevelILOperandType] = []
for operand in self.operands:
if isinstance(operand, LowLevelILInstruction):
assert id(self) != id(operand), f"circular reference {operand}({repr(operand)}) is {self}({repr(self)})"
result.extend(operand.postfix_operands)
else:
result.append(operand)
result.append(LowLevelILOperationAndSize(self.instr.operation, self.instr.size))
return result
@property
def attributes(self) -> Set[ILInstructionAttribute]:
"""The set of optional attributes placed on the instruction"""
result: Set[ILInstructionAttribute] = set()
for flag in ILInstructionAttribute:
if self.instr.attributes & flag.value != 0:
result.add(flag)
return result
@staticmethod
def _make_options_array(options: Optional[List[DataFlowQueryOption]]):
if options is None:
options = []
idx = 0
option_array = (ctypes.c_int * len(options))()
for option in options:
option_array[idx] = option
idx += 1
return option_array, len(options)
[docs]
def get_possible_values(self, options: Optional[List[DataFlowQueryOption]] = None) -> variable.PossibleValueSet:
option_array, option_size = LowLevelILInstruction._make_options_array(options)
value = core.BNGetLowLevelILPossibleExprValues(self.function.handle, self.expr_index, option_array, option_size)
result = variable.PossibleValueSet(self.function.arch, value)
core.BNFreePossibleValueSet(value)
return result
[docs]
def get_reg_value(self, reg: 'architecture.RegisterType') -> variable.RegisterValue:
if self.function.arch is None:
raise Exception("Can not call get_reg_value on function with Architecture set to None")
reg = self.function.arch.get_reg_index(reg)
value = core.BNGetLowLevelILRegisterValueAtInstruction(self.function.handle, reg, self.instr_index)
return variable.RegisterValue.from_BNRegisterValue(value, self.function.arch)
[docs]
def get_reg_value_after(self, reg: 'architecture.RegisterType') -> variable.RegisterValue:
if self.function.arch is None:
raise Exception("Can not call get_reg_value_after on function with Architecture set to None")
reg = self.function.arch.get_reg_index(reg)
value = core.BNGetLowLevelILRegisterValueAfterInstruction(self.function.handle, reg, self.instr_index)
return variable.RegisterValue.from_BNRegisterValue(value, self.function.arch)
[docs]
def get_possible_reg_values(
self, reg: 'architecture.RegisterType', options: Optional[List[DataFlowQueryOption]] = None
) -> 'variable.PossibleValueSet':
if self.function.arch is None:
raise Exception("Can not call get_possible_reg_values on function with Architecture set to None")
reg = self.function.arch.get_reg_index(reg)
option_array, option_size = LowLevelILInstruction._make_options_array(options)
value = core.BNGetLowLevelILPossibleRegisterValuesAtInstruction(
self.function.handle, reg, self.instr_index, option_array, option_size
)
result = variable.PossibleValueSet(self.function.arch, value)
core.BNFreePossibleValueSet(value)
return result
[docs]
def get_possible_reg_values_after(
self, reg: 'architecture.RegisterType', options: Optional[List[DataFlowQueryOption]] = None
) -> 'variable.PossibleValueSet':
if self.function.arch is None:
raise Exception("Can not call get_possible_reg_values_after on function with Architecture set to None")
reg = self.function.arch.get_reg_index(reg)
option_array, option_size = LowLevelILInstruction._make_options_array(options)
value = core.BNGetLowLevelILPossibleRegisterValuesAfterInstruction(
self.function.handle, reg, self.instr_index, option_array, option_size
)
result = variable.PossibleValueSet(self.function.arch, value)
core.BNFreePossibleValueSet(value)
return result
[docs]
def get_flag_value(self, flag: 'architecture.FlagType') -> 'variable.RegisterValue':
if self.function.arch is None:
raise Exception("Can not call get_flag_value on function with Architecture set to None")
flag = self.function.arch.get_flag_index(flag)
value = core.BNGetLowLevelILFlagValueAtInstruction(self.function.handle, flag, self.instr_index)
result = variable.RegisterValue.from_BNRegisterValue(value, self.function.arch)
return result
[docs]
def get_flag_value_after(self, flag: 'architecture.FlagType') -> 'variable.RegisterValue':
if self.function.arch is None:
raise Exception("Can not call get_flag_value_after on function with Architecture set to None")
flag = self.function.arch.get_flag_index(flag)
value = core.BNGetLowLevelILFlagValueAfterInstruction(self.function.handle, flag, self.instr_index)
result = variable.RegisterValue.from_BNRegisterValue(value, self.function.arch)
return result
[docs]
def get_possible_flag_values(
self, flag: 'architecture.FlagType', options: Optional[List[DataFlowQueryOption]] = None
) -> 'variable.PossibleValueSet':
if self.function.arch is None:
raise Exception("Can not call get_possible_flag_values on function with Architecture set to None")
flag = self.function.arch.get_flag_index(flag)
option_array, option_size = LowLevelILInstruction._make_options_array(options)
value = core.BNGetLowLevelILPossibleFlagValuesAtInstruction(
self.function.handle, flag, self.instr_index, option_array, option_size
)
result = variable.PossibleValueSet(self.function.arch, value)
core.BNFreePossibleValueSet(value)
return result
[docs]
def get_possible_flag_values_after(
self, flag: 'architecture.FlagType', options: Optional[List[DataFlowQueryOption]] = None
) -> 'variable.PossibleValueSet':
if self.function.arch is None:
raise Exception("Can not call get_possible_flag_values_after on function with Architecture set to None")
flag = self.function.arch.get_flag_index(flag)
option_array, option_size = LowLevelILInstruction._make_options_array(options)
value = core.BNGetLowLevelILPossibleFlagValuesAfterInstruction(
self.function.handle, flag, self.instr_index, option_array, option_size
)
result = variable.PossibleValueSet(self.function.arch, value)
core.BNFreePossibleValueSet(value)
return result
[docs]
def get_stack_contents(self, offset: int, size: int) -> 'variable.RegisterValue':
value = core.BNGetLowLevelILStackContentsAtInstruction(self.function.handle, offset, size, self.instr_index)
result = variable.RegisterValue.from_BNRegisterValue(value, self.function.arch)
return result
[docs]
def get_stack_contents_after(self, offset: int, size: int) -> 'variable.RegisterValue':
value = core.BNGetLowLevelILStackContentsAfterInstruction(self.function.handle, offset, size, self.instr_index)
result = variable.RegisterValue.from_BNRegisterValue(value, self.function.arch)
return result
[docs]
def get_possible_stack_contents(
self, offset: int, size: int, options: Optional[List[DataFlowQueryOption]] = None
) -> variable.PossibleValueSet:
option_array, option_size = LowLevelILInstruction._make_options_array(options)
value = core.BNGetLowLevelILPossibleStackContentsAtInstruction(
self.function.handle, offset, size, self.instr_index, option_array, option_size
)
result = variable.PossibleValueSet(self.function.arch, value)
core.BNFreePossibleValueSet(value)
return result
[docs]
def get_possible_stack_contents_after(
self, offset: int, size: int, options: Optional[List[DataFlowQueryOption]] = None
) -> variable.PossibleValueSet:
option_array, option_size = LowLevelILInstruction._make_options_array(options)
value = core.BNGetLowLevelILPossibleStackContentsAfterInstruction(
self.function.handle, offset, size, self.instr_index, option_array, option_size
)
result = variable.PossibleValueSet(self.function.arch, value)
core.BNFreePossibleValueSet(value)
return result
@property
def flags(self) -> Optional['architecture.FlagWriteTypeName']:
return self.function.arch.get_flag_write_type_name(architecture.FlagWriteTypeIndex(self.instr.flags))
def _get_reg(self, operand_index: int) -> ILRegister:
return ILRegister(self.function.arch, architecture.RegisterIndex(self.instr.operands[operand_index]))
def _get_flag(self, operand_index: int) -> ILFlag:
return ILFlag(self.function.arch, architecture.FlagIndex(self.instr.operands[operand_index]))
def _get_intrinsic(self, operand_index: int) -> ILIntrinsic:
return ILIntrinsic(self.function.arch, architecture.IntrinsicIndex(self.instr.operands[operand_index]))
def _get_reg_stack(self, operand_index: int) -> ILRegisterStack:
return ILRegisterStack(self.function.arch, architecture.RegisterStackIndex(self.instr.operands[operand_index]))
def _get_int(self, operand_index: int) -> int:
return (self.instr.operands[operand_index] & ((1 << 63) - 1)) - (self.instr.operands[operand_index] & (1 << 63))
def _get_target_map(self, operand_index: int) -> Dict[int, int]:
count = ctypes.c_ulonglong()
operand_list = core.BNLowLevelILGetOperandList(self.function.handle, self.expr_index, operand_index, count)
assert operand_list is not None, "core.BNLowLevelILGetOperandList returned None"
try:
value: Dict[int, int] = {}
for j in range(count.value // 2):
key = operand_list[j * 2]
target = operand_list[(j*2) + 1]
value[key] = target
return value
finally:
core.BNLowLevelILFreeOperandList(operand_list)
def _get_float(self, operand_index: int) -> Union[int, float]:
if self.instr.size == 4:
return struct.unpack("f", struct.pack("I", self.instr.operands[operand_index] & 0xffffffff))[0]
elif self.instr.size == 8:
return struct.unpack("d", struct.pack("Q", self.instr.operands[operand_index]))[0]
else:
return self.instr.operands[operand_index]
def _get_expr(self, operand_index: int) -> 'LowLevelILInstruction':
return LowLevelILInstruction.create(self.function, self.instr.operands[operand_index], self.instr_index)
def _get_reg_stack_adjust(self, operand_index: int) -> Dict['architecture.RegisterStackName', int]:
count = ctypes.c_ulonglong()
operand_list = core.BNLowLevelILGetOperandList(self.function.handle, self.expr_index, operand_index, count)
assert operand_list is not None, "core.BNLowLevelILGetOperandList returned None"
result: Dict['architecture.RegisterStackName', int] = {}
try:
for j in range(count.value // 2):
reg_stack = operand_list[j * 2]
adjust = operand_list[(j*2) + 1]
if adjust & 0x80000000:
adjust |= ~0x80000000
result[self.function.arch.get_reg_stack_name(reg_stack)] = adjust
return result
finally:
core.BNLowLevelILFreeOperandList(operand_list)
def _get_flag_ssa(self, operand_index1: int, operand_index2: int) -> SSAFlag:
return SSAFlag(
ILFlag(self.function.arch, architecture.FlagIndex(self.instr.operands[operand_index1])),
self.instr.operands[operand_index2]
)
def _get_reg_ssa(self, operand_index1: int, operand_index2: int) -> SSARegister:
return SSARegister(
ILRegister(self.function.arch, architecture.RegisterIndex(self.instr.operands[operand_index1])),
self.instr.operands[operand_index2]
)
def _get_reg_stack_ssa(self, operand_index1: int, operand_index2: int) -> SSARegisterStack:
reg_stack = ILRegisterStack(
self.function.arch, architecture.RegisterStackIndex(self.instr.operands[operand_index1])
)
return SSARegisterStack(reg_stack, self.instr.operands[operand_index2])
def _get_sem_class(self, operand_index: int) -> Optional[ILSemanticFlagClass]:
if self.instr.operands[operand_index] == 0:
return None
return ILSemanticFlagClass(
self.function.arch, architecture.SemanticClassIndex(self.instr.operands[operand_index])
)
def _get_sem_group(self, operand_index: int) -> ILSemanticFlagGroup:
return ILSemanticFlagGroup(
self.function.arch, architecture.SemanticGroupIndex(self.instr.operands[operand_index])
)
def _get_cond(self, operand_index: int) -> LowLevelILFlagCondition:
return LowLevelILFlagCondition(self.instr.operands[operand_index])
def _get_int_list(self, operand_index: int) -> List[int]:
count = ctypes.c_ulonglong()
operand_list = core.BNLowLevelILGetOperandList(self.function.handle, self.expr_index, operand_index, count)
assert operand_list is not None, "core.BNLowLevelILGetOperandList returned None"
result: List[int] = []
try:
for j in range(count.value):
result.append(operand_list[j])
return result
finally:
core.BNLowLevelILFreeOperandList(operand_list)
def _get_expr_list(self, operand_index: int) -> List['LowLevelILInstruction']:
count = ctypes.c_ulonglong()
operand_list = core.BNLowLevelILGetOperandList(self.function.handle, self.expr_index, operand_index, count)
assert operand_list is not None, "core.BNLowLevelILGetOperandList returned None"
result = []
try:
for j in range(count.value):
result.append(LowLevelILInstruction.create(self.function, operand_list[j], None))
return result
finally:
core.BNLowLevelILFreeOperandList(operand_list)
def _get_reg_or_flag_list(self, operand_index: int) -> List[Union[ILFlag, ILRegister]]:
count = ctypes.c_ulonglong()
operand_list = core.BNLowLevelILGetOperandList(self.function.handle, self.expr_index, operand_index, count)
assert operand_list is not None, "core.BNLowLevelILGetOperandList returned None"
result: List[Union[ILFlag, ILRegister]] = []
try:
for j in range(count.value):
if (operand_list[j] & (1 << 32)) != 0:
result.append(ILFlag(self.function.arch, operand_list[j] & 0xffffffff))
else:
result.append(ILRegister(self.function.arch, operand_list[j] & 0xffffffff))
return result
finally:
core.BNLowLevelILFreeOperandList(operand_list)
def _get_reg_ssa_list(self, operand_index: int) -> List[SSARegister]:
count = ctypes.c_ulonglong()
operand_list = core.BNLowLevelILGetOperandList(self.function.handle, self.expr_index, operand_index, count)
assert operand_list is not None, "core.BNLowLevelILGetOperandList returned None"
result = []
try:
for j in range(count.value // 2):
reg = operand_list[j * 2]
reg_version = operand_list[(j*2) + 1]
result.append(SSARegister(ILRegister(self.function.arch, reg), reg_version))
return result
finally:
core.BNLowLevelILFreeOperandList(operand_list)
def _get_reg_stack_ssa_list(self, operand_index: int) -> List[SSARegisterStack]:
count = ctypes.c_ulonglong()
operand_list = core.BNLowLevelILGetOperandList(self.function.handle, self.expr_index, operand_index, count)
assert operand_list is not None, "core.BNLowLevelILGetOperandList returned None"
result: List[SSARegisterStack] = []
try:
for j in range(count.value // 2):
reg_stack = operand_list[j * 2]
reg_version = operand_list[(j*2) + 1]
result.append(SSARegisterStack(ILRegisterStack(self.function.arch, reg_stack), reg_version))
return result
finally:
core.BNLowLevelILFreeOperandList(operand_list)
def _get_flag_ssa_list(self, operand_index: int) -> List[SSAFlag]:
count = ctypes.c_ulonglong()
operand_list = core.BNLowLevelILGetOperandList(self.function.handle, self.expr_index, operand_index, count)
assert operand_list is not None, "core.BNLowLevelILGetOperandList returned None"
try:
result: List[SSAFlag] = []
for j in range(count.value // 2):
flag = operand_list[j * 2]
flag_version = operand_list[(j*2) + 1]
result.append(SSAFlag(ILFlag(self.function.arch, flag), flag_version))
return result
finally:
core.BNLowLevelILFreeOperandList(operand_list)
def _get_reg_or_flag_ssa_list(self, operand_index: int) -> List[SSARegisterOrFlag]:
count = ctypes.c_ulonglong()
operand_list = core.BNLowLevelILGetOperandList(self.function.handle, self.expr_index, operand_index, count)
assert operand_list is not None, "core.BNLowLevelILGetOperandList returned None"
result: List[SSARegisterOrFlag] = []
try:
for j in range(count.value // 2):
if (operand_list[j * 2] & (1 << 32)) != 0:
reg_or_flag = ILFlag(self.function.arch, operand_list[j * 2] & 0xffffffff)
else:
reg_or_flag = ILRegister(self.function.arch, operand_list[j * 2] & 0xffffffff)
reg_version = operand_list[(j*2) + 1]
result.append(SSARegisterOrFlag(reg_or_flag, reg_version))
return result
finally:
core.BNLowLevelILFreeOperandList(operand_list)
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILBinaryBase(LowLevelILInstruction, BinaryOperation):
@property
def left(self) -> LowLevelILInstruction:
return self._get_expr(0)
@property
def right(self) -> LowLevelILInstruction:
return self._get_expr(1)
@property
def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
return [
("left", self.left, "LowLevelILInstruction"),
("right", self.right, "LowLevelILInstruction"),
]
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILComparisonBase(LowLevelILBinaryBase, Comparison):
pass
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILCarryBase(LowLevelILInstruction, Carry):
@property
def left(self) -> LowLevelILInstruction:
return self._get_expr(0)
@property
def right(self) -> LowLevelILInstruction:
return self._get_expr(1)
@property
def carry(self) -> LowLevelILInstruction:
return self._get_expr(2)
@property
def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
return [
("left", self.left, "LowLevelILInstruction"),
("right", self.right, "LowLevelILInstruction"),
("carry", self.carry, "LowLevelILInstruction"),
]
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILUnaryBase(LowLevelILInstruction, UnaryOperation):
@property
def src(self) -> LowLevelILInstruction:
return self._get_expr(0)
@property
def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
return [
("src", self.src, "LowLevelILInstruction"),
]
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILConstantBase(LowLevelILInstruction, Constant):
def __int__(self):
return self.constant
def __bool__(self):
return self.constant != 0
def __eq__(self, other: 'LowLevelILConstantBase'):
if not isinstance(other, self.__class__):
return NotImplemented
return self.constant == other.constant
def __ne__(self, other: 'LowLevelILConstantBase'):
if not isinstance(other, self.__class__):
return NotImplemented
return self.constant != other.constant
def __lt__(self, other: 'LowLevelILConstantBase'):
if not isinstance(other, self.__class__):
return NotImplemented
return self.constant < other.constant
def __gt__(self, other: 'LowLevelILConstantBase'):
if not isinstance(other, self.__class__):
return NotImplemented
return self.constant > other.constant
def __le__(self, other: 'LowLevelILConstantBase'):
if not isinstance(other, self.__class__):
return NotImplemented
return self.constant <= other.constant
def __ge__(self, other: 'LowLevelILConstantBase'):
if not isinstance(other, self.__class__):
return NotImplemented
return self.constant >= other.constant
def __hash__(self):
return LowLevelILInstruction.__hash__(self)
@property
def constant(self) -> int:
return self._get_int(0)
@property
def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
return [
("constant", self.constant, "int"),
]
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILNop(LowLevelILInstruction):
pass
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILPop(LowLevelILInstruction, StackOperation):
pass
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILNoret(LowLevelILInstruction, Terminal):
pass
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILSyscall(LowLevelILInstruction, Syscall):
pass
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILBp(LowLevelILInstruction, Terminal):
pass
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILUndef(LowLevelILInstruction, Terminal):
pass
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILUnimpl(LowLevelILInstruction):
pass
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILNeg(LowLevelILUnaryBase, Arithmetic):
pass
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILNot(LowLevelILUnaryBase, Arithmetic):
pass
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILSx(LowLevelILUnaryBase, Arithmetic):
pass
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILZx(LowLevelILUnaryBase, Arithmetic):
pass
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILLowPart(LowLevelILUnaryBase, Arithmetic):
pass
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILJump(LowLevelILInstruction, Terminal):
@property
def dest(self) -> LowLevelILInstruction:
return self._get_expr(0)
@property
def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
return [
("dest", self.dest, "LowLevelILInstruction"),
]
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILCall(LowLevelILInstruction, Localcall):
@property
def dest(self) -> LowLevelILInstruction:
return self._get_expr(0)
@property
def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
return [
("dest", self.dest, "LowLevelILInstruction"),
]
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILTailcall(LowLevelILInstruction, Tailcall):
@property
def dest(self) -> LowLevelILInstruction:
return self._get_expr(0)
@property
def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
return [
("dest", self.dest, "LowLevelILInstruction"),
]
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILRet(LowLevelILInstruction, Return):
@property
def dest(self) -> LowLevelILInstruction:
return self._get_expr(0)
@property
def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
return [
("dest", self.dest, "LowLevelILInstruction"),
]
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILUnimplMem(LowLevelILInstruction, Memory):
@property
def src(self) -> LowLevelILInstruction:
return self._get_expr(0)
@property
def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
return [
("src", self.src, "LowLevelILInstruction"),
]
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILFsqrt(LowLevelILInstruction, FloatingPoint, Arithmetic):
@property
def src(self) -> LowLevelILInstruction:
return self._get_expr(0)
@property
def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
return [
("src", self.src, "LowLevelILInstruction"),
]
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILFneg(LowLevelILInstruction, FloatingPoint, Arithmetic):
@property
def src(self) -> LowLevelILInstruction:
return self._get_expr(0)
@property
def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
return [
("src", self.src, "LowLevelILInstruction"),
]
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILFabs(LowLevelILInstruction, FloatingPoint, Arithmetic):
@property
def src(self) -> LowLevelILInstruction:
return self._get_expr(0)
@property
def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
return [
("src", self.src, "LowLevelILInstruction"),
]
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILFloatToInt(LowLevelILInstruction, FloatingPoint, Arithmetic):
@property
def src(self) -> LowLevelILInstruction:
return self._get_expr(0)
@property
def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
return [
("src", self.src, "LowLevelILInstruction"),
]
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILIntToFloat(LowLevelILInstruction, FloatingPoint, Arithmetic):
@property
def src(self) -> LowLevelILInstruction:
return self._get_expr(0)
@property
def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
return [
("src", self.src, "LowLevelILInstruction"),
]
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILFloatConv(LowLevelILInstruction, FloatingPoint, Arithmetic):
@property
def src(self) -> LowLevelILInstruction:
return self._get_expr(0)
@property
def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
return [
("src", self.src, "LowLevelILInstruction"),
]
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILRoundToInt(LowLevelILInstruction, FloatingPoint, Arithmetic):
@property
def src(self) -> LowLevelILInstruction:
return self._get_expr(0)
@property
def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
return [
("src", self.src, "LowLevelILInstruction"),
]
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILFloor(LowLevelILInstruction, FloatingPoint, Arithmetic):
@property
def src(self) -> LowLevelILInstruction:
return self._get_expr(0)
@property
def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
return [
("src", self.src, "LowLevelILInstruction"),
]
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILCeil(LowLevelILInstruction, FloatingPoint, Arithmetic):
@property
def src(self) -> LowLevelILInstruction:
return self._get_expr(0)
@property
def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
return [
("src", self.src, "LowLevelILInstruction"),
]
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILFtrunc(LowLevelILInstruction, FloatingPoint, Arithmetic):
@property
def src(self) -> LowLevelILInstruction:
return self._get_expr(0)
@property
def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
return [
("src", self.src, "LowLevelILInstruction"),
]
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILLoad(LowLevelILInstruction, Load):
@property
def src(self) -> LowLevelILInstruction:
return self._get_expr(0)
@property
def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
return [
("src", self.src, "LowLevelILInstruction"),
]
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILPush(LowLevelILInstruction, StackOperation):
@property
def src(self) -> LowLevelILInstruction:
return self._get_expr(0)
@property
def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
return [
("src", self.src, "LowLevelILInstruction"),
]
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILReg(LowLevelILInstruction):
@property
def src(self) -> ILRegister:
return self._get_reg(0)
@property
def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
return [
("src", self.src, "ILRegister"),
]
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILRegStackPop(LowLevelILInstruction, RegisterStack):
@property
def stack(self) -> ILRegisterStack:
return self._get_reg_stack(0)
@property
def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
return [
("stack", self.stack, "ILRegisterStack"),
]
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILRegStackFreeReg(LowLevelILInstruction, RegisterStack):
@property
def dest(self) -> ILRegister:
return self._get_reg(0)
@property
def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
return [
("dest", self.dest, "ILRegister"),
]
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILConst(LowLevelILConstantBase):
pass
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILConstPtr(LowLevelILConstantBase):
pass
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILFloatConst(LowLevelILConstantBase, FloatingPoint):
@property
def constant(self) -> Union[int, float]:
return self._get_float(0)
@property
def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
return [
("constant", self.constant, "Union[int, float]"),
]
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILFlag(LowLevelILInstruction):
@property
def src(self) -> ILFlag:
return self._get_flag(0)
@property
def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
return [
("src", self.src, "ILFlag"),
]
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILGoto(LowLevelILInstruction, Terminal):
@property
def dest(self) -> int:
return self._get_int(0)
@property
def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
return [
("dest", self.dest, "int"),
]
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILFlagGroup(LowLevelILInstruction):
@property
def semantic_group(self) -> ILSemanticFlagGroup:
return self._get_sem_group(0)
@property
def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
return [
("semantic_group", self.semantic_group, "ILSemanticFlagGroup"),
]
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILBoolToInt(LowLevelILInstruction):
@property
def src(self) -> LowLevelILInstruction:
return self._get_expr(0)
@property
def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
return [
("src", self.src, "LowLevelILInstruction"),
]
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILTrap(LowLevelILInstruction, Terminal):
@property
def vector(self) -> int:
return self._get_int(0)
@property
def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
return [
("vector", self.vector, "int"),
]
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILRegSplitDestSsa(LowLevelILInstruction, SSA):
@property
def dest(self) -> SSARegister:
return self._get_reg_ssa(0, 1)
@property
def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
return [
("dest", self.dest, "SSARegister"),
]
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILRegStackDestSsa(LowLevelILInstruction, RegisterStack, SSA):
@property
def dest(self) -> SSARegisterStack:
return self._get_reg_stack_ssa(0, 1)
@property
def src(self) -> SSARegisterStack:
return self._get_reg_stack_ssa(0, 2)
@property
def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
return [
("dest", self.dest, "SSARegisterStack"),
("src", self.src, "SSARegisterStack"),
]
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILRegSsa(LowLevelILInstruction, SSA):
@property
def src(self) -> SSARegister:
return self._get_reg_ssa(0, 1)
@property
def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
return [
("src", self.src, "SSARegister"),
]
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILFlagSsa(LowLevelILInstruction, SSA):
@property
def src(self) -> SSAFlag:
return self._get_flag_ssa(0, 1)
@property
def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
return [
("src", self.src, "SSAFlag"),
]
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILCallParam(LowLevelILInstruction, SSA):
def __repr__(self):
return f"<LowLevelILCallParam: {self.src}>"
def __str__(self):
return str(self.src)
@property
def src(self) -> List['LowLevelILInstruction']:
return self._get_expr_list(0)
@property
def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
return [
("src", self.src, "List[LowLevelILInstruction]"),
]
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILSeparateParamListSsa(LowLevelILInstruction, SSA):
def __repr__(self):
return f"<LowLevelILSeparateParamListSsa: {self.src}>"
def __str__(self):
return str(self.src)
@property
def src(self) -> List['LowLevelILInstruction']:
return self._get_expr_list(0)
@property
def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
return [
("src", self.src, "List[LowLevelILInstruction]"),
]
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILSharedParamSlotSsa(LowLevelILInstruction, SSA):
def __repr__(self):
return f"<LowLevelILSharedParamSlotSsa: {self.src}>"
def __str__(self):
return str(self.src)
@property
def src(self) -> List['LowLevelILInstruction']:
return self._get_expr_list(0)
@property
def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
return [
("src", self.src, "List[LowLevelILInstruction]"),
]
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILMemPhi(LowLevelILInstruction, Memory, Phi):
@property
def dest_memory(self) -> int:
return self._get_int(0)
@property
def src_memory(self) -> List[int]:
return self._get_int_list(1)
@property
def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
return [
("dest_memory", self.dest_memory, "int"),
("src_memory", self.src_memory, "List[int]"),
]
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILSetReg(LowLevelILInstruction, SetReg):
@property
def dest(self) -> ILRegister:
return self._get_reg(0)
@property
def src(self) -> LowLevelILInstruction:
return self._get_expr(1)
@property
def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
return [
("dest", self.dest, "ILRegister"),
("src", self.src, "LowLevelILInstruction"),
]
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILRegStackPush(LowLevelILInstruction, RegisterStack):
@property
def stack(self) -> ILRegisterStack:
return self._get_reg_stack(0)
@property
def src(self) -> LowLevelILInstruction:
return self._get_expr(1)
@property
def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
return [
("stack", self.stack, "ILRegisterStack"),
("src", self.src, "LowLevelILInstruction"),
]
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILSetFlag(LowLevelILInstruction):
@property
def dest(self) -> ILFlag:
return self._get_flag(0)
@property
def src(self) -> LowLevelILInstruction:
return self._get_expr(1)
@property
def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
return [
("dest", self.dest, "ILFlag"),
("src", self.src, "LowLevelILInstruction"),
]
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILStore(LowLevelILInstruction, Store):
@property
def dest(self) -> LowLevelILInstruction:
return self._get_expr(0)
@property
def src(self) -> LowLevelILInstruction:
return self._get_expr(1)
@property
def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
return [
("dest", self.dest, "LowLevelILInstruction"),
("src", self.src, "LowLevelILInstruction"),
]
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILRegSplit(LowLevelILInstruction):
@property
def hi(self) -> ILRegister:
return self._get_reg(0)
@property
def lo(self) -> ILRegister:
return self._get_reg(1)
@property
def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
return [
("hi", self.hi, "ILRegister"),
("lo", self.lo, "ILRegister"),
]
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILRegStackRel(LowLevelILInstruction, RegisterStack):
@property
def stack(self) -> ILRegisterStack:
return self._get_reg_stack(0)
@property
def src(self) -> LowLevelILInstruction:
return self._get_expr(1)
@property
def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
return [
("stack", self.stack, "ILRegisterStack"),
("src", self.src, "LowLevelILInstruction"),
]
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILRegStackFreeRel(LowLevelILInstruction, RegisterStack):
@property
def stack(self) -> ILRegisterStack:
return self._get_reg_stack(0)
@property
def dest(self) -> LowLevelILInstruction:
return self._get_expr(1)
@property
def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
return [
("stack", self.stack, "ILRegisterStack"),
("dest", self.dest, "LowLevelILInstruction"),
]
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILExternPtr(LowLevelILConstantBase):
@property
def constant(self) -> int:
return self._get_int(0)
@property
def offset(self) -> int:
return self._get_int(1)
@property
def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
return [
("constant", self.constant, "int"),
("offset", self.offset, "int"),
]
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILFlagBit(LowLevelILInstruction):
@property
def src(self) -> ILFlag:
return self._get_flag(0)
@property
def bit(self) -> int:
return self._get_int(1)
@property
def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
return [
("src", self.src, "ILFlag"),
("bit", self.bit, "int"),
]
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILAdd(LowLevelILBinaryBase, Arithmetic):
pass
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILSub(LowLevelILBinaryBase, Arithmetic):
pass
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILAnd(LowLevelILBinaryBase, Arithmetic):
pass
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILOr(LowLevelILBinaryBase, Arithmetic):
pass
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILXor(LowLevelILBinaryBase, Arithmetic):
pass
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILLsl(LowLevelILBinaryBase, Arithmetic):
pass
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILLsr(LowLevelILBinaryBase, Arithmetic):
pass
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILAsr(LowLevelILBinaryBase, Arithmetic):
pass
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILRol(LowLevelILBinaryBase, Arithmetic):
pass
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILRor(LowLevelILBinaryBase, Arithmetic):
pass
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILMul(LowLevelILBinaryBase, Arithmetic):
pass
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILMuluDp(LowLevelILBinaryBase, DoublePrecision):
pass
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILMulsDp(LowLevelILBinaryBase, DoublePrecision):
pass
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILDivu(LowLevelILBinaryBase, Arithmetic):
pass
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILDivuDp(LowLevelILBinaryBase, DoublePrecision):
pass
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILDivs(LowLevelILBinaryBase, Arithmetic, Signed):
pass
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILDivsDp(LowLevelILBinaryBase, DoublePrecision, Signed):
pass
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILModu(LowLevelILBinaryBase, Arithmetic):
pass
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILModuDp(LowLevelILBinaryBase, DoublePrecision):
pass
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILMods(LowLevelILBinaryBase, Arithmetic, Signed):
pass
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILModsDp(LowLevelILBinaryBase, DoublePrecision, Signed):
pass
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILCmpE(LowLevelILComparisonBase):
pass
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILCmpNe(LowLevelILComparisonBase):
pass
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILCmpSlt(LowLevelILComparisonBase, Signed):
pass
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILCmpUlt(LowLevelILComparisonBase):
pass
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILCmpSle(LowLevelILComparisonBase, Signed):
pass
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILCmpUle(LowLevelILComparisonBase):
pass
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILCmpSge(LowLevelILComparisonBase, Signed):
pass
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILCmpUge(LowLevelILComparisonBase):
pass
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILCmpSgt(LowLevelILComparisonBase, Signed):
pass
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILCmpUgt(LowLevelILComparisonBase):
pass
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILTestBit(LowLevelILBinaryBase, Arithmetic, FloatingPoint):
pass
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILFadd(LowLevelILBinaryBase, Arithmetic, FloatingPoint):
pass
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILFsub(LowLevelILBinaryBase, Arithmetic, FloatingPoint):
pass
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILFmul(LowLevelILBinaryBase, Arithmetic, FloatingPoint):
pass
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILFdiv(LowLevelILBinaryBase, Arithmetic, FloatingPoint):
pass
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILFcmpE(LowLevelILComparisonBase, FloatingPoint):
pass
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILFcmpNe(LowLevelILComparisonBase, FloatingPoint):
pass
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILFcmpLt(LowLevelILComparisonBase, FloatingPoint):
pass
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILFcmpLe(LowLevelILComparisonBase, FloatingPoint):
pass
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILFcmpGe(LowLevelILComparisonBase, FloatingPoint):
pass
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILFcmpGt(LowLevelILComparisonBase, FloatingPoint):
pass
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILFcmpO(LowLevelILComparisonBase, FloatingPoint):
pass
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILFcmpUo(LowLevelILComparisonBase, FloatingPoint):
pass
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILJumpTo(LowLevelILInstruction):
@property
def dest(self) -> LowLevelILInstruction:
return self._get_expr(0)
@property
def targets(self) -> Dict[int, int]:
return self._get_target_map(1)
@property
def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
return [
("dest", self.dest, "LowLevelILInstruction"),
("targets", self.targets, "Dict[int, int]"),
]
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILFlagCond(LowLevelILInstruction):
@property
def condition(self) -> LowLevelILFlagCondition:
return self._get_cond(0)
@property
def semantic_class(self) -> Optional[ILSemanticFlagClass]:
return self._get_sem_class(1)
@property
def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
return [
("condition", self.condition, "LowLevelILFlagCondition"),
("semantic_class", self.semantic_class, "Optional[ILSemanticFlagClass]"),
]
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILAddOverflow(LowLevelILBinaryBase, Arithmetic):
pass
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILSetRegSsa(LowLevelILInstruction, SetReg, SSA):
@property
def dest(self) -> SSARegister:
return self._get_reg_ssa(0, 1)
@property
def src(self) -> LowLevelILInstruction:
return self._get_expr(2)
@property
def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
return [
("dest", self.dest, "SSARegister"),
("src", self.src, "LowLevelILInstruction"),
]
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILRegSsaPartial(LowLevelILInstruction, SetReg, SSA):
@property
def full_reg(self) -> SSARegister:
return self._get_reg_ssa(0, 1)
@property
def src(self) -> ILRegister:
return self._get_reg(2)
@property
def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
return [
("full_reg", self.full_reg, "SSARegister"),
("src", self.src, "ILRegister"),
]
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILRegSplitSsa(LowLevelILInstruction, SetReg, SSA):
@property
def hi(self) -> SSARegister:
return self._get_reg_ssa(0, 1)
@property
def lo(self) -> SSARegister:
return self._get_reg_ssa(2, 3)
@property
def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
return [
("hi", self.hi, "SSARegister"),
("lo", self.lo, "SSARegister"),
]
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILRegStackAbsSsa(LowLevelILInstruction, RegisterStack, SSA):
@property
def stack(self) -> SSARegisterStack:
return self._get_reg_stack_ssa(0, 1)
@property
def src(self) -> ILRegister:
return self._get_reg(2)
@property
def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
return [
("stack", self.stack, "SSARegisterStack"),
("src", self.src, "ILRegister"),
]
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILRegStackFreeAbsSsa(LowLevelILInstruction, RegisterStack):
@property
def stack(self) -> LowLevelILInstruction:
return self._get_expr(0)
@property
def dest(self) -> ILRegister:
return self._get_reg(1)
@property
def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
return [
("stack", self.stack, "LowLevelILInstruction"),
("dest", self.dest, "ILRegister"),
]
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILSetFlagSsa(LowLevelILInstruction, SSA):
@property
def dest(self) -> SSAFlag:
return self._get_flag_ssa(0, 1)
@property
def src(self) -> LowLevelILInstruction:
return self._get_expr(2)
@property
def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
return [
("dest", self.dest, "SSAFlag"),
("src", self.src, "LowLevelILInstruction"),
]
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILFlagBitSsa(LowLevelILInstruction, SSA):
@property
def src(self) -> SSAFlag:
return self._get_flag_ssa(0, 1)
@property
def bit(self) -> int:
return self._get_int(2)
@property
def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
return [
("src", self.src, "SSAFlag"),
("bit", self.bit, "int"),
]
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILCallOutputSsa(LowLevelILInstruction, SSA):
def __repr__(self):
return f"<LowLevelILCallOutputSsa: {self.dest_memory} {self.dest}>"
@property
def dest_memory(self) -> int:
return self._get_int(0)
@property
def dest(self) -> List[SSARegister]:
return self._get_reg_ssa_list(1)
@property
def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
return [
("dest_memory", self.dest_memory, "int"),
("dest", self.dest, "List[SSARegister]"),
]
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILCallStackSsa(LowLevelILInstruction, SSA):
def __repr__(self):
return f"<LowLevelILCallStackSsa: {self.src} @ mem#{self.src_memory}>"
@property
def src(self) -> SSARegister:
return self._get_reg_ssa(0, 1)
@property
def src_memory(self) -> int:
return self._get_int(2)
@property
def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
return [
("src", self.src, "SSARegister"),
("src_memory", self.src_memory, "int"),
]
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILLoadSsa(LowLevelILInstruction, Load, SSA):
@property
def src(self) -> LowLevelILInstruction:
return self._get_expr(0)
@property
def src_memory(self) -> int:
return self._get_int(1)
@property
def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
return [
("src", self.src, "LowLevelILInstruction"),
("src_memory", self.src_memory, "int"),
]
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILRegPhi(LowLevelILInstruction, Phi):
@property
def dest(self) -> SSARegister:
return self._get_reg_ssa(0, 1)
@property
def src(self) -> List[SSARegister]:
return self._get_reg_ssa_list(2)
@property
def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
return [
("dest", self.dest, "SSARegister"),
("src", self.src, "List[SSARegister]"),
]
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILRegStackPhi(LowLevelILInstruction, RegisterStack, Phi):
@property
def dest(self) -> SSARegisterStack:
return self._get_reg_stack_ssa(0, 1)
@property
def src(self) -> List[SSARegisterStack]:
return self._get_reg_stack_ssa_list(2)
@property
def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
return [
("dest", self.dest, "SSARegisterStack"),
("src", self.src, "List[SSARegisterStack]"),
]
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILFlagPhi(LowLevelILInstruction, Phi):
@property
def dest(self) -> SSAFlag:
return self._get_flag_ssa(0, 1)
@property
def src(self) -> List[SSAFlag]:
return self._get_flag_ssa_list(2)
@property
def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
return [
("dest", self.dest, "SSAFlag"),
("src", self.src, "List[SSAFlag]"),
]
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILSetRegSplit(LowLevelILInstruction, SetReg):
@property
def hi(self) -> ILRegister:
return self._get_reg(0)
@property
def lo(self) -> ILRegister:
return self._get_reg(1)
@property
def src(self) -> LowLevelILInstruction:
return self._get_expr(2)
@property
def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
return [
("hi", self.hi, "ILRegister"),
("lo", self.lo, "ILRegister"),
("src", self.src, "LowLevelILInstruction"),
]
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILSetRegStackRel(LowLevelILInstruction, RegisterStack):
@property
def stack(self) -> ILRegisterStack:
return self._get_reg_stack(0)
@property
def dest(self) -> LowLevelILInstruction:
return self._get_expr(1)
@property
def src(self) -> LowLevelILInstruction:
return self._get_expr(2)
@property
def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
return [
("stack", self.stack, "ILRegisterStack"),
("dest", self.dest, "LowLevelILInstruction"),
("src", self.src, "LowLevelILInstruction"),
]
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILSbb(LowLevelILCarryBase):
pass
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILAdc(LowLevelILCarryBase):
pass
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILRlc(LowLevelILCarryBase):
pass
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILRrc(LowLevelILCarryBase):
pass
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILCallStackAdjust(LowLevelILInstruction, Localcall):
@property
def dest(self) -> LowLevelILInstruction:
return self._get_expr(0)
@property
def stack_adjustment(self) -> int:
return self._get_int(1)
@property
def reg_stack_adjustments(self) -> Dict['architecture.RegisterStackName', int]:
return self._get_reg_stack_adjust(2)
@property
def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
return [
("dest", self.dest, "LowLevelILInstruction"),
("stack_adjustment", self.stack_adjustment, "int"),
("reg_stack_adjustments", self.reg_stack_adjustments, "Dict[RegisterStackName, int]"),
]
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILIf(LowLevelILInstruction, ControlFlow):
@property
def condition(self) -> LowLevelILInstruction:
return self._get_expr(0)
@property
def true(self) -> int:
return self._get_int(1)
@property
def false(self) -> int:
return self._get_int(2)
@property
def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
return [
("condition", self.condition, "LowLevelILInstruction"),
("true", self.true, "int"),
("false", self.false, "int"),
]
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILIntrinsic(LowLevelILInstruction, Intrinsic):
@property
def output(self) -> List[Union[ILFlag, ILRegister]]:
return self._get_reg_or_flag_list(0)
@property
def intrinsic(self) -> ILIntrinsic:
return self._get_intrinsic(2)
@property
def param(self) -> LowLevelILCallParam:
# kept for backwards compatibility use 'params' instead
result = self._get_expr(3)
assert isinstance(result, LowLevelILCallParam)
return result
@property
def params(self) -> List['LowLevelILInstruction']:
result = self._get_expr(3)
assert isinstance(result, LowLevelILCallParam)
return result.src
@property
def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
return [
("output", self.output, "List[Union[ILFlag, ILRegister]]"),
("intrinsic", self.intrinsic, "ILIntrinsic"),
("params", self.params, "List['LowLevelILInstruction']"),
]
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILIntrinsicSsa(LowLevelILInstruction, SSA):
@property
def output(self) -> List[SSARegisterOrFlag]:
return self._get_reg_or_flag_ssa_list(0)
@property
def intrinsic(self) -> ILIntrinsic:
return self._get_intrinsic(2)
@property
def param(self) -> LowLevelILCallParam:
# kept for backwards compatibility use 'params' instead
result = self._get_expr(3)
assert isinstance(result, LowLevelILCallParam)
return result
@property
def params(self) -> List[LowLevelILInstruction]:
return self.param.src
@property
def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
return [
("output", self.output, "List[SSARegisterOrFlag]"),
("intrinsic", self.intrinsic, "ILIntrinsic"),
("params", self.params, "List[LowLevelILInstruction]"),
]
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILMemoryIntrinsicOutputSsa(LowLevelILInstruction, SSA):
def __repr__(self):
return f"<LowLevelILMemoryIntrinsicOutputSsa: {self.dest_memory} {self.output}>"
@property
def dest_memory(self) -> int:
return self._get_int(0)
@property
def output(self) -> List[SSARegisterOrFlag]:
return self._get_reg_or_flag_ssa_list(1)
@property
def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
return [
("dest_memory", self.dest_memory, "int"),
("output", self.output, "List[SSARegisterOrFlag]"),
]
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILMemoryIntrinsicSsa(LowLevelILInstruction, SSA):
@property
def output(self) -> List[SSARegisterOrFlag]:
inst = self._get_expr(0)
assert isinstance(inst, LowLevelILMemoryIntrinsicOutputSsa), "LowLevelILMemoryIntrinsicSsa expected LowLevelILMemoryIntrinsicOutputSsa as first operand"
return inst.output
@property
def dest_memory(self) -> int:
inst = self._get_expr(0)
assert isinstance(inst, LowLevelILMemoryIntrinsicOutputSsa), "LowLevelILMemoryIntrinsicSsa expected LowLevelILMemoryIntrinsicOutputSsa as first operand"
return inst.dest_memory
@property
def intrinsic(self) -> ILIntrinsic:
return self._get_intrinsic(1)
@property
def param(self) -> LowLevelILCallParam:
# kept for backwards compatibility use 'params' instead
result = self._get_expr(2)
assert isinstance(result, LowLevelILCallParam)
return result
@property
def params(self) -> List[LowLevelILInstruction]:
return self.param.src
@property
def src_memory(self) -> int:
return self._get_int(3)
@property
def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
return [
("output", self.output, "List[SSARegisterOrFlag]"),
("intrinsic", self.intrinsic, "ILIntrinsic"),
("params", self.params, "List[LowLevelILInstruction]"),
("dest_memory", self.dest_memory, "int"),
("src_memory", self.src_memory, "int"),
]
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILSetRegSsaPartial(LowLevelILInstruction, SetReg, SSA):
@property
def full_reg(self) -> SSARegister:
return self._get_reg_ssa(0, 1)
@property
def dest(self) -> ILRegister:
return self._get_reg(2)
@property
def src(self) -> LowLevelILInstruction:
return self._get_expr(3)
@property
def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
return [
("full_reg", self.full_reg, "SSARegister"),
("dest", self.dest, "ILRegister"),
("src", self.src, "LowLevelILInstruction"),
]
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILSetRegSplitSsa(LowLevelILInstruction, SetReg, SSA):
@property
def hi(self) -> LowLevelILInstruction:
return self._get_expr(0)
@property
def lo(self) -> LowLevelILInstruction:
return self._get_expr(1)
@property
def src(self) -> LowLevelILInstruction:
return self._get_expr(2)
@property
def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
return [
("hi", self.hi, "LowLevelILInstruction"),
("lo", self.lo, "LowLevelILInstruction"),
("src", self.src, "LowLevelILInstruction"),
]
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILSetRegStackAbsSsa(LowLevelILInstruction, RegisterStack, SSA):
@property
def stack(self) -> LowLevelILInstruction:
return self._get_expr(0)
@property
def dest(self) -> ILRegister:
return self._get_reg(1)
@property
def src(self) -> LowLevelILInstruction:
return self._get_expr(2)
@property
def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
return [
("stack", self.stack, "LowLevelILInstruction"),
("dest", self.dest, "ILRegister"),
("src", self.src, "LowLevelILInstruction"),
]
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILRegStackRelSsa(LowLevelILInstruction, RegisterStack, SSA):
@property
def stack(self) -> SSARegisterStack:
return self._get_reg_stack_ssa(0, 1)
@property
def src(self) -> LowLevelILInstruction:
return self._get_expr(2)
@property
def top(self) -> LowLevelILInstruction:
return self._get_expr(3)
@property
def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
return [
("stack", self.stack, "SSARegisterStack"),
("src", self.src, "LowLevelILInstruction"),
("top", self.top, "LowLevelILInstruction"),
]
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILRegStackFreeRelSsa(LowLevelILInstruction, RegisterStack, SSA):
@property
def stack(self) -> LowLevelILInstruction:
return self._get_expr(0)
@property
def dest(self) -> LowLevelILInstruction:
return self._get_expr(1)
@property
def top(self) -> LowLevelILInstruction:
return self._get_expr(2)
@property
def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
return [
("stack", self.stack, "LowLevelILInstruction"),
("dest", self.dest, "LowLevelILInstruction"),
("top", self.top, "LowLevelILInstruction"),
]
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILSyscallSsa(LowLevelILInstruction, Syscall, SSA):
@property
def output(self) -> List[SSARegister]:
inst = self._get_expr(0)
assert isinstance(inst, LowLevelILCallOutputSsa), "LowLevelILSyscallSsa return bad type for output"
return inst.dest
@property
def stack(self) -> LowLevelILCallStackSsa:
result = self._get_expr(1)
assert isinstance(result, LowLevelILCallStackSsa)
return result
@property
def stack_reg(self) -> SSARegister:
return self.stack.src
@property
def stack_memory(self) -> int:
return self.stack.src_memory
@property
def param(self) -> LowLevelILCallParam:
# kept for backwards compatibility use 'params' instead
result = self._get_expr(2)
assert isinstance(result, LowLevelILCallParam)
return result
@property
def params(self) -> List[LowLevelILInstruction]:
return self.param.src
@property
def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
return [
("output", self.output, "List[SSARegister]"),
("stack_reg", self.stack_reg, "SSARegister"),
("stack_memory", self.stack_memory, "int"),
("params", self.params, "List[LowLevelILInstruction]"),
]
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILSetRegStackRelSsa(LowLevelILInstruction, RegisterStack, SSA):
@property
def stack(self) -> LowLevelILInstruction:
return self._get_expr(0)
@property
def dest(self) -> LowLevelILInstruction:
return self._get_expr(1)
@property
def top(self) -> LowLevelILInstruction:
return self._get_expr(2)
@property
def src(self) -> LowLevelILInstruction:
return self._get_expr(3)
@property
def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
return [
("stack", self.stack, "LowLevelILInstruction"),
("dest", self.dest, "LowLevelILInstruction"),
("top", self.top, "LowLevelILInstruction"),
("src", self.src, "LowLevelILInstruction"),
]
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILCallSsa(LowLevelILInstruction, Localcall, SSA):
@property
def output(self) -> List[SSARegister]:
inst = self._get_expr(0)
assert isinstance(inst, LowLevelILCallOutputSsa), "LowLevelILCallSsa return bad type for output"
return inst.dest
@property
def dest(self) -> LowLevelILInstruction:
return self._get_expr(1)
@property
def stack(self) -> LowLevelILInstruction:
return self._get_expr(2)
@property
def param(self) -> LowLevelILCallParam:
# kept for backwards compatibility use 'params' instead
result = self._get_expr(3)
assert isinstance(result, LowLevelILCallParam)
return result
@property
def params(self) -> List[LowLevelILInstruction]:
return self.param.src
@property
def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
return [
("output", self.output, "List[SSARegister]"),
("dest", self.dest, "LowLevelILInstruction"),
("stack", self.stack, "LowLevelILInstruction"),
("params", self.params, "List[LowLevelILInstruction]"),
]
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILTailcallSsa(LowLevelILInstruction, Tailcall, SSA, Terminal):
@property
def output(self) -> List[SSARegister]:
inst = self._get_expr(0)
assert isinstance(inst, LowLevelILCallOutputSsa), "LowLevelILTailcallSsa return bad type for output"
return inst.dest
@property
def dest(self) -> LowLevelILInstruction:
return self._get_expr(1)
@property
def stack(self) -> LowLevelILInstruction:
return self._get_expr(2)
@property
def param(self) -> LowLevelILCallParam:
# kept for backwards compatibility use 'params' instead
result = self._get_expr(3)
assert isinstance(result, LowLevelILCallParam)
return result
@property
def params(self) -> List[LowLevelILInstruction]:
return self.param.src
@property
def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
return [
("output", self.output, "List[SSARegister]"),
("dest", self.dest, "LowLevelILInstruction"),
("stack", self.stack, "LowLevelILInstruction"),
("params", self.params, "List[LowLevelILInstruction]"),
]
[docs]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILStoreSsa(LowLevelILInstruction, Store, SSA):
@property
def dest(self) -> LowLevelILInstruction:
return self._get_expr(0)
@property
def dest_memory(self) -> int:
return self._get_int(1)
@property
def src_memory(self) -> int:
return self._get_int(2)
@property
def src(self) -> LowLevelILInstruction:
return self._get_expr(3)
@property
def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
return [
("dest", self.dest, "LowLevelILInstruction"),
("dest_memory", self.dest_memory, "int"),
("src_memory", self.src_memory, "int"),
("src", self.src, "LowLevelILInstruction"),
]
ILInstruction:Dict[LowLevelILOperation, LowLevelILInstruction] = { # type: ignore
LowLevelILOperation.LLIL_NOP: LowLevelILNop, # [],
LowLevelILOperation.LLIL_SET_REG: LowLevelILSetReg, # [("dest", "reg"), ("src", "expr")],
LowLevelILOperation.LLIL_SET_REG_SPLIT: LowLevelILSetRegSplit, # [("hi", "reg"), ("lo", "reg"), ("src", "expr")],
LowLevelILOperation.LLIL_SET_REG_STACK_REL: LowLevelILSetRegStackRel, # [("stack", "reg_stack"), ("dest", "expr"), ("src", "expr")],
LowLevelILOperation.LLIL_REG_STACK_PUSH: LowLevelILRegStackPush, # [("stack", "reg_stack"), ("src", "expr")],
LowLevelILOperation.LLIL_SET_FLAG: LowLevelILSetFlag, # [("dest", "flag"), ("src", "expr")],
LowLevelILOperation.LLIL_LOAD: LowLevelILLoad, # [("src", "expr")],
LowLevelILOperation.LLIL_STORE: LowLevelILStore, # [("dest", "expr"), ("src", "expr")],
LowLevelILOperation.LLIL_PUSH: LowLevelILPush, # [("src", "expr")],
LowLevelILOperation.LLIL_POP: LowLevelILPop, # [],
LowLevelILOperation.LLIL_REG: LowLevelILReg, # [("src", "reg")],
LowLevelILOperation.LLIL_REG_SPLIT: LowLevelILRegSplit, # [("hi", "reg"), ("lo", "reg")],
LowLevelILOperation.LLIL_REG_STACK_REL: LowLevelILRegStackRel, # [("stack", "reg_stack"), ("src", "expr")],
LowLevelILOperation.LLIL_REG_STACK_POP: LowLevelILRegStackPop, # [("stack", "reg_stack")],
LowLevelILOperation.LLIL_REG_STACK_FREE_REG: LowLevelILRegStackFreeReg, # [("dest", "reg")],
LowLevelILOperation.LLIL_REG_STACK_FREE_REL: LowLevelILRegStackFreeRel, # [("stack", "reg_stack"), ("dest", "expr")],
LowLevelILOperation.LLIL_CONST: LowLevelILConst, # [("constant", "int")],
LowLevelILOperation.LLIL_CONST_PTR: LowLevelILConstPtr, # [("constant", "int")],
LowLevelILOperation.LLIL_EXTERN_PTR: LowLevelILExternPtr, # [("constant", "int"), ("offset", "int")],
LowLevelILOperation.LLIL_FLOAT_CONST: LowLevelILFloatConst, # [("constant", "float")],
LowLevelILOperation.LLIL_FLAG: LowLevelILFlag, # [("src", "flag")],
LowLevelILOperation.LLIL_FLAG_BIT: LowLevelILFlagBit, # [("src", "flag"), ("bit", "int")],
LowLevelILOperation.LLIL_ADD: LowLevelILAdd, # [("left", "expr"), ("right", "expr")],
LowLevelILOperation.LLIL_ADC: LowLevelILAdc, # [("left", "expr"), ("right", "expr"), ("carry", "expr")],
LowLevelILOperation.LLIL_SUB: LowLevelILSub, # [("left", "expr"), ("right", "expr")],
LowLevelILOperation.LLIL_SBB: LowLevelILSbb, # [("left", "expr"), ("right", "expr"), ("carry", "expr")],
LowLevelILOperation.LLIL_AND: LowLevelILAnd, # [("left", "expr"), ("right", "expr")],
LowLevelILOperation.LLIL_OR: LowLevelILOr, # [("left", "expr"), ("right", "expr")],
LowLevelILOperation.LLIL_XOR: LowLevelILXor, # [("left", "expr"), ("right", "expr")],
LowLevelILOperation.LLIL_LSL: LowLevelILLsl, # [("left", "expr"), ("right", "expr")],
LowLevelILOperation.LLIL_LSR: LowLevelILLsr, # [("left", "expr"), ("right", "expr")],
LowLevelILOperation.LLIL_ASR: LowLevelILAsr, # [("left", "expr"), ("right", "expr")],
LowLevelILOperation.LLIL_ROL: LowLevelILRol, # [("left", "expr"), ("right", "expr")],
LowLevelILOperation.LLIL_RLC: LowLevelILRlc, # [("left", "expr"), ("right", "expr"), ("carry", "expr")],
LowLevelILOperation.LLIL_ROR: LowLevelILRor, # [("left", "expr"), ("right", "expr")],
LowLevelILOperation.LLIL_RRC: LowLevelILRrc, # [("left", "expr"), ("right", "expr"), ("carry", "expr")],
LowLevelILOperation.LLIL_MUL: LowLevelILMul, # [("left", "expr"), ("right", "expr")],
LowLevelILOperation.LLIL_MULU_DP: LowLevelILMuluDp, # [("left", "expr"), ("right", "expr")],
LowLevelILOperation.LLIL_MULS_DP: LowLevelILMulsDp, # [("left", "expr"), ("right", "expr")],
LowLevelILOperation.LLIL_DIVU: LowLevelILDivu, # [("left", "expr"), ("right", "expr")],
LowLevelILOperation.LLIL_DIVU_DP: LowLevelILDivuDp, # [("left", "expr"), ("right", "expr")],
LowLevelILOperation.LLIL_DIVS: LowLevelILDivs, # [("left", "expr"), ("right", "expr")],
LowLevelILOperation.LLIL_DIVS_DP: LowLevelILDivsDp, # [("left", "expr"), ("right", "expr")],
LowLevelILOperation.LLIL_MODU: LowLevelILModu, # [("left", "expr"), ("right", "expr")],
LowLevelILOperation.LLIL_MODU_DP: LowLevelILModuDp, # [("left", "expr"), ("right", "expr")],
LowLevelILOperation.LLIL_MODS: LowLevelILMods, # [("left", "expr"), ("right", "expr")],
LowLevelILOperation.LLIL_MODS_DP: LowLevelILModsDp, # [("left", "expr"), ("right", "expr")],
LowLevelILOperation.LLIL_NEG: LowLevelILNeg, # [("src", "expr")],
LowLevelILOperation.LLIL_NOT: LowLevelILNot, # [("src", "expr")],
LowLevelILOperation.LLIL_SX: LowLevelILSx, # [("src", "expr")],
LowLevelILOperation.LLIL_ZX: LowLevelILZx, # [("src", "expr")],
LowLevelILOperation.LLIL_LOW_PART: LowLevelILLowPart, # [("src", "expr")],
LowLevelILOperation.LLIL_JUMP: LowLevelILJump, # [("dest", "expr")],
LowLevelILOperation.LLIL_JUMP_TO: LowLevelILJumpTo, # [("dest", "expr"), ("targets", "target_map")],
LowLevelILOperation.LLIL_CALL: LowLevelILCall, # [("dest", "expr")],
LowLevelILOperation.LLIL_CALL_STACK_ADJUST: LowLevelILCallStackAdjust, # [("dest", "expr"), ("stack_adjustment", "int"), ("reg_stack_adjustments", "reg_stack_adjust")],
LowLevelILOperation.LLIL_TAILCALL: LowLevelILTailcall, # [("dest", "expr")],
LowLevelILOperation.LLIL_RET: LowLevelILRet, # [("dest", "expr")],
LowLevelILOperation.LLIL_NORET: LowLevelILNoret, # [],
LowLevelILOperation.LLIL_IF: LowLevelILIf, # [("condition", "expr"), ("true", "int"), ("false", "int")],
LowLevelILOperation.LLIL_GOTO: LowLevelILGoto, # [("dest", "int")],
LowLevelILOperation.LLIL_FLAG_COND: LowLevelILFlagCond, # [("condition", "cond"), ("semantic_class", "sem_class")],
LowLevelILOperation.LLIL_FLAG_GROUP: LowLevelILFlagGroup, # [("semantic_group", "sem_group")],
LowLevelILOperation.LLIL_CMP_E: LowLevelILCmpE, # [("left", "expr"), ("right", "expr")],
LowLevelILOperation.LLIL_CMP_NE: LowLevelILCmpNe, # [("left", "expr"), ("right", "expr")],
LowLevelILOperation.LLIL_CMP_SLT: LowLevelILCmpSlt, # [("left", "expr"), ("right", "expr")],
LowLevelILOperation.LLIL_CMP_ULT: LowLevelILCmpUlt, # [("left", "expr"), ("right", "expr")],
LowLevelILOperation.LLIL_CMP_SLE: LowLevelILCmpSle, # [("left", "expr"), ("right", "expr")],
LowLevelILOperation.LLIL_CMP_ULE: LowLevelILCmpUle, # [("left", "expr"), ("right", "expr")],
LowLevelILOperation.LLIL_CMP_SGE: LowLevelILCmpSge, # [("left", "expr"), ("right", "expr")],
LowLevelILOperation.LLIL_CMP_UGE: LowLevelILCmpUge, # [("left", "expr"), ("right", "expr")],
LowLevelILOperation.LLIL_CMP_SGT: LowLevelILCmpSgt, # [("left", "expr"), ("right", "expr")],
LowLevelILOperation.LLIL_CMP_UGT: LowLevelILCmpUgt, # [("left", "expr"), ("right", "expr")],
LowLevelILOperation.LLIL_TEST_BIT: LowLevelILTestBit, # [("left", "expr"), ("right", "expr")],
LowLevelILOperation.LLIL_BOOL_TO_INT: LowLevelILBoolToInt, # [("src", "expr")],
LowLevelILOperation.LLIL_ADD_OVERFLOW: LowLevelILAddOverflow, # [("left", "expr"), ("right", "expr")],
LowLevelILOperation.LLIL_SYSCALL: LowLevelILSyscall, # [],
LowLevelILOperation.LLIL_INTRINSIC: LowLevelILIntrinsic, # [("output", "reg_or_flag_list"), ("intrinsic", "intrinsic"), ("param", "expr")],
LowLevelILOperation.LLIL_INTRINSIC_SSA: LowLevelILIntrinsicSsa, # [("output", "reg_or_flag_ssa_list"), ("intrinsic", "intrinsic"), ("params", "expr_list")],
LowLevelILOperation.LLIL_MEMORY_INTRINSIC_OUTPUT_SSA: LowLevelILMemoryIntrinsicOutputSsa, # [("dest_memory", "int"), ("output", "reg_or_flag_ssa_list")],
LowLevelILOperation.LLIL_MEMORY_INTRINSIC_SSA: LowLevelILMemoryIntrinsicSsa, # [("output", "expr"), ("intrinsic", "intrinsic"), ("params", "expr_list"), ("src_memory", "int")],
LowLevelILOperation.LLIL_BP: LowLevelILBp, # [],
LowLevelILOperation.LLIL_TRAP: LowLevelILTrap, # [("vector", "int")],
LowLevelILOperation.LLIL_UNDEF: LowLevelILUndef, # [],
LowLevelILOperation.LLIL_UNIMPL: LowLevelILUnimpl, # [],
LowLevelILOperation.LLIL_UNIMPL_MEM: LowLevelILUnimplMem, # [("src", "expr")],
LowLevelILOperation.LLIL_FADD: LowLevelILFadd, # [("left", "expr"), ("right", "expr")],
LowLevelILOperation.LLIL_FSUB: LowLevelILFsub, # [("left", "expr"), ("right", "expr")],
LowLevelILOperation.LLIL_FMUL: LowLevelILFmul, # [("left", "expr"), ("right", "expr")],
LowLevelILOperation.LLIL_FDIV: LowLevelILFdiv, # [("left", "expr"), ("right", "expr")],
LowLevelILOperation.LLIL_FSQRT: LowLevelILFsqrt, # [("src", "expr")],
LowLevelILOperation.LLIL_FNEG: LowLevelILFneg, # [("src", "expr")],
LowLevelILOperation.LLIL_FABS: LowLevelILFabs, # [("src", "expr")],
LowLevelILOperation.LLIL_FLOAT_TO_INT: LowLevelILFloatToInt, # [("src", "expr")],
LowLevelILOperation.LLIL_INT_TO_FLOAT: LowLevelILIntToFloat, # [("src", "expr")],
LowLevelILOperation.LLIL_FLOAT_CONV: LowLevelILFloatConv, # [("src", "expr")],
LowLevelILOperation.LLIL_ROUND_TO_INT: LowLevelILRoundToInt, # [("src", "expr")],
LowLevelILOperation.LLIL_FLOOR: LowLevelILFloor, # [("src", "expr")],
LowLevelILOperation.LLIL_CEIL: LowLevelILCeil, # [("src", "expr")],
LowLevelILOperation.LLIL_FTRUNC: LowLevelILFtrunc, # [("src", "expr")],
LowLevelILOperation.LLIL_FCMP_E: LowLevelILFcmpE, # [("left", "expr"), ("right", "expr")],
LowLevelILOperation.LLIL_FCMP_NE: LowLevelILFcmpNe, # [("left", "expr"), ("right", "expr")],
LowLevelILOperation.LLIL_FCMP_LT: LowLevelILFcmpLt, # [("left", "expr"), ("right", "expr")],
LowLevelILOperation.LLIL_FCMP_LE: LowLevelILFcmpLe, # [("left", "expr"), ("right", "expr")],
LowLevelILOperation.LLIL_FCMP_GE: LowLevelILFcmpGe, # [("left", "expr"), ("right", "expr")],
LowLevelILOperation.LLIL_FCMP_GT: LowLevelILFcmpGt, # [("left", "expr"), ("right", "expr")],
LowLevelILOperation.LLIL_FCMP_O: LowLevelILFcmpO, # [("left", "expr"), ("right", "expr")],
LowLevelILOperation.LLIL_FCMP_UO: LowLevelILFcmpUo, # [("left", "expr"), ("right", "expr")],
LowLevelILOperation.LLIL_SET_REG_SSA: LowLevelILSetRegSsa, # [("dest", "reg_ssa"), ("src", "expr")],
LowLevelILOperation.LLIL_SET_REG_SSA_PARTIAL: LowLevelILSetRegSsaPartial, # [("full_reg", "reg_ssa"), ("dest", "reg"), ("src", "expr")],
LowLevelILOperation.LLIL_SET_REG_SPLIT_SSA: LowLevelILSetRegSplitSsa, # [("hi", "expr"), ("lo", "expr"), ("src", "expr")],
LowLevelILOperation.LLIL_SET_REG_STACK_REL_SSA: LowLevelILSetRegStackRelSsa, # [("stack", "expr"), ("dest", "expr"), ("top", "expr"), ("src", "expr")],
LowLevelILOperation.LLIL_SET_REG_STACK_ABS_SSA: LowLevelILSetRegStackAbsSsa, # [("stack", "expr"), ("dest", "reg"), ("src", "expr")],
LowLevelILOperation.LLIL_REG_SPLIT_DEST_SSA: LowLevelILRegSplitDestSsa, # [("dest", "reg_ssa")],
LowLevelILOperation.LLIL_REG_STACK_DEST_SSA: LowLevelILRegStackDestSsa, # [("src", "reg_stack_ssa_dest_and_src")],
LowLevelILOperation.LLIL_REG_SSA: LowLevelILRegSsa, # [("src", "reg_ssa")],
LowLevelILOperation.LLIL_REG_SSA_PARTIAL: LowLevelILRegSsaPartial, # [("full_reg", "reg_ssa"), ("src", "reg")],
LowLevelILOperation.LLIL_REG_SPLIT_SSA: LowLevelILRegSplitSsa, # [("hi", "reg_ssa"), ("lo", "reg_ssa")],
LowLevelILOperation.LLIL_REG_STACK_REL_SSA: LowLevelILRegStackRelSsa, # [("stack", "reg_stack_ssa"), ("src", "expr"), ("top", "expr")],
LowLevelILOperation.LLIL_REG_STACK_ABS_SSA: LowLevelILRegStackAbsSsa, # [("stack", "reg_stack_ssa"), ("src", "reg")],
LowLevelILOperation.LLIL_REG_STACK_FREE_REL_SSA: LowLevelILRegStackFreeRelSsa, # [("stack", "expr"), ("dest", "expr"), ("top", "expr")],
LowLevelILOperation.LLIL_REG_STACK_FREE_ABS_SSA: LowLevelILRegStackFreeAbsSsa, # [("stack", "expr"), ("dest", "reg")],
LowLevelILOperation.LLIL_SET_FLAG_SSA: LowLevelILSetFlagSsa, # [("dest", "flag_ssa"), ("src", "expr")],
LowLevelILOperation.LLIL_FLAG_SSA: LowLevelILFlagSsa, # [("src", "flag_ssa")],
LowLevelILOperation.LLIL_FLAG_BIT_SSA: LowLevelILFlagBitSsa, # [("src", "flag_ssa"), ("bit", "int")],
LowLevelILOperation.LLIL_CALL_SSA: LowLevelILCallSsa, # [("output", "expr"), ("dest", "expr"), ("stack", "expr"), ("param", "expr")],
LowLevelILOperation.LLIL_SYSCALL_SSA: LowLevelILSyscallSsa, # [("output", "expr"), ("stack", "expr"), ("param", "expr")],
LowLevelILOperation.LLIL_TAILCALL_SSA: LowLevelILTailcallSsa, # [("output", "expr"), ("dest", "expr"), ("stack", "expr"), ("param", "expr")],
LowLevelILOperation.LLIL_CALL_OUTPUT_SSA: LowLevelILCallOutputSsa, # [("dest_memory", "int"), ("dest", "reg_ssa_list")],
LowLevelILOperation.LLIL_CALL_STACK_SSA: LowLevelILCallStackSsa, # [("src", "reg_ssa"), ("src_memory", "int")],
LowLevelILOperation.LLIL_CALL_PARAM: LowLevelILCallParam, # [("src", "expr_list")],
LowLevelILOperation.LLIL_SEPARATE_PARAM_LIST_SSA: LowLevelILSeparateParamListSsa, # [("src", "expr_list")],
LowLevelILOperation.LLIL_SHARED_PARAM_SLOT_SSA: LowLevelILSharedParamSlotSsa, # [("src", "expr_list")],
LowLevelILOperation.LLIL_LOAD_SSA: LowLevelILLoadSsa, # [("src", "expr"), ("src_memory", "int")],
LowLevelILOperation.LLIL_STORE_SSA: LowLevelILStoreSsa, # [("dest", "expr"), ("dest_memory", "int"), ("src_memory", "int"), ("src", "expr")],
LowLevelILOperation.LLIL_REG_PHI: LowLevelILRegPhi, # [("dest", "reg_ssa"), ("src", "reg_ssa_list")],
LowLevelILOperation.LLIL_REG_STACK_PHI: LowLevelILRegStackPhi, # [("dest", "reg_stack_ssa"), ("src", "reg_stack_ssa_list")],
LowLevelILOperation.LLIL_FLAG_PHI: LowLevelILFlagPhi, # [("dest", "flag_ssa"), ("src", "flag_ssa_list")],
LowLevelILOperation.LLIL_MEM_PHI: LowLevelILMemPhi, # [("dest_memory", "int"), ("src_memory", "int_list")]
}
[docs]
class LowLevelILExpr:
"""
``class LowLevelILExpr`` hold the index of IL Expressions.
.. note:: Deprecated. Use ExpressionIndex instead
"""
def __init__(self, index: ExpressionIndex):
self._index = index
def __int__(self):
return self._index
@property
def index(self) -> ExpressionIndex:
return self._index
[docs]
class LowLevelILFunction:
"""
``class LowLevelILFunction`` contains the list of ExpressionIndex objects that make up a function. ExpressionIndex
objects can be added to the LowLevelILFunction by calling :func:`append` and passing the result of the various class
methods which return ExpressionIndex objects.
LowLevelILFlagCondition values used as parameters in the :func:`flag_condition` method.
======================= ========== ===============================
LowLevelILFlagCondition Operator Description
======================= ========== ===============================
LLFC_E == Equal
LLFC_NE != Not equal
LLFC_SLT s< Signed less than
LLFC_ULT u< Unsigned less than
LLFC_SLE s<= Signed less than or equal
LLFC_ULE u<= Unsigned less than or equal
LLFC_SGE s>= Signed greater than or equal
LLFC_UGE u>= Unsigned greater than or equal
LLFC_SGT s> Signed greater than
LLFC_UGT u> Unsigned greater than
LLFC_NEG - Negative
LLFC_POS + Positive
LLFC_O overflow Overflow
LLFC_NO !overflow No overflow
======================= ========== ===============================
"""
def __init__(
self, arch: Optional['architecture.Architecture'] = None, handle: Optional[core.BNLowLevelILFunction] = None,
source_func: Optional['function.Function'] = None
):
if arch is not None:
self._arch = arch
self._source_function = source_func
if handle is not None:
LLILHandle = ctypes.POINTER(core.BNLowLevelILFunction)
_handle = ctypes.cast(handle, LLILHandle)
if self._source_function is None:
source_handle = core.BNGetLowLevelILOwnerFunction(_handle)
if source_handle:
self._source_function = function.Function(handle=source_handle)
else:
self._source_function = None
if arch is None:
if self._source_function is None:
raise Exception("Can not instantiate LowLevelILFunction without an architecture")
self._arch = self._source_function.arch
else:
if arch is None:
if self._source_function is None:
raise Exception("Can not instantiate LowLevelILFunction without an architecture")
self._arch = self._source_function.arch
assert self._arch is not None
if self._source_function is None:
func_handle = None
else:
func_handle = self._source_function.handle
_handle = core.BNCreateLowLevelILFunction(self._arch.handle, func_handle)
assert _handle is not None
self.handle = _handle
assert self._arch is not None
def __del__(self):
if core is not None and hasattr(self, 'handle'):
core.BNFreeLowLevelILFunction(self.handle)
def __repr__(self):
if self.source_function is not None and self.source_function.arch is not None:
return f"<{self.__class__.__name__}: {self.source_function.arch.name}@{self.source_function.start:#x}>"
elif self.source_function is not None:
return f"<{self.__class__.__name__}: {self.source_function.start:#x}>"
else:
return f"<{self.__class__.__name__}: anonymous>"
def __len__(self):
return int(core.BNGetLowLevelILInstructionCount(self.handle))
def __eq__(self, other):
if not isinstance(other, self.__class__):
return NotImplemented
return ctypes.addressof(self.handle.contents) == ctypes.addressof(other.handle.contents)
def __ne__(self, other):
if not isinstance(other, self.__class__):
return NotImplemented
return not (self == other)
def __hash__(self):
return hash(ctypes.addressof(self.handle.contents))
def __getitem__(self, i: InstructionIndex) -> LowLevelILInstruction:
if isinstance(i, slice) or isinstance(i, tuple):
raise IndexError("expected integer instruction index")
if i < -len(self) or i >= len(self):
raise IndexError(f"index {i} out of range (-{len(self)}, {len(self)})")
if i < 0:
i = len(self) + i
return LowLevelILInstruction.create(
self, ExpressionIndex(core.BNGetLowLevelILIndexForInstruction(self.handle, i)), i
)
def __setitem__(self, i, j):
raise IndexError("instruction modification not implemented")
def __iter__(self) -> Generator['LowLevelILBasicBlock', None, None]:
count = ctypes.c_ulonglong()
blocks = core.BNGetLowLevelILBasicBlockList(self.handle, count)
assert blocks is not None, "core.BNGetLowLevelILBasicBlockList returned None"
view = None
if self._source_function is not None:
view = self._source_function.view
try:
for i in range(0, count.value):
core_block = core.BNNewBasicBlockReference(blocks[i])
assert core_block is not None, "core.BNNewBasicBlockReference returned None"
yield LowLevelILBasicBlock(core_block, self, view)
finally:
core.BNFreeBasicBlockList(blocks, count.value)
@property
def current_address(self) -> int:
"""Current IL Address (read/write)"""
return core.BNLowLevelILGetCurrentAddress(self.handle)
@current_address.setter
def current_address(self, value: int) -> None:
core.BNLowLevelILSetCurrentAddress(self.handle, self.arch.handle, value)
[docs]
def set_current_address(self, value: int, arch: Optional['architecture.Architecture'] = None) -> None:
if arch is None:
arch = self.arch
core.BNLowLevelILSetCurrentAddress(self.handle, arch.handle, value)
[docs]
def set_current_source_block(self, block) -> None:
core.BNLowLevelILSetCurrentSourceBlock(self.handle, block.handle)
@property
def temp_reg_count(self) -> int:
"""Number of temporary registers (read-only)"""
return core.BNGetLowLevelILTemporaryRegisterCount(self.handle)
@property
def temp_flag_count(self) -> int:
"""Number of temporary flags (read-only)"""
return core.BNGetLowLevelILTemporaryFlagCount(self.handle)
def _basic_block_list(self):
count = ctypes.c_ulonglong()
blocks = core.BNGetLowLevelILBasicBlockList(self.handle, count)
assert blocks is not None, "core.BNGetLowLevelILBasicBlockList returned None"
return (count, blocks)
def _instantiate_block(self, handle):
return LowLevelILBasicBlock(handle, self, self.view)
@property
def basic_blocks(self) -> 'function.LowLevelILBasicBlockList':
return function.LowLevelILBasicBlockList(self)
[docs]
def get_basic_block_at(self, index: int) -> Optional['basicblock.BasicBlock']:
"""
``get_basic_block_at`` returns the BasicBlock at the given LLIL instruction ``index``.
:param int index: Index of the LLIL instruction of the BasicBlock to retrieve.
:Example:
>>> current_il_function.get_basic_block_at(current_il_index)
<llil block: x86@19-26>
"""
block = core.BNGetLowLevelILBasicBlockForInstruction(self.handle, index)
if not block:
return None
view = None
if self._source_function is not None:
view = self._source_function.view
return LowLevelILBasicBlock(block, self, view)
@property
def instructions(self) -> Generator['LowLevelILInstruction', None, None]:
"""A generator of llil instructions of the current llil function"""
for block in self.basic_blocks:
yield from block
[docs]
def traverse(self, cb: Callable[['LowLevelILInstruction', Any], Any], *args: Any, **kwargs: Any) -> Iterator[Any]:
"""
``traverse`` iterates through all the instructions in the LowLevelILFunction and calls the callback function for
each instruction and sub-instruction. See the `Developer Docs <https://docs.binary.ninja/dev/concepts.html#walking-ils>`_ for more examples.
:param Callable[[LowLevelILInstruction, Any], Any] cb: The callback function to call for each node in the LowLevelILInstruction
:param Any args: Custom user-defined arguments
:param Any kwargs: Custom user-defined keyword arguments
:return: An iterator of the results of the callback function
:rtype: Iterator[Any]
:Example:
>>> def find_constants(instr) -> Optional[int]:
... if isinstance(instr, Constant):
... return instr.constant
>>> print(list(current_il_function.traverse(find_constants)))
"""
for instr in self.instructions:
yield from instr.traverse(cb, *args, **kwargs)
[docs]
@deprecation.deprecated(deprecated_in="4.0.4907", details="Use :py:func:`LowLevelILFunction.traverse` instead.")
def visit(self, cb: LowLevelILVisitorCallback) -> bool:
"""
Iterates over all the instructions in the function and calls the callback function
for each instruction and each sub-instruction.
:param LowLevelILVisitorCallback cb: Callback function that takes the name of the operand, the operand, operand type, and parent instruction
:return: True if all instructions were visited, False if the callback function returned False.
"""
for instr in self.instructions:
if not instr.visit(cb):
return False
return True
[docs]
@deprecation.deprecated(deprecated_in="4.0.4907", details="Use :py:func:`LowLevelILFunction.traverse` instead.")
def visit_all(self, cb: LowLevelILVisitorCallback) -> bool:
"""
Iterates over all the instructions in the function and calls the callback function for each instruction and their operands.
:param LowLevelILVisitorCallback cb: Callback function that takes the name of the operand, the operand, operand type, and parent instruction
:return: True if all instructions were visited, False if the callback function returned False.
"""
for instr in self.instructions:
if not instr.visit_all(cb):
return False
return True
[docs]
@deprecation.deprecated(deprecated_in="4.0.4907", details="Use :py:func:`LowLevelILFunction.traverse` instead.")
def visit_operands(self, cb: LowLevelILVisitorCallback) -> bool:
"""
Iterates over all the instructions in the function and calls the callback function for each operand and
the operands of each sub-instruction.
:param LowLevelILVisitorCallback cb: Callback function that takes the name of the operand, the operand, operand type, and parent instruction
:return: True if all instructions were visited, False if the callback function returned False.
"""
for instr in self.instructions:
if not instr.visit_operands(cb):
return False
return True
@property
def ssa_form(self) -> 'LowLevelILFunction':
"""Low level IL in SSA form (read-only)"""
result = core.BNGetLowLevelILSSAForm(self.handle)
assert result is not None, "Failed to retrieve ssa-form"
return LowLevelILFunction(self._arch, result, self._source_function)
@property
def non_ssa_form(self) -> 'LowLevelILFunction':
"""Low level IL in non-SSA (default) form (read-only)"""
result = core.BNGetLowLevelILNonSSAForm(self.handle)
assert result is not None, "Failed to retrieve non-ssa-form"
return LowLevelILFunction(self._arch, result, self._source_function)
@property
def medium_level_il(self) -> 'mediumlevelil.MediumLevelILFunction':
"""Medium level IL for this low level IL."""
result = core.BNGetMediumLevelILForLowLevelIL(self.handle)
assert result is not None, "MLIL not present"
return mediumlevelil.MediumLevelILFunction(self._arch, result, self._source_function)
@property
def mlil(self) -> 'mediumlevelil.MediumLevelILFunction':
return self.medium_level_il
@property
def mapped_medium_level_il(self) -> 'mediumlevelil.MediumLevelILFunction':
"""Medium level IL with mappings between low level IL and medium level IL. Unused stores are not removed.
Typically, this should only be used to answer queries on assembly or low level IL where the query is
easier to perform on medium level IL."""
result = core.BNGetMappedMediumLevelIL(self.handle)
assert result is not None, "MLIL not present"
return mediumlevelil.MediumLevelILFunction(self._arch, result, self._source_function)
@property
def mmlil(self) -> 'mediumlevelil.MediumLevelILFunction':
return self.mapped_medium_level_il
@property
def arch(self) -> 'architecture.Architecture':
assert self._arch is not None
return self._arch
@arch.setter
def arch(self, value: 'architecture.Architecture') -> None:
self._arch = value
@property
def source_function(self) -> Optional['function.Function']:
return self._source_function
@source_function.setter
def source_function(self, value: 'function.Function') -> None:
self._source_function = value
@property
def view(self) -> Optional['binaryview.BinaryView']:
return self.source_function.view if self.source_function else None
@property
def il_form(self) -> FunctionGraphType:
if len(list(self.basic_blocks)) < 1:
return FunctionGraphType.InvalidILViewType
return FunctionGraphType(core.BNGetBasicBlockFunctionGraphType(list(self.basic_blocks)[0].handle))
@property
def registers(self) -> List[SSARegister]:
""" Deprecated, use `regs` instead. List of registers used in this IL """
return self.regs
@property
def regs(self) -> List[SSARegister]:
""" List of registers used in this IL """
if self.il_form == FunctionGraphType.LowLevelILSSAFormFunctionGraph:
# If this is a LLIL SSA function, then its registers is SSA registers
return self.ssa_regs
count = ctypes.c_ulonglong()
registers = core.BNGetLowLevelRegisters(self.handle, count)
assert registers is not None, "core.BNGetLowLevelRegisters returned None"
result = []
try:
for var_i in range(count.value):
result.append(ILRegister(self.arch, registers[var_i]))
return result
finally:
core.BNFreeLLILVariablesList(registers)
@property
def is_thunk(self) -> bool:
"""Returns True if the function starts with a Tailcall (read-only)"""
if len(self.basic_blocks) == 1:
return isinstance(self.basic_blocks[0][-1], Tailcall)
return False
@property
def register_stacks(self) -> List[SSARegisterStack]:
""" Deprecated, use `reg_stacks` instead. List of register stacks used in this IL """
return self.reg_stacks
@property
def reg_stacks(self) -> List[SSARegisterStack]:
""" List of register stacks used in this IL """
if self.il_form == FunctionGraphType.LowLevelILSSAFormFunctionGraph:
# If this is a LLIL SSA function, then its registers is SSA registers
return self.ssa_reg_stacks
count = ctypes.c_ulonglong()
registerStacks = core.BNGetLowLevelRegisterStacks(self.handle, count)
assert registerStacks is not None, "core.BNGetLowLevelRegisterStacks returned None"
result = []
try:
for var_i in range(count.value):
result.append(ILRegisterStack(self.arch, registerStacks[var_i]))
return result
finally:
core.BNFreeLLILVariablesList(registerStacks)
@property
def flags(self) -> List[SSAFlag]:
""" List of flags used in this IL """
if self.il_form == FunctionGraphType.LowLevelILSSAFormFunctionGraph:
# If this is a LLIL SSA function, then its registers is SSA registers
return self.ssa_flags
count = ctypes.c_ulonglong()
flags = core.BNGetLowLevelFlags(self.handle, count)
assert flags is not None, "core.BNGetLowLevelFlags returned None"
result = []
try:
for var_i in range(count.value):
result.append(ILFlag(self.arch, flags[var_i]))
return result
finally:
core.BNFreeLLILVariablesList(flags)
@property
def ssa_regs_without_versions(self) -> List[SSARegister]:
""" List of SSA registers used in this IL """
register_count = ctypes.c_ulonglong()
registers = core.BNGetLowLevelSSARegistersWithoutVersions(self.handle, register_count)
assert registers is not None, "core.BNGetLowLevelRegisters returned None"
result = []
try:
for var_i in range(register_count.value):
result.append(SSARegister(ILRegister(self.arch, registers[var_i]), 0))
finally:
core.BNFreeLLILVariablesList(registers)
return result
@property
def ssa_reg_stacks_without_versions(self) -> List[SSARegisterStack]:
""" List of SSA register stacks used in this IL """
register_stack_count = ctypes.c_ulonglong()
register_stacks = core.BNGetLowLevelSSARegisterStacksWithoutVersions(self.handle, register_stack_count)
assert register_stacks is not None, "core.BNGetLowLevelRegisterStacks returned None"
result = []
try:
for var_i in range(register_stack_count.value):
result.append(SSARegisterStack(ILRegisterStack(self.arch, register_stacks[var_i]), 0))
finally:
core.BNFreeLLILVariablesList(register_stacks)
return result
@property
def ssa_flags_without_versions(self) -> List[SSAFlag]:
""" List of SSA flags used in this IL """
flag_count = ctypes.c_ulonglong()
flags = core.BNGetLowLevelSSAFlagsWithoutVersions(self.handle, flag_count)
assert flags is not None, "core.BNGetLowLevelFlags returned None"
result = []
try:
for var_i in range(flag_count.value):
result.append(SSAFlag(ILFlag(self.arch, flags[var_i]), 0))
finally:
core.BNFreeLLILVariablesList(flags)
return result
@property
def ssa_registers(self) -> List[SSARegister]:
return self.ssa_regs
@property
def ssa_register_stacks(self) -> List[SSARegisterStack]:
return self.ssa_reg_stacks
@property
def ssa_regs(self) -> List[SSARegister]:
""" List of all SSA registers and versions used in this IL """
register_count = ctypes.c_ulonglong()
registers = core.BNGetLowLevelSSARegistersWithoutVersions(self.handle, register_count)
assert registers is not None, "core.BNGetLowLevelRegisters returned None"
result = []
try:
for var_i in range(register_count.value):
version_count = ctypes.c_ulonglong()
versions = core.BNGetLowLevelRegisterSSAVersions(self.handle, registers[var_i], version_count)
assert versions is not None, "core.BNGetLowLevelRegisterSSAVersions returned None"
try:
for version_i in range(version_count.value):
result.append(SSARegister(ILRegister(self.arch, registers[var_i]), versions[version_i]))
finally:
core.BNFreeLLILVariableVersionList(versions)
return result
finally:
core.BNFreeLLILVariablesList(registers)
@property
def ssa_reg_stacks(self) -> List[SSARegisterStack]:
""" List of all SSA register stacks and versions used in this IL """
register_stack_count = ctypes.c_ulonglong()
register_stacks = core.BNGetLowLevelSSARegisterStacksWithoutVersions(self.handle, register_stack_count)
assert register_stacks is not None, "core.BNGetLowLevelRegisterStacks returned None"
result = []
try:
for var_i in range(register_stack_count.value):
version_count = ctypes.c_ulonglong()
versions = core.BNGetLowLevelRegisterStackSSAVersions(
self.handle, register_stacks[var_i], version_count
)
assert versions is not None, "core.BNGetLowLevelRegisterStackSSAVersions returned None"
try:
for version_i in range(version_count.value):
result.append(
SSARegisterStack(ILRegisterStack(self.arch, register_stacks[var_i]), versions[version_i])
)
finally:
core.BNFreeLLILVariableVersionList(versions)
finally:
core.BNFreeLLILVariablesList(register_stacks)
return result
@property
def ssa_flags(self) -> List[SSAFlag]:
""" List of all SSA flags and versions used in this IL """
flag_count = ctypes.c_ulonglong()
flags = core.BNGetLowLevelSSAFlagsWithoutVersions(self.handle, flag_count)
assert flags is not None, "core.BNGetLowLevelFlags returned None"
result = []
try:
for var_i in range(flag_count.value):
version_count = ctypes.c_ulonglong()
versions = core.BNGetLowLevelFlagSSAVersions(self.handle, flags[var_i], version_count)
assert versions is not None, "core.BNGetLowLevelFlagSSAVersions returned None"
try:
for version_i in range(version_count.value):
result.append(SSAFlag(ILFlag(self.arch, flags[var_i]), versions[version_i]))
finally:
core.BNFreeLLILVariableVersionList(versions)
finally:
core.BNFreeLLILVariablesList(flags)
return result
@property
def memory_versions(self) -> List[int]:
""" List of memory versions used in this IL """
count = ctypes.c_ulonglong()
memory_versions = core.BNGetLowLevelMemoryVersions(self.handle, count)
assert memory_versions is not None, "core.BNGetLowLevelMemoryVersions returned None"
result = []
try:
for version_i in range(count.value):
result.append(memory_versions[version_i])
return result
finally:
core.BNFreeLLILVariableVersionList(memory_versions)
@property
def vars(self) -> List[Union[ILRegister, ILRegisterStack, ILFlag]]:
"""This is the union `LowLevelILFunction.regs`, `LowLevelILFunction.reg_stacks`, and `LowLevelILFunction.flags`"""
if self._source_function is None:
return []
if self.il_form in [
FunctionGraphType.LiftedILFunctionGraph, FunctionGraphType.LowLevelILFunctionGraph,
FunctionGraphType.LowLevelILSSAFormFunctionGraph
]:
return self.regs + self.reg_stacks + self.flags # type: ignore
return []
@property
def ssa_vars(self) -> List[Union[SSARegister, SSARegisterStack, SSAFlag]]:
"""This is the union `LowLevelILFunction.ssa_regs`, `LowLevelILFunction.ssa_reg_stacks`, and `LowLevelILFunction.ssa_flags`"""
return self.ssa_regs + self.ssa_reg_stacks + self.ssa_flags
@property
def ssa_vars_without_versions(self) -> List[Union[SSARegister, SSARegisterStack, SSAFlag]]:
"""This is the union `LowLevelILFunction.ssa_regs_without_versions`,
`LowLevelILFunction.ssa_reg_stacks_without_versions`, and `LowLevelILFunction.ssa_flags_without_versions`"""
return self.ssa_regs_without_versions + self.ssa_reg_stacks_without_versions + self.ssa_flags_without_versions
[docs]
def get_instruction_start(self, addr: int, arch: Optional['architecture.Architecture'] = None) -> Optional[int]:
if arch is None:
arch = self.arch
result = core.BNLowLevelILGetInstructionStart(self.handle, arch.handle, addr)
if result >= core.BNGetLowLevelILInstructionCount(self.handle):
return None
return result
[docs]
def clear_indirect_branches(self) -> None:
core.BNLowLevelILClearIndirectBranches(self.handle)
[docs]
def set_indirect_branches(self, branches: List[Tuple['architecture.Architecture', int]]) -> None:
branch_list = (core.BNArchitectureAndAddress * len(branches))()
for i in range(len(branches)):
branch_list[i].arch = branches[i][0].handle
branch_list[i].address = branches[i][1]
core.BNLowLevelILSetIndirectBranches(self.handle, branch_list, len(branches))
[docs]
def expr(
self, operation, a: ExpressionIndex = 0, b: ExpressionIndex = 0, c: ExpressionIndex = 0, d: ExpressionIndex = 0, size: int = 0,
flags: Optional[Union['architecture.FlagWriteTypeName', 'architecture.FlagType', 'architecture.FlagIndex']] = None
) -> ExpressionIndex:
_flags = architecture.FlagIndex(0)
if isinstance(operation, str):
operation = LowLevelILOperation[operation]
elif isinstance(operation, LowLevelILOperation):
operation = operation.value
if isinstance(flags, str):
_flags = self.arch.get_flag_write_type_by_name(architecture.FlagWriteTypeName(flags))
elif isinstance(flags, ILFlag):
_flags = flags.index
elif isinstance(flags, int):
_flags = architecture.FlagIndex(flags)
elif flags is None:
_flags = architecture.FlagIndex(0)
else:
assert False, "flags type unsupported"
return ExpressionIndex(core.BNLowLevelILAddExpr(self.handle, operation, size, _flags, a, b, c, d))
[docs]
def get_expr_count(self) -> int:
"""
``get_expr_count`` gives a the total number of expressions in this IL function
You can use this to enumerate all expressions in conjunction with :py:func:`get_expr`
.. warning :: Not all IL expressions are valid, even if their index is within the returned value from this,
they might not be used by the function and might not contain properly structured data.
:return: The number of expressions in the function
"""
return core.BNGetLowLevelILExprCount(self.handle)
[docs]
def get_expr(self, index: ExpressionIndex) -> Optional[LowLevelILInstruction]:
"""
``get_expr`` retrieves the IL expression at a given expression index in the function.
.. warning :: Not all IL expressions are valid, even if their index is within the bounds of the function,
they might not be used by the function and might not contain properly structured data.
:param index: Index of desired expression in function
:return: A LowLevelILInstruction object for the expression, if it exists. Otherwise, None
"""
if index >= self.get_expr_count():
return None
return LowLevelILInstruction.create(self, index)
[docs]
def copy_expr(self, original: LowLevelILInstruction) -> ExpressionIndex:
"""
``copy_expr`` adds an expression to the function which is equivalent to the given expression
:param LowLevelILInstruction original: the original IL Instruction you want to copy
:return: The index of the newly copied expression
"""
return self.expr(original.operation, original.raw_operands[0], original.raw_operands[1], original.raw_operands[2], original.raw_operands[3], original.size, original.flags)
[docs]
def replace_expr(self, original: InstructionOrExpression, new: InstructionOrExpression) -> None:
"""
``replace_expr`` allows modification of expressions but ONLY during lifting.
.. warning:: This function should ONLY be called as a part of a lifter. It will otherwise not do anything useful as there's no way to trigger re-analysis of IL levels at this time.
:param ExpressionIndex original: the ExpressionIndex to replace (may also be an expression index)
:param ExpressionIndex new: the ExpressionIndex to add to the current LowLevelILFunction (may also be an expression index)
:rtype: None
"""
if isinstance(original, LowLevelILInstruction):
original = original.expr_index
elif isinstance(original, int):
original = ExpressionIndex(original)
if isinstance(new, LowLevelILInstruction):
new = new.expr_index
elif isinstance(new, int):
new = ExpressionIndex(new)
core.BNReplaceLowLevelILExpr(self.handle, original, new)
[docs]
def set_expr_attributes(self, expr: InstructionOrExpression, value: ILInstructionAttributeSet):
"""
``set_expr_attributes`` allows modification of instruction attributes but ONLY during lifting.
.. warning:: This function should ONLY be called as a part of a lifter. It will otherwise not do anything useful as there's no way to trigger re-analysis of IL levels at this time.
:param ExpressionIndex expr: the ExpressionIndex to replace (may also be an expression index)
:param set(ILInstructionAttribute) value: the set of attributes to place on the instruction
:rtype: None
"""
if isinstance(expr, LowLevelILInstruction):
expr = expr.expr_index
elif isinstance(expr, int):
expr = ExpressionIndex(expr)
result = 0
for flag in value:
result |= flag.value
core.BNSetLowLevelILExprAttributes(self.handle, expr, result)
[docs]
def append(self, expr: ExpressionIndex) -> int:
"""
``append`` adds the ExpressionIndex ``expr`` to the current LowLevelILFunction.
:param ExpressionIndex expr: the ExpressionIndex to add to the current LowLevelILFunction
:return: number of ExpressionIndex in the current function
:rtype: int
"""
return core.BNLowLevelILAddInstruction(self.handle, expr)
[docs]
def nop(self) -> ExpressionIndex:
"""
``nop`` no operation, this instruction does nothing
:return: The no operation expression
:rtype: ExpressionIndex
"""
return self.expr(LowLevelILOperation.LLIL_NOP)
[docs]
def set_reg(
self, size: int, reg: 'architecture.RegisterType', value: ExpressionIndex,
flags: Optional['architecture.FlagType'] = None
) -> ExpressionIndex:
"""
``set_reg`` sets the register ``reg`` of size ``size`` to the expression ``value``
:param int size: size of the register parameter in bytes
:param str reg: the register name
:param ExpressionIndex value: an expression to set the register to
:param str flags: which flags are set by this operation
:return: The expression ``reg = value``
:rtype: ExpressionIndex
"""
_reg = ExpressionIndex(self.arch.get_reg_index(reg))
if flags is None:
flags = architecture.FlagIndex(0)
return self.expr(LowLevelILOperation.LLIL_SET_REG, _reg, value, size=size, flags=flags)
[docs]
def set_reg_split(
self, size: int, hi: 'architecture.RegisterType', lo: 'architecture.RegisterType', value: ExpressionIndex,
flags: Optional['architecture.FlagType'] = None
) -> ExpressionIndex:
"""
``set_reg_split`` uses ``hi`` and ``lo`` as a single extended register setting ``hi:lo`` to the expression
``value``.
:param int size: size of the register parameter in bytes
:param str hi: the high register name
:param str lo: the low register name
:param ExpressionIndex value: an expression to set the split registers to
:param str flags: which flags are set by this operation
:return: The expression ``hi:lo = value``
:rtype: ExpressionIndex
"""
_hi = ExpressionIndex(self.arch.get_reg_index(hi))
_lo = ExpressionIndex(self.arch.get_reg_index(lo))
if flags is None:
flags = architecture.FlagIndex(0)
return self.expr(LowLevelILOperation.LLIL_SET_REG_SPLIT, _hi, _lo, value, size=size, flags=flags)
[docs]
def set_reg_stack_top_relative(
self, size: int, reg_stack: 'architecture.RegisterStackType', entry: ExpressionIndex, value: ExpressionIndex,
flags: Optional['architecture.FlagType'] = None
) -> ExpressionIndex:
"""
``set_reg_stack_top_relative`` sets the top-relative entry ``entry`` of size ``size`` in register
stack ``reg_stack`` to the expression ``value``
:param int size: size of the register parameter in bytes
:param str reg_stack: the register stack name
:param ExpressionIndex entry: an expression for which stack entry to set
:param ExpressionIndex value: an expression to set the entry to
:param str flags: which flags are set by this operation
:return: The expression ``reg_stack[entry] = value``
:rtype: ExpressionIndex
"""
_reg_stack = ExpressionIndex(self.arch.get_reg_stack_index(reg_stack))
if flags is None:
flags = architecture.FlagIndex(0)
return self.expr(LowLevelILOperation.LLIL_SET_REG_STACK_REL, _reg_stack, entry, value, size=size, flags=flags)
[docs]
def reg_stack_push(
self, size: int, reg_stack: 'architecture.RegisterStackType', value: ExpressionIndex,
flags: Optional['architecture.FlagType'] = None
) -> ExpressionIndex:
"""
``reg_stack_push`` pushes the expression ``value`` of size ``size`` onto the top of the register
stack ``reg_stack``
:param int size: size of the register parameter in bytes
:param str reg_stack: the register stack name
:param ExpressionIndex value: an expression to push
:param str flags: which flags are set by this operation
:return: The expression ``reg_stack.push(value)``
:rtype: ExpressionIndex
"""
_reg_stack = ExpressionIndex(self.arch.get_reg_stack_index(reg_stack))
if flags is None:
flags = architecture.FlagIndex(0)
return self.expr(LowLevelILOperation.LLIL_REG_STACK_PUSH, _reg_stack, value, size=size, flags=flags)
[docs]
def set_flag(self, flag: 'architecture.FlagName', value: ExpressionIndex) -> ExpressionIndex:
"""
``set_flag`` sets the flag ``flag`` to the ExpressionIndex ``value``
:param str flag: the low register name
:param ExpressionIndex value: an expression to set the flag to
:return: The expression FLAG.flag = value
:rtype: ExpressionIndex
"""
return self.expr(LowLevelILOperation.LLIL_SET_FLAG, ExpressionIndex(self.arch.get_flag_by_name(flag)), value)
[docs]
def load(self, size: int, addr: ExpressionIndex) -> ExpressionIndex:
"""
``load`` Reads ``size`` bytes from the expression ``addr``
:param int size: number of bytes to read
:param ExpressionIndex addr: the expression to read memory from
:return: The expression ``[addr].size``
:rtype: ExpressionIndex
"""
return self.expr(LowLevelILOperation.LLIL_LOAD, addr, size=size)
[docs]
def store(
self, size: int, addr: ExpressionIndex, value: ExpressionIndex, flags: Optional['architecture.FlagName'] = None
) -> ExpressionIndex:
"""
``store`` Writes ``size`` bytes to expression ``addr`` read from expression ``value``
:param int size: number of bytes to write
:param ExpressionIndex addr: the expression to write to
:param ExpressionIndex value: the expression to be written
:param FlagName flags: which flags are set by this operation
:return: The expression ``[addr].size = value``
:rtype: ExpressionIndex
"""
return self.expr(LowLevelILOperation.LLIL_STORE, addr, value, size=size, flags=flags)
[docs]
def push(self, size: int, value: ExpressionIndex) -> ExpressionIndex:
"""
``push`` writes ``size`` bytes from expression ``value`` to the stack, adjusting the stack by ``size``.
:param int size: number of bytes to write and adjust the stack by
:param ExpressionIndex value: the expression to write
:return: The expression push(value)
:rtype: ExpressionIndex
"""
return self.expr(LowLevelILOperation.LLIL_PUSH, value, size=size)
[docs]
def pop(self, size: int) -> ExpressionIndex:
"""
``pop`` reads ``size`` bytes from the stack, adjusting the stack by ``size``.
:param int size: number of bytes to read from the stack
:return: The expression ``pop``
:rtype: ExpressionIndex
"""
return self.expr(LowLevelILOperation.LLIL_POP, size=size)
[docs]
def reg(self, size: int, reg: 'architecture.RegisterType') -> ExpressionIndex:
"""
``reg`` returns a register of size ``size`` with name ``reg``
:param int size: the size of the register in bytes
:param str reg: the name of the register
:return: A register expression for the given string
:rtype: ExpressionIndex
"""
_reg = ExpressionIndex(self.arch.get_reg_index(reg))
return self.expr(LowLevelILOperation.LLIL_REG, _reg, size=size)
[docs]
def reg_split(self, size: int, hi: 'architecture.RegisterType', lo: 'architecture.RegisterType') -> ExpressionIndex:
"""
``reg_split`` combines registers of size ``size`` with names ``hi`` and ``lo``
:param int size: the size of the register in bytes
:param str hi: register holding high part of value
:param str lo: register holding low part of value
:return: The expression ``hi:lo``
:rtype: ExpressionIndex
"""
_hi = ExpressionIndex(self.arch.get_reg_index(hi))
_lo = ExpressionIndex(self.arch.get_reg_index(lo))
return self.expr(LowLevelILOperation.LLIL_REG_SPLIT, _hi, _lo, size=size)
[docs]
def reg_stack_top_relative(
self, size: int, reg_stack: 'architecture.RegisterStackType', entry: ExpressionIndex
) -> ExpressionIndex:
"""
``reg_stack_top_relative`` returns a register stack entry of size ``size`` at top-relative
location ``entry`` in register stack with name ``reg_stack``
:param int size: the size of the register in bytes
:param str reg_stack: the name of the register stack
:param ExpressionIndex entry: an expression for which stack entry to fetch
:return: The expression ``reg_stack[entry]``
:rtype: ExpressionIndex
"""
_reg_stack = self.arch.get_reg_stack_index(reg_stack)
return self.expr(LowLevelILOperation.LLIL_REG_STACK_REL, _reg_stack, entry, size=size)
[docs]
def reg_stack_pop(self, size: int, reg_stack: 'architecture.RegisterStackType') -> ExpressionIndex:
"""
``reg_stack_pop`` returns the top entry of size ``size`` in register stack with name ``reg_stack``, and
removes the entry from the stack
:param int size: the size of the register in bytes
:param str reg_stack: the name of the register stack
:return: The expression ``reg_stack.pop``
:rtype: ExpressionIndex
"""
_reg_stack = ExpressionIndex(self.arch.get_reg_stack_index(reg_stack))
return self.expr(LowLevelILOperation.LLIL_REG_STACK_POP, _reg_stack, size=size)
[docs]
def const(self, size: int, value: int) -> ExpressionIndex:
"""
``const`` returns an expression for the constant integer ``value`` with size ``size``
:param int size: the size of the constant in bytes
:param int value: integer value of the constant
:return: A constant expression of given value and size
:rtype: ExpressionIndex
"""
return self.expr(LowLevelILOperation.LLIL_CONST, ExpressionIndex(value), size=size)
[docs]
def const_pointer(self, size: int, value: int) -> ExpressionIndex:
"""
``const_pointer`` returns an expression for the constant pointer ``value`` with size ``size``
:param int size: the size of the pointer in bytes
:param int value: address referenced by pointer
:return: A constant expression of given value and size
:rtype: ExpressionIndex
"""
return self.expr(LowLevelILOperation.LLIL_CONST_PTR, value, size=size)
[docs]
def reloc_pointer(self, size: int, value: int) -> ExpressionIndex:
"""
``reloc_pointer`` returns an expression for the constant relocated pointer ``value`` with size ``size``
:param int size: the size of the pointer in bytes
:param int value: address referenced by pointer
:return: A constant expression of given value and size
:rtype: ExpressionIndex
"""
return self.expr(LowLevelILOperation.LLIL_EXTERN_PTR, value, size=size)
[docs]
def float_const_raw(self, size: int, value: int) -> ExpressionIndex:
"""
``float_const_raw`` returns an expression for the constant raw binary floating point
value ``value`` with size ``size``
:param int size: the size of the constant in bytes
:param int value: integer value for the raw binary representation of the constant
:return: A constant expression of given value and size
:rtype: ExpressionIndex
"""
return self.expr(LowLevelILOperation.LLIL_FLOAT_CONST, value, size=size)
[docs]
def float_const_single(self, value: float) -> ExpressionIndex:
"""
``float_const_single`` returns an expression for the single precision floating point value ``value``
:param float value: float value for the constant
:return: A constant expression of given value and size
:rtype: ExpressionIndex
"""
return self.expr(LowLevelILOperation.LLIL_FLOAT_CONST, struct.unpack("I", struct.pack("f", value))[0], size=4)
[docs]
def float_const_double(self, value: float) -> ExpressionIndex:
"""
``float_const_double`` returns an expression for the double precision floating point value ``value``
:param float value: float value for the constant
:return: A constant expression of given value and size
:rtype: ExpressionIndex
"""
return self.expr(LowLevelILOperation.LLIL_FLOAT_CONST, struct.unpack("Q", struct.pack("d", value))[0], size=8)
[docs]
def flag(self, reg: 'architecture.FlagName') -> ExpressionIndex:
"""
``flag`` returns a flag expression for the given flag name.
:param architecture.FlagName reg: name of the flag expression to retrieve
:return: A flag expression of given flag name
:rtype: ExpressionIndex
"""
return self.expr(LowLevelILOperation.LLIL_FLAG, self.arch.get_flag_by_name(reg))
[docs]
def flag_bit(self, size: int, reg: 'architecture.FlagName', bit: int) -> ExpressionIndex:
"""
``flag_bit`` sets the flag named ``reg`` and size ``size`` to the constant integer value ``bit``
:param int size: the size of the flag
:param str reg: flag value
:param int bit: integer value to set the bit to
:return: A constant expression of given value and size ``FLAG.reg = bit``
:rtype: ExpressionIndex
"""
return self.expr(LowLevelILOperation.LLIL_FLAG_BIT, self.arch.get_flag_by_name(reg), bit, size=size)
[docs]
def add(
self, size: int, a: ExpressionIndex, b: ExpressionIndex, flags: Optional['architecture.FlagType'] = None
) -> ExpressionIndex:
"""
``add`` adds expression ``a`` to expression ``b`` potentially setting flags ``flags`` and returning
an expression of ``size`` bytes.
:param int size: the size of the result in bytes
:param ExpressionIndex a: LHS expression
:param ExpressionIndex b: RHS expression
:param str flags: flags to set
:return: The expression ``add.<size>{<flags>}(a, b)``
:rtype: ExpressionIndex
"""
return self.expr(LowLevelILOperation.LLIL_ADD, a, b, size=size, flags=flags)
[docs]
def add_carry(
self, size: int, a: ExpressionIndex, b: ExpressionIndex, carry: ExpressionIndex,
flags: Optional['architecture.FlagType'] = None
) -> ExpressionIndex:
"""
``add_carry`` adds with carry expression ``a`` to expression ``b`` potentially setting flags ``flags`` and
returning an expression of ``size`` bytes.
:param int size: the size of the result in bytes
:param ExpressionIndex a: LHS expression
:param ExpressionIndex b: RHS expression
:param ExpressionIndex carry: Carry flag expression
:param str flags: flags to set
:return: The expression ``adc.<size>{<flags>}(a, b, carry)``
:rtype: ExpressionIndex
"""
return self.expr(LowLevelILOperation.LLIL_ADC, a, b, carry, size=size, flags=flags)
[docs]
def sub(
self, size: int, a: ExpressionIndex, b: ExpressionIndex, flags: Optional['architecture.FlagType'] = None
) -> ExpressionIndex:
"""
``sub`` subtracts expression ``b`` from expression ``a`` potentially setting flags ``flags`` and returning
an expression of ``size`` bytes.
:param int size: the size of the result in bytes
:param ExpressionIndex a: LHS expression
:param ExpressionIndex b: RHS expression
:param str flags: flags to set
:return: The expression ``sub.<size>{<flags>}(a, b)``
:rtype: ExpressionIndex
"""
return self.expr(LowLevelILOperation.LLIL_SUB, a, b, size=size, flags=flags)
[docs]
def sub_borrow(
self, size: int, a: ExpressionIndex, b: ExpressionIndex, carry: ExpressionIndex,
flags: Optional['architecture.FlagType'] = None
) -> ExpressionIndex:
"""
``sub_borrow`` subtracts with borrow expression ``b`` from expression ``a`` potentially setting flags ``flags``
and returning an expression of ``size`` bytes.
:param int size: the size of the result in bytes
:param ExpressionIndex a: LHS expression
:param ExpressionIndex b: RHS expression
:param ExpressionIndex carry: Carry flag expression
:param str flags: flags to set
:return: The expression ``sbb.<size>{<flags>}(a, b, carry)``
:rtype: ExpressionIndex
"""
return self.expr(LowLevelILOperation.LLIL_SBB, a, b, carry, size=size, flags=flags)
[docs]
def and_expr(
self, size: int, a: ExpressionIndex, b: ExpressionIndex, flags: Optional['architecture.FlagType'] = None
) -> ExpressionIndex:
"""
``and_expr`` bitwise and's expression ``a`` and expression ``b`` potentially setting flags ``flags``
and returning an expression of ``size`` bytes.
:param int size: the size of the result in bytes
:param ExpressionIndex a: LHS expression
:param ExpressionIndex b: RHS expression
:param str flags: optional, flags to set
:return: The expression ``and.<size>{<flags>}(a, b)``
:rtype: ExpressionIndex
"""
return self.expr(LowLevelILOperation.LLIL_AND, a, b, size=size, flags=flags)
[docs]
def or_expr(
self, size: int, a: ExpressionIndex, b: ExpressionIndex, flags: Optional['architecture.FlagType'] = None
) -> ExpressionIndex:
"""
``or_expr`` bitwise or's expression ``a`` and expression ``b`` potentially setting flags ``flags``
and returning an expression of ``size`` bytes.
:param int size: the size of the result in bytes
:param ExpressionIndex a: LHS expression
:param ExpressionIndex b: RHS expression
:param str flags: optional, flags to set
:return: The expression ``or.<size>{<flags>}(a, b)``
:rtype: ExpressionIndex
"""
return self.expr(LowLevelILOperation.LLIL_OR, a, b, size=size, flags=flags)
[docs]
def xor_expr(
self, size: int, a: ExpressionIndex, b: ExpressionIndex, flags: Optional['architecture.FlagType'] = None
) -> ExpressionIndex:
"""
``xor_expr`` xor's expression ``a`` with expression ``b`` potentially setting flags ``flags``
and returning an expression of ``size`` bytes.
:param int size: the size of the result in bytes
:param ExpressionIndex a: LHS expression
:param ExpressionIndex b: RHS expression
:param str flags: optional, flags to set
:return: The expression ``xor.<size>{<flags>}(a, b)``
:rtype: ExpressionIndex
"""
return self.expr(LowLevelILOperation.LLIL_XOR, a, b, size=size, flags=flags)
[docs]
def shift_left(
self, size: int, a: ExpressionIndex, b: ExpressionIndex, flags: Optional['architecture.FlagType'] = None
) -> ExpressionIndex:
"""
``shift_left`` shifts left expression ``a`` by expression ``b`` from expression ``a`` potentially setting flags ``flags``
and returning an expression of ``size`` bytes.
:param int size: the size of the result in bytes
:param ExpressionIndex a: LHS expression
:param ExpressionIndex b: RHS expression
:param str flags: optional, flags to set
:return: The expression ``lsl.<size>{<flags>}(a, b)``
:rtype: ExpressionIndex
"""
return self.expr(LowLevelILOperation.LLIL_LSL, a, b, size=size, flags=flags)
[docs]
def logical_shift_right(
self, size: int, a: ExpressionIndex, b: ExpressionIndex, flags: Optional['architecture.FlagType'] = None
) -> ExpressionIndex:
"""
``logical_shift_right`` shifts logically right expression ``a`` by expression ``b`` potentially setting flags
``flags`` and returning an expression of ``size`` bytes.
:param int size: the size of the result in bytes
:param ExpressionIndex a: LHS expression
:param ExpressionIndex b: RHS expression
:param str flags: optional, flags to set
:return: The expression ``lsr.<size>{<flags>}(a, b)``
:rtype: ExpressionIndex
"""
return self.expr(LowLevelILOperation.LLIL_LSR, a, b, size=size, flags=flags)
[docs]
def arith_shift_right(
self, size: int, a: ExpressionIndex, b: ExpressionIndex, flags: Optional['architecture.FlagType'] = None
) -> ExpressionIndex:
"""
``arith_shift_right`` shifts arithmetic right expression ``a`` by expression ``b`` potentially setting flags
``flags`` and returning an expression of ``size`` bytes.
:param int size: the size of the result in bytes
:param ExpressionIndex a: LHS expression
:param ExpressionIndex b: RHS expression
:param str flags: optional, flags to set
:return: The expression ``asr.<size>{<flags>}(a, b)``
:rtype: ExpressionIndex
"""
return self.expr(LowLevelILOperation.LLIL_ASR, a, b, size=size, flags=flags)
[docs]
def rotate_left(
self, size: int, a: ExpressionIndex, b: ExpressionIndex, flags: Optional['architecture.FlagType'] = None
) -> ExpressionIndex:
"""
``rotate_left`` bitwise rotates left expression ``a`` by expression ``b`` potentially setting flags ``flags``
and returning an expression of ``size`` bytes.
:param int size: the size of the result in bytes
:param ExpressionIndex a: LHS expression
:param ExpressionIndex b: RHS expression
:param str flags: optional, flags to set
:return: The expression ``rol.<size>{<flags>}(a, b)``
:rtype: ExpressionIndex
"""
return self.expr(LowLevelILOperation.LLIL_ROL, a, b, size=size, flags=flags)
[docs]
def rotate_left_carry(
self, size: int, a: ExpressionIndex, b: ExpressionIndex, carry: ExpressionIndex,
flags: Optional['architecture.FlagType'] = None
) -> ExpressionIndex:
"""
``rotate_left_carry`` bitwise rotates left with carry expression ``a`` by expression ``b`` potentially setting
flags ``flags`` and returning an expression of ``size`` bytes.
:param int size: the size of the result in bytes
:param ExpressionIndex a: LHS expression
:param ExpressionIndex b: RHS expression
:param ExpressionIndex carry: Carry flag expression
:param str flags: optional, flags to set
:return: The expression ``rlc.<size>{<flags>}(a, b, carry)``
:rtype: ExpressionIndex
"""
return self.expr(LowLevelILOperation.LLIL_RLC, a, b, carry, size=size, flags=flags)
[docs]
def rotate_right(
self, size: int, a: ExpressionIndex, b: ExpressionIndex, flags: Optional['architecture.FlagType'] = None
) -> ExpressionIndex:
"""
``rotate_right`` bitwise rotates right expression ``a`` by expression ``b`` potentially setting flags ``flags``
and returning an expression of ``size`` bytes.
:param int size: the size of the result in bytes
:param ExpressionIndex a: LHS expression
:param ExpressionIndex b: RHS expression
:param str flags: optional, flags to set
:return: The expression ``ror.<size>{<flags>}(a, b)``
:rtype: ExpressionIndex
"""
return self.expr(LowLevelILOperation.LLIL_ROR, a, b, size=size, flags=flags)
[docs]
def rotate_right_carry(
self, size: int, a: ExpressionIndex, b: ExpressionIndex, carry: ExpressionIndex,
flags: Optional['architecture.FlagType'] = None
) -> ExpressionIndex:
"""
``rotate_right_carry`` bitwise rotates right with carry expression ``a`` by expression ``b`` potentially setting
flags ``flags`` and returning an expression of ``size`` bytes.
:param int size: the size of the result in bytes
:param ExpressionIndex a: LHS expression
:param ExpressionIndex b: RHS expression
:param ExpressionIndex carry: Carry flag expression
:param str flags: optional, flags to set
:return: The expression ``rrc.<size>{<flags>}(a, b, carry)``
:rtype: ExpressionIndex
"""
return self.expr(LowLevelILOperation.LLIL_RRC, a, b, carry, size=size, flags=flags)
[docs]
def mult(
self, size: int, a: ExpressionIndex, b: ExpressionIndex, flags: Optional['architecture.FlagType'] = None
) -> ExpressionIndex:
"""
``mult`` multiplies expression ``a`` by expression ``b`` potentially setting flags ``flags`` and returning an
expression. Both the operands and return value are ``size`` bytes as the product's upper half is discarded.
:param int size: the size of the result and input operands, in bytes
:param ExpressionIndex a: LHS expression
:param ExpressionIndex b: RHS expression
:param str flags: optional, flags to set
:return: The expression ``sbc.<size>{<flags>}(a, b)``
:rtype: ExpressionIndex
"""
return self.expr(LowLevelILOperation.LLIL_MUL, a, b, size=size, flags=flags)
[docs]
def mult_double_prec_signed(
self, size: int, a: ExpressionIndex, b: ExpressionIndex, flags: Optional['architecture.FlagType'] = None
) -> ExpressionIndex:
"""
``mult_double_prec_signed`` multiplies signed with double precision expression ``a`` by expression ``b``,
each ``size`` bytes and potentially setting flags ``flags`` and returning an expression of ``2*size`` bytes.
:param int size: the size of the input operands, in bytes
:param ExpressionIndex a: LHS expression
:param ExpressionIndex b: RHS expression
:param str flags: optional, flags to set
:return: The expression ``muls.dp.<2*size>{<flags>}(a, b)``
:rtype: ExpressionIndex
"""
return self.expr(LowLevelILOperation.LLIL_MULS_DP, a, b, size=size, flags=flags)
[docs]
def mult_double_prec_unsigned(
self, size: int, a: ExpressionIndex, b: ExpressionIndex, flags: Optional['architecture.FlagType'] = None
) -> ExpressionIndex:
"""
``mult_double_prec_unsigned`` multiplies unsigned with double precision expression ``a`` by expression ``b``,
each ``size`` bytes and potentially setting flags ``flags`` and returning an expression of ``2*size`` bytes.
:param int size: the size of the input operands, in bytes
:param ExpressionIndex a: LHS expression
:param ExpressionIndex b: RHS expression
:param str flags: optional, flags to set
:return: The expression ``mulu.dp.<2*size>{<flags>}(a, b)``
:rtype: ExpressionIndex
"""
return self.expr(LowLevelILOperation.LLIL_MULU_DP, a, b, size=size, flags=flags)
[docs]
def div_signed(
self, size: int, a: ExpressionIndex, b: ExpressionIndex, flags: Optional['architecture.FlagType'] = None
) -> ExpressionIndex:
"""
``div_signed`` signed divide expression ``a`` by expression ``b`` potentially setting flags ``flags``
and returning an expression of ``size`` bytes.
:param int size: the size of the result in bytes
:param ExpressionIndex a: LHS expression
:param ExpressionIndex b: RHS expression
:param str flags: optional, flags to set
:return: The expression ``divs.<size>{<flags>}(a, b)``
:rtype: ExpressionIndex
"""
return self.expr(LowLevelILOperation.LLIL_DIVS, a, b, size=size, flags=flags)
[docs]
def div_double_prec_signed(
self, size: int, a: ExpressionIndex, b: ExpressionIndex, flags: Optional['architecture.FlagType'] = None
) -> ExpressionIndex:
"""
``div_double_prec_signed`` signed double precision divide using expression ``a`` as a
single double precision register by expression ``b`` potentially setting flags ``flags`` and returning an
expression of ``size`` bytes.
:param int size: the size of the result in bytes
:param ExpressionIndex a: LHS expression
:param ExpressionIndex b: RHS expression
:param str flags: optional, flags to set
:return: The expression ``divs.dp.<size>{<flags>}(a, b)``
:rtype: ExpressionIndex
"""
return self.expr(LowLevelILOperation.LLIL_DIVS_DP, a, b, size=size, flags=flags)
[docs]
def div_unsigned(
self, size: int, a: ExpressionIndex, b: ExpressionIndex, flags: Optional['architecture.FlagType'] = None
) -> ExpressionIndex:
"""
``div_unsigned`` unsigned divide expression ``a`` by expression ``b`` potentially setting flags ``flags``
and returning an expression of ``size`` bytes.
:param int size: the size of the result in bytes
:param ExpressionIndex a: LHS expression
:param ExpressionIndex b: RHS expression
:param str flags: optional, flags to set
:return: The expression ``divu.<size>{<flags>}(a, b)``
:rtype: ExpressionIndex
"""
return self.expr(LowLevelILOperation.LLIL_DIVU, a, b, size=size, flags=flags)
[docs]
def div_double_prec_unsigned(
self, size: int, a: ExpressionIndex, b: ExpressionIndex, flags: Optional['architecture.FlagType'] = None
) -> ExpressionIndex:
"""
``div_double_prec_unsigned`` unsigned double precision divide using expression ``a`` as
a single double precision register by expression ``b`` potentially setting flags ``flags`` and returning an
expression of ``size`` bytes.
:param int size: the size of the result in bytes
:param ExpressionIndex a: LHS expression
:param ExpressionIndex b: RHS expression
:param str flags: optional, flags to set
:return: The expression ``divu.dp.<size>{<flags>}(a, b)``
:rtype: ExpressionIndex
"""
return self.expr(LowLevelILOperation.LLIL_DIVU_DP, a, b, size=size, flags=flags)
[docs]
def mod_signed(
self, size: int, a: ExpressionIndex, b: ExpressionIndex, flags: Optional['architecture.FlagType'] = None
) -> ExpressionIndex:
"""
``mod_signed`` signed modulus expression ``a`` by expression ``b`` potentially setting flags ``flags``
and returning an expression of ``size`` bytes.
:param int size: the size of the result in bytes
:param ExpressionIndex a: LHS expression
:param ExpressionIndex b: RHS expression
:param str flags: optional, flags to set
:return: The expression ``mods.<size>{<flags>}(a, b)``
:rtype: ExpressionIndex
"""
return self.expr(LowLevelILOperation.LLIL_MODS, a, b, size=size, flags=flags)
[docs]
def mod_double_prec_signed(
self, size: int, a: ExpressionIndex, b: ExpressionIndex, flags: Optional['architecture.FlagType'] = None
) -> ExpressionIndex:
"""
``mod_double_prec_signed`` signed double precision modulus using expression ``a`` as a single
double precision register by expression ``b`` potentially setting flags ``flags`` and returning an expression
of ``size`` bytes.
:param int size: the size of the result in bytes
:param ExpressionIndex a: LHS expression
:param ExpressionIndex b: RHS expression
:param str flags: optional, flags to set
:return: The expression ``mods.dp.<size>{<flags>}(a, b)``
:rtype: ExpressionIndex
"""
return self.expr(LowLevelILOperation.LLIL_MODS_DP, a, b, size=size, flags=flags)
[docs]
def mod_unsigned(
self, size: int, a: ExpressionIndex, b: ExpressionIndex, flags: Optional['architecture.FlagType'] = None
) -> ExpressionIndex:
"""
``mod_unsigned`` unsigned modulus expression ``a`` by expression ``b`` potentially setting flags ``flags``
and returning an expression of ``size`` bytes.
:param int size: the size of the result in bytes
:param ExpressionIndex a: LHS expression
:param ExpressionIndex b: RHS expression
:param str flags: optional, flags to set
:return: The expression ``modu.<size>{<flags>}(a, b)``
:rtype: ExpressionIndex
"""
return self.expr(LowLevelILOperation.LLIL_MODU, a, b, size=size, flags=flags)
[docs]
def mod_double_prec_unsigned(
self, size: int, a: ExpressionIndex, b: ExpressionIndex, flags: Optional['architecture.FlagType'] = None
) -> ExpressionIndex:
"""
``mod_double_prec_unsigned`` unsigned double precision modulus using expression ``a`` as
a single double precision register by expression ``b`` potentially setting flags ``flags`` and returning an
expression of ``size`` bytes.
:param int size: the size of the result in bytes
:param ExpressionIndex a: LHS expression
:param ExpressionIndex b: RHS expression
:param str flags: optional, flags to set
:return: The expression ``modu.dp.<size>{<flags>}(a, b)``
:rtype: ExpressionIndex
"""
return self.expr(LowLevelILOperation.LLIL_MODU_DP, a, b, size=size, flags=flags)
[docs]
def neg_expr(self, size: int, value: ExpressionIndex, flags: Optional['architecture.FlagType'] = None) -> ExpressionIndex:
"""
``neg_expr`` two's complement sign negation of expression ``value`` of size ``size`` potentially setting flags
:param int size: the size of the result in bytes
:param ExpressionIndex value: the expression to negate
:param str flags: optional, flags to set
:return: The expression ``neg.<size>{<flags>}(value)``
:rtype: ExpressionIndex
"""
return self.expr(LowLevelILOperation.LLIL_NEG, value, size=size, flags=flags)
[docs]
def not_expr(self, size: int, value: ExpressionIndex, flags: Optional['architecture.FlagType'] = None) -> ExpressionIndex:
"""
``not_expr`` bitwise inverse of expression ``value`` of size ``size`` potentially setting flags
:param int size: the size of the result in bytes
:param ExpressionIndex value: the expression to bitwise invert
:param str flags: optional, flags to set
:return: The expression ``not.<size>{<flags>}(value)``
:rtype: ExpressionIndex
"""
return self.expr(LowLevelILOperation.LLIL_NOT, value, size=size, flags=flags)
[docs]
def sign_extend(self, size: int, value: ExpressionIndex, flags: Optional['architecture.FlagType'] = None) -> ExpressionIndex:
"""
``sign_extend`` two's complement sign-extends the expression in ``value`` to ``size`` bytes
:param int size: the size of the result in bytes
:param ExpressionIndex value: the expression to sign extend
:param str flags: optional, flags to set
:return: The expression ``sx.<size>(value)``
:rtype: ExpressionIndex
"""
return self.expr(LowLevelILOperation.LLIL_SX, value, size=size, flags=flags)
[docs]
def zero_extend(self, size: int, value: ExpressionIndex, flags: Optional['architecture.FlagType'] = None) -> ExpressionIndex:
"""
``zero_extend`` zero-extends the expression in ``value`` to ``size`` bytes
:param int size: the size of the result in bytes
:param ExpressionIndex value: the expression to zero extend
:return: The expression ``zx.<size>(value)``
:rtype: ExpressionIndex
"""
return self.expr(LowLevelILOperation.LLIL_ZX, value, size=size, flags=flags)
[docs]
def low_part(self, size: int, value: ExpressionIndex, flags: Optional['architecture.FlagType'] = None) -> ExpressionIndex:
"""
``low_part`` truncates ``value`` to ``size`` bytes
:param int size: the size of the result in bytes
:param ExpressionIndex value: the expression to truncate
:return: The expression ``(value).<size>``
:rtype: ExpressionIndex
"""
return self.expr(LowLevelILOperation.LLIL_LOW_PART, value, size=size, flags=flags)
[docs]
def jump(self, dest: ExpressionIndex) -> ExpressionIndex:
"""
``jump`` returns an expression which jumps (branches) to the expression ``dest``
:param ExpressionIndex dest: the expression to jump to
:return: The expression ``jump(dest)``
:rtype: ExpressionIndex
"""
return self.expr(LowLevelILOperation.LLIL_JUMP, dest)
[docs]
def call(self, dest: ExpressionIndex) -> ExpressionIndex:
"""
``call`` returns an expression which first pushes the address of the next instruction onto the stack then jumps
(branches) to the expression ``dest``
:param ExpressionIndex dest: the expression to call
:return: The expression ``call(dest)``
:rtype: ExpressionIndex
"""
return self.expr(LowLevelILOperation.LLIL_CALL, dest)
[docs]
def call_stack_adjust(self, dest: ExpressionIndex, stack_adjust: int) -> ExpressionIndex:
"""
``call_stack_adjust`` returns an expression which first pushes the address of the next instruction onto the stack
then jumps (branches) to the expression ``dest``. After the function exits, ``stack_adjust`` is added to the
stack pointer register.
:param ExpressionIndex dest: the expression to call
:return: The expression ``call(dest), stack += stack_adjust``
:rtype: ExpressionIndex
"""
return self.expr(LowLevelILOperation.LLIL_CALL_STACK_ADJUST, dest, stack_adjust)
[docs]
def tailcall(self, dest: ExpressionIndex) -> ExpressionIndex:
"""
``tailcall`` returns an expression which jumps (branches) to the expression ``dest``
:param ExpressionIndex dest: the expression to jump to
:return: The expression ``tailcall(dest)``
:rtype: ExpressionIndex
"""
return self.expr(LowLevelILOperation.LLIL_TAILCALL, dest)
[docs]
def ret(self, dest: ExpressionIndex) -> ExpressionIndex:
"""
``ret`` returns an expression which jumps (branches) to the expression ``dest``. ``ret`` is a special alias for
jump that makes the disassembler stop disassembling.
:param ExpressionIndex dest: the expression to jump to
:return: The expression ``jump(dest)``
:rtype: ExpressionIndex
"""
return self.expr(LowLevelILOperation.LLIL_RET, dest)
[docs]
def no_ret(self) -> ExpressionIndex:
"""
``no_ret`` returns an expression that halts disassembly
:return: The expression ``noreturn``
:rtype: ExpressionIndex
"""
return self.expr(LowLevelILOperation.LLIL_NORET)
[docs]
def flag_condition(
self, cond: Union[str, LowLevelILFlagCondition, int],
sem_class: Optional['architecture.SemanticClassType'] = None
) -> ExpressionIndex:
"""
``flag_condition`` returns a flag_condition expression for the given LowLevelILFlagCondition
:param LowLevelILFlagCondition cond: Flag condition expression to retrieve
:param str sem_class: Optional semantic flag class
:return: A flag_condition expression
:rtype: ExpressionIndex
"""
if isinstance(cond, str):
cond = LowLevelILFlagCondition[cond]
elif isinstance(cond, LowLevelILFlagCondition):
cond = cond.value
class_index = self.arch.get_semantic_flag_class_index(sem_class)
return self.expr(LowLevelILOperation.LLIL_FLAG_COND, cond, architecture.SemanticClassIndex(class_index))
[docs]
def flag_group(self, sem_group: 'architecture.SemanticGroupName') -> ExpressionIndex:
"""
``flag_group`` returns a flag_group expression for the given semantic flag group
:param SemanticGroupName sem_group: Semantic flag group to access
:return: A flag_group expression
:rtype: ExpressionIndex
"""
group = self.arch.get_semantic_flag_group_index(sem_group)
return self.expr(LowLevelILOperation.LLIL_FLAG_GROUP, group)
[docs]
def compare_equal(self, size: int, a: ExpressionIndex, b: ExpressionIndex) -> ExpressionIndex:
"""
``compare_equal`` returns comparison expression of size ``size`` checking if expression ``a`` is equal to
expression ``b``
:param int size: size in bytes
:param ExpressionIndex a: LHS of comparison
:param ExpressionIndex b: RHS of comparison
:return: a comparison expression.
:rtype: ExpressionIndex
"""
return self.expr(LowLevelILOperation.LLIL_CMP_E, a, b, size=size)
[docs]
def compare_not_equal(self, size: int, a: ExpressionIndex, b: ExpressionIndex) -> ExpressionIndex:
"""
``compare_not_equal`` returns comparison expression of size ``size`` checking if expression ``a`` is not equal to
expression ``b``
:param int size: size in bytes
:param ExpressionIndex a: LHS of comparison
:param ExpressionIndex b: RHS of comparison
:return: a comparison expression.
:rtype: ExpressionIndex
"""
return self.expr(LowLevelILOperation.LLIL_CMP_NE, a, b, size=size)
[docs]
def compare_signed_less_than(self, size: int, a: ExpressionIndex, b: ExpressionIndex) -> ExpressionIndex:
"""
``compare_signed_less_than`` returns comparison expression of size ``size`` checking if expression ``a`` is
signed less than expression ``b``
:param int size: size in bytes
:param ExpressionIndex a: LHS of comparison
:param ExpressionIndex b: RHS of comparison
:return: a comparison expression.
:rtype: ExpressionIndex
"""
return self.expr(LowLevelILOperation.LLIL_CMP_SLT, a, b, size=size)
[docs]
def compare_unsigned_less_than(self, size: int, a: ExpressionIndex, b: ExpressionIndex) -> ExpressionIndex:
"""
``compare_unsigned_less_than`` returns comparison expression of size ``size`` checking if expression ``a`` is
unsigned less than expression ``b``
:param int size: size in bytes
:param ExpressionIndex a: LHS of comparison
:param ExpressionIndex b: RHS of comparison
:return: a comparison expression.
:rtype: ExpressionIndex
"""
return self.expr(LowLevelILOperation.LLIL_CMP_ULT, a, b, size=size)
[docs]
def compare_signed_less_equal(self, size: int, a: ExpressionIndex, b: ExpressionIndex) -> ExpressionIndex:
"""
``compare_signed_less_equal`` returns comparison expression of size ``size`` checking if expression ``a`` is
signed less than or equal to expression ``b``
:param int size: size in bytes
:param ExpressionIndex a: LHS of comparison
:param ExpressionIndex b: RHS of comparison
:return: a comparison expression.
:rtype: ExpressionIndex
"""
return self.expr(LowLevelILOperation.LLIL_CMP_SLE, a, b, size=size)
[docs]
def compare_unsigned_less_equal(self, size: int, a: ExpressionIndex, b: ExpressionIndex) -> ExpressionIndex:
"""
``compare_unsigned_less_equal`` returns comparison expression of size ``size`` checking if expression ``a`` is
unsigned less than or equal to expression ``b``
:param int size: size in bytes
:param ExpressionIndex a: LHS of comparison
:param ExpressionIndex b: RHS of comparison
:return: a comparison expression.
:rtype: ExpressionIndex
"""
return self.expr(LowLevelILOperation.LLIL_CMP_ULE, a, b, size=size)
[docs]
def compare_signed_greater_equal(self, size: int, a: ExpressionIndex, b: ExpressionIndex) -> ExpressionIndex:
"""
``compare_signed_greater_equal`` returns comparison expression of size ``size`` checking if expression ``a`` is
signed greater than or equal to expression ``b``
:param int size: size in bytes
:param ExpressionIndex a: LHS of comparison
:param ExpressionIndex b: RHS of comparison
:return: a comparison expression.
:rtype: ExpressionIndex
"""
return self.expr(LowLevelILOperation.LLIL_CMP_SGE, a, b, size=size)
[docs]
def compare_unsigned_greater_equal(self, size: int, a: ExpressionIndex, b: ExpressionIndex) -> ExpressionIndex:
"""
``compare_unsigned_greater_equal`` returns comparison expression of size ``size`` checking if expression ``a``
is unsigned greater than or equal to expression ``b``
:param int size: size in bytes
:param ExpressionIndex a: LHS of comparison
:param ExpressionIndex b: RHS of comparison
:return: a comparison expression.
:rtype: ExpressionIndex
"""
return self.expr(LowLevelILOperation.LLIL_CMP_UGE, a, b, size=size)
[docs]
def compare_signed_greater_than(self, size: int, a: ExpressionIndex, b: ExpressionIndex) -> ExpressionIndex:
"""
``compare_signed_greater_than`` returns comparison expression of size ``size`` checking if expression ``a`` is
signed greater than or equal to expression ``b``
:param int size: size in bytes
:param ExpressionIndex a: LHS of comparison
:param ExpressionIndex b: RHS of comparison
:return: a comparison expression.
:rtype: ExpressionIndex
"""
return self.expr(LowLevelILOperation.LLIL_CMP_SGT, a, b, size=size)
[docs]
def compare_unsigned_greater_than(self, size: int, a: ExpressionIndex, b: ExpressionIndex) -> ExpressionIndex:
"""
``compare_unsigned_greater_than`` returns comparison expression of size ``size`` checking if expression ``a`` is
unsigned greater than or equal to expression ``b``
:param int size: size in bytes
:param ExpressionIndex a: LHS of comparison
:param ExpressionIndex b: RHS of comparison
:return: a comparison expression.
:rtype: ExpressionIndex
"""
return self.expr(LowLevelILOperation.LLIL_CMP_UGT, a, b, size=size)
[docs]
def test_bit(self, size: int, a: ExpressionIndex, b: ExpressionIndex) -> ExpressionIndex:
return self.expr(LowLevelILOperation.LLIL_TEST_BIT, a, b, size=size)
[docs]
def system_call(self) -> ExpressionIndex:
"""
``system_call`` return a system call expression.
:return: a system call expression.
:rtype: ExpressionIndex
"""
return self.expr(LowLevelILOperation.LLIL_SYSCALL)
[docs]
def intrinsic(
self, outputs: List[Union[ILRegisterType, ILFlag, 'architecture.RegisterInfo']], intrinsic: 'architecture.IntrinsicType',
params: List[ExpressionIndex], flags: Optional['architecture.FlagType'] = None
):
"""
``intrinsic`` return an intrinsic expression.
:return: an intrinsic expression.
:rtype: ExpressionIndex
"""
output_list = []
for output in outputs:
if isinstance(output, str):
if architecture.RegisterName(output) in self.arch.regs:
output_list.append(self.arch.regs[architecture.RegisterName(output)].index)
elif architecture.FlagName(output) in self.arch.flags:
output_list.append((1 << 32) | self.arch.get_flag_by_name(architecture.FlagName(output)))
else:
raise Exception("Invalid register or flag name")
elif isinstance(output, architecture.RegisterInfo):
output_list.append(output.index)
elif isinstance(output, ILRegister):
output_list.append(output.index)
elif isinstance(output, ILFlag):
output_list.append((1 << 32) | output.index)
else:
output_list.append(output)
param_list = []
for param in params:
param_list.append(param)
call_param = self.expr(LowLevelILOperation.LLIL_CALL_PARAM, len(params), self.add_operand_list(param_list))
return self.expr(
LowLevelILOperation.LLIL_INTRINSIC, len(outputs), self.add_operand_list(output_list),
self.arch.get_intrinsic_index(intrinsic), call_param, flags=flags
)
[docs]
def breakpoint(self) -> ExpressionIndex:
"""
``breakpoint`` returns a processor breakpoint expression.
:return: a breakpoint expression.
:rtype: ExpressionIndex
"""
return self.expr(LowLevelILOperation.LLIL_BP)
[docs]
def trap(self, value: int) -> ExpressionIndex:
"""
``trap`` returns a processor trap (interrupt) expression of the given integer ``value``.
:param int value: trap (interrupt) number
:return: a trap expression.
:rtype: ExpressionIndex
"""
return self.expr(LowLevelILOperation.LLIL_TRAP, value)
[docs]
def undefined(self) -> ExpressionIndex:
"""
``undefined`` returns the undefined expression. This should be used for instructions which perform functions but
aren't important for dataflow or partial emulation purposes.
:return: the undefined expression.
:rtype: ExpressionIndex
"""
return self.expr(LowLevelILOperation.LLIL_UNDEF)
[docs]
def unimplemented(self) -> ExpressionIndex:
"""
``unimplemented`` returns the unimplemented expression. This should be used for all instructions which aren't
implemented.
:return: the unimplemented expression.
:rtype: ExpressionIndex
"""
return self.expr(LowLevelILOperation.LLIL_UNIMPL)
[docs]
def unimplemented_memory_ref(self, size: int, addr: ExpressionIndex) -> ExpressionIndex:
"""
``unimplemented_memory_ref`` a memory reference to expression ``addr`` of size ``size`` with unimplemented operation.
:param int size: size in bytes of the memory reference
:param ExpressionIndex addr: expression to reference memory
:return: the unimplemented memory reference expression.
:rtype: ExpressionIndex
"""
return self.expr(LowLevelILOperation.LLIL_UNIMPL_MEM, addr, size=size)
[docs]
def float_add(
self, size: int, a: ExpressionIndex, b: ExpressionIndex, flags: Optional['architecture.FlagType'] = None
) -> ExpressionIndex:
"""
``float_add`` adds floating point expression ``a`` to expression ``b`` potentially setting flags ``flags``
and returning an expression of ``size`` bytes.
:param int size: the size of the result in bytes
:param ExpressionIndex a: LHS expression
:param ExpressionIndex b: RHS expression
:param str flags: flags to set
:return: The expression ``fadd.<size>{<flags>}(a, b)``
:rtype: ExpressionIndex
"""
return self.expr(LowLevelILOperation.LLIL_FADD, a, b, size=size, flags=flags)
[docs]
def float_sub(
self, size: int, a: ExpressionIndex, b: ExpressionIndex, flags: Optional['architecture.FlagType'] = None
) -> ExpressionIndex:
"""
``float_sub`` subtracts floating point expression ``b`` from expression ``a`` potentially setting flags ``flags``
and returning an expression of ``size`` bytes.
:param int size: the size of the result in bytes
:param ExpressionIndex a: LHS expression
:param ExpressionIndex b: RHS expression
:param str flags: flags to set
:return: The expression ``fsub.<size>{<flags>}(a, b)``
:rtype: ExpressionIndex
"""
return self.expr(LowLevelILOperation.LLIL_FSUB, a, b, size=size, flags=flags)
[docs]
def float_mult(
self, size: int, a: ExpressionIndex, b: ExpressionIndex, flags: Optional['architecture.FlagType'] = None
) -> ExpressionIndex:
"""
``float_mult`` multiplies floating point expression ``a`` by expression ``b`` potentially setting flags ``flags``
and returning an expression of ``size`` bytes.
:param int size: the size of the result in bytes
:param ExpressionIndex a: LHS expression
:param ExpressionIndex b: RHS expression
:param str flags: flags to set
:return: The expression ``fmul.<size>{<flags>}(a, b)``
:rtype: ExpressionIndex
"""
return self.expr(LowLevelILOperation.LLIL_FMUL, a, b, size=size, flags=flags)
[docs]
def float_div(
self, size: int, a: ExpressionIndex, b: ExpressionIndex, flags: Optional['architecture.FlagType'] = None
) -> ExpressionIndex:
"""
``float_div`` divides floating point expression ``a`` by expression ``b`` potentially setting flags ``flags``
and returning an expression of ``size`` bytes.
:param int size: the size of the result in bytes
:param ExpressionIndex a: LHS expression
:param ExpressionIndex b: RHS expression
:param str flags: flags to set
:return: The expression ``fdiv.<size>{<flags>}(a, b)``
:rtype: ExpressionIndex
"""
return self.expr(LowLevelILOperation.LLIL_FDIV, a, b, size=size, flags=flags)
[docs]
def float_sqrt(self, size: int, value: ExpressionIndex, flags: Optional['architecture.FlagType'] = None) -> ExpressionIndex:
"""
``float_sqrt`` returns square root of floating point expression ``value`` of size ``size`` potentially setting flags
:param int size: the size of the result in bytes
:param ExpressionIndex value: the expression to calculate the square root of
:param str flags: optional, flags to set
:return: The expression ``sqrt.<size>{<flags>}(value)``
:rtype: ExpressionIndex
"""
return self.expr(LowLevelILOperation.LLIL_FSQRT, value, size=size, flags=flags)
[docs]
def float_neg(self, size: int, value: ExpressionIndex, flags: Optional['architecture.FlagType'] = None) -> ExpressionIndex:
"""
``float_neg`` returns sign negation of floating point expression ``value`` of size ``size`` potentially setting flags
:param int size: the size of the result in bytes
:param ExpressionIndex value: the expression to negate
:param str flags: optional, flags to set
:return: The expression ``fneg.<size>{<flags>}(value)``
:rtype: ExpressionIndex
"""
return self.expr(LowLevelILOperation.LLIL_FNEG, value, size=size, flags=flags)
[docs]
def float_abs(self, size: int, value: ExpressionIndex, flags: Optional['architecture.FlagType'] = None) -> ExpressionIndex:
"""
``float_abs`` returns absolute value of floating point expression ``value`` of size ``size`` potentially setting flags
:param int size: the size of the result in bytes
:param ExpressionIndex value: the expression to get the absolute value of
:param str flags: optional, flags to set
:return: The expression ``fabs.<size>{<flags>}(value)``
:rtype: ExpressionIndex
"""
return self.expr(LowLevelILOperation.LLIL_FABS, value, size=size, flags=flags)
[docs]
def float_to_int(self, size: int, value: ExpressionIndex, flags: Optional['architecture.FlagType'] = None) -> ExpressionIndex:
"""
``float_to_int`` returns integer value of floating point expression ``value`` of size ``size`` potentially setting flags
:param int size: the size of the result in bytes
:param ExpressionIndex value: the expression to convert to an int
:param str flags: optional, flags to set
:return: The expression ``int.<size>{<flags>}(value)``
:rtype: ExpressionIndex
"""
return self.expr(LowLevelILOperation.LLIL_FLOAT_TO_INT, value, size=size, flags=flags)
[docs]
def int_to_float(self, size: int, value: ExpressionIndex, flags: Optional['architecture.FlagType'] = None) -> ExpressionIndex:
"""
``int_to_float`` returns floating point value of integer expression ``value`` of size ``size`` potentially setting flags
:param int size: the size of the result in bytes
:param ExpressionIndex value: the expression to convert to a float
:param str flags: optional, flags to set
:return: The expression ``float.<size>{<flags>}(value)``
:rtype: ExpressionIndex
"""
return self.expr(LowLevelILOperation.LLIL_INT_TO_FLOAT, value, size=size, flags=flags)
[docs]
def float_convert(
self, size: int, value: ExpressionIndex, flags: Optional['architecture.FlagType'] = None
) -> ExpressionIndex:
"""
``int_to_float`` converts floating point value of expression ``value`` to size ``size`` potentially setting flags
:param int size: the size of the result in bytes
:param ExpressionIndex value: the expression to negate
:param str flags: optional, flags to set
:return: The expression ``fconvert.<size>{<flags>}(value)``
:rtype: ExpressionIndex
"""
return self.expr(LowLevelILOperation.LLIL_FLOAT_CONV, value, size=size, flags=flags)
[docs]
def round_to_int(self, size: int, value: ExpressionIndex, flags: Optional['architecture.FlagType'] = None) -> ExpressionIndex:
"""
``round_to_int`` rounds a floating point value to the nearest integer
:param int size: the size of the result in bytes
:param ExpressionIndex value: the expression to round to the nearest integer
:param str flags: optional, flags to set
:return: The expression ``roundint.<size>{<flags>}(value)``
:rtype: ExpressionIndex
"""
return self.expr(LowLevelILOperation.LLIL_ROUND_TO_INT, value, size=size, flags=flags)
[docs]
def floor(self, size: int, value: ExpressionIndex, flags: Optional['architecture.FlagType'] = None) -> ExpressionIndex:
"""
``floor`` rounds a floating point value to an integer towards negative infinity
:param int size: the size of the result in bytes
:param ExpressionIndex value: the expression to round down
:param str flags: optional, flags to set
:return: The expression ``roundint.<size>{<flags>}(value)``
:rtype: ExpressionIndex
"""
return self.expr(LowLevelILOperation.LLIL_FLOOR, value, size=size, flags=flags)
[docs]
def ceil(self, size: int, value: ExpressionIndex, flags: Optional['architecture.FlagType'] = None) -> ExpressionIndex:
"""
``ceil`` rounds a floating point value to an integer towards positive infinity
:param int size: the size of the result in bytes
:param ExpressionIndex value: the expression to round up
:param str flags: optional, flags to set
:return: The expression ``roundint.<size>{<flags>}(value)``
:rtype: ExpressionIndex
"""
return self.expr(LowLevelILOperation.LLIL_CEIL, value, size=size, flags=flags)
[docs]
def float_trunc(self, size: int, value: ExpressionIndex, flags: Optional['architecture.FlagType'] = None) -> ExpressionIndex:
"""
``float_trunc`` rounds a floating point value to an integer towards zero
:param int size: the size of the result in bytes
:param ExpressionIndex value: the expression to truncate
:param str flags: optional, flags to set
:return: The expression ``roundint.<size>{<flags>}(value)``
:rtype: ExpressionIndex
"""
return self.expr(LowLevelILOperation.LLIL_FTRUNC, value, size=size, flags=flags)
[docs]
def float_compare_equal(self, size: int, a: ExpressionIndex, b: ExpressionIndex) -> ExpressionIndex:
"""
``float_compare_equal`` returns floating point comparison expression of size ``size`` checking if
expression ``a`` is equal to expression ``b``
:param int size: the size of the operands in bytes
:param ExpressionIndex a: LHS expression
:param ExpressionIndex b: RHS expression
:param str flags: flags to set
:return: The expression ``a f== b``
:rtype: ExpressionIndex
"""
return self.expr(LowLevelILOperation.LLIL_FCMP_E, a, b)
[docs]
def float_compare_not_equal(self, size: int, a: ExpressionIndex, b: ExpressionIndex) -> ExpressionIndex:
"""
``float_compare_not_equal`` returns floating point comparison expression of size ``size`` checking if
expression ``a`` is not equal to expression ``b``
:param int size: the size of the operands in bytes
:param ExpressionIndex a: LHS expression
:param ExpressionIndex b: RHS expression
:param str flags: flags to set
:return: The expression ``a f!= b``
:rtype: ExpressionIndex
"""
return self.expr(LowLevelILOperation.LLIL_FCMP_NE, a, b)
[docs]
def float_compare_less_than(self, size: int, a: ExpressionIndex, b: ExpressionIndex) -> ExpressionIndex:
"""
``float_compare_less_than`` returns floating point comparison expression of size ``size`` checking if
expression ``a`` is less than expression ``b``
:param int size: the size of the operands in bytes
:param ExpressionIndex a: LHS expression
:param ExpressionIndex b: RHS expression
:param str flags: flags to set
:return: The expression ``a f< b``
:rtype: ExpressionIndex
"""
return self.expr(LowLevelILOperation.LLIL_FCMP_LT, a, b)
[docs]
def float_compare_less_equal(self, size: int, a: ExpressionIndex, b: ExpressionIndex) -> ExpressionIndex:
"""
``float_compare_less_equal`` returns floating point comparison expression of size ``size`` checking if
expression ``a`` is less than or equal to expression ``b``
:param int size: the size of the operands in bytes
:param ExpressionIndex a: LHS expression
:param ExpressionIndex b: RHS expression
:param str flags: flags to set
:return: The expression ``a f<= b``
:rtype: ExpressionIndex
"""
return self.expr(LowLevelILOperation.LLIL_FCMP_LE, a, b)
[docs]
def float_compare_greater_equal(self, size: int, a: ExpressionIndex, b: ExpressionIndex) -> ExpressionIndex:
"""
``float_compare_greater_equal`` returns floating point comparison expression of size ``size`` checking if
expression ``a`` is greater than or equal to expression ``b``
:param int size: the size of the operands in bytes
:param ExpressionIndex a: LHS expression
:param ExpressionIndex b: RHS expression
:param str flags: flags to set
:return: The expression ``a f>= b``
:rtype: ExpressionIndex
"""
return self.expr(LowLevelILOperation.LLIL_FCMP_GE, a, b)
[docs]
def float_compare_greater_than(self, size: int, a: ExpressionIndex, b: ExpressionIndex) -> ExpressionIndex:
"""
``float_compare_greater_than`` returns floating point comparison expression of size ``size`` checking if
expression ``a`` is greater than expression ``b``
:param int size: the size of the operands in bytes
:param ExpressionIndex a: LHS expression
:param ExpressionIndex b: RHS expression
:param str flags: flags to set
:return: The expression ``a f> b``
:rtype: ExpressionIndex
"""
return self.expr(LowLevelILOperation.LLIL_FCMP_GT, a, b)
[docs]
def float_compare_ordered(self, size: int, a: ExpressionIndex, b: ExpressionIndex) -> ExpressionIndex:
"""
``float_compare_ordered`` returns floating point comparison expression of size ``size`` checking if
expression ``a`` is ordered relative to expression ``b``
:param int size: the size of the operands in bytes
:param ExpressionIndex a: LHS expression
:param ExpressionIndex b: RHS expression
:param str flags: flags to set
:return: The expression ``is_ordered(a, b)``
:rtype: ExpressionIndex
"""
return self.expr(LowLevelILOperation.LLIL_FCMP_O, a, b)
[docs]
def float_compare_unordered(self, size: int, a: ExpressionIndex, b: ExpressionIndex) -> ExpressionIndex:
"""
``float_compare_unordered`` returns floating point comparison expression of size ``size`` checking if
expression ``a`` is unordered relative to expression ``b``
:param int size: the size of the operands in bytes
:param ExpressionIndex a: LHS expression
:param ExpressionIndex b: RHS expression
:param str flags: flags to set
:return: The expression ``is_unordered(a, b)``
:rtype: ExpressionIndex
"""
return self.expr(LowLevelILOperation.LLIL_FCMP_UO, a, b)
[docs]
def goto(self, label: LowLevelILLabel) -> ExpressionIndex:
"""
``goto`` returns a goto expression which jumps to the provided LowLevelILLabel.
:param LowLevelILLabel label: Label to jump to
:return: the ExpressionIndex that jumps to the provided label
:rtype: ExpressionIndex
"""
return ExpressionIndex(core.BNLowLevelILGoto(self.handle, label.handle))
[docs]
def if_expr(self, operand: ExpressionIndex, t: LowLevelILLabel, f: LowLevelILLabel) -> ExpressionIndex:
"""
``if_expr`` returns the ``if`` expression which depending on condition ``operand`` jumps to the LowLevelILLabel
``t`` when the condition expression ``operand`` is non-zero and ``f`` when it's zero.
:param ExpressionIndex operand: comparison expression to evaluate.
:param LowLevelILLabel t: Label for the true branch
:param LowLevelILLabel f: Label for the false branch
:return: the ExpressionIndex for the if expression
:rtype: ExpressionIndex
"""
return ExpressionIndex(core.BNLowLevelILIf(self.handle, operand, t.handle, f.handle))
[docs]
def mark_label(self, label: LowLevelILLabel) -> None:
"""
``mark_label`` assigns a LowLevelILLabel to the current IL address.
:param LowLevelILLabel label:
:rtype: None
"""
core.BNLowLevelILMarkLabel(self.handle, label.handle)
[docs]
def add_label_map(self, labels: Dict[int, LowLevelILLabel]) -> ExpressionIndex:
"""
``add_label_map`` returns a label list expression for the given list of LowLevelILLabel objects.
:param labels: the list of LowLevelILLabel to get a label list expression from
:type labels: dict(int, LowLevelILLabel)
:return: the label list expression
:rtype: ExpressionIndex
"""
label_list = (ctypes.POINTER(core.BNLowLevelILLabel) * len(labels))()
value_list = (ctypes.POINTER(ctypes.c_ulonglong) * len(labels))()
for i, (key, value) in enumerate(labels.items()):
value_list[i] = key
label_list[i] = value.handle
return ExpressionIndex(core.BNLowLevelILAddLabelMap(self.handle, value_list, label_list, len(labels)))
[docs]
def add_operand_list(self, operands: List[Union[ExpressionIndex, ExpressionIndex]]) -> ExpressionIndex:
"""
``add_operand_list`` returns an operand list expression for the given list of integer operands.
:param operands: list of operand numbers
:type operands: List(Union[ExpressionIndex, ExpressionIndex])
:return: an operand list expression
:rtype: ExpressionIndex
"""
operand_list = (ctypes.c_ulonglong * len(operands))()
for i in range(len(operands)):
op = operands[i]
if isinstance(op, int):
operand_list[i] = ExpressionIndex(op)
else:
raise Exception("Invalid operand type")
return ExpressionIndex(core.BNLowLevelILAddOperandList(self.handle, operand_list, len(operands)))
[docs]
def operand(self, n: int, expr: ExpressionIndex) -> ExpressionIndex:
"""
``operand`` sets the operand number of the expression ``expr`` and passes back ``expr`` without modification.
:param int n:
:param ExpressionIndex expr:
:return: returns the expression ``expr`` unmodified
:rtype: ExpressionIndex
"""
core.BNLowLevelILSetExprSourceOperand(self.handle, expr, n)
return expr
[docs]
def finalize(self) -> None:
"""
``finalize`` ends the function and computes the list of basic blocks.
:rtype: None
"""
core.BNFinalizeLowLevelILFunction(self.handle)
[docs]
def add_label_for_address(self, arch: 'architecture.Architecture', addr: int) -> None:
"""
``add_label_for_address`` adds a low-level IL label for the given architecture ``arch`` at the given virtual
address ``addr``
:param Architecture arch: Architecture to add labels for
:param int addr: the IL address to add a label at
"""
if arch is not None:
arch = arch.handle
core.BNAddLowLevelILLabelForAddress(self.handle, arch, addr)
[docs]
def get_label_for_address(self, arch: 'architecture.Architecture', addr: int) -> Optional[LowLevelILLabel]:
"""
``get_label_for_address`` returns the LowLevelILLabel for the given Architecture ``arch`` and IL address ``addr``.
:param Architecture arch:
:param int addr: IL Address label to retrieve
:return: the LowLevelILLabel for the given IL address
:rtype: LowLevelILLabel
"""
if arch is not None:
arch = arch.handle
label = core.BNGetLowLevelILLabelForAddress(self.handle, arch, addr)
if label is None:
return None
return LowLevelILLabel(label)
[docs]
def get_ssa_instruction_index(self, instr: InstructionIndex) -> InstructionIndex:
return core.BNGetLowLevelILSSAInstructionIndex(self.handle, instr)
[docs]
def get_non_ssa_instruction_index(self, instr: InstructionIndex) -> InstructionIndex:
return core.BNGetLowLevelILNonSSAInstructionIndex(self.handle, instr)
[docs]
def get_ssa_reg_definition(self, reg_ssa: SSARegister) -> Optional[LowLevelILInstruction]:
reg = self.arch.get_reg_index(reg_ssa.reg)
result = core.BNGetLowLevelILSSARegisterDefinition(self.handle, reg, reg_ssa.version)
if result >= core.BNGetLowLevelILInstructionCount(self.handle):
return None
return self[result]
[docs]
def get_ssa_flag_definition(self, flag_ssa: SSAFlag) -> Optional[LowLevelILInstruction]:
flag = self.arch.get_flag_index(flag_ssa.flag)
result = core.BNGetLowLevelILSSAFlagDefinition(self.handle, flag, flag_ssa.version)
if result >= core.BNGetLowLevelILInstructionCount(self.handle):
return None
return self[result]
[docs]
def get_ssa_memory_definition(self, index: int) -> Optional[LowLevelILInstruction]:
result = core.BNGetLowLevelILSSAMemoryDefinition(self.handle, index)
if result >= core.BNGetLowLevelILInstructionCount(self.handle):
return None
return self[result]
[docs]
def get_ssa_reg_uses(self, reg_ssa: SSARegister) -> List[LowLevelILInstruction]:
reg = self.arch.get_reg_index(reg_ssa.reg)
count = ctypes.c_ulonglong()
instrs = core.BNGetLowLevelILSSARegisterUses(self.handle, reg, reg_ssa.version, count)
assert instrs is not None, "core.BNGetLowLevelILSSARegisterUses returned None"
result = []
for i in range(0, count.value):
result.append(self[instrs[i]])
core.BNFreeILInstructionList(instrs)
return result
[docs]
def get_ssa_flag_uses(self, flag_ssa: SSAFlag) -> List[LowLevelILInstruction]:
flag = self.arch.get_flag_index(flag_ssa.flag)
count = ctypes.c_ulonglong()
instrs = core.BNGetLowLevelILSSAFlagUses(self.handle, flag, flag_ssa.version, count)
assert instrs is not None, "core.BNGetLowLevelILSSAFlagUses returned None"
result = []
for i in range(0, count.value):
result.append(self[instrs[i]])
core.BNFreeILInstructionList(instrs)
return result
[docs]
def get_ssa_memory_uses(self, index: int) -> List[LowLevelILInstruction]:
count = ctypes.c_ulonglong()
instrs = core.BNGetLowLevelILSSAMemoryUses(self.handle, index, count)
assert instrs is not None, "core.BNGetLowLevelILSSAMemoryUses returned None"
result = []
for i in range(0, count.value):
result.append(self[instrs[i]])
core.BNFreeILInstructionList(instrs)
return result
[docs]
def get_ssa_reg_value(self, reg_ssa: SSARegister) -> 'variable.RegisterValue':
reg = self.arch.get_reg_index(reg_ssa.reg)
value = core.BNGetLowLevelILSSARegisterValue(self.handle, reg, reg_ssa.version)
result = variable.RegisterValue.from_BNRegisterValue(value, self._arch)
return result
[docs]
def get_ssa_flag_value(self, flag_ssa: SSAFlag) -> 'variable.RegisterValue':
flag = self.arch.get_flag_index(flag_ssa.flag)
value = core.BNGetLowLevelILSSAFlagValue(self.handle, flag, flag_ssa.version)
result = variable.RegisterValue.from_BNRegisterValue(value, self._arch)
return result
[docs]
def get_medium_level_il_instruction_index(self,
instr: InstructionIndex) -> Optional['mediumlevelil.InstructionIndex']:
med_il = self.medium_level_il
if med_il is None:
return None
result = core.BNGetMediumLevelILInstructionIndex(self.handle, instr)
if result >= core.BNGetMediumLevelILInstructionCount(med_il.handle):
return None
return result
[docs]
def get_medium_level_il_expr_index(self, expr: ExpressionIndex) -> Optional['mediumlevelil.ExpressionIndex']:
med_il = self.medium_level_il
if med_il is None:
return None
result = core.BNGetMediumLevelILExprIndex(self.handle, expr)
if result >= core.BNGetMediumLevelILExprCount(med_il.handle):
return None
return result
[docs]
def get_medium_level_il_expr_indexes(self, expr: ExpressionIndex) -> List['mediumlevelil.ExpressionIndex']:
count = ctypes.c_ulonglong()
exprs = core.BNGetMediumLevelILExprIndexes(self.handle, expr, count)
assert exprs is not None, "core.BNGetMediumLevelILExprIndexes returned None"
result = []
for i in range(0, count.value):
result.append(exprs[i])
core.BNFreeILInstructionList(exprs)
return result
[docs]
def get_mapped_medium_level_il_instruction_index(self, instr: InstructionIndex) -> Optional[InstructionIndex]:
med_il = self.mapped_medium_level_il
if med_il is None:
return None
result = core.BNGetMappedMediumLevelILInstructionIndex(self.handle, instr)
if result >= core.BNGetMediumLevelILInstructionCount(med_il.handle):
return None
return result
[docs]
def get_mapped_medium_level_il_expr_index(self, expr: ExpressionIndex) -> Optional['mediumlevelil.ExpressionIndex']:
med_il = self.mapped_medium_level_il
if med_il is None:
return None
result = core.BNGetMappedMediumLevelILExprIndex(self.handle, expr)
if result >= core.BNGetMediumLevelILExprCount(med_il.handle):
return None
return result
[docs]
def get_high_level_il_instruction_index(self, instr: InstructionIndex) -> Optional['highlevelil.InstructionIndex']:
med_il = self.medium_level_il
if med_il is None:
return None
mlil_instr = self.get_medium_level_il_instruction_index(instr)
if mlil_instr is None:
return None
return med_il.get_high_level_il_instruction_index(mlil_instr)
[docs]
def get_high_level_il_expr_index(self, expr: ExpressionIndex) -> Optional['highlevelil.ExpressionIndex']:
med_il = self.medium_level_il
if med_il is None:
return None
mlil_expr = self.get_medium_level_il_expr_index(expr)
if mlil_expr is None:
return None
return med_il.get_high_level_il_expr_index(mlil_expr)
[docs]
def create_graph(self, settings: Optional['function.DisassemblySettings'] = None) -> flowgraph.CoreFlowGraph:
if settings is not None:
settings_obj = settings.handle
else:
settings_obj = None
return flowgraph.CoreFlowGraph(core.BNCreateLowLevelILFunctionGraph(self.handle, settings_obj))
[docs]
class LowLevelILBasicBlock(basicblock.BasicBlock):
"""
The ``LogLevelILBasicBlock`` object is returned during analysis and should not be directly instantiated.
"""
def __init__(
self, handle: core.BNBasicBlockHandle, owner: LowLevelILFunction, view: Optional['binaryview.BinaryView']
):
super(LowLevelILBasicBlock, self).__init__(handle, view)
self._il_function = owner
def __hash__(self):
return hash((self.start, self.end, self._il_function))
def __contains__(self, instruction):
if not isinstance(instruction, LowLevelILInstruction) or instruction.il_basic_block != self:
return False
return True
def __iter__(self) -> Generator['LowLevelILInstruction', None, None]:
for idx in range(self.start, self.end):
yield self._il_function[idx]
@overload
def __getitem__(self, idx: int) -> 'LowLevelILInstruction': ...
@overload
def __getitem__(self, idx: slice) -> List['LowLevelILInstruction']: ...
def __getitem__(self, idx: Union[int, slice]) -> Union['LowLevelILInstruction', List['LowLevelILInstruction']]:
size = self.end - self.start
if isinstance(idx, slice):
return [self[index] for index in range(*idx.indices(size))]
if idx > size or idx < -size:
raise IndexError("list index is out of range")
if idx >= 0:
return self._il_function[idx + self.start]
else:
return self._il_function[self.end + idx]
def __repr__(self):
arch = self.arch
if arch:
return f"<{self.__class__.__name__}: {arch.name}@{self.start}-{self.end}>"
else:
return f"<{self.__class__.__name__}: {self.start}-{self.end}>"
def _create_instance(self, handle):
"""Internal method by super to instantiate child instances"""
return LowLevelILBasicBlock(handle, self._il_function, self.view)
@property
def instruction_count(self) -> int:
return self.end - self.start
@property
def il_function(self) -> LowLevelILFunction:
return self._il_function
[docs]
def LLIL_TEMP(n: Union[ILRegister, int]) -> 'architecture.RegisterIndex':
return architecture.RegisterIndex(int(n) | 0x80000000)
[docs]
def LLIL_REG_IS_TEMP(n: Union[ILRegister, int]) -> bool:
return (int(n) & 0x80000000) != 0
[docs]
def LLIL_GET_TEMP_REG_INDEX(n: Union[ILRegister, int]) -> int:
return int(n) & 0x7fffffff