Source code for binaryninja.mediumlevelil

# Copyright (c) 2018-2022 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.

from abc import abstractmethod
import ctypes
import struct
from typing import Optional, List, Union, Mapping, Generator, NewType, Tuple, ClassVar
from dataclasses import dataclass

# Binary Ninja components
from . import _binaryninjacore as core
from .enums import MediumLevelILOperation, ILBranchDependence, DataFlowQueryOption, FunctionGraphType, DeadStoreElimination
from . import basicblock
from . import function
from . import types
from . import lowlevelil
from . import highlevelil
from . import flowgraph
from . import variable
from . import architecture
from . import binaryview
from .interaction import show_graph_report
from .commonil import (BaseILInstruction, Constant, BinaryOperation, UnaryOperation, Comparison, SSA,
	Phi, FloatingPoint, ControlFlow, Terminal, Call, Localcall, Syscall, Tailcall, Return,
	Signed, Arithmetic, Carry, DoublePrecision, Memory, Load, Store, RegisterStack, SetVar)

TokenList = List['function.InstructionTextToken']
ExpressionIndex = NewType('ExpressionIndex', int)
InstructionIndex = NewType('InstructionIndex', int)
MLILInstructionsType = Generator['MediumLevelILInstruction', None, None]
MLILBasicBlocksType = Generator['MediumLevelILBasicBlock', None, None]
OperandsType = Tuple[ExpressionIndex, ExpressionIndex, ExpressionIndex, ExpressionIndex, ExpressionIndex]
MediumLevelILOperandType = Union[
		int,
		float,
		'MediumLevelILOperationAndSize',
		'MediumLevelILInstruction',
		'lowlevelil.ILIntrinsic',
		'variable.Variable',
		'SSAVariable',
		List[int],
		List['variable.Variable'],
		List['SSAVariable'],
		List['MediumLevelILInstruction'],
		Mapping[int, int]
	]

[docs]@dataclass(frozen=True, repr=False, order=True) class SSAVariable: var:'variable.Variable' version:int def __repr__(self): return f"<ssa {self.var} version {self.version}>" @property def name(self) -> str: return self.var.name @property def type(self) -> 'types.Type': return self.var.type @property def function(self) -> 'function.Function': return self.var.function @property def dead_store_elimination(self) -> DeadStoreElimination: return self.var.dead_store_elimination
[docs]class MediumLevelILLabel: def __init__(self, handle:Optional[core.BNMediumLevelILLabel]=None): if handle is None: self.handle = (core.BNMediumLevelILLabel * 1)() core.BNMediumLevelILInitLabel(self.handle) else: self.handle = handle
[docs]@dataclass(frozen=True, repr=False) class MediumLevelILOperationAndSize: operation:MediumLevelILOperation size:int def __repr__(self): if self.size == 0: return f"<{self.operation.name}>" return f"<{self.operation.name} {self.size}>"
[docs]@dataclass(frozen=True) class CoreMediumLevelILInstruction: operation:MediumLevelILOperation source_operand:int size:int operands:OperandsType address:int
[docs] @classmethod def from_BNMediumLevelILInstruction(cls, instr:core.BNMediumLevelILInstruction) -> 'CoreMediumLevelILInstruction': operands:OperandsType = tuple([ExpressionIndex(instr.operands[i]) for i in range(5)]) # type: ignore return cls(MediumLevelILOperation(instr.operation), instr.sourceOperand, instr.size, operands, instr.address)
[docs]@dataclass(frozen=True) class MediumLevelILInstruction(BaseILInstruction): """ ``class MediumLevelILInstruction`` Medium 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. MLIL ``eax = 0``). """ function:'MediumLevelILFunction' expr_index:ExpressionIndex instr:CoreMediumLevelILInstruction instr_index:InstructionIndex ILOperations:ClassVar[Mapping[MediumLevelILOperation, List[Tuple[str,str]]]] = { MediumLevelILOperation.MLIL_NOP: [], MediumLevelILOperation.MLIL_SET_VAR: [("dest", "var"), ("src", "expr")], MediumLevelILOperation.MLIL_SET_VAR_FIELD: [("dest", "var"), ("offset", "int"), ("src", "expr")], MediumLevelILOperation.MLIL_SET_VAR_SPLIT: [("high", "var"), ("low", "var"), ("src", "expr")], MediumLevelILOperation.MLIL_LOAD: [("src", "expr")], MediumLevelILOperation.MLIL_LOAD_STRUCT: [("src", "expr"), ("offset", "int")], MediumLevelILOperation.MLIL_STORE: [("dest", "expr"), ("src", "expr")], MediumLevelILOperation.MLIL_STORE_STRUCT: [("dest", "expr"), ("offset", "int"), ("src", "expr")], MediumLevelILOperation.MLIL_VAR: [("src", "var")], MediumLevelILOperation.MLIL_VAR_FIELD: [("src", "var"), ("offset", "int")], MediumLevelILOperation.MLIL_VAR_SPLIT: [("high", "var"), ("low", "var")], MediumLevelILOperation.MLIL_ADDRESS_OF: [("src", "var")], MediumLevelILOperation.MLIL_ADDRESS_OF_FIELD: [("src", "var"), ("offset", "int")], MediumLevelILOperation.MLIL_CONST: [("constant", "int")], MediumLevelILOperation.MLIL_CONST_PTR: [("constant", "int")], MediumLevelILOperation.MLIL_EXTERN_PTR: [("constant", "int"), ("offset", "int")], MediumLevelILOperation.MLIL_FLOAT_CONST: [("constant", "float")], MediumLevelILOperation.MLIL_IMPORT: [("constant", "int")], MediumLevelILOperation.MLIL_ADD: [("left", "expr"), ("right", "expr")], MediumLevelILOperation.MLIL_ADC: [("left", "expr"), ("right", "expr"), ("carry", "expr")], MediumLevelILOperation.MLIL_SUB: [("left", "expr"), ("right", "expr")], MediumLevelILOperation.MLIL_SBB: [("left", "expr"), ("right", "expr"), ("carry", "expr")], MediumLevelILOperation.MLIL_AND: [("left", "expr"), ("right", "expr")], MediumLevelILOperation.MLIL_OR: [("left", "expr"), ("right", "expr")], MediumLevelILOperation.MLIL_XOR: [("left", "expr"), ("right", "expr")], MediumLevelILOperation.MLIL_LSL: [("left", "expr"), ("right", "expr")], MediumLevelILOperation.MLIL_LSR: [("left", "expr"), ("right", "expr")], MediumLevelILOperation.MLIL_ASR: [("left", "expr"), ("right", "expr")], MediumLevelILOperation.MLIL_ROL: [("left", "expr"), ("right", "expr")], MediumLevelILOperation.MLIL_RLC: [("left", "expr"), ("right", "expr"), ("carry", "expr")], MediumLevelILOperation.MLIL_ROR: [("left", "expr"), ("right", "expr")], MediumLevelILOperation.MLIL_RRC: [("left", "expr"), ("right", "expr"), ("carry", "expr")], MediumLevelILOperation.MLIL_MUL: [("left", "expr"), ("right", "expr")], MediumLevelILOperation.MLIL_MULU_DP: [("left", "expr"), ("right", "expr")], MediumLevelILOperation.MLIL_MULS_DP: [("left", "expr"), ("right", "expr")], MediumLevelILOperation.MLIL_DIVU: [("left", "expr"), ("right", "expr")], MediumLevelILOperation.MLIL_DIVU_DP: [("left", "expr"), ("right", "expr")], MediumLevelILOperation.MLIL_DIVS: [("left", "expr"), ("right", "expr")], MediumLevelILOperation.MLIL_DIVS_DP: [("left", "expr"), ("right", "expr")], MediumLevelILOperation.MLIL_MODU: [("left", "expr"), ("right", "expr")], MediumLevelILOperation.MLIL_MODU_DP: [("left", "expr"), ("right", "expr")], MediumLevelILOperation.MLIL_MODS: [("left", "expr"), ("right", "expr")], MediumLevelILOperation.MLIL_MODS_DP: [("left", "expr"), ("right", "expr")], MediumLevelILOperation.MLIL_NEG: [("src", "expr")], MediumLevelILOperation.MLIL_NOT: [("src", "expr")], MediumLevelILOperation.MLIL_SX: [("src", "expr")], MediumLevelILOperation.MLIL_ZX: [("src", "expr")], MediumLevelILOperation.MLIL_LOW_PART: [("src", "expr")], MediumLevelILOperation.MLIL_JUMP: [("dest", "expr")], MediumLevelILOperation.MLIL_JUMP_TO: [("dest", "expr"), ("targets", "target_map")], MediumLevelILOperation.MLIL_RET_HINT: [("dest", "expr")], MediumLevelILOperation.MLIL_CALL: [("output", "var_list"), ("dest", "expr"), ("params", "expr_list")], MediumLevelILOperation.MLIL_CALL_UNTYPED: [("output", "expr"), ("dest", "expr"), ("params", "expr"), ("stack", "expr")], MediumLevelILOperation.MLIL_CALL_OUTPUT: [("dest", "var_list")], MediumLevelILOperation.MLIL_CALL_PARAM: [("src", "var_list")], MediumLevelILOperation.MLIL_RET: [("src", "expr_list")], MediumLevelILOperation.MLIL_NORET: [], MediumLevelILOperation.MLIL_IF: [("condition", "expr"), ("true", "int"), ("false", "int")], MediumLevelILOperation.MLIL_GOTO: [("dest", "int")], MediumLevelILOperation.MLIL_CMP_E: [("left", "expr"), ("right", "expr")], MediumLevelILOperation.MLIL_CMP_NE: [("left", "expr"), ("right", "expr")], MediumLevelILOperation.MLIL_CMP_SLT: [("left", "expr"), ("right", "expr")], MediumLevelILOperation.MLIL_CMP_ULT: [("left", "expr"), ("right", "expr")], MediumLevelILOperation.MLIL_CMP_SLE: [("left", "expr"), ("right", "expr")], MediumLevelILOperation.MLIL_CMP_ULE: [("left", "expr"), ("right", "expr")], MediumLevelILOperation.MLIL_CMP_SGE: [("left", "expr"), ("right", "expr")], MediumLevelILOperation.MLIL_CMP_UGE: [("left", "expr"), ("right", "expr")], MediumLevelILOperation.MLIL_CMP_SGT: [("left", "expr"), ("right", "expr")], MediumLevelILOperation.MLIL_CMP_UGT: [("left", "expr"), ("right", "expr")], MediumLevelILOperation.MLIL_TEST_BIT: [("left", "expr"), ("right", "expr")], MediumLevelILOperation.MLIL_BOOL_TO_INT: [("src", "expr")], MediumLevelILOperation.MLIL_ADD_OVERFLOW: [("left", "expr"), ("right", "expr")], MediumLevelILOperation.MLIL_SYSCALL: [("output", "var_list"), ("params", "expr_list")], MediumLevelILOperation.MLIL_SYSCALL_UNTYPED: [("output", "expr"), ("params", "expr"), ("stack", "expr")], MediumLevelILOperation.MLIL_TAILCALL: [("output", "var_list"), ("dest", "expr"), ("params", "expr_list")], MediumLevelILOperation.MLIL_TAILCALL_UNTYPED: [("output", "expr"), ("dest", "expr"), ("params", "expr"), ("stack", "expr")], MediumLevelILOperation.MLIL_BP: [], MediumLevelILOperation.MLIL_TRAP: [("vector", "int")], MediumLevelILOperation.MLIL_INTRINSIC: [("output", "var_list"), ("intrinsic", "intrinsic"), ("params", "expr_list")], MediumLevelILOperation.MLIL_INTRINSIC_SSA: [("output", "var_ssa_list"), ("intrinsic", "intrinsic"), ("params", "expr_list")], MediumLevelILOperation.MLIL_FREE_VAR_SLOT: [("dest", "var")], MediumLevelILOperation.MLIL_FREE_VAR_SLOT_SSA: [("prev", "var_ssa_dest_and_src")], MediumLevelILOperation.MLIL_UNDEF: [], MediumLevelILOperation.MLIL_UNIMPL: [], MediumLevelILOperation.MLIL_UNIMPL_MEM: [("src", "expr")], MediumLevelILOperation.MLIL_FADD: [("left", "expr"), ("right", "expr")], MediumLevelILOperation.MLIL_FSUB: [("left", "expr"), ("right", "expr")], MediumLevelILOperation.MLIL_FMUL: [("left", "expr"), ("right", "expr")], MediumLevelILOperation.MLIL_FDIV: [("left", "expr"), ("right", "expr")], MediumLevelILOperation.MLIL_FSQRT: [("src", "expr")], MediumLevelILOperation.MLIL_FNEG: [("src", "expr")], MediumLevelILOperation.MLIL_FABS: [("src", "expr")], MediumLevelILOperation.MLIL_FLOAT_TO_INT: [("src", "expr")], MediumLevelILOperation.MLIL_INT_TO_FLOAT: [("src", "expr")], MediumLevelILOperation.MLIL_FLOAT_CONV: [("src", "expr")], MediumLevelILOperation.MLIL_ROUND_TO_INT: [("src", "expr")], MediumLevelILOperation.MLIL_FLOOR: [("src", "expr")], MediumLevelILOperation.MLIL_CEIL: [("src", "expr")], MediumLevelILOperation.MLIL_FTRUNC: [("src", "expr")], MediumLevelILOperation.MLIL_FCMP_E: [("left", "expr"), ("right", "expr")], MediumLevelILOperation.MLIL_FCMP_NE: [("left", "expr"), ("right", "expr")], MediumLevelILOperation.MLIL_FCMP_LT: [("left", "expr"), ("right", "expr")], MediumLevelILOperation.MLIL_FCMP_LE: [("left", "expr"), ("right", "expr")], MediumLevelILOperation.MLIL_FCMP_GE: [("left", "expr"), ("right", "expr")], MediumLevelILOperation.MLIL_FCMP_GT: [("left", "expr"), ("right", "expr")], MediumLevelILOperation.MLIL_FCMP_O: [("left", "expr"), ("right", "expr")], MediumLevelILOperation.MLIL_FCMP_UO: [("left", "expr"), ("right", "expr")], MediumLevelILOperation.MLIL_SET_VAR_SSA: [("dest", "var_ssa"), ("src", "expr")], MediumLevelILOperation.MLIL_SET_VAR_SSA_FIELD: [("prev", "var_ssa_dest_and_src"), ("offset", "int"), ("src", "expr")], MediumLevelILOperation.MLIL_SET_VAR_SPLIT_SSA: [("high", "var_ssa"), ("low", "var_ssa"), ("src", "expr")], MediumLevelILOperation.MLIL_SET_VAR_ALIASED: [("prev", "var_ssa_dest_and_src"), ("src", "expr")], MediumLevelILOperation.MLIL_SET_VAR_ALIASED_FIELD: [("prev", "var_ssa_dest_and_src"), ("offset", "int"), ("src", "expr")], MediumLevelILOperation.MLIL_VAR_SSA: [("src", "var_ssa")], MediumLevelILOperation.MLIL_VAR_SSA_FIELD: [("src", "var_ssa"), ("offset", "int")], MediumLevelILOperation.MLIL_VAR_ALIASED: [("src", "var_ssa")], MediumLevelILOperation.MLIL_VAR_ALIASED_FIELD: [("src", "var_ssa"), ("offset", "int")], MediumLevelILOperation.MLIL_VAR_SPLIT_SSA: [("high", "var_ssa"), ("low", "var_ssa")], MediumLevelILOperation.MLIL_CALL_SSA: [("output", "expr"), ("dest", "expr"), ("params", "expr_list"), ("src_memory", "int")], MediumLevelILOperation.MLIL_CALL_UNTYPED_SSA: [("output", "expr"), ("dest", "expr"), ("params", "expr"), ("stack", "expr")], MediumLevelILOperation.MLIL_SYSCALL_SSA: [("output", "expr"), ("params", "expr_list"), ("src_memory", "int")], MediumLevelILOperation.MLIL_SYSCALL_UNTYPED_SSA: [("output", "expr"), ("params", "expr"), ("stack", "expr")], MediumLevelILOperation.MLIL_TAILCALL_SSA: [("output", "expr"), ("dest", "expr"), ("params", "expr_list"), ("src_memory", "int")], MediumLevelILOperation.MLIL_TAILCALL_UNTYPED_SSA: [("output", "expr"), ("dest", "expr"), ("params", "expr"), ("stack", "expr")], MediumLevelILOperation.MLIL_CALL_OUTPUT_SSA: [("dest_memory", "int"), ("dest", "var_ssa_list")], MediumLevelILOperation.MLIL_CALL_PARAM_SSA: [("src_memory", "int"), ("src", "var_ssa_list")], MediumLevelILOperation.MLIL_LOAD_SSA: [("src", "expr"), ("src_memory", "int")], MediumLevelILOperation.MLIL_LOAD_STRUCT_SSA: [("src", "expr"), ("offset", "int"), ("src_memory", "int")], MediumLevelILOperation.MLIL_STORE_SSA: [("dest", "expr"), ("dest_memory", "int"), ("src_memory", "int"), ("src", "expr")], MediumLevelILOperation.MLIL_STORE_STRUCT_SSA: [("dest", "expr"), ("offset", "int"), ("dest_memory", "int"), ("src_memory", "int"), ("src", "expr")], MediumLevelILOperation.MLIL_VAR_PHI: [("dest", "var_ssa"), ("src", "var_ssa_list")], MediumLevelILOperation.MLIL_MEM_PHI: [("dest_memory", "int"), ("src_memory", "int_list")] }
[docs] @staticmethod def show_mlil_hierarchy(): graph = flowgraph.FlowGraph() nodes = {} for instruction in ILInstruction.values(): instruction.add_subgraph(graph, nodes) show_graph_report("MLIL Class Hierarchy Graph", graph)
[docs] @classmethod def create(cls, func:'MediumLevelILFunction', expr_index:ExpressionIndex, instr_index:Optional[InstructionIndex]=None) -> 'MediumLevelILInstruction': assert func.arch is not None, "Attempted to create IL instruction with function missing an Architecture" inst = core.BNGetMediumLevelILByIndex(func.handle, expr_index) assert inst is not None, "core.BNGetMediumLevelILByIndex returned None" if instr_index is None: instr_index = core.BNGetMediumLevelILInstructionForExpr(func.handle, expr_index) assert instr_index is not None, "core.BNGetMediumLevelILInstructionForExpr returned None" instr = CoreMediumLevelILInstruction.from_BNMediumLevelILInstruction(inst) return ILInstruction[instr.operation](func, expr_index, instr, 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"<mlil: {self}>" def __eq__(self, other:'MediumLevelILInstruction') -> bool: if not isinstance(other, MediumLevelILInstruction): return NotImplemented return self.function == other.function and self.expr_index == other.expr_index def __lt__(self, other:'MediumLevelILInstruction') -> bool: if not isinstance(other, MediumLevelILInstruction): return NotImplemented return self.function == other.function and self.expr_index < other.expr_index def __le__(self, other:'MediumLevelILInstruction') -> bool: if not isinstance(other, MediumLevelILInstruction): return NotImplemented return self.function == other.function and self.expr_index <= other.expr_index def __gt__(self, other:'MediumLevelILInstruction') -> bool: if not isinstance(other, MediumLevelILInstruction): return NotImplemented return self.function == other.function and self.expr_index > other.expr_index def __ge__(self, other:'MediumLevelILInstruction') -> bool: if not isinstance(other, MediumLevelILInstruction): 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 tokens(self) -> TokenList: """MLIL tokens (read-only)""" count = ctypes.c_ulonglong() tokens = ctypes.POINTER(core.BNInstructionTextToken)() assert self.function.arch is not None, f"type(self.function): {type(self.function)} " result = core.BNGetMediumLevelILExprText(self.function.handle, self.function.arch.handle, self.expr_index, tokens, count, None) assert result, "core.BNGetMediumLevelILExprText returned False" try: return function.InstructionTextToken._from_core_struct(tokens, count.value) finally: core.BNFreeInstructionText(tokens, count.value) @property def il_basic_block(self) -> 'MediumLevelILBasicBlock': """IL basic block object containing this expression (read-only) (only available on finalized functions)""" core_block = core.BNGetMediumLevelILBasicBlockForInstruction(self.function.handle, self.instr_index) assert core_block is not None assert self.function.source_function is not None return MediumLevelILBasicBlock(core_block, self.function, self.function.source_function.view) @property def ssa_form(self) -> 'MediumLevelILInstruction': """SSA form of expression (read-only)""" ssa_func = self.function.ssa_form assert ssa_func is not None return MediumLevelILInstruction.create(ssa_func, ExpressionIndex(core.BNGetMediumLevelILSSAExprIndex(self.function.handle, self.expr_index))) @property def non_ssa_form(self) -> 'MediumLevelILInstruction': """Non-SSA form of expression (read-only)""" non_ssa_func = self.function.non_ssa_form assert non_ssa_func is not None return MediumLevelILInstruction.create(non_ssa_func, ExpressionIndex(core.BNGetMediumLevelILNonSSAExprIndex(self.function.handle, self.expr_index))) @property def value(self) -> variable.RegisterValue: """Value of expression if constant or a known value (read-only)""" value = core.BNGetMediumLevelILExprValue(self.function.handle, self.expr_index) result = variable.RegisterValue.from_BNRegisterValue(value, self.function.arch) return result @property def possible_values(self) -> variable.PossibleValueSet: """Possible values of expression using path-sensitive static data flow analysis (read-only)""" value = core.BNGetMediumLevelILPossibleExprValues(self.function.handle, self.expr_index, None, 0) result = variable.PossibleValueSet(self.function.arch, value) core.BNFreePossibleValueSet(value) return result @property def branch_dependence(self) -> Mapping[int, ILBranchDependence]: """Set of branching instructions that must take the true or false path to reach this instruction""" count = ctypes.c_ulonglong() deps = core.BNGetAllMediumLevelILBranchDependence(self.function.handle, self.instr_index, count) assert deps is not None, "core.BNGetAllMediumLevelILBranchDependence returned None" result = {} for i in range(0, count.value): result[deps[i].branch] = ILBranchDependence(deps[i].dependence) core.BNFreeILBranchDependenceList(deps) return result @property def low_level_il(self) -> Optional['lowlevelil.LowLevelILInstruction']: """Low level IL form of this expression""" expr = self.function.get_low_level_il_expr_index(self.expr_index) if expr is None or self.function.low_level_il is None: return None return lowlevelil.LowLevelILInstruction.create(self.function.low_level_il.ssa_form, expr, None) @property def llil(self) -> Optional['lowlevelil.LowLevelILInstruction']: """Alias for low_level_il""" return self.low_level_il @property def llils(self) -> List['lowlevelil.LowLevelILInstruction']: exprs = self.function.get_low_level_il_expr_indexes(self.expr_index) if self.function.low_level_il is None: return [] result = [] for expr in exprs: result.append(lowlevelil.LowLevelILInstruction.create(self.function.low_level_il.ssa_form, expr, None)) return result @property def high_level_il(self) -> Optional[highlevelil.HighLevelILInstruction]: """High level IL form of this expression""" expr = self.function.get_high_level_il_expr_index(self.expr_index) if expr is None or self.function.high_level_il is None: return None return highlevelil.HighLevelILInstruction.create(self.function.high_level_il, expr) @property def hlil(self) -> Optional[highlevelil.HighLevelILInstruction]: """Alias for high_level_il""" return self.high_level_il @property def hlils(self) -> List[highlevelil.HighLevelILInstruction]: exprs = self.function.get_high_level_il_expr_indexes(self.expr_index) result = [] if self.function.high_level_il is None: return result for expr in exprs: result.append(highlevelil.HighLevelILInstruction.create(self.function.high_level_il, expr)) return result @property def ssa_memory_version(self) -> int: """Version of active memory contents in SSA form for this instruction""" return core.BNGetMediumLevelILSSAMemoryVersionAtILInstruction(self.function.handle, self.instr_index) @property def prefix_operands(self) -> List[MediumLevelILOperandType]: """All operands in the expression tree in prefix order""" result:List[MediumLevelILOperandType] = [MediumLevelILOperationAndSize(self.operation, self.size)] for operand in self.operands: if isinstance(operand, MediumLevelILInstruction): result.extend(operand.prefix_operands) else: result.append(operand) return result @property def postfix_operands(self) -> List[MediumLevelILOperandType]: """All operands in the expression tree in postfix order""" result:List[MediumLevelILOperandType] = [] for operand in self.operands: if isinstance(operand, MediumLevelILInstruction): result.extend(operand.postfix_operands) else: result.append(operand) result.append(MediumLevelILOperationAndSize(self.operation, self.size)) return result @property def instruction_operands(self) -> List['MediumLevelILInstruction']: return [i for i in self.operands if isinstance(i, MediumLevelILInstruction)] @property def operands(self) -> List[MediumLevelILOperandType]: """Operands for the instruction""" return [] @property def vars_written(self) -> List[Union[variable.Variable, SSAVariable]]: """List of variables written by instruction""" return [] @property def vars_read(self) -> List[Union[variable.Variable, SSAVariable]]: """List of variables read by instruction""" result = [] for operand in self.operands: if isinstance(operand, (variable.Variable, SSAVariable)): result.append(operand) elif isinstance(operand, MediumLevelILInstruction): result += operand.vars_read return result @property def vars_address_taken(self) -> List[Union[variable.Variable, SSAVariable]]: """Non-unique list of variables whose address is taken by instruction""" result = [] for operand in self.instruction_operands: result.extend(operand.vars_address_taken) return result @property def expr_type(self) -> Optional['types.Type']: """Type of expression""" result = core.BNGetMediumLevelILExprType(self.function.handle, self.expr_index) if result.type: platform = None if self.function.source_function: platform = self.function.source_function.platform return types.Type.create(core.BNNewTypeReference(result.type), platform = platform, confidence = result.confidence) return None @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, size = MediumLevelILInstruction._make_options_array(options) value = core.BNGetMediumLevelILPossibleExprValues(self.function.handle, self.expr_index, option_array, size) result = variable.PossibleValueSet(self.function.arch, value) core.BNFreePossibleValueSet(value) return result
[docs] def get_ssa_var_possible_values(self, ssa_var:SSAVariable, options:List[DataFlowQueryOption]=[]): var_data = ssa_var.var.to_BNVariable() option_array, size = MediumLevelILInstruction._make_options_array(options) value = core.BNGetMediumLevelILPossibleSSAVarValues(self.function.handle, var_data, ssa_var.version, self.instr_index, option_array, size) result = variable.PossibleValueSet(self.function.arch, value) core.BNFreePossibleValueSet(value) return result
[docs] def get_ssa_var_version(self, var:variable.Variable) -> int: var_data = var.to_BNVariable() return core.BNGetMediumLevelILSSAVarVersionAtILInstruction(self.function.handle, var_data, self.instr_index)
[docs] def get_var_for_reg(self, reg:'architecture.RegisterType') -> variable.Variable: reg = self.function.arch.get_reg_index(reg) result = core.BNGetMediumLevelILVariableForRegisterAtInstruction(self.function.handle, reg, self.instr_index) return variable.Variable.from_BNVariable(self.function, result)
[docs] def get_var_for_flag(self, flag:'architecture.FlagType') -> variable.Variable: flag = self.function.arch.get_flag_index(flag) result = core.BNGetMediumLevelILVariableForFlagAtInstruction(self.function.handle, flag, self.instr_index) return variable.Variable.from_BNVariable(self.function, result)
[docs] def get_var_for_stack_location(self, offset:int) -> variable.Variable: result = core.BNGetMediumLevelILVariableForStackLocationAtInstruction(self.function.handle, offset, self.instr_index) return variable.Variable.from_BNVariable(self.function, result)
[docs] def get_reg_value(self, reg:'architecture.RegisterType') -> 'variable.RegisterValue': reg = self.function.arch.get_reg_index(reg) value = core.BNGetMediumLevelILRegisterValueAtInstruction(self.function.handle, reg, self.instr_index) result = variable.RegisterValue.from_BNRegisterValue(value, self.function.arch) return result
[docs] def get_reg_value_after(self, reg:'architecture.RegisterType') -> 'variable.RegisterValue': reg = self.function.arch.get_reg_index(reg) value = core.BNGetMediumLevelILRegisterValueAfterInstruction(self.function.handle, reg, self.instr_index) result = variable.RegisterValue.from_BNRegisterValue(value, self.function.arch) return result
[docs] def get_possible_reg_values(self, reg:'architecture.RegisterType', options:Optional[List[DataFlowQueryOption]]=None) -> 'variable.PossibleValueSet': option_array, size = MediumLevelILInstruction._make_options_array(options) reg = self.function.arch.get_reg_index(reg) value = core.BNGetMediumLevelILPossibleRegisterValuesAtInstruction(self.function.handle, reg, self.instr_index, option_array, 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': reg = self.function.arch.get_reg_index(reg) option_array, size = MediumLevelILInstruction._make_options_array(options) value = core.BNGetMediumLevelILPossibleRegisterValuesAfterInstruction(self.function.handle, reg, self.instr_index, option_array, size) result = variable.PossibleValueSet(self.function.arch, value) core.BNFreePossibleValueSet(value) return result
[docs] def get_flag_value(self, flag:'architecture.FlagType') -> 'variable.RegisterValue': flag = self.function.arch.get_flag_index(flag) value = core.BNGetMediumLevelILFlagValueAtInstruction(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': flag = self.function.arch.get_flag_index(flag) value = core.BNGetMediumLevelILFlagValueAfterInstruction(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': flag = self.function.arch.get_flag_index(flag) option_array, size = MediumLevelILInstruction._make_options_array(options) value = core.BNGetMediumLevelILPossibleFlagValuesAtInstruction(self.function.handle, flag, self.instr_index, option_array, 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': flag = self.function.arch.get_flag_index(flag) option_array, size = MediumLevelILInstruction._make_options_array(options) value = core.BNGetMediumLevelILPossibleFlagValuesAfterInstruction(self.function.handle, flag, self.instr_index, option_array, 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.BNGetMediumLevelILStackContentsAtInstruction(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.BNGetMediumLevelILStackContentsAfterInstruction(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 = MediumLevelILInstruction._make_options_array(options) value = core.BNGetMediumLevelILPossibleStackContentsAtInstruction(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:List[DataFlowQueryOption]=None) -> 'variable.PossibleValueSet': option_array, option_size = MediumLevelILInstruction._make_options_array(options) value = core.BNGetMediumLevelILPossibleStackContentsAfterInstruction(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_branch_dependence(self, branch_instr:int) -> ILBranchDependence: return ILBranchDependence(core.BNGetMediumLevelILBranchDependence(self.function.handle, self.instr_index, branch_instr))
@property def operation(self) -> MediumLevelILOperation: return self.instr.operation @property def size(self) -> int: return self.instr.size @property def address(self) -> int: return self.instr.address @property def source_operand(self) -> ExpressionIndex: return ExpressionIndex(self.instr.source_operand) @property def core_operands(self) -> OperandsType: return self.instr.operands def _get_int(self, operand_index:int) -> int: value = self.instr.operands[operand_index] return (value & ((1 << 63) - 1)) - (value & (1 << 63)) def _get_float(self, operand_index:int) -> float: value = self.instr.operands[operand_index] if self.instr.size == 4: return struct.unpack("f", struct.pack("I", value & 0xffffffff))[0] elif self.instr.size == 8: return struct.unpack("d", struct.pack("Q", value))[0] else: return float(value) def _get_expr(self, operand_index:int) -> 'MediumLevelILInstruction': return MediumLevelILInstruction.create(self.function, ExpressionIndex(self.instr.operands[operand_index])) def _get_intrinsic(self, operand_index:int) -> 'lowlevelil.ILIntrinsic': assert self.function.arch is not None, "Attempting to create ILIntrinsic from function with no Architecture" return lowlevelil.ILIntrinsic(self.function.arch, architecture.IntrinsicIndex(self.instr.operands[operand_index])) def _get_var(self, operand_index:int) -> variable.Variable: value = self.instr.operands[operand_index] return variable.Variable.from_identifier(self.function, value) def _get_var_ssa(self, operand_index1:int, operand_index2:int) -> SSAVariable: var = variable.Variable.from_identifier(self.function, self.instr.operands[operand_index1]) version = self.instr.operands[operand_index2] return SSAVariable(var, version) def _get_var_ssa_dest_and_src(self, operand_index1:int, operand_index2:int) -> SSAVariable: var = variable.Variable.from_identifier(self.function, self.instr.operands[operand_index1]) dest_version = self.instr.operands[operand_index2] return SSAVariable(var, dest_version) def _get_int_list(self, operand_index:int) -> List[int]: count = ctypes.c_ulonglong() operand_list = core.BNMediumLevelILGetOperandList(self.function.handle, self.expr_index, operand_index, count) assert operand_list is not None, "core.BNMediumLevelILGetOperandList returned None" value:List[int] = [] try: for j in range(count.value): value.append(operand_list[j]) return value finally: core.BNMediumLevelILFreeOperandList(operand_list) def _get_var_list(self, operand_index1:int, operand_index2:int) -> List[variable.Variable]: # We keep this extra parameter around because when this function is called # the subclasses that call this don't use the next operand # without this parameter it looks like this operand is being skipped unintentionally # rather this operand is being skipped intentionally. _ = operand_index2 count = ctypes.c_ulonglong() operand_list = core.BNMediumLevelILGetOperandList(self.function.handle, self.expr_index, operand_index1, count) assert operand_list is not None, "core.BNMediumLevelILGetOperandList returned None" value:List[variable.Variable] = [] try: for j in range(count.value): value.append(variable.Variable.from_identifier(self.function, operand_list[j])) return value finally: core.BNMediumLevelILFreeOperandList(operand_list) def _get_var_ssa_list(self, operand_index1:int, _:int) -> List[SSAVariable]: count = ctypes.c_ulonglong() operand_list = core.BNMediumLevelILGetOperandList(self.function.handle, self.expr_index, operand_index1, count) assert operand_list is not None, "core.BNMediumLevelILGetOperandList returned None" value = [] try: for j in range(count.value // 2): var_id = operand_list[j * 2] var_version = operand_list[(j * 2) + 1] value.append(SSAVariable(variable.Variable.from_identifier(self.function, var_id), var_version)) return value finally: core.BNMediumLevelILFreeOperandList(operand_list) def _get_expr_list(self, operand_index1:int, _:int) -> List['MediumLevelILInstruction']: count = ctypes.c_ulonglong() operand_list = core.BNMediumLevelILGetOperandList(self.function.handle, self.expr_index, operand_index1, count) assert operand_list is not None, "core.BNMediumLevelILGetOperandList returned None" value:List['MediumLevelILInstruction'] = [] try: for j in range(count.value): value.append(MediumLevelILInstruction.create(self.function, operand_list[j], None)) return value finally: core.BNMediumLevelILFreeOperandList(operand_list) def _get_target_map(self, operand_index1:int, _:int) -> Mapping[int, int]: count = ctypes.c_ulonglong() operand_list = core.BNMediumLevelILGetOperandList(self.function.handle, self.expr_index, operand_index1, count) assert operand_list is not None, "core.BNMediumLevelILGetOperandList returned None" value:Dict[int, int] = {} try: 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.BNMediumLevelILFreeOperandList(operand_list)
[docs]@dataclass(frozen=True, repr=False, eq=False) class MediumLevelILConstBase(MediumLevelILInstruction, Constant): pass
[docs]@dataclass(frozen=True, repr=False, eq=False) class MediumLevelILCallBase(MediumLevelILInstruction, Call): @property def output(self) -> List[Union[SSAVariable, variable.Variable]]: return NotImplemented @property def vars_written(self) -> List[Union[SSAVariable, variable.Variable]]: return self.output @property def params(self) -> List[Union[SSAVariable, variable.Variable]]: return NotImplemented @property def vars_read(self) -> List[Union[SSAVariable, variable.Variable]]: result = [] for param in self.params: if isinstance(param, MediumLevelILInstruction): result.extend(param.vars_read) elif isinstance(param, (variable.Variable, SSAVariable)): result.append(param) else: assert False, "Call.params returned object other than Variable, SSAVariable or MediumLevelILInstruction" return result
[docs]@dataclass(frozen=True, repr=False, eq=False) class MediumLevelILUnaryBase(MediumLevelILInstruction, UnaryOperation): @property def src(self) -> MediumLevelILInstruction: return self._get_expr(0) @property def operands(self) -> List[MediumLevelILInstruction]: return [self.src]
[docs]@dataclass(frozen=True, repr=False, eq=False) class MediumLevelILBinaryBase(MediumLevelILInstruction, BinaryOperation): @property def left(self) -> MediumLevelILInstruction: return self._get_expr(0) @property def right(self) -> MediumLevelILInstruction: return self._get_expr(1) @property def operands(self) -> List[MediumLevelILInstruction]: return [self.left, self.right]
[docs]@dataclass(frozen=True, repr=False, eq=False) class MediumLevelILComparisonBase(MediumLevelILBinaryBase, Comparison): pass
[docs]@dataclass(frozen=True, repr=False, eq=False) class MediumLevelILCarryBase(MediumLevelILInstruction, Carry): @property def left(self) -> MediumLevelILInstruction: return self._get_expr(0) @property def right(self) -> MediumLevelILInstruction: return self._get_expr(1) @property def carry(self) -> MediumLevelILInstruction: return self._get_expr(2) @property def operands(self) -> List[MediumLevelILInstruction]: return [self.left, self.right, self.carry]
[docs]@dataclass(frozen=True, repr=False, eq=False) class MediumLevelILNop(MediumLevelILInstruction): pass
[docs]@dataclass(frozen=True, repr=False, eq=False) class MediumLevelILNoret(MediumLevelILInstruction, Terminal): pass
[docs]@dataclass(frozen=True, repr=False, eq=False) class MediumLevelILBp(MediumLevelILInstruction, Terminal): pass
[docs]@dataclass(frozen=True, repr=False, eq=False) class MediumLevelILUndef(MediumLevelILInstruction): pass
[docs]@dataclass(frozen=True, repr=False, eq=False) class MediumLevelILUnimpl(MediumLevelILInstruction): pass
[docs]@dataclass(frozen=True, repr=False, eq=False) class MediumLevelILLoad(MediumLevelILInstruction, Load): @property def src(self) -> MediumLevelILInstruction: return self._get_expr(0) @property def operands(self) -> List[MediumLevelILInstruction]: return [self.src]
[docs]@dataclass(frozen=True, repr=False, eq=False) class MediumLevelILVar(MediumLevelILInstruction): @property def src(self) -> variable.Variable: return self._get_var(0) @property def operands(self) -> List[variable.Variable]: return [self.src]
[docs]@dataclass(frozen=True, repr=False, eq=False) class MediumLevelILAddressOf(MediumLevelILInstruction): @property def src(self) -> variable.Variable: return self._get_var(0) @property def operands(self) -> List[variable.Variable]: return [self.src] @property def vars_address_taken(self) -> List[variable.Variable]: return [self.src]
[docs]@dataclass(frozen=True, repr=False, eq=False) class MediumLevelILConst(MediumLevelILConstBase): @property def constant(self) -> int: return self._get_int(0) @property def operands(self) -> List[int]: return [self.constant]
[docs]@dataclass(frozen=True, repr=False, eq=False) class MediumLevelILConstPtr(MediumLevelILConstBase): @property def constant(self) -> int: return self._get_int(0) @property def operands(self) -> List[int]: return [self.constant]
[docs]@dataclass(frozen=True, repr=False, eq=False) class MediumLevelILFloatConst(MediumLevelILConstBase, FloatingPoint): @property def constant(self) -> float: return self._get_float(0) @property def operands(self) -> List[float]: return [self.constant]
[docs]@dataclass(frozen=True, repr=False, eq=False) class MediumLevelILImport(MediumLevelILConstBase): @property def constant(self) -> int: return self._get_int(0) @property def operands(self) -> List[int]: return [self.constant]
[docs]@dataclass(frozen=True, repr=False, eq=False) class MediumLevelILNeg(MediumLevelILUnaryBase, Arithmetic): pass
[docs]@dataclass(frozen=True, repr=False, eq=False) class MediumLevelILNot(MediumLevelILUnaryBase, Arithmetic): pass
[docs]@dataclass(frozen=True, repr=False, eq=False) class MediumLevelILSx(MediumLevelILUnaryBase, Arithmetic): pass
[docs]@dataclass(frozen=True, repr=False, eq=False) class MediumLevelILZx(MediumLevelILUnaryBase, Arithmetic): pass
[docs]@dataclass(frozen=True, repr=False, eq=False) class MediumLevelILLowPart(MediumLevelILUnaryBase, Arithmetic): pass
[docs]@dataclass(frozen=True, repr=False, eq=False) class MediumLevelILJump(MediumLevelILInstruction, Terminal): @property def dest(self) -> MediumLevelILInstruction: return self._get_expr(0) @property def operands(self) -> List[MediumLevelILInstruction]: return [self.dest]
[docs]@dataclass(frozen=True, repr=False, eq=False) class MediumLevelILRetHint(MediumLevelILInstruction, ControlFlow): @property def dest(self) -> MediumLevelILInstruction: return self._get_expr(0) @property def operands(self) -> List[MediumLevelILInstruction]: return [self.dest]
[docs]@dataclass(frozen=True, repr=False, eq=False) class MediumLevelILCallOutput(MediumLevelILInstruction): @property def dest(self) -> List[variable.Variable]: return self._get_var_list(0, 1) @property def vars_written(self) -> List[variable.Variable]: return self.dest @property def operands(self) -> List[variable.Variable]: return self.dest
[docs]@dataclass(frozen=True, repr=False, eq=False) class MediumLevelILCallParam(MediumLevelILInstruction): @property def src(self) -> List[variable.Variable]: return self._get_var_list(0, 1) @property def operands(self) -> List[variable.Variable]: return self.src
[docs]@dataclass(frozen=True, repr=False, eq=False) class MediumLevelILRet(MediumLevelILInstruction, Return): @property def src(self) -> List[MediumLevelILInstruction]: return self._get_expr_list(0, 1) @property def operands(self) -> List[List[MediumLevelILInstruction]]: return [self.src]
[docs]@dataclass(frozen=True, repr=False, eq=False) class MediumLevelILGoto(MediumLevelILInstruction, Terminal): @property def dest(self) -> int: return self._get_int(0) @property def operands(self) -> List[int]: return [self.dest]
[docs]@dataclass(frozen=True, repr=False, eq=False) class MediumLevelILBoolToInt(MediumLevelILInstruction): @property def src(self) -> MediumLevelILInstruction: return self._get_expr(0) @property def operands(self) -> List[MediumLevelILInstruction]: return [self.src]
[docs]@dataclass(frozen=True, repr=False, eq=False) class MediumLevelILFreeVarSlot(MediumLevelILInstruction, RegisterStack): @property def dest(self) -> variable.Variable: return self._get_var(0) @property def operands(self) -> List[variable.Variable]: return [self.dest]
[docs]@dataclass(frozen=True, repr=False, eq=False) class MediumLevelILTrap(MediumLevelILInstruction, Terminal): @property def vector(self) -> int: return self._get_int(0) @property def operands(self) -> List[int]: return [self.vector]
[docs]@dataclass(frozen=True, repr=False, eq=False) class MediumLevelILFreeVarSlotSsa(MediumLevelILInstruction, SSA, RegisterStack): @property def dest(self) -> SSAVariable: return self._get_var_ssa_dest_and_src(0, 1) @property def prev(self) -> SSAVariable: return self._get_var_ssa_dest_and_src(0, 2) @property def operands(self) -> List[SSAVariable]: return [self.dest, self.prev]
[docs]@dataclass(frozen=True, repr=False, eq=False) class MediumLevelILUnimplMem(MediumLevelILInstruction, Memory): @property def src(self) -> MediumLevelILInstruction: return self._get_expr(0) @property def operands(self) -> List[MediumLevelILInstruction]: return [self.src]
[docs]@dataclass(frozen=True, repr=False, eq=False) class MediumLevelILFsqrt(MediumLevelILUnaryBase, Arithmetic, FloatingPoint): pass
[docs]@dataclass(frozen=True, repr=False, eq=False) class MediumLevelILFneg(MediumLevelILUnaryBase, Arithmetic, FloatingPoint): pass
[docs]@dataclass(frozen=True, repr=False, eq=False) class MediumLevelILFabs(MediumLevelILUnaryBase, Arithmetic, FloatingPoint): pass
[docs]@dataclass(frozen=True, repr=False, eq=False) class MediumLevelILFloatToInt(MediumLevelILUnaryBase, Arithmetic, FloatingPoint): pass
[docs]@dataclass(frozen=True, repr=False, eq=False) class MediumLevelILIntToFloat(MediumLevelILUnaryBase, Arithmetic, FloatingPoint): pass
[docs]@dataclass(frozen=True, repr=False, eq=False) class MediumLevelILFloatConv(MediumLevelILUnaryBase, Arithmetic, FloatingPoint): pass
[docs]@dataclass(frozen=True, repr=False, eq=False) class MediumLevelILRoundToInt(MediumLevelILUnaryBase, Arithmetic, FloatingPoint): pass
[docs]@dataclass(frozen=True, repr=False, eq=False) class MediumLevelILFloor(MediumLevelILUnaryBase, Arithmetic, FloatingPoint): pass
[docs]@dataclass(frozen=True, repr=False, eq=False) class MediumLevelILCeil(MediumLevelILUnaryBase, Arithmetic, FloatingPoint): pass
[docs]@dataclass(frozen=True, repr=False, eq=False) class MediumLevelILFtrunc(MediumLevelILUnaryBase, Arithmetic, FloatingPoint): pass
[docs]@dataclass(frozen=True, repr=False, eq=False) class MediumLevelILVarSsa(MediumLevelILInstruction, SSA): @property def src(self) -> SSAVariable: return self._get_var_ssa(0, 1) @property def operands(self) -> List[SSAVariable]: return [self.src]
[docs]@dataclass(frozen=True, repr=False, eq=False) class MediumLevelILVarAliased(MediumLevelILInstruction, SSA): @property def src(self) -> SSAVariable: return self._get_var_ssa(0, 1) @property def operands(self) -> List[SSAVariable]: return [self.src]
[docs]@dataclass(frozen=True, repr=False, eq=False) class MediumLevelILSetVar(MediumLevelILInstruction, SetVar): @property def dest(self) -> variable.Variable: return self._get_var(0) @property def src(self) -> MediumLevelILInstruction: return self._get_expr(1) @property def operands(self) -> List[MediumLevelILOperandType]: return [self.dest, self.src] @property def vars_written(self) -> List[variable.Variable]: return [self.dest] @property def vars_read(self) -> List[Union[variable.Variable, SSAVariable]]: return self.src.vars_read
[docs]@dataclass(frozen=True, repr=False, eq=False) class MediumLevelILLoadStruct(MediumLevelILInstruction, Load): @property def src(self) -> MediumLevelILInstruction: return self._get_expr(0) @property def offset(self) -> int: return self._get_int(1) @property def operands(self) -> List[MediumLevelILOperandType]: return [self.src, self.offset]
[docs]@dataclass(frozen=True, repr=False, eq=False) class MediumLevelILStore(MediumLevelILInstruction, Store): @property def dest(self) -> MediumLevelILInstruction: return self._get_expr(0) @property def src(self) -> MediumLevelILInstruction: return self._get_expr(1) @property def operands(self) -> List[MediumLevelILInstruction]: return [self.dest, self.src]
[docs]@dataclass(frozen=True, repr=False, eq=False) class MediumLevelILVarField(MediumLevelILInstruction): @property def src(self) -> variable.Variable: return self._get_var(0) @property def offset(self) -> int: return self._get_int(1) @property def operands(self) -> List[MediumLevelILOperandType]: return [self.src, self.offset]
[docs]@dataclass(frozen=True, repr=False, eq=False) class MediumLevelILVarSplit(MediumLevelILInstruction): @property def high(self) -> variable.Variable: return self._get_var(0) @property def low(self) -> variable.Variable: return self._get_var(1) @property def operands(self) -> List[variable.Variable]: return [self.high, self.low]
[docs]@dataclass(frozen=True, repr=False, eq=False) class MediumLevelILAddressOfField(MediumLevelILInstruction): @property def src(self) -> variable.Variable: return self._get_var(0) @property def offset(self) -> int: return self._get_int(1) @property def operands(self) -> List[MediumLevelILOperandType]: return [self.src, self.offset]
[docs]@dataclass(frozen=True, repr=False, eq=False) class MediumLevelILExternPtr(MediumLevelILConstBase): @property def constant(self) -> int: return self._get_int(0) @property def offset(self) -> int: return self._get_int(1) @property def operands(self) -> List[int]: return [self.constant, self.offset]
[docs]@dataclass(frozen=True, repr=False, eq=False) class MediumLevelILAdd(MediumLevelILBinaryBase, Arithmetic): pass
[docs]@dataclass(frozen=True, repr=False, eq=False) class MediumLevelILSub(MediumLevelILBinaryBase, Arithmetic): pass
[docs]@dataclass(frozen=True, repr=False, eq=False) class MediumLevelILAnd(MediumLevelILBinaryBase, Arithmetic): pass
[docs]@dataclass(frozen=True, repr=False, eq=False) class MediumLevelILOr(MediumLevelILBinaryBase, Arithmetic): pass
[docs]@dataclass(frozen=True, repr=False, eq=False) class MediumLevelILXor(MediumLevelILBinaryBase, Arithmetic): pass
[docs]@dataclass(frozen=True, repr=False, eq=False) class MediumLevelILLsl(MediumLevelILBinaryBase, Arithmetic): pass
[docs]@dataclass(frozen=True, repr=False, eq=False) class MediumLevelILLsr(MediumLevelILBinaryBase, Arithmetic): pass
[docs]@dataclass(frozen=True, repr=False, eq=False) class MediumLevelILAsr(MediumLevelILBinaryBase, Arithmetic): pass
[docs]@dataclass(frozen=True, repr=False, eq=False) class MediumLevelILRol(MediumLevelILBinaryBase, Arithmetic): pass
[docs]@dataclass(frozen=True, repr=False, eq=False) class MediumLevelILRor(MediumLevelILBinaryBase, Arithmetic): pass
[docs]@dataclass(frozen=True, repr=False, eq=False) class MediumLevelILMul(MediumLevelILBinaryBase, Arithmetic): pass
[docs]@dataclass(frozen=True, repr=False, eq=False) class MediumLevelILMuluDp(MediumLevelILBinaryBase, DoublePrecision): pass
[docs]@dataclass(frozen=True, repr=False, eq=False) class MediumLevelILMulsDp(MediumLevelILBinaryBase, DoublePrecision, Signed): pass
[docs]@dataclass(frozen=True, repr=False, eq=False) class MediumLevelILDivu(MediumLevelILBinaryBase, Arithmetic): pass
[docs]@dataclass(frozen=True, repr=False, eq=False) class MediumLevelILDivuDp(MediumLevelILBinaryBase, DoublePrecision): pass
[docs]@dataclass(frozen=True, repr=False, eq=False) class MediumLevelILDivs(MediumLevelILBinaryBase, Arithmetic, Signed): pass
[docs]@dataclass(frozen=True, repr=False, eq=False) class MediumLevelILDivsDp(MediumLevelILBinaryBase, DoublePrecision, Signed): pass
[docs]@dataclass(frozen=True, repr=False, eq=False) class MediumLevelILModu(MediumLevelILBinaryBase, Arithmetic): pass
[docs]@dataclass(frozen=True, repr=False, eq=False) class MediumLevelILModuDp(MediumLevelILBinaryBase, DoublePrecision): pass
[docs]@dataclass(frozen=True, repr=False, eq=False) class MediumLevelILMods(MediumLevelILBinaryBase, Arithmetic, Signed): pass
[docs]@dataclass(frozen=True, repr=False, eq=False) class MediumLevelILModsDp(MediumLevelILBinaryBase, DoublePrecision, Signed): pass
[docs]@dataclass(frozen=True, repr=False, eq=False) class MediumLevelILCmpE(MediumLevelILComparisonBase): pass
[docs]@dataclass(frozen=True, repr=False, eq=False) class MediumLevelILCmpNe(MediumLevelILComparisonBase): pass
[docs]@dataclass(frozen=True, repr=False, eq=False) class MediumLevelILCmpSlt(MediumLevelILComparisonBase, Signed): pass
[docs]@dataclass(frozen=True, repr=False, eq=False) class MediumLevelILCmpUlt(MediumLevelILComparisonBase): pass
[docs]@dataclass(frozen=True, repr=False, eq=False) class MediumLevelILCmpSle(MediumLevelILComparisonBase, Signed): pass
[docs]@dataclass(frozen=True, repr=False, eq=False) class MediumLevelILCmpUle(MediumLevelILComparisonBase): pass
[docs]@dataclass(frozen=True, repr=False, eq=False) class MediumLevelILCmpSge(MediumLevelILComparisonBase, Signed): pass
[docs]@dataclass(frozen=True, repr=False, eq=False) class MediumLevelILCmpUge(MediumLevelILComparisonBase): pass
[docs]@dataclass(frozen=True, repr=False, eq=False) class MediumLevelILCmpSgt(MediumLevelILComparisonBase, Signed): pass
[docs]@dataclass(frozen=True, repr=False, eq=False) class MediumLevelILCmpUgt(MediumLevelILComparisonBase): pass
[docs]@dataclass(frozen=True, repr=False, eq=False) class MediumLevelILTestBit(MediumLevelILComparisonBase): pass
[docs]@dataclass(frozen=True, repr=False, eq=False) class MediumLevelILAddOverflow(MediumLevelILBinaryBase, Arithmetic): pass
[docs]@dataclass(frozen=True, repr=False, eq=False) class MediumLevelILSyscall(MediumLevelILInstruction, Syscall): @property def output(self) -> List[variable.Variable]: return self._get_var_list(0, 1) @property def params(self) -> List[MediumLevelILInstruction]: return self._get_expr_list(2, 3) @property def operands(self) -> List[MediumLevelILOperandType]: return [self.output, self.params]
[docs]@dataclass(frozen=True, repr=False, eq=False) class MediumLevelILVarSsaField(MediumLevelILInstruction, SSA): @property def src(self) -> SSAVariable: return self._get_var_ssa(0, 1) @property def offset(self) -> int: return self._get_int(2) @property def operands(self) -> List[MediumLevelILOperandType]: return [self.src, self.offset]
[docs]@dataclass(frozen=True, repr=False, eq=False) class MediumLevelILVarAliasedField(MediumLevelILInstruction, SSA): @property def src(self) -> SSAVariable: return self._get_var_ssa(0, 1) @property def offset(self) -> int: return self._get_int(2) @property def operands(self) -> List[MediumLevelILOperandType]: return [self.src, self.offset]
[docs]@dataclass(frozen=True, repr=False, eq=False) class MediumLevelILVarSplitSsa(MediumLevelILInstruction, SSA): @property def high(self) -> SSAVariable: return self._get_var_ssa(0, 1) @property def low(self) -> SSAVariable: return self._get_var_ssa(2, 3) @property def operands(self) -> List[SSAVariable]: return [self.high, self.low]
[docs]@dataclass(frozen=True, repr=False, eq=False) class MediumLevelILCallOutputSsa(MediumLevelILInstruction, SSA): @property def dest_memory(self) -> int: return self._get_int(0) @property def dest(self) -> List[SSAVariable]: return self._get_var_ssa_list(1, 2) @property def vars_written(self) -> List[SSAVariable]: return self.dest @property def operands(self) -> List[MediumLevelILOperandType]: return [self.dest_memory, self.dest]
[docs]@dataclass(frozen=True, repr=False, eq=False) class MediumLevelILCallParamSsa(MediumLevelILInstruction, SSA): @property def src_memory(self) -> int: return self._get_int(0) @property def src(self) -> List[SSAVariable]: return self._get_var_ssa_list(1, 2) @property def operands(self) -> List[MediumLevelILOperandType]: return [self.src_memory, self.src]
[docs]@dataclass(frozen=True, repr=False, eq=False) class MediumLevelILLoadSsa(MediumLevelILInstruction, Load, SSA): @property def src(self) -> MediumLevelILInstruction: return self._get_expr(0) @property def src_memory(self) -> int: return self._get_int(1) @property def operands(self) -> List[MediumLevelILOperandType]: return [self.src, self.src_memory]
[docs]@dataclass(frozen=True, repr=False, eq=False) class MediumLevelILVarPhi(MediumLevelILInstruction, SetVar, Phi, SSA): @property def dest(self) -> SSAVariable: return self._get_var_ssa(0, 1) @property def src(self) -> List[SSAVariable]: return self._get_var_ssa_list(2, 3) @property def operands(self) -> List[MediumLevelILOperandType]: return [self.dest, self.src] @property def vars_read(self) -> List[SSAVariable]: return self.src
[docs]@dataclass(frozen=True, repr=False, eq=False) class MediumLevelILMemPhi(MediumLevelILInstruction, 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 operands(self) -> List[MediumLevelILOperandType]: return [self.dest_memory, self.src_memory]
[docs]@dataclass(frozen=True, repr=False, eq=False) class MediumLevelILSetVarSsa(MediumLevelILInstruction, SetVar, SSA): @property def dest(self) -> SSAVariable: return self._get_var_ssa(0, 1) @property def src(self) -> MediumLevelILInstruction: return self._get_expr(2) @property def operands(self) -> List[MediumLevelILOperandType]: return [self.dest, self.src] @property def vars_read(self) -> List[Union[variable.Variable, SSAVariable]]: return self.src.vars_read @property def vars_written(self) -> List[SSAVariable]: return [self.dest]
[docs]@dataclass(frozen=True, repr=False, eq=False) class MediumLevelILFcmpE(MediumLevelILComparisonBase, FloatingPoint): pass
[docs]@dataclass(frozen=True, repr=False, eq=False) class MediumLevelILFcmpNe(MediumLevelILComparisonBase, FloatingPoint): pass
[docs]@dataclass(frozen=True, repr=False, eq=False) class MediumLevelILFcmpLt(MediumLevelILComparisonBase, FloatingPoint): pass
[docs]@dataclass(frozen=True, repr=False, eq=False) class MediumLevelILFcmpLe(MediumLevelILComparisonBase, FloatingPoint): pass
[docs]@dataclass(frozen=True, repr=False, eq=False) class MediumLevelILFcmpGe(MediumLevelILComparisonBase, FloatingPoint): pass
[docs]@dataclass(frozen=True, repr=False, eq=False) class MediumLevelILFcmpGt(MediumLevelILComparisonBase, FloatingPoint): pass
[docs]@dataclass(frozen=True, repr=False, eq=False) class MediumLevelILFcmpO(MediumLevelILComparisonBase, FloatingPoint): pass
[docs]@dataclass(frozen=True, repr=False, eq=False) class MediumLevelILFcmpUo(MediumLevelILComparisonBase, FloatingPoint): pass
[docs]@dataclass(frozen=True, repr=False, eq=False) class MediumLevelILFadd(MediumLevelILBinaryBase, Arithmetic, FloatingPoint): pass
[docs]@dataclass(frozen=True, repr=False, eq=False) class MediumLevelILFsub(MediumLevelILBinaryBase, Arithmetic, FloatingPoint): pass
[docs]@dataclass(frozen=True, repr=False, eq=False) class MediumLevelILFmul(MediumLevelILBinaryBase, Arithmetic, FloatingPoint): pass
[docs]@dataclass(frozen=True, repr=False, eq=False) class MediumLevelILFdiv(MediumLevelILBinaryBase, Arithmetic, FloatingPoint): pass
[docs]@dataclass(frozen=True, repr=False, eq=False) class MediumLevelILJumpTo(MediumLevelILInstruction, Terminal): @property def dest(self) -> MediumLevelILInstruction: return self._get_expr(0) @property def targets(self) -> Mapping[int, int]: return self._get_target_map(1, 2) @property def operands(self) -> List[MediumLevelILOperandType]: return [self.dest, self.targets]
[docs]@dataclass(frozen=True, repr=False, eq=False) class MediumLevelILSetVarAliased(MediumLevelILInstruction, SetVar, SSA): @property def dest(self) -> SSAVariable: return self._get_var_ssa_dest_and_src(0, 1) @property def prev(self) -> SSAVariable: return self._get_var_ssa_dest_and_src(0, 2) @property def src(self) -> MediumLevelILInstruction: return self._get_expr(3) @property def operands(self) -> List[MediumLevelILOperandType]: return [self.dest, self.prev, self.src] @property def vars_read(self) -> List[Union[variable.Variable, SSAVariable]]: return self.src.vars_read @property def vars_written(self) -> List[SSAVariable]: return [self.dest]
[docs]@dataclass(frozen=True, repr=False, eq=False) class MediumLevelILSyscallUntyped(MediumLevelILCallBase, Syscall): @property def output(self) -> List[variable.Variable]: inst = self._get_expr(0) assert isinstance(inst, MediumLevelILCallOutput), "MediumLevelILCallUntyped return bad type for 'output'" return inst.dest @property def params(self) -> List[variable.Variable]: inst = self._get_expr(1) assert isinstance(inst, MediumLevelILCallParam), "MediumLevelILCallUntyped return bad type for 'params'" return inst.src @property def stack(self) -> MediumLevelILInstruction: return self._get_expr(2) @property def operands(self) -> List[MediumLevelILOperandType]: return [self.output, self.params, self.stack]
[docs]@dataclass(frozen=True, repr=False, eq=False) class MediumLevelILIntrinsic(MediumLevelILInstruction): @property def output(self) -> List[variable.Variable]: return self._get_var_list(0, 1) @property def intrinsic(self) -> 'lowlevelil.ILIntrinsic': return self._get_intrinsic(2) @property def params(self) -> List[MediumLevelILInstruction]: return self._get_expr_list(3, 4) @property def vars_read(self) -> List[variable.Variable]: result:List[variable.Variable] = [] for i in self.params: result.extend(i.vars_read) # type: ignore return result @property def vars_written(self) -> List[variable.Variable]: return self.output @property def operands(self) -> List[MediumLevelILOperandType]: return [self.output, self.intrinsic, self.params]
[docs]@dataclass(frozen=True, repr=False, eq=False) class MediumLevelILIntrinsicSsa(MediumLevelILInstruction, SSA): @property def output(self) -> List[SSAVariable]: return self._get_var_ssa_list(0, 1) @property def intrinsic(self) -> 'lowlevelil.ILIntrinsic': return self._get_intrinsic(2) @property def params(self) -> List[MediumLevelILInstruction]: return self._get_expr_list(3, 4) @property def vars_read(self) -> List[SSAVariable]: result:List[SSAVariable] = [] for i in self.params: result.extend(i.vars_read) # type: ignore return result @property def vars_written(self) -> List[SSAVariable]: return self.output @property def operands(self) -> List[MediumLevelILOperandType]: return [self.output, self.intrinsic, self.params]
[docs]@dataclass(frozen=True, repr=False, eq=False) class MediumLevelILSetVarSsaField(MediumLevelILInstruction, SetVar, SSA): @property def dest(self) -> SSAVariable: return self._get_var_ssa_dest_and_src(0, 1) @property def prev(self) -> SSAVariable: return self._get_var_ssa_dest_and_src(0, 2) @property def offset(self) -> int: return self._get_int(3) @property def src(self) -> MediumLevelILInstruction: return self._get_expr(4) @property def vars_read(self) -> List[SSAVariable]: return [self.prev, *self.src.vars_read] # type: ignore # we're guaranteed not to return non-SSAVariables here @property def vars_written(self) -> List[SSAVariable]: return [self.dest] @property def operands(self) -> List[MediumLevelILOperandType]: return [self.dest, self.prev, self.offset, self.src]
[docs]@dataclass(frozen=True, repr=False, eq=False) class MediumLevelILSetVarSplitSsa(MediumLevelILInstruction, SetVar, SSA): @property def high(self) -> SSAVariable: return self._get_var_ssa(0, 1) @property def low(self) -> SSAVariable: return self._get_var_ssa(2, 3) @property def src(self) -> MediumLevelILInstruction: return self._get_expr(4) @property def vars_read(self) -> List[Union[variable.Variable, SSAVariable]]: return self.src.vars_read @property def vars_written(self) -> List[SSAVariable]: return [self.high, self.low] @property def operands(self) -> List[MediumLevelILOperandType]: return [self.high, self.low, self.src]
[docs]@dataclass(frozen=True, repr=False, eq=False) class MediumLevelILSetVarAliasedField(MediumLevelILInstruction, SetVar, SSA): @property def dest(self) -> SSAVariable: return self._get_var_ssa_dest_and_src(0, 1) @property def prev(self) -> SSAVariable: return self._get_var_ssa_dest_and_src(0, 2) @property def offset(self) -> int: return self._get_int(3) @property def src(self) -> MediumLevelILInstruction: return self._get_expr(4) @property def vars_read(self) -> List[SSAVariable]: return [self.prev, *self.src.vars_read] # type: ignore # we're guaranteed not to return non-SSAVariables here @property def operands(self) -> List[MediumLevelILOperandType]: return [self.dest, self.prev, self.offset, self.src]
[docs]@dataclass(frozen=True, repr=False, eq=False) class MediumLevelILSyscallSsa(MediumLevelILCallBase, Syscall, SSA): @property def output(self) -> List[SSAVariable]: inst = self._get_expr(0) assert isinstance(inst, MediumLevelILCallOutputSsa), "MediumLevelILSyscallSsa return bad type for output" return inst.dest @property def output_dest_memory(self) -> int: inst = self._get_expr(0) assert isinstance(inst, MediumLevelILCallOutputSsa), "MediumLevelILSyscallSsa return bad type for output" return inst.dest_memory @property def params(self) -> List[MediumLevelILInstruction]: return self._get_expr_list(1, 2) @property def src_memory(self) -> int: return self._get_int(3) @property def operands(self) -> List[MediumLevelILOperandType]: return [self.output, self.params, self.src_memory]
[docs]@dataclass(frozen=True, repr=False, eq=False) class MediumLevelILSyscallUntypedSsa(MediumLevelILCallBase, Syscall, SSA): @property def output(self) -> List[SSAVariable]: inst = self._get_expr(0) assert isinstance(inst, MediumLevelILCallOutputSsa), "MediumLevelILSyscallUntypedSsa return bad type for 'output'" return inst.dest @property def output_dest_memory(self) -> int: inst = self._get_expr(0) assert isinstance(inst, MediumLevelILCallOutputSsa), "MediumLevelILSyscallUntypedSsa return bad type for 'output_dest_memory'" return inst.dest_memory @property def params(self) -> List[SSAVariable]: inst = self._get_expr(1) assert isinstance(inst, MediumLevelILCallParamSsa), "MediumLevelILSyscallUntypedSsa return bad type for 'params'" return inst.src @property def params_src_memory(self) -> int: inst = self._get_expr(1) assert isinstance(inst, MediumLevelILCallParamSsa), "MediumLevelILSyscallUntypedSsa return bad type for 'params_src_memory'" return inst.src_memory @property def stack(self) -> MediumLevelILInstruction: return self._get_expr(2) @property def operands(self) -> List[MediumLevelILOperandType]: return [self.output, self.params, self.stack]
[docs]@dataclass(frozen=True, repr=False, eq=False) class MediumLevelILLoadStructSsa(MediumLevelILInstruction, Load, SSA): @property def src(self) -> MediumLevelILInstruction: return self._get_expr(0) @property def offset(self) -> int: return self._get_int(1) @property def src_memory(self) -> int: return self._get_int(2) @property def operands(self) -> List[MediumLevelILOperandType]: return [self.src, self.offset, self.src_memory]
[docs]@dataclass(frozen=True, repr=False, eq=False) class MediumLevelILSetVarField(MediumLevelILInstruction, SetVar): @property def dest(self) -> variable.Variable: return self._get_var(0) @property def offset(self) -> int: return self._get_int(1) @property def src(self) -> MediumLevelILInstruction: return self._get_expr(2) @property def operands(self) -> List[MediumLevelILOperandType]: return [self.dest, self.offset, self.src]
[docs]@dataclass(frozen=True, repr=False, eq=False) class MediumLevelILSetVarSplit(MediumLevelILInstruction, SetVar): @property def high(self) -> variable.Variable: return self._get_var(0) @property def low(self) -> variable.Variable: return self._get_var(1) @property def src(self) -> MediumLevelILInstruction: return self._get_expr(2) @property def vars_written(self) -> List[variable.Variable]: return [self.high, self.low] @property def operands(self) -> List[MediumLevelILOperandType]: return [self.high, self.low, self.src]
[docs]@dataclass(frozen=True, repr=False, eq=False) class MediumLevelILStoreStruct(MediumLevelILInstruction, Store): @property def dest(self) -> MediumLevelILInstruction: return self._get_expr(0) @property def offset(self) -> int: return self._get_int(1) @property def src(self) -> MediumLevelILInstruction: return self._get_expr(2) @property def operands(self) -> List[MediumLevelILOperandType]: return [self.dest, self.offset, self.src]
[docs]@dataclass(frozen=True, repr=False, eq=False) class MediumLevelILAdc(MediumLevelILCarryBase): pass
[docs]@dataclass(frozen=True, repr=False, eq=False) class MediumLevelILSbb(MediumLevelILCarryBase): pass
[docs]@dataclass(frozen=True, repr=False, eq=False) class MediumLevelILRlc(MediumLevelILCarryBase): pass
[docs]@dataclass(frozen=True, repr=False, eq=False) class MediumLevelILRrc(MediumLevelILCarryBase): pass
[docs]@dataclass(frozen=True, repr=False, eq=False) class MediumLevelILCall(MediumLevelILCallBase, Localcall): @property def output(self) -> List[variable.Variable]: return self._get_var_list(0, 1) @property def dest(self) -> MediumLevelILInstruction: return self._get_expr(2) @property def params(self) -> List[MediumLevelILInstruction]: return self._get_expr_list(3, 4) @property def operands(self) -> List[MediumLevelILOperandType]: return [self.output, self.dest, self.params]
[docs]@dataclass(frozen=True, repr=False, eq=False) class MediumLevelILIf(MediumLevelILInstruction, Terminal): @property def condition(self) -> MediumLevelILInstruction: 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 operands(self) -> List[MediumLevelILOperandType]: return [self.condition, self.true, self.false]
[docs]@dataclass(frozen=True, repr=False, eq=False) class MediumLevelILTailcallUntyped(MediumLevelILCallBase, Tailcall): @property def output(self) -> List[variable.Variable]: inst = self._get_expr(0) assert isinstance(inst, MediumLevelILCallOutput), "MediumLevelILTailcallUntyped return bad type for 'output'" return inst.dest @property def dest(self) -> MediumLevelILInstruction: return self._get_expr(1) @property def params(self) -> List[variable.Variable]: inst = self._get_expr(2) assert isinstance(inst, MediumLevelILCallParam), "MediumLevelILTailcallUntyped return bad type for 'params'" return inst.src @property def stack(self) -> MediumLevelILInstruction: return self._get_expr(3) @property def operands(self) -> List[MediumLevelILOperandType]: return [self.output, self.dest, self.params, self.stack]
[docs]@dataclass(frozen=True, repr=False, eq=False) class MediumLevelILCallSsa(MediumLevelILCallBase, Localcall, SSA): @property def output(self) -> List[SSAVariable]: inst = self._get_expr(0) assert isinstance(inst, MediumLevelILCallOutputSsa), "MediumLevelILCallSsa return bad type for output" return inst.dest @property def output_dest_memory(self) -> int: inst = self._get_expr(0) assert isinstance(inst, MediumLevelILCallOutputSsa), "MediumLevelILCallSsa return bad type for output" return inst.dest_memory @property def dest(self) -> MediumLevelILInstruction: return self._get_expr(1) @property def params(self) -> List[MediumLevelILInstruction]: return self._get_expr_list(2, 3) @property def src_memory(self) -> int: return self._get_int(4) @property def operands(self) -> List[MediumLevelILOperandType]: return [self.output, self.dest, self.params, self.src_memory]
[docs]@dataclass(frozen=True, repr=False, eq=False) class MediumLevelILCallUntypedSsa(MediumLevelILCallBase, Localcall, SSA): @property def output(self) -> List[SSAVariable]: inst = self._get_expr(0) assert isinstance(inst, MediumLevelILCallOutputSsa), "MediumLevelILCallUntypedSsa return bad type for output" return inst.dest @property def output_dest_memory(self) -> int: inst = self._get_expr(0) assert isinstance(inst, MediumLevelILCallOutputSsa), "MediumLevelILCallUntypedSsa return bad type for output" return inst.dest_memory @property def dest(self) -> MediumLevelILInstruction: return self._get_expr(1) @property def params(self) -> List[SSAVariable]: inst = self._get_expr(2) assert isinstance(inst, MediumLevelILCallParamSsa), "MediumLevelILCallUntypedSsa return bad type for 'params'" return inst.src @property def params_src_memory(self): inst = self._get_expr(2) assert isinstance(inst, MediumLevelILCallParamSsa), "MediumLevelILCallUntypedSsa return bad type for 'params_src_memory'" return inst.src_memory @property def stack(self) -> MediumLevelILInstruction: return self._get_expr(3) @property def operands(self) -> List[MediumLevelILOperandType]: return [self.output, self.dest, self.params, self.stack]
[docs]@dataclass(frozen=True, repr=False, eq=False) class MediumLevelILTailcall(MediumLevelILCallBase, Tailcall): @property def output(self) -> List[variable.Variable]: return self._get_var_list(0, 1) @property def dest(self) -> MediumLevelILInstruction: return self._get_expr(2) @property def params(self) -> List[MediumLevelILInstruction]: return self._get_expr_list(3, 4) @property def operands(self) -> List[MediumLevelILOperandType]: return [self.output, self.dest, self.params]
[docs]@dataclass(frozen=True, repr=False, eq=False) class MediumLevelILTailcallSsa(MediumLevelILCallBase, Tailcall, SSA): @property def output(self) -> List[SSAVariable]: inst = self._get_expr(0) assert isinstance(inst, MediumLevelILCallOutputSsa), "MediumLevelILTailcallSsa return bad type for output" return inst.dest @property def output_dest_memory(self) -> int: inst = self._get_expr(0) assert isinstance(inst, MediumLevelILCallOutputSsa), "MediumLevelILTailcallSsa return bad type for output" return inst.dest_memory @property def dest(self) -> MediumLevelILInstruction: return self._get_expr(1) @property def params(self) -> List[MediumLevelILInstruction]: return self._get_expr_list(2, 3) @property def src_memory(self) -> int: return self._get_int(4) @property def operands(self) -> List[MediumLevelILOperandType]: return [self.output, self.dest, self.params, self.src_memory]
[docs]@dataclass(frozen=True, repr=False, eq=False) class MediumLevelILTailcallUntypedSsa(MediumLevelILCallBase, Tailcall, SSA): @property def output(self) -> List[SSAVariable]: inst = self._get_expr(0) assert isinstance(inst, MediumLevelILCallOutputSsa), "MediumLevelILTailcallUntypedSsa return bad type for 'output'" return inst.dest @property def output_dest_memory(self) -> int: inst = self._get_expr(0) assert isinstance(inst, MediumLevelILCallOutputSsa), "MediumLevelILTailcallUntypedSsa return bad type for 'output'" return inst.dest_memory @property def dest(self) -> MediumLevelILInstruction: return self._get_expr(1) @property def params(self) -> List[SSAVariable]: inst = self._get_expr(2) assert isinstance(inst, MediumLevelILCallParamSsa), "MediumLevelILTailcallUntypedSsa return bad type for 'params'" return inst.src @property def stack(self) -> MediumLevelILInstruction: return self._get_expr(3) @property def operands(self) -> List[MediumLevelILOperandType]: return [self.output, self.dest, self.params, self.stack]
[docs]@dataclass(frozen=True, repr=False, eq=False) class MediumLevelILStoreSsa(MediumLevelILInstruction, Store, SSA): @property def dest(self) -> MediumLevelILInstruction: 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) -> MediumLevelILInstruction: return self._get_expr(3) @property def operands(self) -> List[MediumLevelILOperandType]: return [self.dest, self.dest_memory, self.src_memory, self.src]
[docs]@dataclass(frozen=True, repr=False, eq=False) class MediumLevelILCallUntyped(MediumLevelILCallBase, Localcall): @property def output(self) -> List[variable.Variable]: inst = self._get_expr(0) assert isinstance(inst, MediumLevelILCallOutput), "MediumLevelILCallUntyped return bad type for 'output'" return inst.dest @property def dest(self) -> MediumLevelILInstruction: return self._get_expr(1) @property def params(self) -> List[variable.Variable]: inst = self._get_expr(2) assert isinstance(inst, MediumLevelILCallParam), "MediumLevelILCallUntyped return bad type for 'params'" return inst.src @property def stack(self) -> MediumLevelILInstruction: return self._get_expr(3) @property def operands(self) -> List[MediumLevelILOperandType]: return [self.output, self.dest, self.params, self.stack]
[docs]@dataclass(frozen=True, repr=False, eq=False) class MediumLevelILStoreStructSsa(MediumLevelILInstruction, Store, SSA): @property def dest(self) -> MediumLevelILInstruction: return self._get_expr(0) @property def offset(self) -> int: return self._get_int(1) @property def dest_memory(self) -> int: return self._get_int(2) @property def src_memory(self) -> int: return self._get_int(3) @property def src(self) -> MediumLevelILInstruction: return self._get_expr(4) @property def operands(self) -> List[MediumLevelILOperandType]: return [self.dest, self.offset, self.dest_memory, self.src_memory, self.src]
ILInstruction = { MediumLevelILOperation.MLIL_NOP:MediumLevelILNop, # [], MediumLevelILOperation.MLIL_NORET:MediumLevelILNoret, # [], MediumLevelILOperation.MLIL_BP:MediumLevelILBp, # [], MediumLevelILOperation.MLIL_UNDEF:MediumLevelILUndef, # [], MediumLevelILOperation.MLIL_UNIMPL:MediumLevelILUnimpl, # [], MediumLevelILOperation.MLIL_LOAD:MediumLevelILLoad, # [("src", "expr")], MediumLevelILOperation.MLIL_VAR:MediumLevelILVar, # [("src", "var")], MediumLevelILOperation.MLIL_ADDRESS_OF:MediumLevelILAddressOf, # [("src", "var")], MediumLevelILOperation.MLIL_CONST:MediumLevelILConst, # [("constant", "int")], MediumLevelILOperation.MLIL_CONST_PTR:MediumLevelILConstPtr, # [("constant", "int")], MediumLevelILOperation.MLIL_FLOAT_CONST:MediumLevelILFloatConst, # [("constant", "float")], MediumLevelILOperation.MLIL_IMPORT:MediumLevelILImport, # [("constant", "int")], MediumLevelILOperation.MLIL_SET_VAR:MediumLevelILSetVar, # [("dest", "var"), ("src", "expr")], MediumLevelILOperation.MLIL_LOAD_STRUCT:MediumLevelILLoadStruct, # [("src", "expr"), ("offset", "int")], MediumLevelILOperation.MLIL_STORE:MediumLevelILStore, # [("dest", "expr"), ("src", "expr")], MediumLevelILOperation.MLIL_VAR_FIELD:MediumLevelILVarField, # [("src", "var"), ("offset", "int")], MediumLevelILOperation.MLIL_VAR_SPLIT:MediumLevelILVarSplit, # [("high", "var"), ("low", "var")], MediumLevelILOperation.MLIL_ADDRESS_OF_FIELD:MediumLevelILAddressOfField, # [("src", "var"), ("offset", "int")], MediumLevelILOperation.MLIL_EXTERN_PTR:MediumLevelILExternPtr, # [("constant", "int"), ("offset", "int")], MediumLevelILOperation.MLIL_ADD:MediumLevelILAdd, # [("left", "expr"), ("right", "expr")], MediumLevelILOperation.MLIL_SUB:MediumLevelILSub, # [("left", "expr"), ("right", "expr")], MediumLevelILOperation.MLIL_AND:MediumLevelILAnd, # [("left", "expr"), ("right", "expr")], MediumLevelILOperation.MLIL_OR:MediumLevelILOr, # [("left", "expr"), ("right", "expr")], MediumLevelILOperation.MLIL_XOR:MediumLevelILXor, # [("left", "expr"), ("right", "expr")], MediumLevelILOperation.MLIL_LSL:MediumLevelILLsl, # [("left", "expr"), ("right", "expr")], MediumLevelILOperation.MLIL_LSR:MediumLevelILLsr, # [("left", "expr"), ("right", "expr")], MediumLevelILOperation.MLIL_ASR:MediumLevelILAsr, # [("left", "expr"), ("right", "expr")], MediumLevelILOperation.MLIL_ROL:MediumLevelILRol, # [("left", "expr"), ("right", "expr")], MediumLevelILOperation.MLIL_ROR:MediumLevelILRor, # [("left", "expr"), ("right", "expr")], MediumLevelILOperation.MLIL_MUL:MediumLevelILMul, # [("left", "expr"), ("right", "expr")], MediumLevelILOperation.MLIL_MULU_DP:MediumLevelILMuluDp, # [("left", "expr"), ("right", "expr")], MediumLevelILOperation.MLIL_MULS_DP:MediumLevelILMulsDp, # [("left", "expr"), ("right", "expr")], MediumLevelILOperation.MLIL_DIVU:MediumLevelILDivu, # [("left", "expr"), ("right", "expr")], MediumLevelILOperation.MLIL_DIVU_DP:MediumLevelILDivuDp, # [("left", "expr"), ("right", "expr")], MediumLevelILOperation.MLIL_DIVS:MediumLevelILDivs, # [("left", "expr"), ("right", "expr")], MediumLevelILOperation.MLIL_DIVS_DP:MediumLevelILDivsDp, # [("left", "expr"), ("right", "expr")], MediumLevelILOperation.MLIL_MODU:MediumLevelILModu, # [("left", "expr"), ("right", "expr")], MediumLevelILOperation.MLIL_MODU_DP:MediumLevelILModuDp, # [("left", "expr"), ("right", "expr")], MediumLevelILOperation.MLIL_MODS:MediumLevelILMods, # [("left", "expr"), ("right", "expr")], MediumLevelILOperation.MLIL_MODS_DP:MediumLevelILModsDp, # [("left", "expr"), ("right", "expr")], MediumLevelILOperation.MLIL_NEG:MediumLevelILNeg, # [("src", "expr")], MediumLevelILOperation.MLIL_NOT:MediumLevelILNot, # [("src", "expr")], MediumLevelILOperation.MLIL_SX:MediumLevelILSx, # [("src", "expr")], MediumLevelILOperation.MLIL_ZX:MediumLevelILZx, # [("src", "expr")], MediumLevelILOperation.MLIL_LOW_PART:MediumLevelILLowPart, # [("src", "expr")], MediumLevelILOperation.MLIL_JUMP:MediumLevelILJump, # [("dest", "expr")], MediumLevelILOperation.MLIL_RET_HINT:MediumLevelILRetHint, # [("dest", "expr")], MediumLevelILOperation.MLIL_CALL_OUTPUT:MediumLevelILCallOutput, # [("dest", "var_list")], MediumLevelILOperation.MLIL_CALL_PARAM:MediumLevelILCallParam, # [("src", "var_list")], MediumLevelILOperation.MLIL_RET:MediumLevelILRet, # [("src", "expr_list")], MediumLevelILOperation.MLIL_GOTO:MediumLevelILGoto, # [("dest", "int")], MediumLevelILOperation.MLIL_BOOL_TO_INT:MediumLevelILBoolToInt, # [("src", "expr")], MediumLevelILOperation.MLIL_FREE_VAR_SLOT:MediumLevelILFreeVarSlot, # [("dest", "var")], MediumLevelILOperation.MLIL_TRAP:MediumLevelILTrap, # [("vector", "int")], MediumLevelILOperation.MLIL_FREE_VAR_SLOT_SSA:MediumLevelILFreeVarSlotSsa, # [("prev", "var_ssa_dest_and_src")], MediumLevelILOperation.MLIL_UNIMPL_MEM:MediumLevelILUnimplMem, # [("src", "expr")], MediumLevelILOperation.MLIL_FSQRT:MediumLevelILFsqrt, # [("src", "expr")], MediumLevelILOperation.MLIL_FNEG:MediumLevelILFneg, # [("src", "expr")], MediumLevelILOperation.MLIL_FABS:MediumLevelILFabs, # [("src", "expr")], MediumLevelILOperation.MLIL_FLOAT_TO_INT:MediumLevelILFloatToInt, # [("src", "expr")], MediumLevelILOperation.MLIL_INT_TO_FLOAT:MediumLevelILIntToFloat, # [("src", "expr")], MediumLevelILOperation.MLIL_FLOAT_CONV:MediumLevelILFloatConv, # [("src", "expr")], MediumLevelILOperation.MLIL_ROUND_TO_INT:MediumLevelILRoundToInt, # [("src", "expr")], MediumLevelILOperation.MLIL_FLOOR:MediumLevelILFloor, # [("src", "expr")], MediumLevelILOperation.MLIL_CEIL:MediumLevelILCeil, # [("src", "expr")], MediumLevelILOperation.MLIL_FTRUNC:MediumLevelILFtrunc, # [("src", "expr")], MediumLevelILOperation.MLIL_VAR_SSA:MediumLevelILVarSsa, # [("src", "var_ssa")], MediumLevelILOperation.MLIL_VAR_ALIASED:MediumLevelILVarAliased, # [("src", "var_ssa")], MediumLevelILOperation.MLIL_CMP_E:MediumLevelILCmpE, # [("left", "expr"), ("right", "expr")], MediumLevelILOperation.MLIL_CMP_NE:MediumLevelILCmpNe, # [("left", "expr"), ("right", "expr")], MediumLevelILOperation.MLIL_CMP_SLT:MediumLevelILCmpSlt, # [("left", "expr"), ("right", "expr")], MediumLevelILOperation.MLIL_CMP_ULT:MediumLevelILCmpUlt, # [("left", "expr"), ("right", "expr")], MediumLevelILOperation.MLIL_CMP_SLE:MediumLevelILCmpSle, # [("left", "expr"), ("right", "expr")], MediumLevelILOperation.MLIL_CMP_ULE:MediumLevelILCmpUle, # [("left", "expr"), ("right", "expr")], MediumLevelILOperation.MLIL_CMP_SGE:MediumLevelILCmpSge, # [("left", "expr"), ("right", "expr")], MediumLevelILOperation.MLIL_CMP_UGE:MediumLevelILCmpUge, # [("left", "expr"), ("right", "expr")], MediumLevelILOperation.MLIL_CMP_SGT:MediumLevelILCmpSgt, # [("left", "expr"), ("right", "expr")], MediumLevelILOperation.MLIL_CMP_UGT:MediumLevelILCmpUgt, # [("left", "expr"), ("right", "expr")], MediumLevelILOperation.MLIL_TEST_BIT:MediumLevelILTestBit, # [("left", "expr"), ("right", "expr")], MediumLevelILOperation.MLIL_ADD_OVERFLOW:MediumLevelILAddOverflow, # [("left", "expr"), ("right", "expr")], MediumLevelILOperation.MLIL_SYSCALL:MediumLevelILSyscall, # [("output", "var_list"), ("params", "expr_list")], MediumLevelILOperation.MLIL_VAR_SSA_FIELD:MediumLevelILVarSsaField, # [("src", "var_ssa"), ("offset", "int")], MediumLevelILOperation.MLIL_VAR_ALIASED_FIELD:MediumLevelILVarAliasedField, # [("src", "var_ssa"), ("offset", "int")], MediumLevelILOperation.MLIL_VAR_SPLIT_SSA:MediumLevelILVarSplitSsa, # [("high", "var_ssa"), ("low", "var_ssa")], MediumLevelILOperation.MLIL_CALL_OUTPUT_SSA:MediumLevelILCallOutputSsa, # [("dest_memory", "int"), ("dest", "var_ssa_list")], MediumLevelILOperation.MLIL_CALL_PARAM_SSA:MediumLevelILCallParamSsa, # [("src_memory", "int"), ("src", "var_ssa_list")], MediumLevelILOperation.MLIL_LOAD_SSA:MediumLevelILLoadSsa, # [("src", "expr"), ("src_memory", "int")], MediumLevelILOperation.MLIL_VAR_PHI:MediumLevelILVarPhi, # [("dest", "var_ssa"), ("src", "var_ssa_list")], MediumLevelILOperation.MLIL_MEM_PHI:MediumLevelILMemPhi, # [("dest_memory", "int"), ("src_memory", "int_list")], MediumLevelILOperation.MLIL_SET_VAR_SSA:MediumLevelILSetVarSsa, # [("dest", "var_ssa"), ("src", "expr")], MediumLevelILOperation.MLIL_FCMP_E:MediumLevelILFcmpE, # [("left", "expr"), ("right", "expr")], MediumLevelILOperation.MLIL_FCMP_NE:MediumLevelILFcmpNe, # [("left", "expr"), ("right", "expr")], MediumLevelILOperation.MLIL_FCMP_LT:MediumLevelILFcmpLt, # [("left", "expr"), ("right", "expr")], MediumLevelILOperation.MLIL_FCMP_LE:MediumLevelILFcmpLe, # [("left", "expr"), ("right", "expr")], MediumLevelILOperation.MLIL_FCMP_GE:MediumLevelILFcmpGe, # [("left", "expr"), ("right", "expr")], MediumLevelILOperation.MLIL_FCMP_GT:MediumLevelILFcmpGt, # [("left", "expr"), ("right", "expr")], MediumLevelILOperation.MLIL_FCMP_O:MediumLevelILFcmpO, # [("left", "expr"), ("right", "expr")], MediumLevelILOperation.MLIL_FCMP_UO:MediumLevelILFcmpUo, # [("left", "expr"), ("right", "expr")], MediumLevelILOperation.MLIL_FADD:MediumLevelILFadd, # [("left", "expr"), ("right", "expr")], MediumLevelILOperation.MLIL_FSUB:MediumLevelILFsub, # [("left", "expr"), ("right", "expr")], MediumLevelILOperation.MLIL_FMUL:MediumLevelILFmul, # [("left", "expr"), ("right", "expr")], MediumLevelILOperation.MLIL_FDIV:MediumLevelILFdiv, # [("left", "expr"), ("right", "expr")], MediumLevelILOperation.MLIL_JUMP_TO:MediumLevelILJumpTo, # [("dest", "expr"), ("targets", "target_map")], MediumLevelILOperation.MLIL_SET_VAR_ALIASED:MediumLevelILSetVarAliased, # [("prev", "var_ssa_dest_and_src"), ("src", "expr")], MediumLevelILOperation.MLIL_SYSCALL_UNTYPED:MediumLevelILSyscallUntyped, # [("output", "expr"), ("params", "expr"), ("stack", "expr")], MediumLevelILOperation.MLIL_TAILCALL:MediumLevelILTailcall, # [("output", "var_list"), ("dest", "expr"), ("params", "expr_list")], MediumLevelILOperation.MLIL_INTRINSIC:MediumLevelILIntrinsic, # [("output", "var_list"), ("intrinsic", "intrinsic"), ("params", "expr_list")], MediumLevelILOperation.MLIL_INTRINSIC_SSA:MediumLevelILIntrinsicSsa, # [("output", "var_ssa_list"), ("intrinsic", "intrinsic"), ("params", "expr_list")], MediumLevelILOperation.MLIL_SET_VAR_SSA_FIELD:MediumLevelILSetVarSsaField, # [("prev", "var_ssa_dest_and_src"), ("offset", "int"), ("src", "expr")], MediumLevelILOperation.MLIL_SET_VAR_SPLIT_SSA:MediumLevelILSetVarSplitSsa, # [("high", "var_ssa"), ("low", "var_ssa"), ("src", "expr")], MediumLevelILOperation.MLIL_SET_VAR_ALIASED_FIELD:MediumLevelILSetVarAliasedField, # [("prev", "var_ssa_dest_and_src"), ("offset", "int"), ("src", "expr")], MediumLevelILOperation.MLIL_SYSCALL_SSA:MediumLevelILSyscallSsa, # [("output", "expr"), ("params", "expr_list"), ("src_memory", "int")], MediumLevelILOperation.MLIL_SYSCALL_UNTYPED_SSA:MediumLevelILSyscallUntypedSsa, # [("output", "expr"), ("params", "expr"), ("stack", "expr")], MediumLevelILOperation.MLIL_LOAD_STRUCT_SSA:MediumLevelILLoadStructSsa, # [("src", "expr"), ("offset", "int"), ("src_memory", "int")], MediumLevelILOperation.MLIL_SET_VAR_FIELD:MediumLevelILSetVarField, # [("dest", "var"), ("offset", "int"), ("src", "expr")], MediumLevelILOperation.MLIL_SET_VAR_SPLIT:MediumLevelILSetVarSplit, # [("high", "var"), ("low", "var"), ("src", "expr")], MediumLevelILOperation.MLIL_STORE_STRUCT:MediumLevelILStoreStruct, # [("dest", "expr"), ("offset", "int"), ("src", "expr")], MediumLevelILOperation.MLIL_ADC:MediumLevelILAdc, # [("left", "expr"), ("right", "expr"), ("carry", "expr")], MediumLevelILOperation.MLIL_SBB:MediumLevelILSbb, # [("left", "expr"), ("right", "expr"), ("carry", "expr")], MediumLevelILOperation.MLIL_RLC:MediumLevelILRlc, # [("left", "expr"), ("right", "expr"), ("carry", "expr")], MediumLevelILOperation.MLIL_RRC:MediumLevelILRrc, # [("left", "expr"), ("right", "expr"), ("carry", "expr")], MediumLevelILOperation.MLIL_TAILCALL_UNTYPED:MediumLevelILTailcallUntyped, # [("output", "expr"), ("dest", "expr"), ("params", "expr"), ("stack", "expr")], MediumLevelILOperation.MLIL_CALL_SSA:MediumLevelILCallSsa, # [("output", "expr"), ("dest", "expr"), ("params", "expr_list"), ("src_memory", "int")], MediumLevelILOperation.MLIL_CALL_UNTYPED_SSA:MediumLevelILCallUntypedSsa, # [("output", "expr"), ("dest", "expr"), ("params", "expr"), ("stack", "expr")], MediumLevelILOperation.MLIL_TAILCALL_SSA:MediumLevelILTailcallSsa, # [("output", "expr"), ("dest", "expr"), ("params", "expr_list"), ("src_memory", "int")], MediumLevelILOperation.MLIL_TAILCALL_UNTYPED_SSA:MediumLevelILTailcallUntypedSsa, # [("output", "expr"), ("dest", "expr"), ("params", "expr"), ("stack", "expr")], MediumLevelILOperation.MLIL_CALL:MediumLevelILCall, # [("output", "var_list"), ("dest", "expr"), ("params", "expr_list")], MediumLevelILOperation.MLIL_IF:MediumLevelILIf, # [("condition", "expr"), ("true", "int"), ("false", "int")], MediumLevelILOperation.MLIL_STORE_SSA:MediumLevelILStoreSsa, # [("dest", "expr"), ("dest_memory", "int"), ("src_memory", "int"), ("src", "expr")], MediumLevelILOperation.MLIL_CALL_UNTYPED:MediumLevelILCallUntyped, # [("output", "expr"), ("dest", "expr"), ("params", "expr"), ("stack", "expr")], MediumLevelILOperation.MLIL_STORE_STRUCT_SSA:MediumLevelILStoreStructSsa, # [("dest", "expr"), ("offset", "int"), ("dest_memory", "int"), ("src_memory", "int"), ("src", "expr")], }
[docs]class MediumLevelILExpr: """ ``class MediumLevelILExpr`` hold the index of IL Expressions. .. note:: Deprecated. Use ExpressionIndex instead """ def __init__(self, index): self._index = index def __int__(self): return self._index @property def index(self): return self._index
[docs]class MediumLevelILFunction: """ ``class MediumLevelILFunction`` contains the list of ExpressionIndex objects that make up a function. ExpressionIndex objects can be added to the MediumLevelILFunction by calling :func:`append` and passing the result of the various class methods which return ExpressionIndex objects. """ def __init__(self, arch:Optional['architecture.Architecture']=None, handle:Optional[core.BNMediumLevelILFunction]=None, source_func:Optional['function.Function']=None): _arch = arch _source_function = source_func if handle is not None: MLILHandle = ctypes.POINTER(core.BNMediumLevelILFunction) _handle = ctypes.cast(handle, MLILHandle) if _source_function is None: _source_function = function.Function(handle = core.BNGetMediumLevelILOwnerFunction(_handle)) if _arch is None: _arch = _source_function.arch else: if _source_function is None: raise ValueError("IL functions must be created with an associated function") if _arch is None: _arch = _source_function.arch func_handle = _source_function.handle _handle = core.BNCreateMediumLevelILFunction(self.arch.handle, func_handle) assert _source_function is not None assert _arch is not None assert _handle is not None self.handle = _handle self._arch = _arch self._source_function = _source_function def __del__(self): if core is not None: core.BNFreeMediumLevelILFunction(self.handle) def __repr__(self): arch = self.source_function.arch if arch: return f"<mlil func: {arch.name}@{self.source_function.start:#x}>" else: return f"<mlil func: {self.source_function.start:#x}>" def __len__(self): return int(core.BNGetMediumLevelILInstructionCount(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(('MLIL', self._source_function)) def __getitem__(self, i) -> 'MediumLevelILInstruction': if isinstance(i, slice) or isinstance(i, tuple): raise IndexError("expected integer instruction index") elif isinstance(i, MediumLevelILInstruction): # for backwards compatibility return i if i < -len(self) or i >= len(self): raise IndexError("index out of range") if i < 0: i = len(self) + i return MediumLevelILInstruction.create(self, ExpressionIndex(core.BNGetMediumLevelILIndexForInstruction(self.handle, i)), i) def __setitem__(self, i, j): raise IndexError("instruction modification not implemented") def __iter__(self): count = ctypes.c_ulonglong() blocks = core.BNGetMediumLevelILBasicBlockList(self.handle, count) assert blocks is not None, "core.BNGetMediumLevelILBasicBlockList 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, "Got None from core.BNNewBasicBlockReference" yield MediumLevelILBasicBlock(core_block, self, view) finally: core.BNFreeBasicBlockList(blocks, count.value) @property def current_address(self) -> int: """Current IL Address (read/write)""" return core.BNMediumLevelILGetCurrentAddress(self.handle) @current_address.setter def current_address(self, value:int) -> None: core.BNMediumLevelILSetCurrentAddress(self.handle, self._arch.handle, value)
[docs] def set_current_address(self, value:int, arch:Optional['architecture.Architecture']=None) -> None: _arch = arch if _arch is None: _arch = self._arch core.BNMediumLevelILSetCurrentAddress(self.handle, _arch.handle, value)
def _basic_block_list(self): count = ctypes.c_ulonglong() blocks = core.BNGetMediumLevelILBasicBlockList(self.handle, count) assert blocks is not None, "core.BNGetMediumLevelILBasicBlockList returned None" return count, blocks def _instantiate_block(self, handle): return MediumLevelILBasicBlock(handle, self, self.view) @property def basic_blocks(self) -> 'function.MediumLevelILBasicBlockList': return function.MediumLevelILBasicBlockList(self) @property def instructions(self) -> Generator[MediumLevelILInstruction, None, None]: """A generator of mlil instructions of the current function""" for block in self.basic_blocks: yield from block @property def ssa_form(self) -> Optional['MediumLevelILFunction']: """Medium level IL in SSA form (read-only)""" result = core.BNGetMediumLevelILSSAForm(self.handle) if not result: return None return MediumLevelILFunction(self._arch, result, self._source_function) @property def non_ssa_form(self) -> Optional['MediumLevelILFunction']: """Medium level IL in non-SSA (default) form (read-only)""" result = core.BNGetMediumLevelILNonSSAForm(self.handle) if not result: return None return MediumLevelILFunction(self._arch, result, self._source_function) @property def low_level_il(self) -> Optional['lowlevelil.LowLevelILFunction']: """Low level IL for this function""" result = core.BNGetLowLevelILForMediumLevelIL(self.handle) if not result: return None return lowlevelil.LowLevelILFunction(self._arch, result, self._source_function) @property def llil(self) -> Optional['lowlevelil.LowLevelILFunction']: """Alias for low_level_il""" return self.low_level_il @property def high_level_il(self) -> Optional[highlevelil.HighLevelILFunction]: """High level IL for this medium level IL.""" result = core.BNGetHighLevelILForMediumLevelIL(self.handle) if not result: return None return highlevelil.HighLevelILFunction(self._arch, result, self._source_function) @property def hlil(self) -> Optional[highlevelil.HighLevelILFunction]: return self.high_level_il
[docs] def get_instruction_start(self, addr:int, arch:Optional['architecture.Architecture']=None) -> Optional[int]: _arch = arch if _arch is None: if self._arch is None: raise Exception("Attempting to get_instruction_start from a MLIL Function without an Architecture") _arch = self._arch result = core.BNMediumLevelILGetInstructionStart(self.handle, _arch.handle, addr) if result >= core.BNGetMediumLevelILInstructionCount(self.handle): return None return result
[docs] def expr(self, operation:MediumLevelILOperation, a:int=0, b:int=0, c:int=0, d:int=0, e:int=0, size:int=0) -> ExpressionIndex: _operation = operation if isinstance(operation, str): _operation = MediumLevelILOperation[operation] elif isinstance(operation, MediumLevelILOperation): _operation = operation.value return ExpressionIndex(core.BNMediumLevelILAddExpr(self.handle, _operation, size, a, b, c, d, e))
[docs] def append(self, expr:ExpressionIndex) -> int: """ ``append`` adds the ExpressionIndex ``expr`` to the current MediumLevelILFunction. :param ExpressionIndex expr: the ExpressionIndex to add to the current MediumLevelILFunction :return: number of ExpressionIndex in the current function :rtype: int """ return core.BNMediumLevelILAddInstruction(self.handle, expr)
[docs] def goto(self, label:MediumLevelILLabel) -> ExpressionIndex: """ ``goto`` returns a goto expression which jumps to the provided MediumLevelILLabel. :param MediumLevelILLabel label: Label to jump to :return: the ExpressionIndex that jumps to the provided label :rtype: ExpressionIndex """ return ExpressionIndex(core.BNMediumLevelILGoto(self.handle, label.handle))
[docs] def if_expr(self, operand:ExpressionIndex, t:MediumLevelILLabel, f:MediumLevelILLabel) -> ExpressionIndex: """ ``if_expr`` returns the ``if`` expression which depending on condition ``operand`` jumps to the MediumLevelILLabel ``t`` when the condition expression ``operand`` is non-zero and ``f`` when it's zero. :param ExpressionIndex operand: comparison expression to evaluate. :param MediumLevelILLabel t: Label for the true branch :param MediumLevelILLabel f: Label for the false branch :return: the ExpressionIndex for the if expression :rtype: ExpressionIndex """ return ExpressionIndex(core.BNMediumLevelILIf(self.handle, operand, t.handle, f.handle))
[docs] def mark_label(self, label:MediumLevelILLabel) -> None: """ ``mark_label`` assigns a MediumLevelILLabel to the current IL address. :param MediumLevelILLabel label: :rtype: None """ core.BNMediumLevelILMarkLabel(self.handle, label.handle)
[docs] def add_label_map(self, labels:Mapping[int, MediumLevelILLabel]) -> ExpressionIndex: """ ``add_label_map`` returns a label list expression for the given list of MediumLevelILLabel objects. :param labels: the list of MediumLevelILLabel to get a label list expression from :type labels: dict(int, MediumLevelILLabel) :return: the label list expression :rtype: ExpressionIndex """ label_list = (ctypes.POINTER(core.BNMediumLevelILLabel) * len(labels))() # type: ignore value_list = (ctypes.POINTER(ctypes.c_ulonglong) * len(labels))() # type: ignore for i, (key, value) in enumerate(labels.items()): value_list[i] = key label_list[i] = value.handle return ExpressionIndex(core.BNMediumLevelILAddLabelMap(self.handle, value_list, label_list, len(labels)))
[docs] def add_operand_list(self, operands:List[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(int) :return: an operand list expression :rtype: ExpressionIndex """ operand_list = (ctypes.c_ulonglong * len(operands))() for i in range(len(operands)): operand_list[i] = operands[i] return ExpressionIndex(core.BNMediumLevelILAddOperandList(self.handle, operand_list, len(operands)))
[docs] def finalize(self) -> None: """ ``finalize`` ends the function and computes the list of basic blocks. :rtype: None """ core.BNFinalizeMediumLevelILFunction(self.handle)
[docs] def get_ssa_instruction_index(self, instr:InstructionIndex) -> InstructionIndex: return InstructionIndex(core.BNGetMediumLevelILSSAInstructionIndex(self.handle, instr))
[docs] def get_non_ssa_instruction_index(self, instr:InstructionIndex) -> InstructionIndex: return InstructionIndex(core.BNGetMediumLevelILNonSSAInstructionIndex(self.handle, instr))
[docs] def get_ssa_var_definition(self, ssa_var:SSAVariable) -> Optional[MediumLevelILInstruction]: var_data = ssa_var.var.to_BNVariable() result = core.BNGetMediumLevelILSSAVarDefinition(self.handle, var_data, ssa_var.version) if result >= core.BNGetMediumLevelILInstructionCount(self.handle): return None return self[result]
[docs] def get_ssa_memory_definition(self, version:int) -> Optional[MediumLevelILInstruction]: result = core.BNGetMediumLevelILSSAMemoryDefinition(self.handle, version) if result >= core.BNGetMediumLevelILInstructionCount(self.handle): return None return self[result]
[docs] def get_ssa_var_uses(self, ssa_var:SSAVariable) -> List[MediumLevelILInstruction]: count = ctypes.c_ulonglong() var_data = ssa_var.var.to_BNVariable() instrs = core.BNGetMediumLevelILSSAVarUses(self.handle, var_data, ssa_var.version, count) assert instrs is not None, "core.BNGetMediumLevelILSSAVarUses 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, version:int) -> List[MediumLevelILInstruction]: count = ctypes.c_ulonglong() instrs = core.BNGetMediumLevelILSSAMemoryUses(self.handle, version, count) assert instrs is not None, "core.BNGetMediumLevelILSSAMemoryUses returned None" result = [] for i in range(0, count.value): result.append(self[instrs[i]]) core.BNFreeILInstructionList(instrs) return result
[docs] def is_ssa_var_live(self, ssa_var:SSAVariable) -> bool: """ ``is_ssa_var_live`` determines if ``ssa_var`` is live at any point in the function :param SSAVariable ssa_var: the SSA variable to query :return: whether the variable is live at any point in the function :rtype: bool """ var_data = ssa_var.var.to_BNVariable() return core.BNIsMediumLevelILSSAVarLive(self.handle, var_data, ssa_var.version)
[docs] def get_var_definitions(self, var:'variable.Variable') -> List[MediumLevelILInstruction]: count = ctypes.c_ulonglong() var_data = var.to_BNVariable() instrs = core.BNGetMediumLevelILVariableDefinitions(self.handle, var_data, count) assert instrs is not None, "core.BNGetMediumLevelILVariableDefinitions returned None" result = [] for i in range(0, count.value): result.append(self[instrs[i]]) core.BNFreeILInstructionList(instrs) return result
[docs] def get_var_uses(self, var:'variable.Variable') -> List[MediumLevelILInstruction]: count = ctypes.c_ulonglong() var_data = var.to_BNVariable() instrs = core.BNGetMediumLevelILVariableUses(self.handle, var_data, count) assert instrs is not None, "core.BNGetMediumLevelILVariableUses returned None" try: result = [] for i in range(0, count.value): result.append(self[instrs[i]]) return result finally: core.BNFreeILInstructionList(instrs)
[docs] def get_ssa_var_value(self, ssa_var:SSAVariable) -> 'variable.RegisterValue': var_data = ssa_var.var.to_BNVariable() value = core.BNGetMediumLevelILSSAVarValue(self.handle, var_data, ssa_var.version) result = variable.RegisterValue.from_BNRegisterValue(value, self._arch) return result
[docs] def get_low_level_il_instruction_index(self, instr:InstructionIndex) -> Optional['lowlevelil.InstructionIndex']: low_il = self.low_level_il if low_il is None: return None low_il = low_il.ssa_form if low_il is None: return None result = core.BNGetLowLevelILInstructionIndex(self.handle, instr) if result >= core.BNGetLowLevelILInstructionCount(low_il.handle): return None return lowlevelil.InstructionIndex(result)
[docs] def get_low_level_il_expr_index(self, expr:ExpressionIndex) -> Optional['lowlevelil.ExpressionIndex']: low_il = self.low_level_il if low_il is None: return None low_il = low_il.ssa_form if low_il is None: return None result = core.BNGetLowLevelILExprIndex(self.handle, expr) if result >= core.BNGetLowLevelILExprCount(low_il.handle): return None return lowlevelil.ExpressionIndex(result)
[docs] def get_low_level_il_expr_indexes(self, expr:ExpressionIndex) -> List['lowlevelil.ExpressionIndex']: count = ctypes.c_ulonglong() exprs = core.BNGetLowLevelILExprIndexes(self.handle, expr, count) assert exprs is not None, "core.BNGetLowLevelILExprIndexes returned None" result:List['lowlevelil.ExpressionIndex'] = [] for i in range(0, count.value): result.append(lowlevelil.ExpressionIndex(exprs[i])) core.BNFreeILInstructionList(exprs) return result
[docs] def get_high_level_il_instruction_index(self, instr:InstructionIndex) -> Optional['highlevelil.InstructionIndex']: high_il = self.high_level_il if high_il is None: return None result = core.BNGetHighLevelILInstructionIndex(self.handle, instr) if result >= core.BNGetHighLevelILInstructionCount(high_il.handle): return None return highlevelil.InstructionIndex(result)
[docs] def get_high_level_il_expr_index(self, expr:ExpressionIndex) -> Optional['highlevelil.ExpressionIndex']: high_il = self.high_level_il if high_il is None: return None result = core.BNGetHighLevelILExprIndex(self.handle, expr) if result >= core.BNGetHighLevelILExprCount(high_il.handle): return None return highlevelil.ExpressionIndex(result)
[docs] def get_high_level_il_expr_indexes(self, expr:ExpressionIndex) -> List['highlevelil.ExpressionIndex']: count = ctypes.c_ulonglong() exprs = core.BNGetHighLevelILExprIndexes(self.handle, expr, count) assert exprs is not None, "core.BNGetHighLevelILExprIndexes returned None" result:List['highlevelil.ExpressionIndex'] = [] for i in range(0, count.value): result.append(highlevelil.ExpressionIndex(exprs[i])) core.BNFreeILInstructionList(exprs) return result
[docs] def create_graph(self, settings:'function.DisassemblySettings'=None) -> flowgraph.CoreFlowGraph: if settings is not None: settings_obj = settings.handle else: settings_obj = None return flowgraph.CoreFlowGraph(core.BNCreateMediumLevelILFunctionGraph(self.handle, settings_obj))
@property def arch(self) -> 'architecture.Architecture': return self._arch @property def view(self) -> 'binaryview.BinaryView': return self.source_function.view @property def source_function(self) -> 'function.Function': return self._source_function @source_function.setter def source_function(self, value): self._source_function = value @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 vars(self) -> List['variable.Variable']: """This gets just the MLIL variables - you may be interested in the union of `MediumLevelIlFunction.aliased_vars` and `MediumLevelIlFunction.source_function.param_vars` for all the variables used in the function""" if self.source_function is None: return [] if self.il_form in [FunctionGraphType.MediumLevelILFunctionGraph, FunctionGraphType.MediumLevelILSSAFormFunctionGraph, FunctionGraphType.MappedMediumLevelILFunctionGraph, FunctionGraphType.MappedMediumLevelILSSAFormFunctionGraph]: count = ctypes.c_ulonglong() core_variables = core.BNGetMediumLevelILVariables(self.handle, count) assert core_variables is not None, "core.BNGetMediumLevelILVariables returned None" result = [] try: for var_i in range(count.value): result.append(variable.Variable(self, core_variables[var_i].type, core_variables[var_i].index, core_variables[var_i].storage)) return result finally: core.BNFreeVariableList(core_variables) return [] @property def aliased_vars(self) -> List["variable.Variable"]: """This returns a list of Variables that are taken reference to and used elsewhere. You may also wish to consider `MediumLevelIlFunction.vars` and `MediumLevelIlFunction.source_function.param_vars`""" if self.source_function is None: return [] if self.il_form in [FunctionGraphType.MediumLevelILFunctionGraph, FunctionGraphType.MediumLevelILSSAFormFunctionGraph]: count = ctypes.c_ulonglong() core_variables = core.BNGetMediumLevelILAliasedVariables(self.handle, count) assert core_variables is not None, "core.BNGetMediumLevelILAliasedVariables returned None" try: result = [] for var_i in range(count.value): result.append(variable.Variable(self, core_variables[var_i].type, core_variables[var_i].index, core_variables[var_i].storage)) return result finally: core.BNFreeVariableList(core_variables) return [] @property def ssa_vars(self) -> List[SSAVariable]: """This gets just the MLIL SSA variables - you may be interested in the union of `MediumLevelIlFunction.aliased_vars` and `MediumLevelIlFunction.source_function.param_vars` for all the variables used in the function""" if self.source_function is None: return [] if self.il_form in [FunctionGraphType.MediumLevelILSSAFormFunctionGraph, FunctionGraphType.MappedMediumLevelILSSAFormFunctionGraph]: variable_count = ctypes.c_ulonglong() core_variables = core.BNGetMediumLevelILVariables(self.handle, variable_count) assert core_variables is not None, "core.BNGetMediumLevelILVariables returned None" try: result = [] for var_i in range(variable_count.value): version_count = ctypes.c_ulonglong() versions = core.BNGetMediumLevelILVariableSSAVersions(self.handle, core_variables[var_i], version_count) assert versions is not None, "core.BNGetMediumLevelILVariableSSAVersions returned None" try: for version_i in range(version_count.value): result.append(SSAVariable(variable.Variable(self, core_variables[var_i].type, core_variables[var_i].index, core_variables[var_i].storage), versions[version_i])) finally: core.BNFreeILInstructionList(versions) return result finally: core.BNFreeVariableList(core_variables) elif self.il_form in [FunctionGraphType.MediumLevelILFunctionGraph, FunctionGraphType.MappedMediumLevelILFunctionGraph]: return self.ssa_form.ssa_vars return []
[docs]class MediumLevelILBasicBlock(basicblock.BasicBlock): def __init__(self, handle:core.BNBasicBlockHandle, owner:MediumLevelILFunction, view:Optional['binaryview.BinaryView']=None): super(MediumLevelILBasicBlock, self).__init__(handle, view) self._il_function = owner def __repr__(self): arch = self.arch if arch: return f"<mlil block: {arch.name}@{self.start}-{self.end}>" else: return f"<mlil block: {self.start}-{self.end}>" def __iter__(self): for idx in range(self.start, self.end): yield self._il_function[idx] def __getitem__(self, idx) -> Union[List['MediumLevelILInstruction'], 'MediumLevelILInstruction']: size = self.end - self.start if isinstance(idx, slice): return [self[index] for index in range(*idx.indices(size))] # type: ignore 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 __hash__(self): return hash((self.start, self.end, self._il_function)) def __contains__(self, instruction): if type(instruction) != MediumLevelILInstruction or instruction.il_basic_block != self: return False if self.start <= instruction.instr_index <= self.end: return True else: return False def _create_instance(self, handle:core.BNBasicBlockHandle, view:'binaryview.BinaryView') -> 'MediumLevelILBasicBlock': """Internal method by super to instantiate child instances""" return MediumLevelILBasicBlock(handle, self.il_function, view) @property def instruction_count(self) -> int: return self.end - self.start @property def il_function(self) -> 'MediumLevelILFunction': return self._il_function