From dd8b176133ff587b837a3b28237a2f8f960a2f02 Mon Sep 17 00:00:00 2001 From: Peter LaFosse Date: Fri, 25 Jun 2021 13:57:27 -0400 Subject: Refactor ILs for greater speed and utility --- python/lowlevelil.py | 3651 +++++++++++++++++++++++++++++++++++--------------- 1 file changed, 2541 insertions(+), 1110 deletions(-) (limited to 'python/lowlevelil.py') diff --git a/python/lowlevelil.py b/python/lowlevelil.py index 093dd212..21b12909 100644 --- a/python/lowlevelil.py +++ b/python/lowlevelil.py @@ -21,11 +21,11 @@ import ctypes from enum import Flag import struct -from typing import Generator, List, Optional, Any, Mapping, Union, Tuple, NewType +from typing import Generator, List, Optional, Mapping, Union, Tuple, NewType from dataclasses import dataclass # Binary Ninja components -from .enums import LowLevelILOperation, LowLevelILFlagCondition, InstructionTextTokenType, DataFlowQueryOption, FunctionGraphType +from .enums import LowLevelILOperation, LowLevelILFlagCondition, DataFlowQueryOption, FunctionGraphType from . import _binaryninjacore as core from . import basicblock #required for LowLevelILBasicBlock from . import function @@ -41,11 +41,11 @@ ExpressionIndex = NewType('ExpressionIndex', int) InstructionIndex = NewType('InstructionIndex', int) Index = Union[ExpressionIndex, InstructionIndex] TokenList = List['function.InstructionTextToken'] -InstructionOrExpression = Union['LowLevelILInstruction', 'LowLevelILExpr', Index] +InstructionOrExpression = Union['LowLevelILInstruction', Index] ILRegisterType = Union[str, 'ILRegister', int] LLILInstructionsType = Generator['LowLevelILInstruction', None, None] LLILBasicBlocksType = Generator['LowLevelILBasicBlock', None, None] - +OperandsType = Tuple[ExpressionIndex, ExpressionIndex, ExpressionIndex, ExpressionIndex] class LowLevelILLabel: def __init__(self, handle:core.BNLowLevelILLabel=None): @@ -87,7 +87,7 @@ class ILRegister: return (self.index & 0x80000000) != 0 @property - def name(self) -> architecture.RegisterName: + def name(self) -> 'architecture.RegisterName': if self.temp: return architecture.RegisterName(f"temp{self.index & 0x7fffffff}") else: @@ -216,741 +216,2179 @@ class SSARegister: return f"" -@dataclass(frozen=True) -class SSARegisterStack: - reg_stack:ILRegisterStack - version:int +@dataclass(frozen=True) +class SSARegisterStack: + reg_stack:ILRegisterStack + version:int + + def __repr__(self): + return f"" + + +@dataclass(frozen=True) +class SSAFlag: + flag:ILFlag + version:int + + def __repr__(self): + return f"" + + +@dataclass(frozen=True) +class SSARegisterOrFlag: + reg_or_flag:Union[ILRegister, ILFlag] + version:int + + def __repr__(self): + return f"" + + +@dataclass(frozen=True) +class LowLevelILOperationAndSize: + operation:'LowLevelILOperation' + size:int + + def __repr__(self): + if self.size == 0: + return f"<{self.operation.name}>" + return f"<{self.operation.name} {self.size}>" + +LowLevelILOperandType = Union[ + LowLevelILOperationAndSize, + ILRegister, + ILFlag, + ILIntrinsic, + ILRegisterStack, + int, + Mapping[int, int], + float, + 'LowLevelILInstruction', + Mapping['architecture.RegisterStackName', int], + SSAFlag, + SSARegister, + SSARegisterStack, + ILSemanticFlagClass, + ILSemanticFlagGroup, + LowLevelILFlagCondition, + List[int], + List['LowLevelILInstruction'], + List[Union[ILFlag, ILRegister]], + List[SSARegister], + List[SSARegisterStack], + List[SSAFlag], + List[SSARegisterOrFlag], +] + +@dataclass(frozen=True) +class CoreLowLevelILInstruction: + operation:LowLevelILOperation + size:int + flags:int + source_operand:ExpressionIndex + operands:OperandsType + address:int + + @classmethod + def from_BNLowLevelILInstruction(cls, instr:core.BNLowLevelILInstruction) -> 'CoreLowLevelILInstruction': + operands:OperandsType = tuple([ExpressionIndex(instr.operands[i]) for i in range(4)]) # type: ignore + return cls(LowLevelILOperation(instr.operation), instr.size, instr.flags, instr.sourceOperand, operands, instr.address) + + +@dataclass(frozen=True) +class LowLevelILInstruction: + """ + ``class LowLevelILInstruction`` Low Level Intermediate Language Instructions are infinite length tree-based + instructions. Tree-based instructions use infix notation with the left hand operand being the destination operand. + Infix notation is thus more natural to read than other notations (e.g. x86 ``mov eax, 0`` vs. LLIL ``eax = 0``). + """ + + function:'LowLevelILFunction' + expr_index:ExpressionIndex + instr:CoreLowLevelILInstruction + instr_index:Optional[InstructionIndex] + operand_names = tuple() + + @classmethod + def create(cls, func:'LowLevelILFunction', expr_index:ExpressionIndex, instr_index:Optional[InstructionIndex]=None) -> 'LowLevelILInstruction': + assert func.arch is not None, "Attempted to create IL instruction with function missing an Architecture" + inst = core.BNGetLowLevelILByIndex(func.handle, expr_index) + assert inst is not None, "core.BNGetLowLevelILByIndex returned None" + core_inst = CoreLowLevelILInstruction.from_BNLowLevelILInstruction(inst) + return ILInstruction[core_inst.operation](func, expr_index, core_inst, instr_index) # type: ignore + + def __str__(self): + tokens = self.tokens + if tokens is None: + return "invalid" + result = "" + for token in tokens: + result += token.text + return result + + def __repr__(self): + return "" % str(self) + + def __eq__(self, other): + if not isinstance(other, self.__class__): + return NotImplemented + return self.function == other.function and self.expr_index == other.expr_index + + def __ne__(self, other): + if not isinstance(other, self.__class__): + return NotImplemented + return not (self == other) + + def __lt__(self, other): + if not isinstance(other, self.__class__): + return NotImplemented + return self.function == other.function and self.expr_index < other.expr_index + + def __le__(self, other): + if not isinstance(other, self.__class__): + return NotImplemented + return self.function == other.function and self.expr_index <= other.expr_index + + def __gt__(self, other): + if not isinstance(other, self.__class__): + return NotImplemented + return self.function == other.function and self.expr_index > other.expr_index + + def __ge__(self, other): + if not isinstance(other, self.__class__): + 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 address(self) -> int: + return self.instr.address + + @property + def operation(self) -> LowLevelILOperation: + return self.instr.operation + + @property + def source_operand(self) -> Optional[ExpressionIndex]: + return self.instr.source_operand + + @property + def tokens(self) -> Optional[TokenList]: + """LLIL tokens (read-only)""" + count = ctypes.c_ulonglong() + assert self.function.arch is not None, f"type(self.function): {type(self.function)} " + tokens = ctypes.POINTER(core.BNInstructionTextToken)() + if (self.instr_index is not None) and (self.function.source_function is not None): + if not core.BNGetLowLevelILInstructionText(self.function.handle, self.function.source_function.handle, + self.function.arch.handle, self.instr_index, tokens, count): + return None + else: + # TODO: Special case LLIL_CALL_OUTPUT_SSA + if not core.BNGetLowLevelILExprText(self.function.handle, self.function.arch.handle, + self.expr_index, tokens, count): + return None + result = function.InstructionTextToken._from_core_struct(tokens, count.value) + core.BNFreeInstructionText(tokens, count.value) + return result + + @property + def il_basic_block(self) -> 'LowLevelILBasicBlock': + """IL basic block object containing this expression (read-only) (only available on finalized functions)""" + assert self.function.source_function is not None + view = self.function.source_function.view + core_block = core.BNGetLowLevelILBasicBlockForInstruction(self.function.handle, self.instr_index) + assert core_block is not None, "BNGetLowLevelILBasicBlockForInstruction returned None" + return LowLevelILBasicBlock(view, core_block, self.function) + + @property + def ssa_form(self) -> 'LowLevelILInstruction': + """SSA form of expression (read-only)""" + ssa_func = self.function.ssa_form + assert ssa_func is not None + return LowLevelILInstruction.create(ssa_func, + core.BNGetLowLevelILSSAExprIndex(self.function.handle, self.expr_index), + core.BNGetLowLevelILSSAInstructionIndex(self.function.handle, self.instr_index) if self.instr_index is not None else None) + + @property + def non_ssa_form(self) -> 'LowLevelILInstruction': + """Non-SSA form of expression (read-only)""" + non_ssa_function = self.function.non_ssa_form + assert non_ssa_function is not None + return LowLevelILInstruction.create(non_ssa_function, + core.BNGetLowLevelILNonSSAExprIndex(self.function.handle, self.expr_index), + core.BNGetLowLevelILNonSSAInstructionIndex(self.function.handle, self.instr_index) if self.instr_index is not None else None) + + @property + def medium_level_il(self) -> Optional['mediumlevelil.MediumLevelILInstruction']: + """Gets the medium level IL expression corresponding to this expression (may be None for eliminated instructions)""" + expr = self.function.get_medium_level_il_expr_index(self.expr_index) + if expr is None: + return None + mlil_func = self.function.medium_level_il + assert mlil_func is not None, "self.function.medium_level_il is None" + return mediumlevelil.MediumLevelILInstruction.create(mlil_func, expr) + + @property + def mlil(self) -> Optional['mediumlevelil.MediumLevelILInstruction']: + return self.medium_level_il + + @property + def mlils(self) -> List['mediumlevelil.MediumLevelILInstruction']: + result = [] + for expr in self.function.get_medium_level_il_expr_indexes(self.expr_index): + result.append(mediumlevelil.MediumLevelILInstruction.create(self.function.medium_level_il, expr)) + return result + + @property + def mapped_medium_level_il(self) -> Optional['mediumlevelil.MediumLevelILInstruction']: + """Gets the mapped medium level IL expression corresponding to this expression""" + expr = self.function.get_mapped_medium_level_il_expr_index(self.expr_index) + if expr is None: + return None + return mediumlevelil.MediumLevelILInstruction.create(self.function.mapped_medium_level_il, expr) + + @property + def mmlil(self) -> Optional['mediumlevelil.MediumLevelILInstruction']: + return self.mapped_medium_level_il + + @property + def high_level_il(self) -> Optional['highlevelil.HighLevelILInstruction']: + """Gets the high level IL expression corresponding to this expression (may be None for eliminated instructions)""" + if self.mlil is None: + return None + return self.mlil.hlil + + @property + def hlil(self) -> Optional['highlevelil.HighLevelILInstruction']: + return self.high_level_il + + @property + def hlils(self) -> List['highlevelil.HighLevelILInstruction']: + result = set() + for mlil_expr in self.mlils: + for hlil_expr in mlil_expr.hlils: + try: + result.add(hlil_expr) + except: + assert False, f"mlil_expr.hlils returned list of lists: {hlil_expr} {type(hlil_expr)}" + return list(result) + + @property + def value(self) -> 'variable.RegisterValue': + """Value of expression if constant or a known value (read-only)""" + value = core.BNGetLowLevelILExprValue(self.function.handle, self.expr_index) + return variable.RegisterValue.from_BNRegisterValue(value, self.function.arch) + + @property + def possible_values(self) -> 'variable.PossibleValueSet': + """Possible values of expression using path-sensitive static data flow analysis (read-only)""" + value = core.BNGetLowLevelILPossibleExprValues(self.function.handle, self.expr_index, None, 0) + result = variable.PossibleValueSet(self.function.arch, value) + core.BNFreePossibleValueSet(value) + return result + + @property + def operands(self) -> Generator[LowLevelILOperandType, None, None]: + for operand_name in self.operand_names: + assert hasattr(self, operand_name), f"No operand '{operand_name}' for instruction {repr(self)}({self.operation})" + yield self.__getattribute__(operand_name) + + @property + def prefix_operands(self) -> List[LowLevelILOperandType]: + """All operands in the expression tree in prefix order""" + result:List[LowLevelILOperandType] = [LowLevelILOperationAndSize(self.instr.operation, self.instr.size)] + for operand in self.operands: + if isinstance(operand, LowLevelILInstruction): + assert id(self) != id(operand), f"circular reference {operand}({repr(operand)}) is {self}({repr(self)})" + result.extend(operand.prefix_operands) + else: + result.append(operand) + return result + + @property + def postfix_operands(self) -> List[LowLevelILOperandType]: + """All operands in the expression tree in postfix order""" + result:List[LowLevelILOperandType] = [] + for operand in self.operands: + if isinstance(operand, LowLevelILInstruction): + assert id(self) != id(operand), f"circular reference {operand}({repr(operand)}) is {self}({repr(self)})" + result.extend(operand.postfix_operands) + else: + result.append(operand) + result.append(LowLevelILOperationAndSize(self.instr.operation, self.instr.size)) + return result + + def get_possible_values(self, options:List[DataFlowQueryOption]=[]) -> variable.PossibleValueSet: + option_array = (ctypes.c_int * len(options))() + idx = 0 + for option in options: + option_array[idx] = option + idx += 1 + value = core.BNGetLowLevelILPossibleExprValues(self.function.handle, self.expr_index, option_array, len(options)) + result = variable.PossibleValueSet(self.function.arch, value) + core.BNFreePossibleValueSet(value) + return result + + def get_reg_value(self, reg:'architecture.RegisterType') -> variable.RegisterValue: + if self.function.arch is None: + raise Exception("Can not call get_reg_value on function with Architecture set to None") + reg = self.function.arch.get_reg_index(reg) + value = core.BNGetLowLevelILRegisterValueAtInstruction(self.function.handle, reg, self.instr_index) + return variable.RegisterValue.from_BNRegisterValue(value, self.function.arch) + + def get_reg_value_after(self, reg:'architecture.RegisterType') -> variable.RegisterValue: + if self.function.arch is None: + raise Exception("Can not call get_reg_value_after on function with Architecture set to None") + reg = self.function.arch.get_reg_index(reg) + value = core.BNGetLowLevelILRegisterValueAfterInstruction(self.function.handle, reg, self.instr_index) + return variable.RegisterValue.from_BNRegisterValue(value, self.function.arch) + + def get_possible_reg_values(self, reg:'architecture.RegisterType', options:List[DataFlowQueryOption]=[]) -> 'variable.PossibleValueSet': + if self.function.arch is None: + raise Exception("Can not call get_possible_reg_values on function with Architecture set to None") + reg = self.function.arch.get_reg_index(reg) + option_array = (ctypes.c_int * len(options))() + idx = 0 + for option in options: + option_array[idx] = option + idx += 1 + value = core.BNGetLowLevelILPossibleRegisterValuesAtInstruction(self.function.handle, reg, self.instr_index, + option_array, len(options)) + result = variable.PossibleValueSet(self.function.arch, value) + core.BNFreePossibleValueSet(value) + return result + + def get_possible_reg_values_after(self, reg:'architecture.RegisterType', options:List[DataFlowQueryOption]=[]) -> 'variable.PossibleValueSet': + if self.function.arch is None: + raise Exception("Can not call get_possible_reg_values_after on function with Architecture set to None") + reg = self.function.arch.get_reg_index(reg) + option_array = (ctypes.c_int * len(options))() + idx = 0 + for option in options: + option_array[idx] = option + idx += 1 + value = core.BNGetLowLevelILPossibleRegisterValuesAfterInstruction(self.function.handle, reg, self.instr_index, + option_array, len(options)) + result = variable.PossibleValueSet(self.function.arch, value) + core.BNFreePossibleValueSet(value) + return result + + def get_flag_value(self, flag:'architecture.FlagType') -> 'variable.RegisterValue': + if self.function.arch is None: + raise Exception("Can not call get_flag_value on function with Architecture set to None") + flag = self.function.arch.get_flag_index(flag) + value = core.BNGetLowLevelILFlagValueAtInstruction(self.function.handle, flag, self.instr_index) + result = variable.RegisterValue.from_BNRegisterValue(value, self.function.arch) + return result + + def get_flag_value_after(self, flag:'architecture.FlagType') -> 'variable.RegisterValue': + if self.function.arch is None: + raise Exception("Can not call get_flag_value_after on function with Architecture set to None") + flag = self.function.arch.get_flag_index(flag) + value = core.BNGetLowLevelILFlagValueAfterInstruction(self.function.handle, flag, self.instr_index) + result = variable.RegisterValue.from_BNRegisterValue(value, self.function.arch) + return result + + def get_possible_flag_values(self, flag:'architecture.FlagType', options:List[DataFlowQueryOption]=[]) -> 'variable.PossibleValueSet': + if self.function.arch is None: + raise Exception("Can not call get_possible_flag_values on function with Architecture set to None") + flag = self.function.arch.get_flag_index(flag) + option_array = (ctypes.c_int * len(options))() + idx = 0 + for option in options: + option_array[idx] = option + idx += 1 + value = core.BNGetLowLevelILPossibleFlagValuesAtInstruction(self.function.handle, flag, self.instr_index, + option_array, len(options)) + result = variable.PossibleValueSet(self.function.arch, value) + core.BNFreePossibleValueSet(value) + return result + + def get_possible_flag_values_after(self, flag:'architecture.FlagType', options:List[DataFlowQueryOption]=[]) -> 'variable.PossibleValueSet': + if self.function.arch is None: + raise Exception("Can not call get_possible_flag_values_after on function with Architecture set to None") + flag = self.function.arch.get_flag_index(flag) + option_array = (ctypes.c_int * len(options))() + idx = 0 + for option in options: + option_array[idx] = option + idx += 1 + value = core.BNGetLowLevelILPossibleFlagValuesAfterInstruction(self.function.handle, flag, self.instr_index, + option_array, len(options)) + result = variable.PossibleValueSet(self.function.arch, value) + core.BNFreePossibleValueSet(value) + return result + + def get_stack_contents(self, offset:int, size:int) -> 'variable.RegisterValue': + value = core.BNGetLowLevelILStackContentsAtInstruction(self.function.handle, offset, size, self.instr_index) + result = variable.RegisterValue.from_BNRegisterValue(value, self.function.arch) + return result + + def get_stack_contents_after(self, offset:int, size:int) -> 'variable.RegisterValue': + value = core.BNGetLowLevelILStackContentsAfterInstruction(self.function.handle, offset, size, self.instr_index) + result = variable.RegisterValue.from_BNRegisterValue(value, self.function.arch) + return result + + def get_possible_stack_contents(self, offset:int, size:int, options:List[DataFlowQueryOption]=[]) -> variable.PossibleValueSet: + option_array = (ctypes.c_int * len(options))() + idx = 0 + for option in options: + option_array[idx] = option + idx += 1 + value = core.BNGetLowLevelILPossibleStackContentsAtInstruction(self.function.handle, offset, size, self.instr_index, + option_array, len(options)) + result = variable.PossibleValueSet(self.function.arch, value) + core.BNFreePossibleValueSet(value) + return result + + def get_possible_stack_contents_after(self, offset:int, size:int, options:List[DataFlowQueryOption]=[]) -> variable.PossibleValueSet: + option_array = (ctypes.c_int * len(options))() + idx = 0 + for option in options: + option_array[idx] = option + idx += 1 + value = core.BNGetLowLevelILPossibleStackContentsAfterInstruction(self.function.handle, offset, size, self.instr_index, + option_array, len(options)) + result = variable.PossibleValueSet(self.function.arch, value) + core.BNFreePossibleValueSet(value) + return result + + @property + def flags(self) -> Optional['architecture.FlagWriteTypeName']: + return self.function.arch.get_flag_write_type_name(architecture.FlagWriteTypeIndex(self.instr.flags)) + + def get_reg(self, operand_index:int) -> ILRegister: + return ILRegister(self.function.arch, architecture.RegisterIndex(self.instr.operands[operand_index])) + + def get_flag(self, operand_index:int) -> ILFlag: + return ILFlag(self.function.arch, architecture.FlagIndex(self.instr.operands[operand_index])) + + def get_intrinsic(self, operand_index:int) -> ILIntrinsic: + return ILIntrinsic(self.function.arch, architecture.IntrinsicIndex(self.instr.operands[operand_index])) + + def get_reg_stack(self, operand_index:int) -> ILRegisterStack: + return ILRegisterStack(self.function.arch, architecture.RegisterStackIndex(self.instr.operands[operand_index])) + + def get_int(self, operand_index:int) -> int: + return (self.instr.operands[operand_index] & ((1 << 63) - 1)) - (self.instr.operands[operand_index] & (1 << 63)) + + def get_target_map(self, operand_index:int) -> Mapping[int, int]: + count = ctypes.c_ulonglong() + operand_list = core.BNLowLevelILGetOperandList(self.function.handle, self.expr_index, operand_index, count) + assert operand_list is not None, "core.BNLowLevelILGetOperandList returned None" + try: + value:Mapping[int, int] = {} + for j in range(count.value // 2): + key = operand_list[j * 2] + target = operand_list[(j * 2) + 1] + value[key] = target + return value + finally: + core.BNLowLevelILFreeOperandList(operand_list) + + def get_float(self, operand_index:int) -> float: + if self.instr.size == 4: + return struct.unpack("f", struct.pack("I", self.instr.operands[operand_index] & 0xffffffff))[0] + elif self.instr.size == 8: + return struct.unpack("d", struct.pack("Q", self.instr.operands[operand_index]))[0] + else: + return float(self.instr.operands[operand_index]) + + def get_expr(self, operand_index:int) -> 'LowLevelILInstruction': + return LowLevelILInstruction.create(self.function, self.instr.operands[operand_index], self.instr_index) + + def get_reg_stack_adjust(self, operand_index:int) -> Mapping['architecture.RegisterStackName', int]: + count = ctypes.c_ulonglong() + operand_list = core.BNLowLevelILGetOperandList(self.function.handle, self.expr_index, operand_index, count) + assert operand_list is not None, "core.BNLowLevelILGetOperandList returned None" + result:Mapping['architecture.RegisterStackName', int] = {} + try: + for j in range(count.value // 2): + reg_stack = operand_list[j * 2] + adjust = operand_list[(j * 2) + 1] + if adjust & 0x80000000: + adjust |= ~0x80000000 + result[self.function.arch.get_reg_stack_name(reg_stack)] = adjust + return result + finally: + core.BNLowLevelILFreeOperandList(operand_list) + + def get_flag_ssa(self, operand_index1:int, operand_index2:int) -> SSAFlag: + return SSAFlag(ILFlag(self.function.arch, architecture.FlagIndex(self.instr.operands[operand_index1])), + self.instr.operands[operand_index2]) + + def get_reg_ssa(self, operand_index1:int, operand_index2:int) -> SSARegister: + return SSARegister(ILRegister(self.function.arch, + architecture.RegisterIndex(self.instr.operands[operand_index1])), + self.instr.operands[operand_index2]) + + def get_reg_stack_ssa(self, operand_index1:int, operand_index2:int) -> SSARegisterStack: + reg_stack = ILRegisterStack(self.function.arch, + architecture.RegisterStackIndex(self.instr.operands[operand_index1])) + return SSARegisterStack(reg_stack, self.instr.operands[operand_index2]) + + def get_sem_class(self, operand_index:int) -> ILSemanticFlagClass: + return ILSemanticFlagClass(self.function.arch, + architecture.SemanticClassIndex(self.instr.operands[operand_index])) + + def get_sem_group(self, operand_index:int) -> ILSemanticFlagGroup: + return ILSemanticFlagGroup(self.function.arch, + architecture.SemanticGroupIndex(self.instr.operands[operand_index])) + + def get_cond(self, operand_index:int) -> LowLevelILFlagCondition: + return LowLevelILFlagCondition(self.instr.operands[operand_index]) + + def get_int_list(self, operand_index:int) -> List[int]: + count = ctypes.c_ulonglong() + operand_list = core.BNLowLevelILGetOperandList(self.function.handle, self.expr_index, operand_index, count) + assert operand_list is not None, "core.BNLowLevelILGetOperandList returned None" + result:List[int] = [] + try: + for j in range(count.value): + result.append(operand_list[j]) + return result + finally: + core.BNLowLevelILFreeOperandList(operand_list) + + def get_expr_list(self, operand_index:int) -> List['LowLevelILInstruction']: + count = ctypes.c_ulonglong() + operand_list = core.BNLowLevelILGetOperandList(self.function.handle, self.expr_index, operand_index, count) + assert operand_list is not None, "core.BNLowLevelILGetOperandList returned None" + result = [] + try: + for j in range(count.value): + result.append(LowLevelILInstruction.create(self.function, operand_list[j], None)) + return result + finally: + core.BNLowLevelILFreeOperandList(operand_list) + + def get_reg_or_flag_list(self, operand_index:int) -> List[Union[ILFlag, ILRegister]]: + count = ctypes.c_ulonglong() + operand_list = core.BNLowLevelILGetOperandList(self.function.handle, self.expr_index, operand_index, count) + assert operand_list is not None, "core.BNLowLevelILGetOperandList returned None" + + result:List[Union[ILFlag, ILRegister]] = [] + try: + for j in range(count.value): + if (operand_list[j] & (1 << 32)) != 0: + result.append(ILFlag(self.function.arch, operand_list[j] & 0xffffffff)) + else: + result.append(ILRegister(self.function.arch, operand_list[j] & 0xffffffff)) + return result + finally: + core.BNLowLevelILFreeOperandList(operand_list) + + def get_reg_ssa_list(self, operand_index:int) -> List[SSARegister]: + count = ctypes.c_ulonglong() + operand_list = core.BNLowLevelILGetOperandList(self.function.handle, self.expr_index, operand_index, count) + assert operand_list is not None, "core.BNLowLevelILGetOperandList returned None" + result = [] + try: + for j in range(count.value // 2): + reg = operand_list[j * 2] + reg_version = operand_list[(j * 2) + 1] + result.append(SSARegister(ILRegister(self.function.arch, reg), reg_version)) + return result + finally: + core.BNLowLevelILFreeOperandList(operand_list) + + def get_reg_stack_ssa_list(self, operand_index:int) -> List[SSARegisterStack]: + count = ctypes.c_ulonglong() + operand_list = core.BNLowLevelILGetOperandList(self.function.handle, self.expr_index, operand_index, count) + assert operand_list is not None, "core.BNLowLevelILGetOperandList returned None" + result:List[SSARegisterStack] = [] + try: + for j in range(count.value // 2): + reg_stack = operand_list[j * 2] + reg_version = operand_list[(j * 2) + 1] + result.append(SSARegisterStack(ILRegisterStack(self.function.arch, reg_stack), reg_version)) + return result + finally: + core.BNLowLevelILFreeOperandList(operand_list) + + def get_flag_ssa_list(self, operand_index:int) -> List[SSAFlag]: + count = ctypes.c_ulonglong() + operand_list = core.BNLowLevelILGetOperandList(self.function.handle, self.expr_index, operand_index, count) + assert operand_list is not None, "core.BNLowLevelILGetOperandList returned None" + try: + result:List[SSAFlag] = [] + for j in range(count.value // 2): + flag = operand_list[j * 2] + flag_version = operand_list[(j * 2) + 1] + result.append(SSAFlag(ILFlag(self.function.arch, flag), flag_version)) + return result + finally: + core.BNLowLevelILFreeOperandList(operand_list) + + def get_reg_or_flag_ssa_list(self, operand_index:int) -> List[SSARegisterOrFlag]: + count = ctypes.c_ulonglong() + operand_list = core.BNLowLevelILGetOperandList(self.function.handle, self.expr_index, operand_index, count) + assert operand_list is not None, "core.BNLowLevelILGetOperandList returned None" + result:List[SSARegisterOrFlag] = [] + try: + for j in range(count.value // 2): + if (operand_list[j * 2] & (1 << 32)) != 0: + reg_or_flag = ILFlag(self.function.arch, operand_list[j * 2] & 0xffffffff) + else: + reg_or_flag = ILRegister(self.function.arch, operand_list[j * 2] & 0xffffffff) + reg_version = operand_list[(j * 2) + 1] + result.append(SSARegisterOrFlag(reg_or_flag, reg_version)) + return result + finally: + core.BNLowLevelILFreeOperandList(operand_list) + + +@dataclass(frozen=True, repr=False) +class Terminal(LowLevelILInstruction): + """This class indicates that the instruction ends a BasicBlock""" + pass + +@dataclass(frozen=True, repr=False) +class BinaryOperation(LowLevelILInstruction): + operand_names = tuple(['left', 'right']) + + @property + def left(self) -> LowLevelILInstruction: + return self.get_expr(0) + + @property + def right(self) -> LowLevelILInstruction: + return self.get_expr(1) + + +@dataclass(frozen=True, repr=False) +class UnaryOperation(LowLevelILInstruction): + operand_names = tuple(['src']) + + @property + def src(self) -> LowLevelILInstruction: + return self.get_expr(0) + + +@dataclass(frozen=True, repr=False) +class Arithmetic(LowLevelILInstruction): + pass + + +@dataclass(frozen=True, repr=False) +class Signed(LowLevelILInstruction): + """The operation is a signed operation""" + pass + + +@dataclass(frozen=True, repr=False) +class Carry(LowLevelILInstruction): + """Arithmetic with carry operation""" + pass + + +@dataclass(frozen=True, repr=False) +class Comparison(BinaryOperation): + pass + + +@dataclass(frozen=True, repr=False) +class Constant(LowLevelILInstruction): + operand_names = tuple(['constant']) + + def __int__(self): + return self.constant + + def __bool__(self): + return self.constant != 0 + + def __eq__(self, other): + return int(self) == int(other) + + def __ne__(self, other): + return int(self) != int(other) + + def __lt__(self, other): + return int(self) < int(other) + + def __gt__(self, other): + return int(self) > int(other) + + def __le__(self, other): + return int(self) <= int(other) + + def __ge__(self, other): + return int(self) >= int(other) + + @property + def constant(self) -> int: + return self.get_int(0) + + +@dataclass(frozen=True, repr=False) +class FloatingPoint(LowLevelILInstruction): + pass + + +@dataclass(frozen=True, repr=False) +class ControlFlow(LowLevelILInstruction): + pass + + +@dataclass(frozen=True, repr=False) +class Memory(LowLevelILInstruction): + pass + + +@dataclass(frozen=True, repr=False) +class Return(Terminal): + pass + + +@dataclass(frozen=True, repr=False) +class RegisterStack(LowLevelILInstruction): + pass + + +@dataclass(frozen=True, repr=False) +class SSA(LowLevelILInstruction): + pass + + +@dataclass(frozen=True, repr=False) +class StackOperation(LowLevelILInstruction): + pass + + +@dataclass(frozen=True, repr=False) +class SetReg(LowLevelILInstruction): + pass + + +@dataclass(frozen=True, repr=False) +class DoublePrecision(LowLevelILInstruction): + pass + + +@dataclass(frozen=True, repr=False) +class Store(Memory): + pass + + +@dataclass(frozen=True, repr=False) +class Load(Memory): + pass + + +@dataclass(frozen=True, repr=False) +class Call(LowLevelILInstruction): + pass + + +@dataclass(frozen=True, repr=False) +class LowLevelILNop(LowLevelILInstruction): + operand_names = tuple() + + +@dataclass(frozen=True, repr=False) +class LowLevelILPop(StackOperation): + operand_names = tuple() + + +@dataclass(frozen=True, repr=False) +class LowLevelILNoret(Terminal): + operand_names = tuple() + + +@dataclass(frozen=True, repr=False) +class LowLevelILSyscall(Call): + operand_names = tuple() + + +@dataclass(frozen=True, repr=False) +class LowLevelILBp(Terminal): + operand_names = tuple() + + +@dataclass(frozen=True, repr=False) +class LowLevelILUndef(Terminal): + operand_names = tuple() + + +@dataclass(frozen=True, repr=False) +class LowLevelILUnimpl(LowLevelILInstruction): + operand_names = tuple() + + +@dataclass(frozen=True, repr=False) +class LowLevelILNeg(UnaryOperation, Arithmetic): + pass + + +@dataclass(frozen=True, repr=False) +class LowLevelILNot(UnaryOperation, Arithmetic): + pass + + +@dataclass(frozen=True, repr=False) +class LowLevelILSx(UnaryOperation, Arithmetic): + pass + +@dataclass(frozen=True, repr=False) +class LowLevelILZx(UnaryOperation, Arithmetic): + pass + + +@dataclass(frozen=True, repr=False) +class LowLevelILLow_part(UnaryOperation, Arithmetic): + pass + + +@dataclass(frozen=True, repr=False) +class LowLevelILJump(ControlFlow, Terminal): + operand_names = tuple(["dest"]) + + @property + def dest(self): + return self.get_expr(0) + + +@dataclass(frozen=True, repr=False) +class LowLevelILCall(Call): + operand_names = tuple(["dest"]) + + @property + def dest(self): + return self.get_expr(0) + + +@dataclass(frozen=True, repr=False) +class LowLevelILTailcall(Call): + operand_names = tuple(["dest"]) + + @property + def dest(self): + return self.get_expr(0) + + +@dataclass(frozen=True, repr=False) +class LowLevelILRet(Return): + operand_names = tuple(["dest"]) + + @property + def dest(self): + return self.get_expr(0) + + +@dataclass(frozen=True, repr=False) +class LowLevelILUnimpl_mem(Memory): + operand_names = tuple(["src"]) + + @property + def src(self): + return self.get_expr(0) + + +@dataclass(frozen=True, repr=False) +class LowLevelILFsqrt(FloatingPoint, Arithmetic): + operand_names = tuple(["src"]) + + @property + def src(self): + return self.get_expr(0) + + +@dataclass(frozen=True, repr=False) +class LowLevelILFneg(FloatingPoint, Arithmetic): + operand_names = tuple(["src"]) + + @property + def src(self): + return self.get_expr(0) + + +@dataclass(frozen=True, repr=False) +class LowLevelILFabs(FloatingPoint, Arithmetic): + operand_names = tuple(["src"]) + + @property + def src(self): + return self.get_expr(0) + + +@dataclass(frozen=True, repr=False) +class LowLevelILFloat_to_int(FloatingPoint, Arithmetic): + operand_names = tuple(["src"]) + + @property + def src(self): + return self.get_expr(0) + + +@dataclass(frozen=True, repr=False) +class LowLevelILInt_to_float(FloatingPoint, Arithmetic): + operand_names = tuple(["src"]) + + @property + def src(self): + return self.get_expr(0) + + +@dataclass(frozen=True, repr=False) +class LowLevelILFloat_conv(FloatingPoint, Arithmetic): + operand_names = tuple(["src"]) + + @property + def src(self): + return self.get_expr(0) + + +@dataclass(frozen=True, repr=False) +class LowLevelILRound_to_int(FloatingPoint, Arithmetic): + operand_names = tuple(["src"]) + + @property + def src(self): + return self.get_expr(0) + + +@dataclass(frozen=True, repr=False) +class LowLevelILFloor(FloatingPoint, Arithmetic): + operand_names = tuple(["src"]) + + @property + def src(self): + return self.get_expr(0) + + +@dataclass(frozen=True, repr=False) +class LowLevelILCeil(FloatingPoint, Arithmetic): + operand_names = tuple(["src"]) + + @property + def src(self): + return self.get_expr(0) + + +@dataclass(frozen=True, repr=False) +class LowLevelILFtrunc(FloatingPoint, Arithmetic): + operand_names = tuple(["src"]) + + @property + def src(self): + return self.get_expr(0) + + +@dataclass(frozen=True, repr=False) +class LowLevelILLoad(Memory): + operand_names = tuple(["src"]) + + @property + def src(self): + return self.get_expr(0) + + +@dataclass(frozen=True, repr=False) +class LowLevelILPush(StackOperation): + operand_names = tuple(["src"]) + + @property + def src(self): + return self.get_expr(0) + + +@dataclass(frozen=True, repr=False) +class LowLevelILReg(LowLevelILInstruction): + operand_names = tuple(["src"]) + + @property + def src(self): + return self.get_reg(0) + + +@dataclass(frozen=True, repr=False) +class LowLevelILReg_stack_pop(RegisterStack): + operand_names = tuple(["stack"]) + + @property + def stack(self): + return self.get_reg_stack(0) + + +@dataclass(frozen=True, repr=False) +class LowLevelILReg_stack_free_reg(RegisterStack): + operand_names = tuple(["dest"]) + + @property + def dest(self): + return self.get_reg(0) + + +@dataclass(frozen=True, repr=False) +class LowLevelILConst(Constant): + pass + + +@dataclass(frozen=True, repr=False) +class LowLevelILConst_ptr(Constant): + pass + + +@dataclass(frozen=True, repr=False) +class LowLevelILFloat_const(Constant, FloatingPoint): + + @property + def constant(self) -> float: + return self.get_float(0) + + +@dataclass(frozen=True, repr=False) +class LowLevelILFlag(LowLevelILInstruction): + operand_names = tuple(["src"]) + + @property + def src(self): + return self.get_flag(0) + + +@dataclass(frozen=True, repr=False) +class LowLevelILGoto(Terminal): + operand_names = tuple(["dest"]) + + @property + def dest(self): + return self.get_int(0) + + +@dataclass(frozen=True, repr=False) +class LowLevelILFlag_group(LowLevelILInstruction): + operand_names = tuple(["semantic_group"]) + + @property + def semantic_group(self): + return self.get_sem_group(0) + + +@dataclass(frozen=True, repr=False) +class LowLevelILBool_to_int(LowLevelILInstruction): + operand_names = tuple(["src"]) + + @property + def src(self): + return self.get_expr(0) + + +@dataclass(frozen=True, repr=False) +class LowLevelILTrap(Terminal): + operand_names = tuple(["vector"]) + + @property + def vector(self): + return self.get_int(0) + + +@dataclass(frozen=True, repr=False) +class LowLevelILReg_split_dest_ssa(SSA): + operand_names = tuple(["dest"]) + + @property + def dest(self): + return self.get_reg_ssa(0, 1) + + +@dataclass(frozen=True, repr=False) +class LowLevelILReg_stack_dest_ssa(RegisterStack, SSA): + operand_names = tuple(["dest", "src"]) + + @property + def dest(self): + return self.get_reg_stack_ssa(0, 1) + + @property + def src(self): + return self.get_reg_stack_ssa(0, 2) + + +@dataclass(frozen=True, repr=False) +class LowLevelILReg_ssa(SSA): + operand_names = tuple(["src"]) + + @property + def src(self): + return self.get_reg_ssa(0, 1) + + +@dataclass(frozen=True, repr=False) +class LowLevelILFlag_ssa(SSA): + operand_names = tuple(["src"]) + + @property + def src(self): + return self.get_flag_ssa(0, 1) + + +@dataclass(frozen=True, repr=False) +class LowLevelILCall_param(SSA): + operand_names = tuple(["src"]) + + @property + def src(self): + return self.get_expr_list(0) + + +@dataclass(frozen=True, repr=False) +class LowLevelILMem_phi(Memory, SSA): + operand_names = tuple(["dest_memory", "src_memory"]) + + @property + def dest_memory(self): + return self.get_int(0) + + @property + def src_memory(self): + return self.get_int_list(1) + + +@dataclass(frozen=True, repr=False) +class LowLevelILSet_reg(SetReg): + operand_names = tuple(["dest", "src"]) + + @property + def dest(self): + return self.get_reg(0) + + @property + def src(self): + return self.get_expr(1) + + +@dataclass(frozen=True, repr=False) +class LowLevelILReg_stack_push(RegisterStack): + operand_names = tuple(["stack", "src"]) + + @property + def stack(self): + return self.get_reg_stack(0) + + @property + def src(self): + return self.get_expr(1) + + +@dataclass(frozen=True, repr=False) +class LowLevelILSet_flag(LowLevelILInstruction): + operand_names = tuple(["dest", "src"]) + + @property + def dest(self): + return self.get_flag(0) + + @property + def src(self): + return self.get_expr(1) + + +@dataclass(frozen=True, repr=False) +class LowLevelILStore(Memory): + operand_names = tuple(["dest", "src"]) + + @property + def dest(self): + return self.get_expr(0) + + @property + def src(self): + return self.get_expr(1) + + +@dataclass(frozen=True, repr=False) +class LowLevelILReg_split(LowLevelILInstruction): + operand_names = tuple(["hi", "lo"]) + + @property + def hi(self): + return self.get_reg(0) + + @property + def lo(self): + return self.get_reg(1) + + +@dataclass(frozen=True, repr=False) +class LowLevelILReg_stack_rel(RegisterStack): + operand_names = tuple(["stack", "src"]) + + @property + def stack(self): + return self.get_reg_stack(0) + + @property + def src(self): + return self.get_expr(1) + + +@dataclass(frozen=True, repr=False) +class LowLevelILReg_stack_free_rel(RegisterStack): + operand_names = tuple(["stack", "dest"]) + + @property + def stack(self): + return self.get_reg_stack(0) + + @property + def dest(self): + return self.get_expr(1) + + +@dataclass(frozen=True, repr=False) +class LowLevelILExtern_ptr(Constant): + operand_names = tuple(["constant", "offset"]) + + @property + def constant(self): + return self.get_int(0) + + @property + def offset(self): + return self.get_int(1) + + +@dataclass(frozen=True, repr=False) +class LowLevelILFlag_bit(LowLevelILInstruction): + operand_names = tuple(["src", "bit"]) + + @property + def src(self): + return self.get_flag(0) + + @property + def bit(self): + return self.get_int(1) + + +@dataclass(frozen=True, repr=False) +class LowLevelILAdd(BinaryOperation, Arithmetic): + pass + + +@dataclass(frozen=True, repr=False) +class LowLevelILSub(BinaryOperation, Arithmetic): + pass + + +@dataclass(frozen=True, repr=False) +class LowLevelILAnd(BinaryOperation, Arithmetic): + pass + + +@dataclass(frozen=True, repr=False) +class LowLevelILOr(BinaryOperation, Arithmetic): + pass + + +@dataclass(frozen=True, repr=False) +class LowLevelILXor(BinaryOperation, Arithmetic): + pass + + +@dataclass(frozen=True, repr=False) +class LowLevelILLsl(BinaryOperation, Arithmetic): + pass + + +@dataclass(frozen=True, repr=False) +class LowLevelILLsr(BinaryOperation, Arithmetic): + pass + + +@dataclass(frozen=True, repr=False) +class LowLevelILAsr(BinaryOperation, Arithmetic): + pass + + +@dataclass(frozen=True, repr=False) +class LowLevelILRol(BinaryOperation, Arithmetic): + pass + +@dataclass(frozen=True, repr=False) +class LowLevelILRor(BinaryOperation, Arithmetic): + pass + + +@dataclass(frozen=True, repr=False) +class LowLevelILMul(BinaryOperation, Arithmetic): + pass + + +@dataclass(frozen=True, repr=False) +class LowLevelILMulu_dp(BinaryOperation, DoublePrecision): + pass + +@dataclass(frozen=True, repr=False) +class LowLevelILMuls_dp(BinaryOperation, DoublePrecision): + pass + + +@dataclass(frozen=True, repr=False) +class LowLevelILDivu(BinaryOperation, Arithmetic): + pass + + +@dataclass(frozen=True, repr=False) +class LowLevelILDivu_dp(BinaryOperation, DoublePrecision): + pass + + +@dataclass(frozen=True, repr=False) +class LowLevelILDivs(BinaryOperation, Arithmetic, Signed): + pass + + +@dataclass(frozen=True, repr=False) +class LowLevelILDivs_dp(BinaryOperation, DoublePrecision, Signed): + pass + + +@dataclass(frozen=True, repr=False) +class LowLevelILModu(BinaryOperation, Arithmetic): + pass + + +@dataclass(frozen=True, repr=False) +class LowLevelILModu_dp(BinaryOperation, DoublePrecision): + pass + +@dataclass(frozen=True, repr=False) +class LowLevelILMods(BinaryOperation, Arithmetic, Signed): + pass + + +@dataclass(frozen=True, repr=False) +class LowLevelILMods_dp(BinaryOperation, DoublePrecision, Signed): + pass + + +@dataclass(frozen=True, repr=False) +class LowLevelILCmp_e(Comparison): + pass + + +@dataclass(frozen=True, repr=False) +class LowLevelILCmp_ne(Comparison): + pass + + +@dataclass(frozen=True, repr=False) +class LowLevelILCmp_slt(Comparison, Signed): + pass + + +@dataclass(frozen=True, repr=False) +class LowLevelILCmp_ult(Comparison): + pass + + +@dataclass(frozen=True, repr=False) +class LowLevelILCmp_sle(Comparison,Signed): + pass + + +@dataclass(frozen=True, repr=False) +class LowLevelILCmp_ule(Comparison): + pass + + +@dataclass(frozen=True, repr=False) +class LowLevelILCmp_sge(Comparison, Signed): + pass + + +@dataclass(frozen=True, repr=False) +class LowLevelILCmp_uge(Comparison): + pass + + +@dataclass(frozen=True, repr=False) +class LowLevelILCmp_sgt(Comparison, Signed): + pass + + +@dataclass(frozen=True, repr=False) +class LowLevelILCmp_ugt(Comparison): + pass + + +@dataclass(frozen=True, repr=False) +class LowLevelILTest_bit(BinaryOperation, Arithmetic, FloatingPoint): + pass + + +@dataclass(frozen=True, repr=False) +class LowLevelILFadd(BinaryOperation, Arithmetic, FloatingPoint): + pass + + +@dataclass(frozen=True, repr=False) +class LowLevelILFsub(BinaryOperation, Arithmetic, FloatingPoint): + pass + + +@dataclass(frozen=True, repr=False) +class LowLevelILFmul(BinaryOperation, Arithmetic, FloatingPoint): + pass + + +@dataclass(frozen=True, repr=False) +class LowLevelILFdiv(BinaryOperation, Arithmetic, FloatingPoint): + pass + + +@dataclass(frozen=True, repr=False) +class LowLevelILFcmp_e(Comparison, FloatingPoint): + pass + + +@dataclass(frozen=True, repr=False) +class LowLevelILFcmp_ne(Comparison, FloatingPoint): + pass + + +@dataclass(frozen=True, repr=False) +class LowLevelILFcmp_lt(Comparison, FloatingPoint): + pass + + +@dataclass(frozen=True, repr=False) +class LowLevelILFcmp_le(Comparison, FloatingPoint): + pass + + +@dataclass(frozen=True, repr=False) +class LowLevelILFcmp_ge(Comparison, FloatingPoint): + pass + + +@dataclass(frozen=True, repr=False) +class LowLevelILFcmp_gt(Comparison, FloatingPoint): + pass + +@dataclass(frozen=True, repr=False) +class LowLevelILFcmp_o(Comparison, FloatingPoint): + pass + + +@dataclass(frozen=True, repr=False) +class LowLevelILFcmp_uo(Comparison, FloatingPoint): + pass + + +@dataclass(frozen=True, repr=False) +class LowLevelILJump_to(LowLevelILInstruction): + operand_names = tuple(["dest", "targets"]) + + @property + def dest(self): + return self.get_expr(0) + + @property + def targets(self): + return self.get_target_map(1) + + +@dataclass(frozen=True, repr=False) +class LowLevelILFlag_cond(LowLevelILInstruction): + operand_names = tuple(["condition", "semantic_class"]) + + @property + def condition(self): + return self.get_cond(0) + + @property + def semantic_class(self): + return self.get_sem_class(1) + + +@dataclass(frozen=True, repr=False) +class LowLevelILAdd_overflow(BinaryOperation, Arithmetic): + operand_names = tuple(["left", "right"]) + + @property + def left(self): + return self.get_expr(0) + + @property + def right(self): + return self.get_expr(1) + + +@dataclass(frozen=True, repr=False) +class LowLevelILSet_reg_ssa(SetReg, SSA): + operand_names = tuple(["dest", "src"]) + + @property + def dest(self): + return self.get_reg_ssa(0, 1) + + @property + def src(self): + return self.get_expr(1) + + +@dataclass(frozen=True, repr=False) +class LowLevelILReg_ssa_partial(SetReg, SSA): + operand_names = tuple(["full_reg", "src"]) + + @property + def full_reg(self): + return self.get_reg_ssa(0, 1) + + @property + def src(self): + return self.get_reg(1) + + +@dataclass(frozen=True, repr=False) +class LowLevelILReg_split_ssa(SetReg, SSA): + operand_names = tuple(["hi", "lo"]) + + @property + def hi(self): + return self.get_reg_ssa(0, 1) + + @property + def lo(self): + return self.get_reg_ssa(2, 3) + + +@dataclass(frozen=True, repr=False) +class LowLevelILReg_stack_abs_ssa(RegisterStack, SSA): + operand_names = tuple(["stack", "src"]) + + @property + def stack(self): + return self.get_reg_stack_ssa(0, 1) + + @property + def src(self): + return self.get_reg(2) + + +@dataclass(frozen=True, repr=False) +class LowLevelILReg_stack_free_abs_ssa(RegisterStack): + operand_names = tuple(["stack", "dest"]) + + @property + def stack(self): + return self.get_expr(0) + + @property + def dest(self): + return self.get_reg(1) + + +@dataclass(frozen=True, repr=False) +class LowLevelILSet_flag_ssa(SSA): + operand_names = tuple(["dest", "src"]) + + @property + def dest(self): + return self.get_flag_ssa(0, 1) + + @property + def src(self): + return self.get_expr(2) + + +@dataclass(frozen=True, repr=False) +class LowLevelILFlag_bit_ssa(SSA): + operand_names = tuple(["src", "bit"]) + + @property + def src(self): + return self.get_flag_ssa(0, 1) + + @property + def bit(self): + return self.get_int(2) + + +@dataclass(frozen=True, repr=False) +class LowLevelILCall_output_ssa(SSA): + operand_names = tuple(["dest_memory", "dest"]) + + @property + def dest_memory(self): + return self.get_int(0) + + @property + def dest(self): + return self.get_reg_ssa_list(1) + + +@dataclass(frozen=True, repr=False) +class LowLevelILCall_stack_ssa(SSA): + operand_names = tuple(["src", "src_memory"]) + + @property + def src(self): + return self.get_reg_ssa(0, 1) + + @property + def src_memory(self): + return self.get_int(2) + + +@dataclass(frozen=True, repr=False) +class LowLevelILLoad_ssa(Load, SSA): + operand_names = tuple(["src", "src_memory"]) + + @property + def src(self): + return self.get_expr(0) + + @property + def src_memory(self): + return self.get_int(1) + + +@dataclass(frozen=True, repr=False) +class LowLevelILReg_phi(SSA): + operand_names = tuple(["dest", "src"]) + + @property + def dest(self): + return self.get_reg_ssa(0, 1) + + @property + def src(self): + return self.get_reg_ssa_list(2) + + +@dataclass(frozen=True, repr=False) +class LowLevelILReg_stack_phi(RegisterStack, SSA): + operand_names = tuple(["dest", "src"]) + + @property + def dest(self): + return self.get_reg_stack_ssa(0, 1) + + @property + def src(self): + return self.get_reg_stack_ssa_list(2) + + +@dataclass(frozen=True, repr=False) +class LowLevelILFlag_phi(SSA): + operand_names = tuple(["dest", "src"]) + + @property + def dest(self): + return self.get_flag_ssa(0, 1) + + @property + def src(self): + return self.get_flag_ssa_list(2) + + +@dataclass(frozen=True, repr=False) +class LowLevelILSet_reg_split(SetReg): + operand_names = tuple(["hi", "lo", "src"]) + + @property + def hi(self): + return self.get_reg(0) + + @property + def lo(self): + return self.get_reg(1) + + @property + def src(self): + return self.get_expr(2) + + +@dataclass(frozen=True, repr=False) +class LowLevelILSet_reg_stack_rel(RegisterStack): + operand_names = tuple(["stack", "dest", "src"]) + + @property + def stack(self): + return self.get_reg_stack(0) + + @property + def dest(self): + return self.get_expr(1) + + @property + def src(self): + return self.get_expr(2) + + +@dataclass(frozen=True, repr=False) +class LowLevelILSbb(Carry): + operand_names = tuple(["left", "right", "carry"]) + + @property + def left(self): + return self.get_expr(0) + + @property + def right(self): + return self.get_expr(1) + + @property + def carry(self): + return self.get_expr(2) + + +@dataclass(frozen=True, repr=False) +class LowLevelILAdc(Carry): + operand_names = tuple(["left", "right", "carry"]) + + @property + def left(self): + return self.get_expr(0) + + @property + def right(self): + return self.get_expr(1) + + @property + def carry(self): + return self.get_expr(2) + + +@dataclass(frozen=True, repr=False) +class LowLevelILRlc(Carry): + operand_names = tuple(["left", "right", "carry"]) + + @property + def left(self): + return self.get_expr(0) + + @property + def right(self): + return self.get_expr(1) + + @property + def carry(self): + return self.get_expr(2) + + +@dataclass(frozen=True, repr=False) +class LowLevelILRrc(Carry): + operand_names = tuple(["left", "right", "carry"]) - def __repr__(self): - return f"" + @property + def left(self): + return self.get_expr(0) + @property + def right(self): + return self.get_expr(1) -@dataclass(frozen=True) -class SSAFlag: - flag:ILFlag - version:int + @property + def carry(self): + return self.get_expr(2) - def __repr__(self): - return f"" +@dataclass(frozen=True, repr=False) +class LowLevelILCall_stack_adjust(Call): + operand_names = tuple(["dest", "stack_adjustment", "reg_stack_adjustments"]) -@dataclass(frozen=True) -class SSARegisterOrFlag: - reg_or_flag:Union[ILRegister, ILFlag] - version:int + @property + def dest(self): + return self.get_expr(0) - def __repr__(self): - return f"" + @property + def stack_adjustment(self): + return self.get_int(1) + @property + def reg_stack_adjustments(self): + return self.get_reg_stack_adjust(2) -@dataclass(frozen=True) -class LowLevelILOperationAndSize: - operation:'LowLevelILOperation' - size:int - def __repr__(self): - if self.size == 0: - return f"<{self.operation.name}>" - return "<{self.operation.name} {self.size}>" +@dataclass(frozen=True, repr=False) +class LowLevelILIf(Terminal): + operand_names = tuple(["condition", "true", "false"]) + @property + def condition(self): + return self.get_expr(0) -class LowLevelILInstruction: - """ - ``class LowLevelILInstruction`` Low Level Intermediate Language Instructions are infinite length tree-based - instructions. Tree-based instructions use infix notation with the left hand operand being the destination operand. - Infix notation is thus more natural to read than other notations (e.g. x86 ``mov eax, 0`` vs. LLIL ``eax = 0``). - """ + @property + def true(self): + return self.get_int(1) - ILOperations = { - LowLevelILOperation.LLIL_NOP: [], - LowLevelILOperation.LLIL_SET_REG: [("dest", "reg"), ("src", "expr")], - LowLevelILOperation.LLIL_SET_REG_SPLIT: [("hi", "reg"), ("lo", "reg"), ("src", "expr")], - LowLevelILOperation.LLIL_SET_REG_STACK_REL: [("stack", "reg_stack"), ("dest", "expr"), ("src", "expr")], - LowLevelILOperation.LLIL_REG_STACK_PUSH: [("stack", "reg_stack"), ("src", "expr")], - LowLevelILOperation.LLIL_SET_FLAG: [("dest", "flag"), ("src", "expr")], - LowLevelILOperation.LLIL_LOAD: [("src", "expr")], - LowLevelILOperation.LLIL_STORE: [("dest", "expr"), ("src", "expr")], - LowLevelILOperation.LLIL_PUSH: [("src", "expr")], - LowLevelILOperation.LLIL_POP: [], - LowLevelILOperation.LLIL_REG: [("src", "reg")], - LowLevelILOperation.LLIL_REG_SPLIT: [("hi", "reg"), ("lo", "reg")], - LowLevelILOperation.LLIL_REG_STACK_REL: [("stack", "reg_stack"), ("src", "expr")], - LowLevelILOperation.LLIL_REG_STACK_POP: [("stack", "reg_stack")], - LowLevelILOperation.LLIL_REG_STACK_FREE_REG: [("dest", "reg")], - LowLevelILOperation.LLIL_REG_STACK_FREE_REL: [("stack", "reg_stack"), ("dest", "expr")], - LowLevelILOperation.LLIL_CONST: [("constant", "int")], - LowLevelILOperation.LLIL_CONST_PTR: [("constant", "int")], - LowLevelILOperation.LLIL_EXTERN_PTR: [("constant", "int"), ("offset", "int")], - LowLevelILOperation.LLIL_FLOAT_CONST: [("constant", "float")], - LowLevelILOperation.LLIL_FLAG: [("src", "flag")], - LowLevelILOperation.LLIL_FLAG_BIT: [("src", "flag"), ("bit", "int")], - LowLevelILOperation.LLIL_ADD: [("left", "expr"), ("right", "expr")], - LowLevelILOperation.LLIL_ADC: [("left", "expr"), ("right", "expr"), ("carry", "expr")], - LowLevelILOperation.LLIL_SUB: [("left", "expr"), ("right", "expr")], - LowLevelILOperation.LLIL_SBB: [("left", "expr"), ("right", "expr"), ("carry", "expr")], - LowLevelILOperation.LLIL_AND: [("left", "expr"), ("right", "expr")], - LowLevelILOperation.LLIL_OR: [("left", "expr"), ("right", "expr")], - LowLevelILOperation.LLIL_XOR: [("left", "expr"), ("right", "expr")], - LowLevelILOperation.LLIL_LSL: [("left", "expr"), ("right", "expr")], - LowLevelILOperation.LLIL_LSR: [("left", "expr"), ("right", "expr")], - LowLevelILOperation.LLIL_ASR: [("left", "expr"), ("right", "expr")], - LowLevelILOperation.LLIL_ROL: [("left", "expr"), ("right", "expr")], - LowLevelILOperation.LLIL_RLC: [("left", "expr"), ("right", "expr"), ("carry", "expr")], - LowLevelILOperation.LLIL_ROR: [("left", "expr"), ("right", "expr")], - LowLevelILOperation.LLIL_RRC: [("left", "expr"), ("right", "expr"), ("carry", "expr")], - LowLevelILOperation.LLIL_MUL: [("left", "expr"), ("right", "expr")], - LowLevelILOperation.LLIL_MULU_DP: [("left", "expr"), ("right", "expr")], - LowLevelILOperation.LLIL_MULS_DP: [("left", "expr"), ("right", "expr")], - LowLevelILOperation.LLIL_DIVU: [("left", "expr"), ("right", "expr")], - LowLevelILOperation.LLIL_DIVU_DP: [("left", "expr"), ("right", "expr")], - LowLevelILOperation.LLIL_DIVS: [("left", "expr"), ("right", "expr")], - LowLevelILOperation.LLIL_DIVS_DP: [("left", "expr"), ("right", "expr")], - LowLevelILOperation.LLIL_MODU: [("left", "expr"), ("right", "expr")], - LowLevelILOperation.LLIL_MODU_DP: [("left", "expr"), ("right", "expr")], - LowLevelILOperation.LLIL_MODS: [("left", "expr"), ("right", "expr")], - LowLevelILOperation.LLIL_MODS_DP: [("left", "expr"), ("right", "expr")], - LowLevelILOperation.LLIL_NEG: [("src", "expr")], - LowLevelILOperation.LLIL_NOT: [("src", "expr")], - LowLevelILOperation.LLIL_SX: [("src", "expr")], - LowLevelILOperation.LLIL_ZX: [("src", "expr")], - LowLevelILOperation.LLIL_LOW_PART: [("src", "expr")], - LowLevelILOperation.LLIL_JUMP: [("dest", "expr")], - LowLevelILOperation.LLIL_JUMP_TO: [("dest", "expr"), ("targets", "target_map")], - LowLevelILOperation.LLIL_CALL: [("dest", "expr")], - LowLevelILOperation.LLIL_CALL_STACK_ADJUST: [("dest", "expr"), ("stack_adjustment", "int"), ("reg_stack_adjustments", "reg_stack_adjust")], - LowLevelILOperation.LLIL_TAILCALL: [("dest", "expr")], - LowLevelILOperation.LLIL_RET: [("dest", "expr")], - LowLevelILOperation.LLIL_NORET: [], - LowLevelILOperation.LLIL_IF: [("condition", "expr"), ("true", "int"), ("false", "int")], - LowLevelILOperation.LLIL_GOTO: [("dest", "int")], - LowLevelILOperation.LLIL_FLAG_COND: [("condition", "cond"), ("semantic_class", "sem_class")], - LowLevelILOperation.LLIL_FLAG_GROUP: [("semantic_group", "sem_group")], - LowLevelILOperation.LLIL_CMP_E: [("left", "expr"), ("right", "expr")], - LowLevelILOperation.LLIL_CMP_NE: [("left", "expr"), ("right", "expr")], - LowLevelILOperation.LLIL_CMP_SLT: [("left", "expr"), ("right", "expr")], - LowLevelILOperation.LLIL_CMP_ULT: [("left", "expr"), ("right", "expr")], - LowLevelILOperation.LLIL_CMP_SLE: [("left", "expr"), ("right", "expr")], - LowLevelILOperation.LLIL_CMP_ULE: [("left", "expr"), ("right", "expr")], - LowLevelILOperation.LLIL_CMP_SGE: [("left", "expr"), ("right", "expr")], - LowLevelILOperation.LLIL_CMP_UGE: [("left", "expr"), ("right", "expr")], - LowLevelILOperation.LLIL_CMP_SGT: [("left", "expr"), ("right", "expr")], - LowLevelILOperation.LLIL_CMP_UGT: [("left", "expr"), ("right", "expr")], - LowLevelILOperation.LLIL_TEST_BIT: [("left", "expr"), ("right", "expr")], - LowLevelILOperation.LLIL_BOOL_TO_INT: [("src", "expr")], - LowLevelILOperation.LLIL_ADD_OVERFLOW: [("left", "expr"), ("right", "expr")], - LowLevelILOperation.LLIL_SYSCALL: [], - LowLevelILOperation.LLIL_INTRINSIC: [("output", "reg_or_flag_list"), ("intrinsic", "intrinsic"), ("param", "expr")], - LowLevelILOperation.LLIL_INTRINSIC_SSA: [("output", "reg_or_flag_ssa_list"), ("intrinsic", "intrinsic"), ("param", "expr")], - LowLevelILOperation.LLIL_BP: [], - LowLevelILOperation.LLIL_TRAP: [("vector", "int")], - LowLevelILOperation.LLIL_UNDEF: [], - LowLevelILOperation.LLIL_UNIMPL: [], - LowLevelILOperation.LLIL_UNIMPL_MEM: [("src", "expr")], - LowLevelILOperation.LLIL_FADD: [("left", "expr"), ("right", "expr")], - LowLevelILOperation.LLIL_FSUB: [("left", "expr"), ("right", "expr")], - LowLevelILOperation.LLIL_FMUL: [("left", "expr"), ("right", "expr")], - LowLevelILOperation.LLIL_FDIV: [("left", "expr"), ("right", "expr")], - LowLevelILOperation.LLIL_FSQRT: [("src", "expr")], - LowLevelILOperation.LLIL_FNEG: [("src", "expr")], - LowLevelILOperation.LLIL_FABS: [("src", "expr")], - LowLevelILOperation.LLIL_FLOAT_TO_INT: [("src", "expr")], - LowLevelILOperation.LLIL_INT_TO_FLOAT: [("src", "expr")], - LowLevelILOperation.LLIL_FLOAT_CONV: [("src", "expr")], - LowLevelILOperation.LLIL_ROUND_TO_INT: [("src", "expr")], - LowLevelILOperation.LLIL_FLOOR: [("src", "expr")], - LowLevelILOperation.LLIL_CEIL: [("src", "expr")], - LowLevelILOperation.LLIL_FTRUNC: [("src", "expr")], - LowLevelILOperation.LLIL_FCMP_E: [("left", "expr"), ("right", "expr")], - LowLevelILOperation.LLIL_FCMP_NE: [("left", "expr"), ("right", "expr")], - LowLevelILOperation.LLIL_FCMP_LT: [("left", "expr"), ("right", "expr")], - LowLevelILOperation.LLIL_FCMP_LE: [("left", "expr"), ("right", "expr")], - LowLevelILOperation.LLIL_FCMP_GE: [("left", "expr"), ("right", "expr")], - LowLevelILOperation.LLIL_FCMP_GT: [("left", "expr"), ("right", "expr")], - LowLevelILOperation.LLIL_FCMP_O: [("left", "expr"), ("right", "expr")], - LowLevelILOperation.LLIL_FCMP_UO: [("left", "expr"), ("right", "expr")], - LowLevelILOperation.LLIL_SET_REG_SSA: [("dest", "reg_ssa"), ("src", "expr")], - LowLevelILOperation.LLIL_SET_REG_SSA_PARTIAL: [("full_reg", "reg_ssa"), ("dest", "reg"), ("src", "expr")], - LowLevelILOperation.LLIL_SET_REG_SPLIT_SSA: [("hi", "expr"), ("lo", "expr"), ("src", "expr")], - LowLevelILOperation.LLIL_SET_REG_STACK_REL_SSA: [("stack", "expr"), ("dest", "expr"), ("top", "expr"), ("src", "expr")], - LowLevelILOperation.LLIL_SET_REG_STACK_ABS_SSA: [("stack", "expr"), ("dest", "reg"), ("src", "expr")], - LowLevelILOperation.LLIL_REG_SPLIT_DEST_SSA: [("dest", "reg_ssa")], - LowLevelILOperation.LLIL_REG_STACK_DEST_SSA: [("src", "reg_stack_ssa_dest_and_src")], - LowLevelILOperation.LLIL_REG_SSA: [("src", "reg_ssa")], - LowLevelILOperation.LLIL_REG_SSA_PARTIAL: [("full_reg", "reg_ssa"), ("src", "reg")], - LowLevelILOperation.LLIL_REG_SPLIT_SSA: [("hi", "reg_ssa"), ("lo", "reg_ssa")], - LowLevelILOperation.LLIL_REG_STACK_REL_SSA: [("stack", "reg_stack_ssa"), ("src", "expr"), ("top", "expr")], - LowLevelILOperation.LLIL_REG_STACK_ABS_SSA: [("stack", "reg_stack_ssa"), ("src", "reg")], - LowLevelILOperation.LLIL_REG_STACK_FREE_REL_SSA: [("stack", "expr"), ("dest", "expr"), ("top", "expr")], - LowLevelILOperation.LLIL_REG_STACK_FREE_ABS_SSA: [("stack", "expr"), ("dest", "reg")], - LowLevelILOperation.LLIL_SET_FLAG_SSA: [("dest", "flag_ssa"), ("src", "expr")], - LowLevelILOperation.LLIL_FLAG_SSA: [("src", "flag_ssa")], - LowLevelILOperation.LLIL_FLAG_BIT_SSA: [("src", "flag_ssa"), ("bit", "int")], - LowLevelILOperation.LLIL_CALL_SSA: [("output", "expr"), ("dest", "expr"), ("stack", "expr"), ("param", "expr")], - LowLevelILOperation.LLIL_SYSCALL_SSA: [("output", "expr"), ("stack", "expr"), ("param", "expr")], - LowLevelILOperation.LLIL_TAILCALL_SSA: [("output", "expr"), ("dest", "expr"), ("stack", "expr"), ("param", "expr")], - LowLevelILOperation.LLIL_CALL_OUTPUT_SSA: [("dest_memory", "int"), ("dest", "reg_ssa_list")], - LowLevelILOperation.LLIL_CALL_STACK_SSA: [("src", "reg_ssa"), ("src_memory", "int")], - LowLevelILOperation.LLIL_CALL_PARAM: [("src", "expr_list")], - LowLevelILOperation.LLIL_LOAD_SSA: [("src", "expr"), ("src_memory", "int")], - LowLevelILOperation.LLIL_STORE_SSA: [("dest", "expr"), ("dest_memory", "int"), ("src_memory", "int"), ("src", "expr")], - LowLevelILOperation.LLIL_REG_PHI: [("dest", "reg_ssa"), ("src", "reg_ssa_list")], - LowLevelILOperation.LLIL_REG_STACK_PHI: [("dest", "reg_stack_ssa"), ("src", "reg_stack_ssa_list")], - LowLevelILOperation.LLIL_FLAG_PHI: [("dest", "flag_ssa"), ("src", "flag_ssa_list")], - LowLevelILOperation.LLIL_MEM_PHI: [("dest_memory", "int"), ("src_memory", "int_list")] - } - - def __init__(self, func:'LowLevelILFunction', expr_index:ExpressionIndex, instr_index:InstructionIndex=None): - instr = core.BNGetLowLevelILByIndex(func.handle, expr_index) - if func.arch is None: - raise Exception("Attempting to create a LowLevelILInstruction with function that doesn't have an architecture.") - self._function = func - self._expr_index = expr_index - self._instr_index = instr_index - self._operation = LowLevelILOperation(instr.operation) - self._size = instr.size - self._address = instr.address - self._source_operand = instr.sourceOperand - if instr.flags == 0: - self._flags = None - else: - self._flags = func.arch.get_flag_write_type_name(instr.flags) - if self._source_operand == 0xffffffff: - self._source_operand = None - operands = LowLevelILInstruction.ILOperations[instr.operation] - self._operands = [] - i = 0 - - for operand in operands: - name, operand_type = operand - value:Optional[Any] = None - if operand_type == "int": - value = instr.operands[i] - assert isinstance(value, int) - value = (value & ((1 << 63) - 1)) - (value & (1 << 63)) - elif operand_type == "float": - if instr.size == 4: - value = struct.unpack("f", struct.pack("I", instr.operands[i] & 0xffffffff))[0] - elif instr.size == 8: - value = struct.unpack("d", struct.pack("Q", instr.operands[i]))[0] - else: - value = instr.operands[i] - elif operand_type == "expr": - value = LowLevelILInstruction(func, instr.operands[i]) - elif operand_type == "reg": - value = ILRegister(func.arch, instr.operands[i]) - elif operand_type == "reg_stack": - value = ILRegisterStack(func.arch, instr.operands[i]) - elif operand_type == "intrinsic": - value = ILIntrinsic(func.arch, instr.operands[i]) - elif operand_type == "reg_ssa": - reg = ILRegister(func.arch, instr.operands[i]) - i += 1 - value = SSARegister(reg, instr.operands[i]) - elif operand_type == "reg_stack_ssa": - reg_stack = ILRegisterStack(func.arch, instr.operands[i]) - i += 1 - value = SSARegisterStack(reg_stack, instr.operands[i]) - elif operand_type == "reg_stack_ssa_dest_and_src": - reg_stack = ILRegisterStack(func.arch, instr.operands[i]) - i += 1 - value = SSARegisterStack(reg_stack, instr.operands[i]) - i += 1 - self._operands.append(value) - self.__dict__['dest'] = value - value = SSARegisterStack(reg_stack, instr.operands[i]) - elif operand_type == "flag": - value = ILFlag(func.arch, instr.operands[i]) - elif operand_type == "flag_ssa": - flag = ILFlag(func.arch, instr.operands[i]) - i += 1 - value = SSAFlag(flag, instr.operands[i]) - elif operand_type == "sem_class": - if instr.operands[i] == 0: - value = None - else: - value = ILSemanticFlagClass(func.arch, instr.operands[i]) - elif operand_type == "sem_group": - value = ILSemanticFlagGroup(func.arch, instr.operands[i]) - elif operand_type == "cond": - value = LowLevelILFlagCondition(instr.operands[i]) - elif operand_type == "int_list": - count = ctypes.c_ulonglong() - operand_list = core.BNLowLevelILGetOperandList(func.handle, self.expr_index, i, count) - assert operand_list is not None, "core.BNLowLevelILGetOperandList returned None" - i += 1 - value = [] - for j in range(count.value): - value.append(operand_list[j]) - core.BNLowLevelILFreeOperandList(operand_list) - elif operand_type == "expr_list": - count = ctypes.c_ulonglong() - operand_list = core.BNLowLevelILGetOperandList(func.handle, self.expr_index, i, count) - assert operand_list is not None, "core.BNLowLevelILGetOperandList returned None" - i += 1 - value = [] - for j in range(count.value): - value.append(LowLevelILInstruction(func, operand_list[j])) - core.BNLowLevelILFreeOperandList(operand_list) - elif operand_type == "reg_or_flag_list": - count = ctypes.c_ulonglong() - operand_list = core.BNLowLevelILGetOperandList(func.handle, self.expr_index, i, count) - assert operand_list is not None, "core.BNLowLevelILGetOperandList returned None" - i += 1 - value = [] - for j in range(count.value): - if (operand_list[j] & (1 << 32)) != 0: - value.append(ILFlag(func.arch, operand_list[j] & 0xffffffff)) - else: - value.append(ILRegister(func.arch, operand_list[j] & 0xffffffff)) - core.BNLowLevelILFreeOperandList(operand_list) - elif operand_type == "reg_ssa_list": - count = ctypes.c_ulonglong() - operand_list = core.BNLowLevelILGetOperandList(func.handle, self.expr_index, i, count) - assert operand_list is not None, "core.BNLowLevelILGetOperandList returned None" - i += 1 - value = [] - for j in range(count.value // 2): - reg = operand_list[j * 2] - reg_version = operand_list[(j * 2) + 1] - value.append(SSARegister(ILRegister(func.arch, reg), reg_version)) - core.BNLowLevelILFreeOperandList(operand_list) - elif operand_type == "reg_stack_ssa_list": - count = ctypes.c_ulonglong() - operand_list = core.BNLowLevelILGetOperandList(func.handle, self.expr_index, i, count) - assert operand_list is not None, "core.BNLowLevelILGetOperandList returned None" - i += 1 - value = [] - for j in range(count.value // 2): - reg_stack = operand_list[j * 2] - reg_version = operand_list[(j * 2) + 1] - value.append(SSARegisterStack(ILRegisterStack(func.arch, reg_stack), reg_version)) - core.BNLowLevelILFreeOperandList(operand_list) - elif operand_type == "flag_ssa_list": - count = ctypes.c_ulonglong() - operand_list = core.BNLowLevelILGetOperandList(func.handle, self.expr_index, i, count) - assert operand_list is not None, "core.BNLowLevelILGetOperandList returned None" - i += 1 - value = [] - for j in range(count.value // 2): - flag = operand_list[j * 2] - flag_version = operand_list[(j * 2) + 1] - value.append(SSAFlag(ILFlag(func.arch, flag), flag_version)) - core.BNLowLevelILFreeOperandList(operand_list) - elif operand_type == "reg_or_flag_ssa_list": - count = ctypes.c_ulonglong() - operand_list = core.BNLowLevelILGetOperandList(func.handle, self.expr_index, i, count) - assert operand_list is not None, "core.BNLowLevelILGetOperandList returned None" - i += 1 - value = [] - for j in range(count.value // 2): - if (operand_list[j * 2] & (1 << 32)) != 0: - reg_or_flag = ILFlag(func.arch, operand_list[j * 2] & 0xffffffff) - else: - reg_or_flag = ILRegister(func.arch, operand_list[j * 2] & 0xffffffff) - reg_version = operand_list[(j * 2) + 1] - value.append(SSARegisterOrFlag(reg_or_flag, reg_version)) - core.BNLowLevelILFreeOperandList(operand_list) - elif operand_type == "reg_stack_adjust": - count = ctypes.c_ulonglong() - operand_list = core.BNLowLevelILGetOperandList(func.handle, self.expr_index, i, count) - assert operand_list is not None, "core.BNLowLevelILGetOperandList returned None" - i += 1 - value = {} - for j in range(count.value // 2): - reg_stack = operand_list[j * 2] - adjust = operand_list[(j * 2) + 1] - if adjust & 0x80000000: - adjust |= ~0x80000000 - value[func.arch.get_reg_stack_name(reg_stack)] = adjust - core.BNLowLevelILFreeOperandList(operand_list) - elif operand_type == "target_map": - count = ctypes.c_ulonglong() - operand_list = core.BNLowLevelILGetOperandList(func.handle, self.expr_index, i, count) - assert operand_list is not None, "core.BNLowLevelILGetOperandList returned None" - i += 1 - value = {} - for j in range(count.value // 2): - key = operand_list[j * 2] - target = operand_list[(j * 2) + 1] - value[key] = target - core.BNLowLevelILFreeOperandList(operand_list) - self._operands.append(value) - self.__dict__[name] = value - i += 1 + @property + def false(self): + return self.get_int(2) - 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 "" % str(self) +@dataclass(frozen=True, repr=False) +class LowLevelILIntrinsic(LowLevelILInstruction): + operand_names = tuple(["output", "intrinsic", "param"]) - def __eq__(self, other): - if not isinstance(other, self.__class__): - return NotImplemented - return self._function == other.function and self.expr_index == other.expr_index + @property + def output(self): + return self.get_reg_or_flag_list(0) - def __ne__(self, other): - if not isinstance(other, self.__class__): - return NotImplemented - return not (self == other) + @property + def intrinsic(self): + return self.get_intrinsic(2) - def __lt__(self, other): - if not isinstance(other, self.__class__): - return NotImplemented - return self._function == other.function and self.expr_index < other.expr_index + @property + def param(self): + return self.get_expr(3) - def __le__(self, other): - if not isinstance(other, self.__class__): - return NotImplemented - return self._function == other.function and self.expr_index <= other.expr_index - def __gt__(self, other): - if not isinstance(other, self.__class__): - return NotImplemented - return self._function == other.function and self.expr_index > other.expr_index +@dataclass(frozen=True, repr=False) +class LowLevelILIntrinsic_ssa(SSA): + operand_names = tuple(["output", "intrinsic", "param"]) - def __ge__(self, other): - if not isinstance(other, self.__class__): - return NotImplemented - return self._function == other.function and self.expr_index >= other.expr_index + @property + def output(self): + return self.get_reg_or_flag_ssa_list(0) - def __hash__(self): - return hash((self._function, self.expr_index)) + @property + def intrinsic(self): + return self.get_intrinsic(2) @property - def tokens(self) -> Optional[TokenList]: - """LLIL tokens (read-only)""" - count = ctypes.c_ulonglong() - assert self._function.arch is not None - tokens = ctypes.POINTER(core.BNInstructionTextToken)() - if (self._instr_index is not None) and (self._function.source_function is not None): - if not core.BNGetLowLevelILInstructionText(self._function.handle, self._function.source_function.handle, - self._function.arch.handle, self._instr_index, tokens, count): - return None - else: - # TODO: Special case LLIL_CALL_OUTPUT_SSA - if not core.BNGetLowLevelILExprText(self._function.handle, self._function.arch.handle, - self.expr_index, tokens, count): - return None - result = function.InstructionTextToken._from_core_struct(tokens, count.value) - core.BNFreeInstructionText(tokens, count.value) - return result + def param(self): + return self.get_expr(3) + + +@dataclass(frozen=True, repr=False) +class LowLevelILSet_reg_ssa_partial(SetReg, SSA): + operand_names = tuple(["full_reg", "dest", "src"]) @property - def il_basic_block(self) -> 'LowLevelILBasicBlock': - """IL basic block object containing this expression (read-only) (only available on finalized functions)""" - assert self._function.source_function is not None - view = self._function.source_function.view - core_block = core.BNGetLowLevelILBasicBlockForInstruction(self._function.handle, self._insstr_index) - assert core_block is not None, "BNGetLowLevelILBasicBlockForInstruction returned None" - return LowLevelILBasicBlock(view, core_block, self._function) + def full_reg(self): + return self.get_reg_ssa(0, 1) @property - def ssa_form(self) -> 'LowLevelILInstruction': - """SSA form of expression (read-only)""" - ssa_func = self._function.ssa_form - assert ssa_func is not None - return LowLevelILInstruction(ssa_func, - core.BNGetLowLevelILSSAExprIndex(self._function.handle, self.expr_index), - core.BNGetLowLevelILSSAInstructionIndex(self._function.handle, self._instr_index) if self._instr_index is not None else None) + def dest(self): + return self.get_reg(2) @property - def non_ssa_form(self) -> 'LowLevelILInstruction': - """Non-SSA form of expression (read-only)""" - non_ssa_function = self._function.non_ssa_form - assert non_ssa_function is not None - return LowLevelILInstruction(non_ssa_function, - core.BNGetLowLevelILNonSSAExprIndex(self._function.handle, self.expr_index), - core.BNGetLowLevelILNonSSAInstructionIndex(self._function.handle, self._instr_index) if self._instr_index is not None else None) + def src(self): + return self.get_expr(3) + + +@dataclass(frozen=True, repr=False) +class LowLevelILSet_reg_split_ssa(SetReg, SSA): + operand_names = tuple(["hi", "lo", "src"]) @property - def medium_level_il(self) -> Optional['mediumlevelil.MediumLevelILInstruction']: - """Gets the medium level IL expression corresponding to this expression (may be None for eliminated instructions)""" - expr = self._function.get_medium_level_il_expr_index(self.expr_index) - if expr is None: - return None - mlil_func = self._function.medium_level_il - assert mlil_func is not None, "self._function.medium_level_il is None" - return mediumlevelil.MediumLevelILInstruction(mlil_func, expr) + def hi(self): + return self.get_expr(0) @property - def mlil(self) -> Optional['mediumlevelil.MediumLevelILInstruction']: - return self.medium_level_il + def lo(self): + return self.get_expr(1) @property - def mlils(self) -> List['mediumlevelil.MediumLevelILInstruction']: - result = [] - for expr in self._function.get_medium_level_il_expr_indexes(self.expr_index): - result.append(mediumlevelil.MediumLevelILInstruction(self._function.medium_level_il, expr)) - return result + def src(self): + return self.get_expr(2) + + +@dataclass(frozen=True, repr=False) +class LowLevelILSet_reg_stack_abs_ssa(RegisterStack, SSA): + operand_names = tuple(["stack", "dest", "src"]) @property - def mapped_medium_level_il(self) -> Optional['mediumlevelil.MediumLevelILInstruction']: - """Gets the mapped medium level IL expression corresponding to this expression""" - expr = self._function.get_mapped_medium_level_il_expr_index(self.expr_index) - if expr is None: - return None - return mediumlevelil.MediumLevelILInstruction(self._function.mapped_medium_level_il, expr) + def stack(self): + return self.get_expr(0) @property - def mmlil(self) -> Optional['mediumlevelil.MediumLevelILInstruction']: - return self.mapped_medium_level_il + def dest(self): + return self.get_reg(1) @property - def high_level_il(self) -> Optional['highlevelil.HighLevelILInstruction']: - """Gets the high level IL expression corresponding to this expression (may be None for eliminated instructions)""" - if self.mlil is None: - return None - return self.mlil.hlil + def src(self): + return self.get_expr(2) + + +@dataclass(frozen=True, repr=False) +class LowLevelILReg_stack_rel_ssa(RegisterStack, SSA): + operand_names = tuple(["stack", "src", "top"]) @property - def hlil(self) -> Optional['highlevelil.HighLevelILInstruction']: - return self.high_level_il + def stack(self): + return self.get_reg_stack_ssa(0, 1) @property - def hlils(self) -> List['highlevelil.HighLevelILInstruction']: - result = set() - for mlil_expr in self.mlils: - for hlil_expr in mlil_expr.hlils: - result.add(hlil_expr) - return list(result) + def src(self): + return self.get_expr(2) @property - def value(self) -> 'variable.RegisterValue': - """Value of expression if constant or a known value (read-only)""" - value = core.BNGetLowLevelILExprValue(self._function.handle, self.expr_index) - return variable.RegisterValue.from_BNRegisterValue(value, self._function.arch) + def top(self): + return self.get_expr(3) + + +@dataclass(frozen=True, repr=False) +class LowLevelILReg_stack_free_rel_ssa(RegisterStack, SSA): + operand_names = tuple(["stack", "dest", "top"]) @property - def possible_values(self) -> 'variable.PossibleValueSet': - """Possible values of expression using path-sensitive static data flow analysis (read-only)""" - value = core.BNGetLowLevelILPossibleExprValues(self._function.handle, self.expr_index, None, 0) - result = variable.PossibleValueSet(self._function.arch, value) - core.BNFreePossibleValueSet(value) - return result + def stack(self): + return self.get_expr(0) @property - def prefix_operands(self) -> List[Any]: - """All operands in the expression tree in prefix order""" - # TODO: There is probably a much better type hint we can provide here - result = [LowLevelILOperationAndSize(self._operation, self._size)] - for operand in self._operands: - if isinstance(operand, LowLevelILInstruction): - result += operand.prefix_operands - else: - result.append(operand) - return result + def dest(self): + return self.get_expr(1) @property - def postfix_operands(self) -> List[Any]: - """All operands in the expression tree in postfix order""" - # TODO: There is probably a much better type hint we can provide here - result = [] - for operand in self._operands: - if isinstance(operand, LowLevelILInstruction): - result += operand.postfix_operands - else: - result.append(operand) - result.append(LowLevelILOperationAndSize(self._operation, self._size)) - return result + def top(self): + return self.get_expr(2) - def get_possible_values(self, options:List[DataFlowQueryOption]=[]) -> variable.PossibleValueSet: - option_array = (ctypes.c_int * len(options))() - idx = 0 - for option in options: - option_array[idx] = option - idx += 1 - value = core.BNGetLowLevelILPossibleExprValues(self._function.handle, self.expr_index, option_array, len(options)) - result = variable.PossibleValueSet(self._function.arch, value) - core.BNFreePossibleValueSet(value) - return result - def get_reg_value(self, reg:'architecture.RegisterType') -> variable.RegisterValue: - if self._function.arch is None: - raise Exception("Can not call get_reg_value on function with Architecture set to None") - reg = self._function.arch.get_reg_index(reg) - value = core.BNGetLowLevelILRegisterValueAtInstruction(self._function.handle, reg, self._instr_index) - return variable.RegisterValue.from_BNRegisterValue(value, self._function.arch) +@dataclass(frozen=True, repr=False) +class LowLevelILSyscall_ssa(Call, SSA): + operand_names = tuple(["output", "stack", "param"]) - def get_reg_value_after(self, reg:'architecture.RegisterType') -> variable.RegisterValue: - if self._function.arch is None: - raise Exception("Can not call get_reg_value_after on function with Architecture set to None") - reg = self._function.arch.get_reg_index(reg) - value = core.BNGetLowLevelILRegisterValueAfterInstruction(self._function.handle, reg, self._instr_index) - return variable.RegisterValue.from_BNRegisterValue(value, self._function.arch) + @property + def output(self): + return self.get_expr(0) - def get_possible_reg_values(self, reg:'architecture.RegisterType', options:List[DataFlowQueryOption]=[]) -> 'variable.PossibleValueSet': - if self._function.arch is None: - raise Exception("Can not call get_possible_reg_values on function with Architecture set to None") - reg = self._function.arch.get_reg_index(reg) - option_array = (ctypes.c_int * len(options))() - idx = 0 - for option in options: - option_array[idx] = option - idx += 1 - value = core.BNGetLowLevelILPossibleRegisterValuesAtInstruction(self._function.handle, reg, self._instr_index, - option_array, len(options)) - result = variable.PossibleValueSet(self._function.arch, value) - core.BNFreePossibleValueSet(value) - return result + @property + def stack(self): + return self.get_expr(1) - def get_possible_reg_values_after(self, reg:'architecture.RegisterType', options:List[DataFlowQueryOption]=[]) -> 'variable.PossibleValueSet': - if self._function.arch is None: - raise Exception("Can not call get_possible_reg_values_after on function with Architecture set to None") - reg = self._function.arch.get_reg_index(reg) - option_array = (ctypes.c_int * len(options))() - idx = 0 - for option in options: - option_array[idx] = option - idx += 1 - value = core.BNGetLowLevelILPossibleRegisterValuesAfterInstruction(self._function.handle, reg, self._instr_index, - option_array, len(options)) - result = variable.PossibleValueSet(self._function.arch, value) - core.BNFreePossibleValueSet(value) - return result + @property + def param(self): + return self.get_expr(2) - def get_flag_value(self, flag:'architecture.FlagType') -> 'variable.RegisterValue': - if self._function.arch is None: - raise Exception("Can not call get_flag_value on function with Architecture set to None") - flag = self._function.arch.get_flag_index(flag) - value = core.BNGetLowLevelILFlagValueAtInstruction(self._function.handle, flag, self._instr_index) - result = variable.RegisterValue.from_BNRegisterValue(value, self._function.arch) - return result - def get_flag_value_after(self, flag:'architecture.FlagType') -> 'variable.RegisterValue': - if self._function.arch is None: - raise Exception("Can not call get_flag_value_after on function with Architecture set to None") - flag = self._function.arch.get_flag_index(flag) - value = core.BNGetLowLevelILFlagValueAfterInstruction(self._function.handle, flag, self._instr_index) - result = variable.RegisterValue.from_BNRegisterValue(value, self._function.arch) - return result +@dataclass(frozen=True, repr=False) +class LowLevelILSet_reg_stack_rel_ssa(RegisterStack, SSA): + operand_names = tuple(["stack", "dest", "top", "src"]) - def get_possible_flag_values(self, flag:'architecture.FlagType', options:List[DataFlowQueryOption]=[]) -> 'variable.PossibleValueSet': - if self._function.arch is None: - raise Exception("Can not call get_possible_flag_values on function with Architecture set to None") - flag = self._function.arch.get_flag_index(flag) - option_array = (ctypes.c_int * len(options))() - idx = 0 - for option in options: - option_array[idx] = option - idx += 1 - value = core.BNGetLowLevelILPossibleFlagValuesAtInstruction(self._function.handle, flag, self._instr_index, - option_array, len(options)) - result = variable.PossibleValueSet(self._function.arch, value) - core.BNFreePossibleValueSet(value) - return result + @property + def stack(self): + return self.get_expr(0) - def get_possible_flag_values_after(self, flag:'architecture.FlagType', options:List[DataFlowQueryOption]=[]) -> 'variable.PossibleValueSet': - if self._function.arch is None: - raise Exception("Can not call get_possible_flag_values_after on function with Architecture set to None") - flag = self._function.arch.get_flag_index(flag) - option_array = (ctypes.c_int * len(options))() - idx = 0 - for option in options: - option_array[idx] = option - idx += 1 - value = core.BNGetLowLevelILPossibleFlagValuesAfterInstruction(self._function.handle, flag, self._instr_index, - option_array, len(options)) - result = variable.PossibleValueSet(self._function.arch, value) - core.BNFreePossibleValueSet(value) - return result + @property + def dest(self): + return self.get_expr(1) - def get_stack_contents(self, offset:int, size:int) -> 'variable.RegisterValue': - value = core.BNGetLowLevelILStackContentsAtInstruction(self._function.handle, offset, size, self._instr_index) - result = variable.RegisterValue.from_BNRegisterValue(value, self._function.arch) - return result + @property + def top(self): + return self.get_expr(2) - def get_stack_contents_after(self, offset:int, size:int) -> 'variable.RegisterValue': - value = core.BNGetLowLevelILStackContentsAfterInstruction(self._function.handle, offset, size, self._instr_index) - result = variable.RegisterValue.from_BNRegisterValue(value, self._function.arch) - return result + @property + def src(self): + return self.get_expr(3) - def get_possible_stack_contents(self, offset:int, size:int, options:List[DataFlowQueryOption]=[]) -> variable.PossibleValueSet: - option_array = (ctypes.c_int * len(options))() - idx = 0 - for option in options: - option_array[idx] = option - idx += 1 - value = core.BNGetLowLevelILPossibleStackContentsAtInstruction(self._function.handle, offset, size, self._instr_index, - option_array, len(options)) - result = variable.PossibleValueSet(self._function.arch, value) - core.BNFreePossibleValueSet(value) - return result - def get_possible_stack_contents_after(self, offset:int, size:int, options:List[DataFlowQueryOption]=[]) -> variable.PossibleValueSet: - option_array = (ctypes.c_int * len(options))() - idx = 0 - for option in options: - option_array[idx] = option - idx += 1 - value = core.BNGetLowLevelILPossibleStackContentsAfterInstruction(self._function.handle, offset, size, self._instr_index, - option_array, len(options)) - result = variable.PossibleValueSet(self._function.arch, value) - core.BNFreePossibleValueSet(value) - return result +@dataclass(frozen=True, repr=False) +class LowLevelILCall_ssa(Call, SSA): + operand_names = tuple(["output", "dest", "stack", "param"]) @property - def function(self) -> 'LowLevelILFunction': - return self._function + def output(self): + return self.get_expr(0) @property - def expr_index(self) -> ExpressionIndex: - return self._expr_index + def dest(self): + return self.get_expr(1) @property - def instr_index(self) -> Optional[InstructionIndex]: - return self._instr_index + def stack(self): + return self.get_expr(2) @property - def operation(self) -> LowLevelILOperation: - return self._operation + def param(self): + return self.get_expr(3) - @property - def size(self) -> int: - return self._size + +@dataclass(frozen=True, repr=False) +class LowLevelILTailcall_ssa(Call, SSA, Terminal): + operand_names = tuple(["output", "dest", "stack", "param"]) @property - def address(self) -> int: - return self._address + def output(self): + return self.get_expr(0) @property - def source_operand(self) -> Optional[ExpressionIndex]: - return self._source_operand + def dest(self): + return self.get_expr(1) @property - def flags(self) -> Optional[str]: - return self._flags + def stack(self): + return self.get_expr(2) @property - def operands(self) -> List[Any]: - return self._operands + def param(self): + return self.get_expr(3) -@dataclass(frozen=True) -class LowLevelILExpr: - """ - ``class LowLevelILExpr`` hold the index of IL Expressions. +@dataclass(frozen=True, repr=False) +class LowLevelILStore_ssa(Store, SSA): + operand_names = tuple(["dest", "dest_memory", "src_memory", "src"]) - .. note:: This class shouldn't be instantiated directly. Rather the helper members of LowLevelILFunction should be \ - used instead. - """ - index:ExpressionIndex + @property + def dest(self): + return self.get_expr(0) - def __int__(self) -> int: - return self.index + @property + def dest_memory(self): + return self.get_int(1) + + @property + def src_memory(self): + return self.get_int(2) + + @property + def src(self): + return self.get_expr(3) + + + + + +ILInstruction:Mapping[LowLevelILOperation, LowLevelILInstruction] = { # type: ignore + LowLevelILOperation.LLIL_NOP: LowLevelILNop, # [], + LowLevelILOperation.LLIL_SET_REG: LowLevelILSet_reg, # [("dest", "reg"), ("src", "expr")], + LowLevelILOperation.LLIL_SET_REG_SPLIT: LowLevelILSet_reg_split, # [("hi", "reg"), ("lo", "reg"), ("src", "expr")], + LowLevelILOperation.LLIL_SET_REG_STACK_REL: LowLevelILSet_reg_stack_rel, # [("stack", "reg_stack"), ("dest", "expr"), ("src", "expr")], + LowLevelILOperation.LLIL_REG_STACK_PUSH: LowLevelILReg_stack_push, # [("stack", "reg_stack"), ("src", "expr")], + LowLevelILOperation.LLIL_SET_FLAG: LowLevelILSet_flag, # [("dest", "flag"), ("src", "expr")], + LowLevelILOperation.LLIL_LOAD: LowLevelILLoad, # [("src", "expr")], + LowLevelILOperation.LLIL_STORE: LowLevelILStore, # [("dest", "expr"), ("src", "expr")], + LowLevelILOperation.LLIL_PUSH: LowLevelILPush, # [("src", "expr")], + LowLevelILOperation.LLIL_POP: LowLevelILPop, # [], + LowLevelILOperation.LLIL_REG: LowLevelILReg, # [("src", "reg")], + LowLevelILOperation.LLIL_REG_SPLIT: LowLevelILReg_split, # [("hi", "reg"), ("lo", "reg")], + LowLevelILOperation.LLIL_REG_STACK_REL: LowLevelILReg_stack_rel, # [("stack", "reg_stack"), ("src", "expr")], + LowLevelILOperation.LLIL_REG_STACK_POP: LowLevelILReg_stack_pop, # [("stack", "reg_stack")], + LowLevelILOperation.LLIL_REG_STACK_FREE_REG: LowLevelILReg_stack_free_reg, # [("dest", "reg")], + LowLevelILOperation.LLIL_REG_STACK_FREE_REL: LowLevelILReg_stack_free_rel, # [("stack", "reg_stack"), ("dest", "expr")], + LowLevelILOperation.LLIL_CONST: LowLevelILConst, # [("constant", "int")], + LowLevelILOperation.LLIL_CONST_PTR: LowLevelILConst_ptr, # [("constant", "int")], + LowLevelILOperation.LLIL_EXTERN_PTR: LowLevelILExtern_ptr, # [("constant", "int"), ("offset", "int")], + LowLevelILOperation.LLIL_FLOAT_CONST: LowLevelILFloat_const, # [("constant", "float")], + LowLevelILOperation.LLIL_FLAG: LowLevelILFlag, # [("src", "flag")], + LowLevelILOperation.LLIL_FLAG_BIT: LowLevelILFlag_bit, # [("src", "flag"), ("bit", "int")], + LowLevelILOperation.LLIL_ADD: LowLevelILAdd, # [("left", "expr"), ("right", "expr")], + LowLevelILOperation.LLIL_ADC: LowLevelILAdc, # [("left", "expr"), ("right", "expr"), ("carry", "expr")], + LowLevelILOperation.LLIL_SUB: LowLevelILSub, # [("left", "expr"), ("right", "expr")], + LowLevelILOperation.LLIL_SBB: LowLevelILSbb, # [("left", "expr"), ("right", "expr"), ("carry", "expr")], + LowLevelILOperation.LLIL_AND: LowLevelILAnd, # [("left", "expr"), ("right", "expr")], + LowLevelILOperation.LLIL_OR: LowLevelILOr, # [("left", "expr"), ("right", "expr")], + LowLevelILOperation.LLIL_XOR: LowLevelILXor, # [("left", "expr"), ("right", "expr")], + LowLevelILOperation.LLIL_LSL: LowLevelILLsl, # [("left", "expr"), ("right", "expr")], + LowLevelILOperation.LLIL_LSR: LowLevelILLsr, # [("left", "expr"), ("right", "expr")], + LowLevelILOperation.LLIL_ASR: LowLevelILAsr, # [("left", "expr"), ("right", "expr")], + LowLevelILOperation.LLIL_ROL: LowLevelILRol, # [("left", "expr"), ("right", "expr")], + LowLevelILOperation.LLIL_RLC: LowLevelILRlc, # [("left", "expr"), ("right", "expr"), ("carry", "expr")], + LowLevelILOperation.LLIL_ROR: LowLevelILRor, # [("left", "expr"), ("right", "expr")], + LowLevelILOperation.LLIL_RRC: LowLevelILRrc, # [("left", "expr"), ("right", "expr"), ("carry", "expr")], + LowLevelILOperation.LLIL_MUL: LowLevelILMul, # [("left", "expr"), ("right", "expr")], + LowLevelILOperation.LLIL_MULU_DP: LowLevelILMulu_dp, # [("left", "expr"), ("right", "expr")], + LowLevelILOperation.LLIL_MULS_DP: LowLevelILMuls_dp, # [("left", "expr"), ("right", "expr")], + LowLevelILOperation.LLIL_DIVU: LowLevelILDivu, # [("left", "expr"), ("right", "expr")], + LowLevelILOperation.LLIL_DIVU_DP: LowLevelILDivu_dp, # [("left", "expr"), ("right", "expr")], + LowLevelILOperation.LLIL_DIVS: LowLevelILDivs, # [("left", "expr"), ("right", "expr")], + LowLevelILOperation.LLIL_DIVS_DP: LowLevelILDivs_dp, # [("left", "expr"), ("right", "expr")], + LowLevelILOperation.LLIL_MODU: LowLevelILModu, # [("left", "expr"), ("right", "expr")], + LowLevelILOperation.LLIL_MODU_DP: LowLevelILModu_dp, # [("left", "expr"), ("right", "expr")], + LowLevelILOperation.LLIL_MODS: LowLevelILMods, # [("left", "expr"), ("right", "expr")], + LowLevelILOperation.LLIL_MODS_DP: LowLevelILMods_dp, # [("left", "expr"), ("right", "expr")], + LowLevelILOperation.LLIL_NEG: LowLevelILNeg, # [("src", "expr")], + LowLevelILOperation.LLIL_NOT: LowLevelILNot, # [("src", "expr")], + LowLevelILOperation.LLIL_SX: LowLevelILSx, # [("src", "expr")], + LowLevelILOperation.LLIL_ZX: LowLevelILZx, # [("src", "expr")], + LowLevelILOperation.LLIL_LOW_PART: LowLevelILLow_part, # [("src", "expr")], + LowLevelILOperation.LLIL_JUMP: LowLevelILJump, # [("dest", "expr")], + LowLevelILOperation.LLIL_JUMP_TO: LowLevelILJump_to, # [("dest", "expr"), ("targets", "target_map")], + LowLevelILOperation.LLIL_CALL: LowLevelILCall, # [("dest", "expr")], + LowLevelILOperation.LLIL_CALL_STACK_ADJUST: LowLevelILCall_stack_adjust, # [("dest", "expr"), ("stack_adjustment", "int"), ("reg_stack_adjustments", "reg_stack_adjust")], + LowLevelILOperation.LLIL_TAILCALL: LowLevelILTailcall, # [("dest", "expr")], + LowLevelILOperation.LLIL_RET: LowLevelILRet, # [("dest", "expr")], + LowLevelILOperation.LLIL_NORET: LowLevelILNoret, # [], + LowLevelILOperation.LLIL_IF: LowLevelILIf, # [("condition", "expr"), ("true", "int"), ("false", "int")], + LowLevelILOperation.LLIL_GOTO: LowLevelILGoto, # [("dest", "int")], + LowLevelILOperation.LLIL_FLAG_COND: LowLevelILFlag_cond, # [("condition", "cond"), ("semantic_class", "sem_class")], + LowLevelILOperation.LLIL_FLAG_GROUP: LowLevelILFlag_group, # [("semantic_group", "sem_group")], + LowLevelILOperation.LLIL_CMP_E: LowLevelILCmp_e, # [("left", "expr"), ("right", "expr")], + LowLevelILOperation.LLIL_CMP_NE: LowLevelILCmp_ne, # [("left", "expr"), ("right", "expr")], + LowLevelILOperation.LLIL_CMP_SLT: LowLevelILCmp_slt, # [("left", "expr"), ("right", "expr")], + LowLevelILOperation.LLIL_CMP_ULT: LowLevelILCmp_ult, # [("left", "expr"), ("right", "expr")], + LowLevelILOperation.LLIL_CMP_SLE: LowLevelILCmp_sle, # [("left", "expr"), ("right", "expr")], + LowLevelILOperation.LLIL_CMP_ULE: LowLevelILCmp_ule, # [("left", "expr"), ("right", "expr")], + LowLevelILOperation.LLIL_CMP_SGE: LowLevelILCmp_sge, # [("left", "expr"), ("right", "expr")], + LowLevelILOperation.LLIL_CMP_UGE: LowLevelILCmp_uge, # [("left", "expr"), ("right", "expr")], + LowLevelILOperation.LLIL_CMP_SGT: LowLevelILCmp_sgt, # [("left", "expr"), ("right", "expr")], + LowLevelILOperation.LLIL_CMP_UGT: LowLevelILCmp_ugt, # [("left", "expr"), ("right", "expr")], + LowLevelILOperation.LLIL_TEST_BIT: LowLevelILTest_bit, # [("left", "expr"), ("right", "expr")], + LowLevelILOperation.LLIL_BOOL_TO_INT: LowLevelILBool_to_int, # [("src", "expr")], + LowLevelILOperation.LLIL_ADD_OVERFLOW: LowLevelILAdd_overflow, # [("left", "expr"), ("right", "expr")], + LowLevelILOperation.LLIL_SYSCALL: LowLevelILSyscall, # [], + LowLevelILOperation.LLIL_INTRINSIC: LowLevelILIntrinsic, # [("output", "reg_or_flag_list"), ("intrinsic", "intrinsic"), ("param", "expr")], + LowLevelILOperation.LLIL_INTRINSIC_SSA: LowLevelILIntrinsic_ssa, # [("output", "reg_or_flag_ssa_list"), ("intrinsic", "intrinsic"), ("param", "expr")], + LowLevelILOperation.LLIL_BP: LowLevelILBp, # [], + LowLevelILOperation.LLIL_TRAP: LowLevelILTrap, # [("vector", "int")], + LowLevelILOperation.LLIL_UNDEF: LowLevelILUndef, # [], + LowLevelILOperation.LLIL_UNIMPL: LowLevelILUnimpl, # [], + LowLevelILOperation.LLIL_UNIMPL_MEM: LowLevelILUnimpl_mem, # [("src", "expr")], + LowLevelILOperation.LLIL_FADD: LowLevelILFadd, # [("left", "expr"), ("right", "expr")], + LowLevelILOperation.LLIL_FSUB: LowLevelILFsub, # [("left", "expr"), ("right", "expr")], + LowLevelILOperation.LLIL_FMUL: LowLevelILFmul, # [("left", "expr"), ("right", "expr")], + LowLevelILOperation.LLIL_FDIV: LowLevelILFdiv, # [("left", "expr"), ("right", "expr")], + LowLevelILOperation.LLIL_FSQRT: LowLevelILFsqrt, # [("src", "expr")], + LowLevelILOperation.LLIL_FNEG: LowLevelILFneg, # [("src", "expr")], + LowLevelILOperation.LLIL_FABS: LowLevelILFabs, # [("src", "expr")], + LowLevelILOperation.LLIL_FLOAT_TO_INT: LowLevelILFloat_to_int, # [("src", "expr")], + LowLevelILOperation.LLIL_INT_TO_FLOAT: LowLevelILInt_to_float, # [("src", "expr")], + LowLevelILOperation.LLIL_FLOAT_CONV: LowLevelILFloat_conv, # [("src", "expr")], + LowLevelILOperation.LLIL_ROUND_TO_INT: LowLevelILRound_to_int, # [("src", "expr")], + LowLevelILOperation.LLIL_FLOOR: LowLevelILFloor, # [("src", "expr")], + LowLevelILOperation.LLIL_CEIL: LowLevelILCeil, # [("src", "expr")], + LowLevelILOperation.LLIL_FTRUNC: LowLevelILFtrunc, # [("src", "expr")], + LowLevelILOperation.LLIL_FCMP_E: LowLevelILFcmp_e, # [("left", "expr"), ("right", "expr")], + LowLevelILOperation.LLIL_FCMP_NE: LowLevelILFcmp_ne, # [("left", "expr"), ("right", "expr")], + LowLevelILOperation.LLIL_FCMP_LT: LowLevelILFcmp_lt, # [("left", "expr"), ("right", "expr")], + LowLevelILOperation.LLIL_FCMP_LE: LowLevelILFcmp_le, # [("left", "expr"), ("right", "expr")], + LowLevelILOperation.LLIL_FCMP_GE: LowLevelILFcmp_ge, # [("left", "expr"), ("right", "expr")], + LowLevelILOperation.LLIL_FCMP_GT: LowLevelILFcmp_gt, # [("left", "expr"), ("right", "expr")], + LowLevelILOperation.LLIL_FCMP_O: LowLevelILFcmp_o, # [("left", "expr"), ("right", "expr")], + LowLevelILOperation.LLIL_FCMP_UO: LowLevelILFcmp_uo, # [("left", "expr"), ("right", "expr")], + LowLevelILOperation.LLIL_SET_REG_SSA: LowLevelILSet_reg_ssa, # [("dest", "reg_ssa"), ("src", "expr")], + LowLevelILOperation.LLIL_SET_REG_SSA_PARTIAL: LowLevelILSet_reg_ssa_partial, # [("full_reg", "reg_ssa"), ("dest", "reg"), ("src", "expr")], + LowLevelILOperation.LLIL_SET_REG_SPLIT_SSA: LowLevelILSet_reg_split_ssa, # [("hi", "expr"), ("lo", "expr"), ("src", "expr")], + LowLevelILOperation.LLIL_SET_REG_STACK_REL_SSA: LowLevelILSet_reg_stack_rel_ssa, # [("stack", "expr"), ("dest", "expr"), ("top", "expr"), ("src", "expr")], + LowLevelILOperation.LLIL_SET_REG_STACK_ABS_SSA: LowLevelILSet_reg_stack_abs_ssa, # [("stack", "expr"), ("dest", "reg"), ("src", "expr")], + LowLevelILOperation.LLIL_REG_SPLIT_DEST_SSA: LowLevelILReg_split_dest_ssa, # [("dest", "reg_ssa")], + LowLevelILOperation.LLIL_REG_STACK_DEST_SSA: LowLevelILReg_stack_dest_ssa, # [("src", "reg_stack_ssa_dest_and_src")], + LowLevelILOperation.LLIL_REG_SSA: LowLevelILReg_ssa, # [("src", "reg_ssa")], + LowLevelILOperation.LLIL_REG_SSA_PARTIAL: LowLevelILReg_ssa_partial, # [("full_reg", "reg_ssa"), ("src", "reg")], + LowLevelILOperation.LLIL_REG_SPLIT_SSA: LowLevelILReg_split_ssa, # [("hi", "reg_ssa"), ("lo", "reg_ssa")], + LowLevelILOperation.LLIL_REG_STACK_REL_SSA: LowLevelILReg_stack_rel_ssa, # [("stack", "reg_stack_ssa"), ("src", "expr"), ("top", "expr")], + LowLevelILOperation.LLIL_REG_STACK_ABS_SSA: LowLevelILReg_stack_abs_ssa, # [("stack", "reg_stack_ssa"), ("src", "reg")], + LowLevelILOperation.LLIL_REG_STACK_FREE_REL_SSA: LowLevelILReg_stack_free_rel_ssa, # [("stack", "expr"), ("dest", "expr"), ("top", "expr")], + LowLevelILOperation.LLIL_REG_STACK_FREE_ABS_SSA: LowLevelILReg_stack_free_abs_ssa, # [("stack", "expr"), ("dest", "reg")], + LowLevelILOperation.LLIL_SET_FLAG_SSA: LowLevelILSet_flag_ssa, # [("dest", "flag_ssa"), ("src", "expr")], + LowLevelILOperation.LLIL_FLAG_SSA: LowLevelILFlag_ssa, # [("src", "flag_ssa")], + LowLevelILOperation.LLIL_FLAG_BIT_SSA: LowLevelILFlag_bit_ssa, # [("src", "flag_ssa"), ("bit", "int")], + LowLevelILOperation.LLIL_CALL_SSA: LowLevelILCall_ssa, # [("output", "expr"), ("dest", "expr"), ("stack", "expr"), ("param", "expr")], + LowLevelILOperation.LLIL_SYSCALL_SSA: LowLevelILSyscall_ssa, # [("output", "expr"), ("stack", "expr"), ("param", "expr")], + LowLevelILOperation.LLIL_TAILCALL_SSA: LowLevelILTailcall_ssa, # [("output", "expr"), ("dest", "expr"), ("stack", "expr"), ("param", "expr")], + LowLevelILOperation.LLIL_CALL_OUTPUT_SSA: LowLevelILCall_output_ssa, # [("dest_memory", "int"), ("dest", "reg_ssa_list")], + LowLevelILOperation.LLIL_CALL_STACK_SSA: LowLevelILCall_stack_ssa, # [("src", "reg_ssa"), ("src_memory", "int")], + LowLevelILOperation.LLIL_CALL_PARAM: LowLevelILCall_param, # [("src", "expr_list")], + LowLevelILOperation.LLIL_LOAD_SSA: LowLevelILLoad_ssa, # [("src", "expr"), ("src_memory", "int")], + LowLevelILOperation.LLIL_STORE_SSA: LowLevelILStore_ssa, # [("dest", "expr"), ("dest_memory", "int"), ("src_memory", "int"), ("src", "expr")], + LowLevelILOperation.LLIL_REG_PHI: LowLevelILReg_phi, # [("dest", "reg_ssa"), ("src", "reg_ssa_list")], + LowLevelILOperation.LLIL_REG_STACK_PHI: LowLevelILReg_stack_phi, # [("dest", "reg_stack_ssa"), ("src", "reg_stack_ssa_list")], + LowLevelILOperation.LLIL_FLAG_PHI: LowLevelILFlag_phi, # [("dest", "flag_ssa"), ("src", "flag_ssa_list")], + LowLevelILOperation.LLIL_MEM_PHI: LowLevelILMem_phi, # [("dest_memory", "int"), ("src_memory", "int_list")] +} class LowLevelILFunction: """ - ``class LowLevelILFunction`` contains the list of LowLevelILExpr objects that make up a function. LowLevelILExpr + ``class LowLevelILFunction`` contains the list of ExpressionIndex objects that make up a function. ExpressionIndex objects can be added to the LowLevelILFunction by calling :func:`append` and passing the result of the various class - methods which return LowLevelILExpr objects. + methods which return ExpressionIndex objects. LowLevelILFlagCondition values used as parameters in the :func:`flag_condition` method. @@ -1011,12 +2449,10 @@ class LowLevelILFunction: core.BNFreeLowLevelILFunction(self.handle) def __repr__(self): - source_function = getattr(self, "source_function", None) - arch = getattr(source_function, "arch", None) - if arch and source_function: - return "" % (arch.name, self.__dict__['source_function'].start) - elif source_function: - return "" % self.__dict__['source_function'].start + if self.source_function is not None and self.source_function.arch is not None: + return f"" + elif self.source_function is not None: + return f"" else: return "" @@ -1042,16 +2478,11 @@ class LowLevelILFunction: def __getitem__(self, i): if isinstance(i, slice) or isinstance(i, tuple): raise IndexError("expected integer instruction index") - if isinstance(i, LowLevelILExpr): - return LowLevelILInstruction(self, i.index) - # for backwards compatibility - if isinstance(i, LowLevelILInstruction): - return i if i < -len(self) or i >= len(self): raise IndexError("index out of range") if i < 0: i = len(self) + i - return LowLevelILInstruction(self, core.BNGetLowLevelILIndexForInstruction(self.handle, i), i) + return LowLevelILInstruction.create(self, core.BNGetLowLevelILIndexForInstruction(self.handle, i), i) def __setitem__(self, i, j): raise IndexError("instruction modification not implemented") @@ -1341,68 +2772,68 @@ class LowLevelILFunction: _flags = architecture.FlagIndex(0) else: assert False, "flags type unsupported" - return LowLevelILExpr(core.BNLowLevelILAddExpr(self.handle, operation, size, _flags, a, b, c, d)) + return ExpressionIndex(core.BNLowLevelILAddExpr(self.handle, operation, size, _flags, a, b, c, d)) def replace_expr(self, original:InstructionOrExpression, new:InstructionOrExpression) -> None: """ - ``replace_expr`` allows modification of LowLevelILExpressions but ONLY during lifting. + ``replace_expr`` allows modification of ExpressionIndexessions but ONLY during lifting. .. warning:: This function should ONLY be called as a part of a lifter. It will otherwise not do anything useful as there's no way to trigger re-analysis of IL levels at this time. - :param LowLevelILExpr original: the LowLevelILExpr to replace (may also be an expression index) - :param LowLevelILExpr new: the LowLevelILExpr to add to the current LowLevelILFunction (may also be an expression index) + :param ExpressionIndex original: the ExpressionIndex to replace (may also be an expression index) + :param ExpressionIndex new: the ExpressionIndex to add to the current LowLevelILFunction (may also be an expression index) :rtype: None """ if isinstance(original, LowLevelILInstruction): original = original.expr_index - elif isinstance(original, LowLevelILExpr): - original = original.index + elif isinstance(original, ExpressionIndex): + original = original if isinstance(new, LowLevelILInstruction): new = new.expr_index - elif isinstance(new, LowLevelILExpr): - new = new.index + elif isinstance(new, ExpressionIndex): + new = new core.BNReplaceLowLevelILExpr(self.handle, original, new) - def append(self, expr:LowLevelILExpr) -> int: + def append(self, expr:ExpressionIndex) -> int: """ - ``append`` adds the LowLevelILExpr ``expr`` to the current LowLevelILFunction. + ``append`` adds the ExpressionIndex ``expr`` to the current LowLevelILFunction. - :param LowLevelILExpr expr: the LowLevelILExpr to add to the current LowLevelILFunction - :return: number of LowLevelILExpr in the current function + :param ExpressionIndex expr: the ExpressionIndex to add to the current LowLevelILFunction + :return: number of ExpressionIndex in the current function :rtype: int """ - return core.BNLowLevelILAddInstruction(self.handle, expr.index) + return core.BNLowLevelILAddInstruction(self.handle, expr) - def nop(self) -> LowLevelILExpr: + def nop(self) -> ExpressionIndex: """ ``nop`` no operation, this instruction does nothing :return: The no operation expression - :rtype: LowLevelILExpr + :rtype: ExpressionIndex """ return self.expr(LowLevelILOperation.LLIL_NOP) - def set_reg(self, size:int, reg:'architecture.RegisterType', value:LowLevelILExpr, - flags:Optional['architecture.FlagType']=None) -> LowLevelILExpr: + def set_reg(self, size:int, reg:'architecture.RegisterType', value:ExpressionIndex, + flags:Optional['architecture.FlagType']=None) -> ExpressionIndex: """ ``set_reg`` sets the register ``reg`` of size ``size`` to the expression ``value`` :param int size: size of the register parameter in bytes :param str reg: the register name - :param LowLevelILExpr value: an expression to set the register to + :param ExpressionIndex value: an expression to set the register to :param str flags: which flags are set by this operation :return: The expression ``reg = value`` - :rtype: LowLevelILExpr + :rtype: ExpressionIndex """ _reg = ExpressionIndex(self.arch.get_reg_index(reg)) if flags is None: flags = architecture.FlagIndex(0) - return self.expr(LowLevelILOperation.LLIL_SET_REG, _reg, value.index, size = size, flags = flags) + return self.expr(LowLevelILOperation.LLIL_SET_REG, _reg, value, size = size, flags = flags) def set_reg_split(self, size:int, hi:'architecture.RegisterType', lo:'architecture.RegisterType', - value:LowLevelILExpr, flags:'architecture.FlagType'=None) -> LowLevelILExpr: + value:ExpressionIndex, flags:'architecture.FlagType'=None) -> ExpressionIndex: """ ``set_reg_split`` uses ``hi`` and ``lo`` as a single extended register setting ``hi:lo`` to the expression ``value``. @@ -1410,125 +2841,125 @@ class LowLevelILFunction: :param int size: size of the register parameter in bytes :param str hi: the high register name :param str lo: the low register name - :param LowLevelILExpr value: an expression to set the split registers to + :param ExpressionIndex value: an expression to set the split registers to :param str flags: which flags are set by this operation :return: The expression ``hi:lo = value`` - :rtype: LowLevelILExpr + :rtype: ExpressionIndex """ _hi = ExpressionIndex(self.arch.get_reg_index(hi)) _lo = ExpressionIndex(self.arch.get_reg_index(lo)) if flags is None: flags = architecture.FlagIndex(0) - return self.expr(LowLevelILOperation.LLIL_SET_REG_SPLIT, _hi, _lo, value.index, size = size, flags = flags) + return self.expr(LowLevelILOperation.LLIL_SET_REG_SPLIT, _hi, _lo, value, size = size, flags = flags) - def set_reg_stack_top_relative(self, size:int, reg_stack:'architecture.RegisterStackType', entry:LowLevelILExpr, - value:LowLevelILExpr, flags:'architecture.FlagType'=None) -> LowLevelILExpr: + def set_reg_stack_top_relative(self, size:int, reg_stack:'architecture.RegisterStackType', entry:ExpressionIndex, + value:ExpressionIndex, flags:'architecture.FlagType'=None) -> ExpressionIndex: """ ``set_reg_stack_top_relative`` sets the top-relative entry ``entry`` of size ``size`` in register stack ``reg_stack`` to the expression ``value`` :param int size: size of the register parameter in bytes :param str reg_stack: the register stack name - :param LowLevelILExpr entry: an expression for which stack entry to set - :param LowLevelILExpr value: an expression to set the entry to + :param ExpressionIndex entry: an expression for which stack entry to set + :param ExpressionIndex value: an expression to set the entry to :param str flags: which flags are set by this operation :return: The expression ``reg_stack[entry] = value`` - :rtype: LowLevelILExpr + :rtype: ExpressionIndex """ _reg_stack = ExpressionIndex(self.arch.get_reg_stack_index(reg_stack)) if flags is None: flags = architecture.FlagIndex(0) - return self.expr(LowLevelILOperation.LLIL_SET_REG_STACK_REL, _reg_stack, entry.index, value.index, + return self.expr(LowLevelILOperation.LLIL_SET_REG_STACK_REL, _reg_stack, entry, value, size = size, flags = flags) - def reg_stack_push(self, size:int, reg_stack:'architecture.RegisterStackType', value:LowLevelILExpr, - flags:'architecture.FlagType'=None) -> LowLevelILExpr: + def reg_stack_push(self, size:int, reg_stack:'architecture.RegisterStackType', value:ExpressionIndex, + flags:'architecture.FlagType'=None) -> ExpressionIndex: """ ``reg_stack_push`` pushes the expression ``value`` of size ``size`` onto the top of the register stack ``reg_stack`` :param int size: size of the register parameter in bytes :param str reg_stack: the register stack name - :param LowLevelILExpr value: an expression to push + :param ExpressionIndex value: an expression to push :param str flags: which flags are set by this operation :return: The expression ``reg_stack.push(value)`` - :rtype: LowLevelILExpr + :rtype: ExpressionIndex """ _reg_stack = ExpressionIndex(self.arch.get_reg_stack_index(reg_stack)) if flags is None: flags = architecture.FlagIndex(0) - return self.expr(LowLevelILOperation.LLIL_REG_STACK_PUSH, _reg_stack, value.index, size = size, flags = flags) + return self.expr(LowLevelILOperation.LLIL_REG_STACK_PUSH, _reg_stack, value, size = size, flags = flags) - def set_flag(self, flag:'architecture.FlagName', value:LowLevelILExpr) -> LowLevelILExpr: + def set_flag(self, flag:'architecture.FlagName', value:ExpressionIndex) -> ExpressionIndex: """ - ``set_flag`` sets the flag ``flag`` to the LowLevelILExpr ``value`` + ``set_flag`` sets the flag ``flag`` to the ExpressionIndex ``value`` :param str flag: the low register name - :param LowLevelILExpr value: an expression to set the flag to + :param ExpressionIndex value: an expression to set the flag to :return: The expression FLAG.flag = value - :rtype: LowLevelILExpr + :rtype: ExpressionIndex """ return self.expr(LowLevelILOperation.LLIL_SET_FLAG, ExpressionIndex(self.arch.get_flag_by_name(flag)), - value.index) + value) - def load(self, size:int, addr:LowLevelILExpr) -> LowLevelILExpr: + def load(self, size:int, addr:ExpressionIndex) -> ExpressionIndex: """ ``load`` Reads ``size`` bytes from the expression ``addr`` :param int size: number of bytes to read - :param LowLevelILExpr addr: the expression to read memory from + :param ExpressionIndex addr: the expression to read memory from :return: The expression ``[addr].size`` - :rtype: LowLevelILExpr + :rtype: ExpressionIndex """ - return self.expr(LowLevelILOperation.LLIL_LOAD, addr.index, size=size) + return self.expr(LowLevelILOperation.LLIL_LOAD, addr, size=size) - def store(self, size:int, addr:LowLevelILExpr, value:LowLevelILExpr, flags=None) -> LowLevelILExpr: + def store(self, size:int, addr:ExpressionIndex, value:ExpressionIndex, flags=None) -> ExpressionIndex: """ ``store`` Writes ``size`` bytes to expression ``addr`` read from expression ``value`` :param int size: number of bytes to write - :param LowLevelILExpr addr: the expression to write to - :param LowLevelILExpr value: the expression to be written + :param ExpressionIndex addr: the expression to write to + :param ExpressionIndex value: the expression to be written :param str flags: which flags are set by this operation :return: The expression ``[addr].size = value`` - :rtype: LowLevelILExpr + :rtype: ExpressionIndex """ - return self.expr(LowLevelILOperation.LLIL_STORE, addr.index, value.index, size=size, flags=flags) + return self.expr(LowLevelILOperation.LLIL_STORE, addr, value, size=size, flags=flags) - def push(self, size:int, value:LowLevelILExpr) -> LowLevelILExpr: + def push(self, size:int, value:ExpressionIndex) -> ExpressionIndex: """ ``push`` writes ``size`` bytes from expression ``value`` to the stack, adjusting the stack by ``size``. :param int size: number of bytes to write and adjust the stack by - :param LowLevelILExpr value: the expression to write + :param ExpressionIndex value: the expression to write :return: The expression push(value) - :rtype: LowLevelILExpr + :rtype: ExpressionIndex """ - return self.expr(LowLevelILOperation.LLIL_PUSH, value.index, size=size) + return self.expr(LowLevelILOperation.LLIL_PUSH, value, size=size) - def pop(self, size:int) -> LowLevelILExpr: + def pop(self, size:int) -> ExpressionIndex: """ ``pop`` reads ``size`` bytes from the stack, adjusting the stack by ``size``. :param int size: number of bytes to read from the stack :return: The expression ``pop`` - :rtype: LowLevelILExpr + :rtype: ExpressionIndex """ return self.expr(LowLevelILOperation.LLIL_POP, size=size) - def reg(self, size:int, reg:'architecture.RegisterType') -> LowLevelILExpr: + def reg(self, size:int, reg:'architecture.RegisterType') -> ExpressionIndex: """ ``reg`` returns a register of size ``size`` with name ``reg`` :param int size: the size of the register in bytes :param str reg: the name of the register :return: A register expression for the given string - :rtype: LowLevelILExpr + :rtype: ExpressionIndex """ _reg = ExpressionIndex(self.arch.get_reg_index(reg)) return self.expr(LowLevelILOperation.LLIL_REG, _reg, size=size) - def reg_split(self, size:int, hi:'architecture.RegisterType', lo:'architecture.RegisterType') -> LowLevelILExpr: + def reg_split(self, size:int, hi:'architecture.RegisterType', lo:'architecture.RegisterType') -> ExpressionIndex: """ ``reg_split`` combines registers of size ``size`` with names ``hi`` and ``lo`` @@ -1536,27 +2967,27 @@ class LowLevelILFunction: :param str hi: register holding high part of value :param str lo: register holding low part of value :return: The expression ``hi:lo`` - :rtype: LowLevelILExpr + :rtype: ExpressionIndex """ _hi = ExpressionIndex(self.arch.get_reg_index(hi)) _lo = ExpressionIndex(self.arch.get_reg_index(lo)) return self.expr(LowLevelILOperation.LLIL_REG_SPLIT, _hi, _lo, size=size) - def reg_stack_top_relative(self, size:int, reg_stack:'architecture.RegisterStackType', entry:LowLevelILExpr) -> LowLevelILExpr: + def reg_stack_top_relative(self, size:int, reg_stack:'architecture.RegisterStackType', entry:ExpressionIndex) -> ExpressionIndex: """ ``reg_stack_top_relative`` returns a register stack entry of size ``size`` at top-relative location ``entry`` in register stack with name ``reg_stack`` :param int size: the size of the register in bytes :param str reg_stack: the name of the register stack - :param LowLevelILExpr entry: an expression for which stack entry to fetch + :param ExpressionIndex entry: an expression for which stack entry to fetch :return: The expression ``reg_stack[entry]`` - :rtype: LowLevelILExpr + :rtype: ExpressionIndex """ _reg_stack = self.arch.get_reg_stack_index(reg_stack) - return self.expr(LowLevelILOperation.LLIL_REG_STACK_REL, _reg_stack, entry.index, size=size) + return self.expr(LowLevelILOperation.LLIL_REG_STACK_REL, _reg_stack, entry, size=size) - def reg_stack_pop(self, size:int, reg_stack:'architecture.RegisterStackType') -> LowLevelILExpr: + def reg_stack_pop(self, size:int, reg_stack:'architecture.RegisterStackType') -> ExpressionIndex: """ ``reg_stack_pop`` returns the top entry of size ``size`` in register stack with name ``reg_stack``, and removes the entry from the stack @@ -1564,45 +2995,45 @@ class LowLevelILFunction: :param int size: the size of the register in bytes :param str reg_stack: the name of the register stack :return: The expression ``reg_stack.pop`` - :rtype: LowLevelILExpr + :rtype: ExpressionIndex """ _reg_stack = ExpressionIndex(self.arch.get_reg_stack_index(reg_stack)) return self.expr(LowLevelILOperation.LLIL_REG_STACK_POP, _reg_stack, size=size) - def const(self, size:int, value:int) -> LowLevelILExpr: + def const(self, size:int, value:int) -> ExpressionIndex: """ ``const`` returns an expression for the constant integer ``value`` with size ``size`` :param int size: the size of the constant in bytes :param int value: integer value of the constant :return: A constant expression of given value and size - :rtype: LowLevelILExpr + :rtype: ExpressionIndex """ return self.expr(LowLevelILOperation.LLIL_CONST, ExpressionIndex(value), size=size) - def const_pointer(self, size:int, value:int) -> LowLevelILExpr: + def const_pointer(self, size:int, value:int) -> ExpressionIndex: """ ``const_pointer`` returns an expression for the constant pointer ``value`` with size ``size`` :param int size: the size of the pointer in bytes :param int value: address referenced by pointer :return: A constant expression of given value and size - :rtype: LowLevelILExpr + :rtype: ExpressionIndex """ return self.expr(LowLevelILOperation.LLIL_CONST_PTR, value, size=size) - def reloc_pointer(self, size:int, value:int) -> LowLevelILExpr: + def reloc_pointer(self, size:int, value:int) -> ExpressionIndex: """ ``reloc_pointer`` returns an expression for the constant relocated pointer ``value`` with size ``size`` :param int size: the size of the pointer in bytes :param int value: address referenced by pointer :return: A constant expression of given value and size - :rtype: LowLevelILExpr + :rtype: ExpressionIndex """ return self.expr(LowLevelILOperation.LLIL_EXTERN_PTR, value, size=size) - def float_const_raw(self, size:int, value:int) -> LowLevelILExpr: + def float_const_raw(self, size:int, value:int) -> ExpressionIndex: """ ``float_const_raw`` returns an expression for the constant raw binary floating point value ``value`` with size ``size`` @@ -1610,41 +3041,41 @@ class LowLevelILFunction: :param int size: the size of the constant in bytes :param int value: integer value for the raw binary representation of the constant :return: A constant expression of given value and size - :rtype: LowLevelILExpr + :rtype: ExpressionIndex """ return self.expr(LowLevelILOperation.LLIL_FLOAT_CONST, value, size=size) - def float_const_single(self, value:float) -> LowLevelILExpr: + def float_const_single(self, value:float) -> ExpressionIndex: """ ``float_const_single`` returns an expression for the single precision floating point value ``value`` :param float value: float value for the constant :return: A constant expression of given value and size - :rtype: LowLevelILExpr + :rtype: ExpressionIndex """ return self.expr(LowLevelILOperation.LLIL_FLOAT_CONST, struct.unpack("I", struct.pack("f", value))[0], size=4) - def float_const_double(self, value:float) -> LowLevelILExpr: + def float_const_double(self, value:float) -> ExpressionIndex: """ ``float_const_double`` returns an expression for the double precision floating point value ``value`` :param float value: float value for the constant :return: A constant expression of given value and size - :rtype: LowLevelILExpr + :rtype: ExpressionIndex """ return self.expr(LowLevelILOperation.LLIL_FLOAT_CONST, struct.unpack("Q", struct.pack("d", value))[0], size=8) - def flag(self, reg:'architecture.FlagName') -> LowLevelILExpr: + def flag(self, reg:'architecture.FlagName') -> ExpressionIndex: """ ``flag`` returns a flag expression for the given flag name. :param architecture.FlagName reg: name of the flag expression to retrieve :return: A flag expression of given flag name - :rtype: LowLevelILExpr + :rtype: ExpressionIndex """ return self.expr(LowLevelILOperation.LLIL_FLAG, self.arch.get_flag_by_name(reg)) - def flag_bit(self, size:int, reg:'architecture.FlagName', bit:int) -> LowLevelILExpr: + def flag_bit(self, size:int, reg:'architecture.FlagName', bit:int) -> ExpressionIndex: """ ``flag_bit`` sets the flag named ``reg`` and size ``size`` to the constant integer value ``bit`` @@ -1652,502 +3083,502 @@ class LowLevelILFunction: :param str reg: flag value :param int bit: integer value to set the bit to :return: A constant expression of given value and size ``FLAG.reg = bit`` - :rtype: LowLevelILExpr + :rtype: ExpressionIndex """ return self.expr(LowLevelILOperation.LLIL_FLAG_BIT, self.arch.get_flag_by_name(reg), bit, size=size) - def add(self, size:int, a:LowLevelILExpr, b:LowLevelILExpr, flags:'architecture.FlagType'=None) -> LowLevelILExpr: + def add(self, size:int, a:ExpressionIndex, b:ExpressionIndex, flags:'architecture.FlagType'=None) -> ExpressionIndex: """ ``add`` adds expression ``a`` to expression ``b`` potentially setting flags ``flags`` and returning an expression of ``size`` bytes. :param int size: the size of the result in bytes - :param LowLevelILExpr a: LHS expression - :param LowLevelILExpr b: RHS expression + :param ExpressionIndex a: LHS expression + :param ExpressionIndex b: RHS expression :param str flags: flags to set :return: The expression ``add.{}(a, b)`` - :rtype: LowLevelILExpr + :rtype: ExpressionIndex """ - return self.expr(LowLevelILOperation.LLIL_ADD, a.index, b.index, size=size, flags=flags) + return self.expr(LowLevelILOperation.LLIL_ADD, a, b, size=size, flags=flags) - def add_carry(self, size:int, a:LowLevelILExpr, b:LowLevelILExpr, carry:LowLevelILExpr, - flags:'architecture.FlagType'=None) -> LowLevelILExpr: + def add_carry(self, size:int, a:ExpressionIndex, b:ExpressionIndex, carry:ExpressionIndex, + flags:'architecture.FlagType'=None) -> ExpressionIndex: """ ``add_carry`` adds with carry expression ``a`` to expression ``b`` potentially setting flags ``flags`` and returning an expression of ``size`` bytes. :param int size: the size of the result in bytes - :param LowLevelILExpr a: LHS expression - :param LowLevelILExpr b: RHS expression - :param LowLevelILExpr carry: Carry flag expression + :param ExpressionIndex a: LHS expression + :param ExpressionIndex b: RHS expression + :param ExpressionIndex carry: Carry flag expression :param str flags: flags to set :return: The expression ``adc.{}(a, b, carry)`` - :rtype: LowLevelILExpr + :rtype: ExpressionIndex """ - return self.expr(LowLevelILOperation.LLIL_ADC, a.index, b.index, carry.index, size=size, flags=flags) + return self.expr(LowLevelILOperation.LLIL_ADC, a, b, carry, size=size, flags=flags) - def sub(self, size:int, a:LowLevelILExpr, b:LowLevelILExpr, flags:'architecture.FlagType'=None) -> LowLevelILExpr: + def sub(self, size:int, a:ExpressionIndex, b:ExpressionIndex, flags:'architecture.FlagType'=None) -> ExpressionIndex: """ ``sub`` subtracts expression ``b`` from expression ``a`` potentially setting flags ``flags`` and returning an expression of ``size`` bytes. :param int size: the size of the result in bytes - :param LowLevelILExpr a: LHS expression - :param LowLevelILExpr b: RHS expression + :param ExpressionIndex a: LHS expression + :param ExpressionIndex b: RHS expression :param str flags: flags to set :return: The expression ``sub.{}(a, b)`` - :rtype: LowLevelILExpr + :rtype: ExpressionIndex """ - return self.expr(LowLevelILOperation.LLIL_SUB, a.index, b.index, size=size, flags=flags) + return self.expr(LowLevelILOperation.LLIL_SUB, a, b, size=size, flags=flags) - def sub_borrow(self, size:int, a:LowLevelILExpr, b:LowLevelILExpr, carry:LowLevelILExpr, - flags:'architecture.FlagType'=None) -> LowLevelILExpr: + def sub_borrow(self, size:int, a:ExpressionIndex, b:ExpressionIndex, carry:ExpressionIndex, + flags:'architecture.FlagType'=None) -> ExpressionIndex: """ ``sub_borrow`` subtracts with borrow expression ``b`` from expression ``a`` potentially setting flags ``flags`` and returning an expression of ``size`` bytes. :param int size: the size of the result in bytes - :param LowLevelILExpr a: LHS expression - :param LowLevelILExpr b: RHS expression - :param LowLevelILExpr carry: Carry flag expression + :param ExpressionIndex a: LHS expression + :param ExpressionIndex b: RHS expression + :param ExpressionIndex carry: Carry flag expression :param str flags: flags to set :return: The expression ``sbb.{}(a, b, carry)`` - :rtype: LowLevelILExpr + :rtype: ExpressionIndex """ - return self.expr(LowLevelILOperation.LLIL_SBB, a.index, b.index, carry.index, size=size, flags=flags) + return self.expr(LowLevelILOperation.LLIL_SBB, a, b, carry, size=size, flags=flags) - def and_expr(self, size:int, a:LowLevelILExpr, b:LowLevelILExpr, flags:'architecture.FlagType'=None) -> LowLevelILExpr: + def and_expr(self, size:int, a:ExpressionIndex, b:ExpressionIndex, flags:'architecture.FlagType'=None) -> ExpressionIndex: """ ``and_expr`` bitwise and's expression ``a`` and expression ``b`` potentially setting flags ``flags`` and returning an expression of ``size`` bytes. :param int size: the size of the result in bytes - :param LowLevelILExpr a: LHS expression - :param LowLevelILExpr b: RHS expression + :param ExpressionIndex a: LHS expression + :param ExpressionIndex b: RHS expression :param str flags: optional, flags to set :return: The expression ``and.{}(a, b)`` - :rtype: LowLevelILExpr + :rtype: ExpressionIndex """ - return self.expr(LowLevelILOperation.LLIL_AND, a.index, b.index, size=size, flags=flags) + return self.expr(LowLevelILOperation.LLIL_AND, a, b, size=size, flags=flags) - def or_expr(self, size:int, a:LowLevelILExpr, b:LowLevelILExpr, flags:'architecture.FlagType'=None) -> LowLevelILExpr: + def or_expr(self, size:int, a:ExpressionIndex, b:ExpressionIndex, flags:'architecture.FlagType'=None) -> ExpressionIndex: """ ``or_expr`` bitwise or's expression ``a`` and expression ``b`` potentially setting flags ``flags`` and returning an expression of ``size`` bytes. :param int size: the size of the result in bytes - :param LowLevelILExpr a: LHS expression - :param LowLevelILExpr b: RHS expression + :param ExpressionIndex a: LHS expression + :param ExpressionIndex b: RHS expression :param str flags: optional, flags to set :return: The expression ``or.{}(a, b)`` - :rtype: LowLevelILExpr + :rtype: ExpressionIndex """ - return self.expr(LowLevelILOperation.LLIL_OR, a.index, b.index, size=size, flags=flags) + return self.expr(LowLevelILOperation.LLIL_OR, a, b, size=size, flags=flags) - def xor_expr(self, size:int, a:LowLevelILExpr, b:LowLevelILExpr, flags:'architecture.FlagType'=None) -> LowLevelILExpr: + def xor_expr(self, size:int, a:ExpressionIndex, b:ExpressionIndex, flags:'architecture.FlagType'=None) -> ExpressionIndex: """ ``xor_expr`` xor's expression ``a`` with expression ``b`` potentially setting flags ``flags`` and returning an expression of ``size`` bytes. :param int size: the size of the result in bytes - :param LowLevelILExpr a: LHS expression - :param LowLevelILExpr b: RHS expression + :param ExpressionIndex a: LHS expression + :param ExpressionIndex b: RHS expression :param str flags: optional, flags to set :return: The expression ``xor.{}(a, b)`` - :rtype: LowLevelILExpr + :rtype: ExpressionIndex """ - return self.expr(LowLevelILOperation.LLIL_XOR, a.index, b.index, size=size, flags=flags) + return self.expr(LowLevelILOperation.LLIL_XOR, a, b, size=size, flags=flags) - def shift_left(self, size:int, a:LowLevelILExpr, b:LowLevelILExpr, flags:'architecture.FlagType'=None) -> LowLevelILExpr: + def shift_left(self, size:int, a:ExpressionIndex, b:ExpressionIndex, flags:'architecture.FlagType'=None) -> ExpressionIndex: """ ``shift_left`` shifts left expression ``a`` by expression ``b`` from expression ``a`` potentially setting flags ``flags`` and returning an expression of ``size`` bytes. :param int size: the size of the result in bytes - :param LowLevelILExpr a: LHS expression - :param LowLevelILExpr b: RHS expression + :param ExpressionIndex a: LHS expression + :param ExpressionIndex b: RHS expression :param str flags: optional, flags to set :return: The expression ``lsl.{}(a, b)`` - :rtype: LowLevelILExpr + :rtype: ExpressionIndex """ - return self.expr(LowLevelILOperation.LLIL_LSL, a.index, b.index, size=size, flags=flags) + return self.expr(LowLevelILOperation.LLIL_LSL, a, b, size=size, flags=flags) - def logical_shift_right(self, size:int, a:LowLevelILExpr, b:LowLevelILExpr, flags:'architecture.FlagType'=None) -> LowLevelILExpr: + def logical_shift_right(self, size:int, a:ExpressionIndex, b:ExpressionIndex, flags:'architecture.FlagType'=None) -> ExpressionIndex: """ ``logical_shift_right`` shifts logically right expression ``a`` by expression ``b`` potentially setting flags ``flags`` and returning an expression of ``size`` bytes. :param int size: the size of the result in bytes - :param LowLevelILExpr a: LHS expression - :param LowLevelILExpr b: RHS expression + :param ExpressionIndex a: LHS expression + :param ExpressionIndex b: RHS expression :param str flags: optional, flags to set :return: The expression ``lsr.{}(a, b)`` - :rtype: LowLevelILExpr + :rtype: ExpressionIndex """ - return self.expr(LowLevelILOperation.LLIL_LSR, a.index, b.index, size=size, flags=flags) + return self.expr(LowLevelILOperation.LLIL_LSR, a, b, size=size, flags=flags) - def arith_shift_right(self, size:int, a:LowLevelILExpr, b:LowLevelILExpr, flags:'architecture.FlagType'=None) -> LowLevelILExpr: + def arith_shift_right(self, size:int, a:ExpressionIndex, b:ExpressionIndex, flags:'architecture.FlagType'=None) -> ExpressionIndex: """ ``arith_shift_right`` shifts arithmetic right expression ``a`` by expression ``b`` potentially setting flags ``flags`` and returning an expression of ``size`` bytes. :param int size: the size of the result in bytes - :param LowLevelILExpr a: LHS expression - :param LowLevelILExpr b: RHS expression + :param ExpressionIndex a: LHS expression + :param ExpressionIndex b: RHS expression :param str flags: optional, flags to set :return: The expression ``asr.{}(a, b)`` - :rtype: LowLevelILExpr + :rtype: ExpressionIndex """ - return self.expr(LowLevelILOperation.LLIL_ASR, a.index, b.index, size=size, flags=flags) + return self.expr(LowLevelILOperation.LLIL_ASR, a, b, size=size, flags=flags) - def rotate_left(self, size:int, a:LowLevelILExpr, b:LowLevelILExpr, flags:'architecture.FlagType'=None) -> LowLevelILExpr: + def rotate_left(self, size:int, a:ExpressionIndex, b:ExpressionIndex, flags:'architecture.FlagType'=None) -> ExpressionIndex: """ ``rotate_left`` bitwise rotates left expression ``a`` by expression ``b`` potentially setting flags ``flags`` and returning an expression of ``size`` bytes. :param int size: the size of the result in bytes - :param LowLevelILExpr a: LHS expression - :param LowLevelILExpr b: RHS expression + :param ExpressionIndex a: LHS expression + :param ExpressionIndex b: RHS expression :param str flags: optional, flags to set :return: The expression ``rol.{}(a, b)`` - :rtype: LowLevelILExpr + :rtype: ExpressionIndex """ - return self.expr(LowLevelILOperation.LLIL_ROL, a.index, b.index, size=size, flags=flags) + return self.expr(LowLevelILOperation.LLIL_ROL, a, b, size=size, flags=flags) - def rotate_left_carry(self, size:int, a:LowLevelILExpr, b:LowLevelILExpr, carry:LowLevelILExpr, - flags:'architecture.FlagType'=None) -> LowLevelILExpr: + def rotate_left_carry(self, size:int, a:ExpressionIndex, b:ExpressionIndex, carry:ExpressionIndex, + flags:'architecture.FlagType'=None) -> ExpressionIndex: """ ``rotate_left_carry`` bitwise rotates left with carry expression ``a`` by expression ``b`` potentially setting flags ``flags`` and returning an expression of ``size`` bytes. :param int size: the size of the result in bytes - :param LowLevelILExpr a: LHS expression - :param LowLevelILExpr b: RHS expression - :param LowLevelILExpr carry: Carry flag expression + :param ExpressionIndex a: LHS expression + :param ExpressionIndex b: RHS expression + :param ExpressionIndex carry: Carry flag expression :param str flags: optional, flags to set :return: The expression ``rlc.{}(a, b, carry)`` - :rtype: LowLevelILExpr + :rtype: ExpressionIndex """ - return self.expr(LowLevelILOperation.LLIL_RLC, a.index, b.index, carry.index, size=size, flags=flags) + return self.expr(LowLevelILOperation.LLIL_RLC, a, b, carry, size=size, flags=flags) - def rotate_right(self, size:int, a:LowLevelILExpr, b:LowLevelILExpr, flags:'architecture.FlagType'=None) -> LowLevelILExpr: + def rotate_right(self, size:int, a:ExpressionIndex, b:ExpressionIndex, flags:'architecture.FlagType'=None) -> ExpressionIndex: """ ``rotate_right`` bitwise rotates right expression ``a`` by expression ``b`` potentially setting flags ``flags`` and returning an expression of ``size`` bytes. :param int size: the size of the result in bytes - :param LowLevelILExpr a: LHS expression - :param LowLevelILExpr b: RHS expression + :param ExpressionIndex a: LHS expression + :param ExpressionIndex b: RHS expression :param str flags: optional, flags to set :return: The expression ``ror.{}(a, b)`` - :rtype: LowLevelILExpr + :rtype: ExpressionIndex """ - return self.expr(LowLevelILOperation.LLIL_ROR, a.index, b.index, size=size, flags=flags) + return self.expr(LowLevelILOperation.LLIL_ROR, a, b, size=size, flags=flags) - def rotate_right_carry(self, size:int, a:LowLevelILExpr, b:LowLevelILExpr, carry:LowLevelILExpr, - flags:'architecture.FlagType'=None) -> LowLevelILExpr: + def rotate_right_carry(self, size:int, a:ExpressionIndex, b:ExpressionIndex, carry:ExpressionIndex, + flags:'architecture.FlagType'=None) -> ExpressionIndex: """ ``rotate_right_carry`` bitwise rotates right with carry expression ``a`` by expression ``b`` potentially setting flags ``flags`` and returning an expression of ``size`` bytes. :param int size: the size of the result in bytes - :param LowLevelILExpr a: LHS expression - :param LowLevelILExpr b: RHS expression - :param LowLevelILExpr carry: Carry flag expression + :param ExpressionIndex a: LHS expression + :param ExpressionIndex b: RHS expression + :param ExpressionIndex carry: Carry flag expression :param str flags: optional, flags to set :return: The expression ``rrc.{}(a, b, carry)`` - :rtype: LowLevelILExpr + :rtype: ExpressionIndex """ - return self.expr(LowLevelILOperation.LLIL_RRC, a.index, b.index, carry.index, size=size, flags=flags) + return self.expr(LowLevelILOperation.LLIL_RRC, a, b, carry, size=size, flags=flags) - def mult(self, size:int, a:LowLevelILExpr, b:LowLevelILExpr, flags:'architecture.FlagType'=None) -> LowLevelILExpr: + def mult(self, size:int, a:ExpressionIndex, b:ExpressionIndex, flags:'architecture.FlagType'=None) -> ExpressionIndex: """ ``mult`` multiplies expression ``a`` by expression ``b`` potentially setting flags ``flags`` and returning an expression of ``size`` bytes. :param int size: the size of the result in bytes - :param LowLevelILExpr a: LHS expression - :param LowLevelILExpr b: RHS expression + :param ExpressionIndex a: LHS expression + :param ExpressionIndex b: RHS expression :param str flags: optional, flags to set :return: The expression ``sbc.{}(a, b)`` - :rtype: LowLevelILExpr + :rtype: ExpressionIndex """ - return self.expr(LowLevelILOperation.LLIL_MUL, a.index, b.index, size=size, flags=flags) + return self.expr(LowLevelILOperation.LLIL_MUL, a, b, size=size, flags=flags) - def mult_double_prec_signed(self, size:int, a:LowLevelILExpr, b:LowLevelILExpr, flags:'architecture.FlagType'=None) -> LowLevelILExpr: + def mult_double_prec_signed(self, size:int, a:ExpressionIndex, b:ExpressionIndex, flags:'architecture.FlagType'=None) -> ExpressionIndex: """ ``mult_double_prec_signed`` multiplies signed with double precision expression ``a`` by expression ``b`` potentially setting flags ``flags`` and returning an expression of ``size`` bytes. :param int size: the size of the result in bytes - :param LowLevelILExpr a: LHS expression - :param LowLevelILExpr b: RHS expression + :param ExpressionIndex a: LHS expression + :param ExpressionIndex b: RHS expression :param str flags: optional, flags to set :return: The expression ``muls.dp.{}(a, b)`` - :rtype: LowLevelILExpr + :rtype: ExpressionIndex """ - return self.expr(LowLevelILOperation.LLIL_MULS_DP, a.index, b.index, size=size, flags=flags) + return self.expr(LowLevelILOperation.LLIL_MULS_DP, a, b, size=size, flags=flags) - def mult_double_prec_unsigned(self, size:int, a:LowLevelILExpr, b:LowLevelILExpr, flags:'architecture.FlagType'=None) -> LowLevelILExpr: + def mult_double_prec_unsigned(self, size:int, a:ExpressionIndex, b:ExpressionIndex, flags:'architecture.FlagType'=None) -> ExpressionIndex: """ ``mult_double_prec_unsigned`` multiplies unsigned with double precision expression ``a`` by expression ``b`` potentially setting flags ``flags`` and returning an expression of ``size`` bytes. :param int size: the size of the result in bytes - :param LowLevelILExpr a: LHS expression - :param LowLevelILExpr b: RHS expression + :param ExpressionIndex a: LHS expression + :param ExpressionIndex b: RHS expression :param str flags: optional, flags to set :return: The expression ``mulu.dp.{}(a, b)`` - :rtype: LowLevelILExpr + :rtype: ExpressionIndex """ - return self.expr(LowLevelILOperation.LLIL_MULU_DP, a.index, b.index, size=size, flags=flags) + return self.expr(LowLevelILOperation.LLIL_MULU_DP, a, b, size=size, flags=flags) - def div_signed(self, size:int, a:LowLevelILExpr, b:LowLevelILExpr, flags:'architecture.FlagType'=None) -> LowLevelILExpr: + def div_signed(self, size:int, a:ExpressionIndex, b:ExpressionIndex, flags:'architecture.FlagType'=None) -> ExpressionIndex: """ ``div_signed`` signed divide expression ``a`` by expression ``b`` potentially setting flags ``flags`` and returning an expression of ``size`` bytes. :param int size: the size of the result in bytes - :param LowLevelILExpr a: LHS expression - :param LowLevelILExpr b: RHS expression + :param ExpressionIndex a: LHS expression + :param ExpressionIndex b: RHS expression :param str flags: optional, flags to set :return: The expression ``divs.{}(a, b)`` - :rtype: LowLevelILExpr + :rtype: ExpressionIndex """ - return self.expr(LowLevelILOperation.LLIL_DIVS, a.index, b.index, size=size, flags=flags) + return self.expr(LowLevelILOperation.LLIL_DIVS, a, b, size=size, flags=flags) - def div_double_prec_signed(self, size:int, a:LowLevelILExpr, b:LowLevelILExpr, flags:'architecture.FlagType'=None) -> LowLevelILExpr: + def div_double_prec_signed(self, size:int, a:ExpressionIndex, b:ExpressionIndex, flags:'architecture.FlagType'=None) -> ExpressionIndex: """ ``div_double_prec_signed`` signed double precision divide using expression ``a`` as a single double precision register by expression ``b`` potentially setting flags ``flags`` and returning an expression of ``size`` bytes. :param int size: the size of the result in bytes - :param LowLevelILExpr a: LHS expression - :param LowLevelILExpr b: RHS expression + :param ExpressionIndex a: LHS expression + :param ExpressionIndex b: RHS expression :param str flags: optional, flags to set :return: The expression ``divs.dp.{}(a, b)`` - :rtype: LowLevelILExpr + :rtype: ExpressionIndex """ - return self.expr(LowLevelILOperation.LLIL_DIVS_DP, a.index, b.index, size=size, flags=flags) + return self.expr(LowLevelILOperation.LLIL_DIVS_DP, a, b, size=size, flags=flags) - def div_unsigned(self, size:int, a:LowLevelILExpr, b:LowLevelILExpr, flags:'architecture.FlagType'=None) -> LowLevelILExpr: + def div_unsigned(self, size:int, a:ExpressionIndex, b:ExpressionIndex, flags:'architecture.FlagType'=None) -> ExpressionIndex: """ ``div_unsigned`` unsigned divide expression ``a`` by expression ``b`` potentially setting flags ``flags`` and returning an expression of ``size`` bytes. :param int size: the size of the result in bytes - :param LowLevelILExpr a: LHS expression - :param LowLevelILExpr b: RHS expression + :param ExpressionIndex a: LHS expression + :param ExpressionIndex b: RHS expression :param str flags: optional, flags to set :return: The expression ``divu.{}(a, b)`` - :rtype: LowLevelILExpr + :rtype: ExpressionIndex """ - return self.expr(LowLevelILOperation.LLIL_DIVU, a.index, b.index, size=size, flags=flags) + return self.expr(LowLevelILOperation.LLIL_DIVU, a, b, size=size, flags=flags) - def div_double_prec_unsigned(self, size:int, a:LowLevelILExpr, b:LowLevelILExpr, flags:'architecture.FlagType'=None) -> LowLevelILExpr: + def div_double_prec_unsigned(self, size:int, a:ExpressionIndex, b:ExpressionIndex, flags:'architecture.FlagType'=None) -> ExpressionIndex: """ ``div_double_prec_unsigned`` unsigned double precision divide using expression ``a`` as a single double precision register by expression ``b`` potentially setting flags ``flags`` and returning an expression of ``size`` bytes. :param int size: the size of the result in bytes - :param LowLevelILExpr a: LHS expression - :param LowLevelILExpr b: RHS expression + :param ExpressionIndex a: LHS expression + :param ExpressionIndex b: RHS expression :param str flags: optional, flags to set :return: The expression ``divu.dp.{}(a, b)`` - :rtype: LowLevelILExpr + :rtype: ExpressionIndex """ - return self.expr(LowLevelILOperation.LLIL_DIVU_DP, a.index, b.index, size=size, flags=flags) + return self.expr(LowLevelILOperation.LLIL_DIVU_DP, a, b, size=size, flags=flags) - def mod_signed(self, size:int, a:LowLevelILExpr, b:LowLevelILExpr, flags:'architecture.FlagType'=None) -> LowLevelILExpr: + def mod_signed(self, size:int, a:ExpressionIndex, b:ExpressionIndex, flags:'architecture.FlagType'=None) -> ExpressionIndex: """ ``mod_signed`` signed modulus expression ``a`` by expression ``b`` potentially setting flags ``flags`` and returning an expression of ``size`` bytes. :param int size: the size of the result in bytes - :param LowLevelILExpr a: LHS expression - :param LowLevelILExpr b: RHS expression + :param ExpressionIndex a: LHS expression + :param ExpressionIndex b: RHS expression :param str flags: optional, flags to set :return: The expression ``mods.{}(a, b)`` - :rtype: LowLevelILExpr + :rtype: ExpressionIndex """ - return self.expr(LowLevelILOperation.LLIL_MODS, a.index, b.index, size=size, flags=flags) + return self.expr(LowLevelILOperation.LLIL_MODS, a, b, size=size, flags=flags) - def mod_double_prec_signed(self, size:int, a:LowLevelILExpr, b:LowLevelILExpr, flags:'architecture.FlagType'=None) -> LowLevelILExpr: + def mod_double_prec_signed(self, size:int, a:ExpressionIndex, b:ExpressionIndex, flags:'architecture.FlagType'=None) -> ExpressionIndex: """ ``mod_double_prec_signed`` signed double precision modulus using expression ``a`` as a single double precision register by expression ``b`` potentially setting flags ``flags`` and returning an expression of ``size`` bytes. :param int size: the size of the result in bytes - :param LowLevelILExpr a: LHS expression - :param LowLevelILExpr b: RHS expression + :param ExpressionIndex a: LHS expression + :param ExpressionIndex b: RHS expression :param str flags: optional, flags to set :return: The expression ``mods.dp.{}(a, b)`` - :rtype: LowLevelILExpr + :rtype: ExpressionIndex """ - return self.expr(LowLevelILOperation.LLIL_MODS_DP, a.index, b.index, size=size, flags=flags) + return self.expr(LowLevelILOperation.LLIL_MODS_DP, a, b, size=size, flags=flags) - def mod_unsigned(self, size:int, a:LowLevelILExpr, b:LowLevelILExpr, flags:'architecture.FlagType'=None) -> LowLevelILExpr: + def mod_unsigned(self, size:int, a:ExpressionIndex, b:ExpressionIndex, flags:'architecture.FlagType'=None) -> ExpressionIndex: """ ``mod_unsigned`` unsigned modulus expression ``a`` by expression ``b`` potentially setting flags ``flags`` and returning an expression of ``size`` bytes. :param int size: the size of the result in bytes - :param LowLevelILExpr a: LHS expression - :param LowLevelILExpr b: RHS expression + :param ExpressionIndex a: LHS expression + :param ExpressionIndex b: RHS expression :param str flags: optional, flags to set :return: The expression ``modu.{}(a, b)`` - :rtype: LowLevelILExpr + :rtype: ExpressionIndex """ - return self.expr(LowLevelILOperation.LLIL_MODU, a.index, b.index, size=size, flags=flags) + return self.expr(LowLevelILOperation.LLIL_MODU, a, b, size=size, flags=flags) - def mod_double_prec_unsigned(self, size:int, a:LowLevelILExpr, b:LowLevelILExpr, flags:'architecture.FlagType'=None) -> LowLevelILExpr: + def mod_double_prec_unsigned(self, size:int, a:ExpressionIndex, b:ExpressionIndex, flags:'architecture.FlagType'=None) -> ExpressionIndex: """ ``mod_double_prec_unsigned`` unsigned double precision modulus using expression ``a`` as a single double precision register by expression ``b`` potentially setting flags ``flags`` and returning an expression of ``size`` bytes. :param int size: the size of the result in bytes - :param LowLevelILExpr a: LHS expression - :param LowLevelILExpr b: RHS expression + :param ExpressionIndex a: LHS expression + :param ExpressionIndex b: RHS expression :param str flags: optional, flags to set :return: The expression ``modu.dp.{}(a, b)`` - :rtype: LowLevelILExpr + :rtype: ExpressionIndex """ - return self.expr(LowLevelILOperation.LLIL_MODU_DP, a.index, b.index, size=size, flags=flags) + return self.expr(LowLevelILOperation.LLIL_MODU_DP, a, b, size=size, flags=flags) - def neg_expr(self, size:int, value:LowLevelILExpr, flags:'architecture.FlagType'=None) -> LowLevelILExpr: + def neg_expr(self, size:int, value:ExpressionIndex, flags:'architecture.FlagType'=None) -> ExpressionIndex: """ ``neg_expr`` two's complement sign negation of expression ``value`` of size ``size`` potentially setting flags :param int size: the size of the result in bytes - :param LowLevelILExpr value: the expression to negate + :param ExpressionIndex value: the expression to negate :param str flags: optional, flags to set :return: The expression ``neg.{}(value)`` - :rtype: LowLevelILExpr + :rtype: ExpressionIndex """ - return self.expr(LowLevelILOperation.LLIL_NEG, value.index, size=size, flags=flags) + return self.expr(LowLevelILOperation.LLIL_NEG, value, size=size, flags=flags) - def not_expr(self, size:int, value:LowLevelILExpr, flags:'architecture.FlagType'=None) -> LowLevelILExpr: + def not_expr(self, size:int, value:ExpressionIndex, flags:'architecture.FlagType'=None) -> ExpressionIndex: """ ``not_expr`` bitwise inverse of expression ``value`` of size ``size`` potentially setting flags :param int size: the size of the result in bytes - :param LowLevelILExpr value: the expression to bitwise invert + :param ExpressionIndex value: the expression to bitwise invert :param str flags: optional, flags to set :return: The expression ``not.{}(value)`` - :rtype: LowLevelILExpr + :rtype: ExpressionIndex """ - return self.expr(LowLevelILOperation.LLIL_NOT, value.index, size=size, flags=flags) + return self.expr(LowLevelILOperation.LLIL_NOT, value, size=size, flags=flags) - def sign_extend(self, size:int, value:LowLevelILExpr, flags:'architecture.FlagType'=None) -> LowLevelILExpr: + def sign_extend(self, size:int, value:ExpressionIndex, flags:'architecture.FlagType'=None) -> ExpressionIndex: """ ``sign_extend`` two's complement sign-extends the expression in ``value`` to ``size`` bytes :param int size: the size of the result in bytes - :param LowLevelILExpr value: the expression to sign extend + :param ExpressionIndex value: the expression to sign extend :param str flags: optional, flags to set :return: The expression ``sx.(value)`` - :rtype: LowLevelILExpr + :rtype: ExpressionIndex """ - return self.expr(LowLevelILOperation.LLIL_SX, value.index, size=size, flags=flags) + return self.expr(LowLevelILOperation.LLIL_SX, value, size=size, flags=flags) - def zero_extend(self, size:int, value:LowLevelILExpr, flags:'architecture.FlagType'=None) -> LowLevelILExpr: + def zero_extend(self, size:int, value:ExpressionIndex, flags:'architecture.FlagType'=None) -> ExpressionIndex: """ ``zero_extend`` zero-extends the expression in ``value`` to ``size`` bytes :param int size: the size of the result in bytes - :param LowLevelILExpr value: the expression to zero extend + :param ExpressionIndex value: the expression to zero extend :return: The expression ``zx.(value)`` - :rtype: LowLevelILExpr + :rtype: ExpressionIndex """ - return self.expr(LowLevelILOperation.LLIL_ZX, value.index, size=size, flags=flags) + return self.expr(LowLevelILOperation.LLIL_ZX, value, size=size, flags=flags) - def low_part(self, size:int, value:LowLevelILExpr, flags:'architecture.FlagType'=None) -> LowLevelILExpr: + def low_part(self, size:int, value:ExpressionIndex, flags:'architecture.FlagType'=None) -> ExpressionIndex: """ ``low_part`` truncates ``value`` to ``size`` bytes :param int size: the size of the result in bytes - :param LowLevelILExpr value: the expression to zero extend + :param ExpressionIndex value: the expression to zero extend :return: The expression ``(value).`` - :rtype: LowLevelILExpr + :rtype: ExpressionIndex """ - return self.expr(LowLevelILOperation.LLIL_LOW_PART, value.index, size=size, flags=flags) + return self.expr(LowLevelILOperation.LLIL_LOW_PART, value, size=size, flags=flags) - def jump(self, dest:LowLevelILExpr) -> LowLevelILExpr: + def jump(self, dest:ExpressionIndex) -> ExpressionIndex: """ ``jump`` returns an expression which jumps (branches) to the expression ``dest`` - :param LowLevelILExpr dest: the expression to jump to + :param ExpressionIndex dest: the expression to jump to :return: The expression ``jump(dest)`` - :rtype: LowLevelILExpr + :rtype: ExpressionIndex """ - return self.expr(LowLevelILOperation.LLIL_JUMP, dest.index) + return self.expr(LowLevelILOperation.LLIL_JUMP, dest) - def call(self, dest:LowLevelILExpr) -> LowLevelILExpr: + def call(self, dest:ExpressionIndex) -> ExpressionIndex: """ ``call`` returns an expression which first pushes the address of the next instruction onto the stack then jumps (branches) to the expression ``dest`` - :param LowLevelILExpr dest: the expression to call + :param ExpressionIndex dest: the expression to call :return: The expression ``call(dest)`` - :rtype: LowLevelILExpr + :rtype: ExpressionIndex """ - return self.expr(LowLevelILOperation.LLIL_CALL, dest.index) + return self.expr(LowLevelILOperation.LLIL_CALL, dest) - def call_stack_adjust(self, dest:LowLevelILExpr, stack_adjust:int) -> LowLevelILExpr: + def call_stack_adjust(self, dest:ExpressionIndex, stack_adjust:int) -> ExpressionIndex: """ ``call_stack_adjust`` returns an expression which first pushes the address of the next instruction onto the stack then jumps (branches) to the expression ``dest``. After the function exits, ``stack_adjust`` is added to the stack pointer register. - :param LowLevelILExpr dest: the expression to call + :param ExpressionIndex dest: the expression to call :return: The expression ``call(dest), stack += stack_adjust`` - :rtype: LowLevelILExpr + :rtype: ExpressionIndex """ - return self.expr(LowLevelILOperation.LLIL_CALL_STACK_ADJUST, dest.index, stack_adjust) + return self.expr(LowLevelILOperation.LLIL_CALL_STACK_ADJUST, dest, stack_adjust) - def tailcall(self, dest:LowLevelILExpr) -> LowLevelILExpr: + def tailcall(self, dest:ExpressionIndex) -> ExpressionIndex: """ ``tailcall`` returns an expression which jumps (branches) to the expression ``dest`` - :param LowLevelILExpr dest: the expression to jump to + :param ExpressionIndex dest: the expression to jump to :return: The expression ``tailcall(dest)`` - :rtype: LowLevelILExpr + :rtype: ExpressionIndex """ - return self.expr(LowLevelILOperation.LLIL_TAILCALL, dest.index) + return self.expr(LowLevelILOperation.LLIL_TAILCALL, dest) - def ret(self, dest:LowLevelILExpr) -> LowLevelILExpr: + def ret(self, dest:ExpressionIndex) -> ExpressionIndex: """ ``ret`` returns an expression which jumps (branches) to the expression ``dest``. ``ret`` is a special alias for jump that makes the disassembler stop disassembling. - :param LowLevelILExpr dest: the expression to jump to + :param ExpressionIndex dest: the expression to jump to :return: The expression ``jump(dest)`` - :rtype: LowLevelILExpr + :rtype: ExpressionIndex """ - return self.expr(LowLevelILOperation.LLIL_RET, dest.index) + return self.expr(LowLevelILOperation.LLIL_RET, dest) - def no_ret(self) -> LowLevelILExpr: + def no_ret(self) -> ExpressionIndex: """ ``no_ret`` returns an expression halts disassembly :return: The expression ``noreturn`` - :rtype: LowLevelILExpr + :rtype: ExpressionIndex """ return self.expr(LowLevelILOperation.LLIL_NORET) def flag_condition(self, cond:Union[str, LowLevelILFlagCondition, int], - sem_class:Optional['architecture.SemanticClassType']=None) -> LowLevelILExpr: + sem_class:Optional['architecture.SemanticClassType']=None) -> ExpressionIndex: """ ``flag_condition`` returns a flag_condition expression for the given LowLevelILFlagCondition :param LowLevelILFlagCondition cond: Flag condition expression to retrieve :param str sem_class: Optional semantic flag class :return: A flag_condition expression - :rtype: LowLevelILExpr + :rtype: ExpressionIndex """ if isinstance(cond, str): cond = LowLevelILFlagCondition[cond] @@ -2165,520 +3596,520 @@ class LowLevelILFunction: :param str sem_group: Semantic flag group to access :return: A flag_group expression - :rtype: LowLevelILExpr + :rtype: ExpressionIndex """ group = self.arch.get_semantic_flag_group_index(sem_group) return self.expr(LowLevelILOperation.LLIL_FLAG_GROUP, group) - def compare_equal(self, size:int, a:LowLevelILExpr, b:LowLevelILExpr) -> LowLevelILExpr: + def compare_equal(self, size:int, a:ExpressionIndex, b:ExpressionIndex) -> ExpressionIndex: """ ``compare_equal`` returns comparison expression of size ``size`` checking if expression ``a`` is equal to expression ``b`` :param int size: size in bytes - :param LowLevelILExpr a: LHS of comparison - :param LowLevelILExpr b: RHS of comparison + :param ExpressionIndex a: LHS of comparison + :param ExpressionIndex b: RHS of comparison :return: a comparison expression. - :rtype: LowLevelILExpr + :rtype: ExpressionIndex """ - return self.expr(LowLevelILOperation.LLIL_CMP_E, a.index, b.index, size = size) + return self.expr(LowLevelILOperation.LLIL_CMP_E, a, b, size = size) - def compare_not_equal(self, size:int, a:LowLevelILExpr, b:LowLevelILExpr) -> LowLevelILExpr: + def compare_not_equal(self, size:int, a:ExpressionIndex, b:ExpressionIndex) -> ExpressionIndex: """ ``compare_not_equal`` returns comparison expression of size ``size`` checking if expression ``a`` is not equal to expression ``b`` :param int size: size in bytes - :param LowLevelILExpr a: LHS of comparison - :param LowLevelILExpr b: RHS of comparison + :param ExpressionIndex a: LHS of comparison + :param ExpressionIndex b: RHS of comparison :return: a comparison expression. - :rtype: LowLevelILExpr + :rtype: ExpressionIndex """ - return self.expr(LowLevelILOperation.LLIL_CMP_NE, a.index, b.index, size = size) + return self.expr(LowLevelILOperation.LLIL_CMP_NE, a, b, size = size) - def compare_signed_less_than(self, size:int, a:LowLevelILExpr, b:LowLevelILExpr) -> LowLevelILExpr: + def compare_signed_less_than(self, size:int, a:ExpressionIndex, b:ExpressionIndex) -> ExpressionIndex: """ ``compare_signed_less_than`` returns comparison expression of size ``size`` checking if expression ``a`` is signed less than expression ``b`` :param int size: size in bytes - :param LowLevelILExpr a: LHS of comparison - :param LowLevelILExpr b: RHS of comparison + :param ExpressionIndex a: LHS of comparison + :param ExpressionIndex b: RHS of comparison :return: a comparison expression. - :rtype: LowLevelILExpr + :rtype: ExpressionIndex """ - return self.expr(LowLevelILOperation.LLIL_CMP_SLT, a.index, b.index, size = size) + return self.expr(LowLevelILOperation.LLIL_CMP_SLT, a, b, size = size) - def compare_unsigned_less_than(self, size:int, a:LowLevelILExpr, b:LowLevelILExpr) -> LowLevelILExpr: + def compare_unsigned_less_than(self, size:int, a:ExpressionIndex, b:ExpressionIndex) -> ExpressionIndex: """ ``compare_unsigned_less_than`` returns comparison expression of size ``size`` checking if expression ``a`` is unsigned less than expression ``b`` :param int size: size in bytes - :param LowLevelILExpr a: LHS of comparison - :param LowLevelILExpr b: RHS of comparison + :param ExpressionIndex a: LHS of comparison + :param ExpressionIndex b: RHS of comparison :return: a comparison expression. - :rtype: LowLevelILExpr + :rtype: ExpressionIndex """ - return self.expr(LowLevelILOperation.LLIL_CMP_ULT, a.index, b.index, size = size) + return self.expr(LowLevelILOperation.LLIL_CMP_ULT, a, b, size = size) - def compare_signed_less_equal(self, size:int, a:LowLevelILExpr, b:LowLevelILExpr) -> LowLevelILExpr: + def compare_signed_less_equal(self, size:int, a:ExpressionIndex, b:ExpressionIndex) -> ExpressionIndex: """ ``compare_signed_less_equal`` returns comparison expression of size ``size`` checking if expression ``a`` is signed less than or equal to expression ``b`` :param int size: size in bytes - :param LowLevelILExpr a: LHS of comparison - :param LowLevelILExpr b: RHS of comparison + :param ExpressionIndex a: LHS of comparison + :param ExpressionIndex b: RHS of comparison :return: a comparison expression. - :rtype: LowLevelILExpr + :rtype: ExpressionIndex """ - return self.expr(LowLevelILOperation.LLIL_CMP_SLE, a.index, b.index, size = size) + return self.expr(LowLevelILOperation.LLIL_CMP_SLE, a, b, size = size) - def compare_unsigned_less_equal(self, size:int, a:LowLevelILExpr, b:LowLevelILExpr) -> LowLevelILExpr: + def compare_unsigned_less_equal(self, size:int, a:ExpressionIndex, b:ExpressionIndex) -> ExpressionIndex: """ ``compare_unsigned_less_equal`` returns comparison expression of size ``size`` checking if expression ``a`` is unsigned less than or equal to expression ``b`` :param int size: size in bytes - :param LowLevelILExpr a: LHS of comparison - :param LowLevelILExpr b: RHS of comparison + :param ExpressionIndex a: LHS of comparison + :param ExpressionIndex b: RHS of comparison :return: a comparison expression. - :rtype: LowLevelILExpr + :rtype: ExpressionIndex """ - return self.expr(LowLevelILOperation.LLIL_CMP_ULE, a.index, b.index, size = size) + return self.expr(LowLevelILOperation.LLIL_CMP_ULE, a, b, size = size) - def compare_signed_greater_equal(self, size:int, a:LowLevelILExpr, b:LowLevelILExpr) -> LowLevelILExpr: + def compare_signed_greater_equal(self, size:int, a:ExpressionIndex, b:ExpressionIndex) -> ExpressionIndex: """ ``compare_signed_greater_equal`` returns comparison expression of size ``size`` checking if expression ``a`` is signed greater than or equal to expression ``b`` :param int size: size in bytes - :param LowLevelILExpr a: LHS of comparison - :param LowLevelILExpr b: RHS of comparison + :param ExpressionIndex a: LHS of comparison + :param ExpressionIndex b: RHS of comparison :return: a comparison expression. - :rtype: LowLevelILExpr + :rtype: ExpressionIndex """ - return self.expr(LowLevelILOperation.LLIL_CMP_SGE, a.index, b.index, size = size) + return self.expr(LowLevelILOperation.LLIL_CMP_SGE, a, b, size = size) - def compare_unsigned_greater_equal(self, size:int, a:LowLevelILExpr, b:LowLevelILExpr) -> LowLevelILExpr: + def compare_unsigned_greater_equal(self, size:int, a:ExpressionIndex, b:ExpressionIndex) -> ExpressionIndex: """ ``compare_unsigned_greater_equal`` returns comparison expression of size ``size`` checking if expression ``a`` is unsigned greater than or equal to expression ``b`` :param int size: size in bytes - :param LowLevelILExpr a: LHS of comparison - :param LowLevelILExpr b: RHS of comparison + :param ExpressionIndex a: LHS of comparison + :param ExpressionIndex b: RHS of comparison :return: a comparison expression. - :rtype: LowLevelILExpr + :rtype: ExpressionIndex """ - return self.expr(LowLevelILOperation.LLIL_CMP_UGE, a.index, b.index, size = size) + return self.expr(LowLevelILOperation.LLIL_CMP_UGE, a, b, size = size) - def compare_signed_greater_than(self, size:int, a:LowLevelILExpr, b:LowLevelILExpr) -> LowLevelILExpr: + def compare_signed_greater_than(self, size:int, a:ExpressionIndex, b:ExpressionIndex) -> ExpressionIndex: """ ``compare_signed_greater_than`` returns comparison expression of size ``size`` checking if expression ``a`` is signed greater than or equal to expression ``b`` :param int size: size in bytes - :param LowLevelILExpr a: LHS of comparison - :param LowLevelILExpr b: RHS of comparison + :param ExpressionIndex a: LHS of comparison + :param ExpressionIndex b: RHS of comparison :return: a comparison expression. - :rtype: LowLevelILExpr + :rtype: ExpressionIndex """ - return self.expr(LowLevelILOperation.LLIL_CMP_SGT, a.index, b.index, size = size) + return self.expr(LowLevelILOperation.LLIL_CMP_SGT, a, b, size = size) - def compare_unsigned_greater_than(self, size:int, a:LowLevelILExpr, b:LowLevelILExpr) -> LowLevelILExpr: + def compare_unsigned_greater_than(self, size:int, a:ExpressionIndex, b:ExpressionIndex) -> ExpressionIndex: """ ``compare_unsigned_greater_than`` returns comparison expression of size ``size`` checking if expression ``a`` is unsigned greater than or equal to expression ``b`` :param int size: size in bytes - :param LowLevelILExpr a: LHS of comparison - :param LowLevelILExpr b: RHS of comparison + :param ExpressionIndex a: LHS of comparison + :param ExpressionIndex b: RHS of comparison :return: a comparison expression. - :rtype: LowLevelILExpr + :rtype: ExpressionIndex """ - return self.expr(LowLevelILOperation.LLIL_CMP_UGT, a.index, b.index, size = size) + return self.expr(LowLevelILOperation.LLIL_CMP_UGT, a, b, size = size) - def test_bit(self, size:int, a:LowLevelILExpr, b:LowLevelILExpr) -> LowLevelILExpr: - return self.expr(LowLevelILOperation.LLIL_TEST_BIT, a.index, b.index, size = size) + def test_bit(self, size:int, a:ExpressionIndex, b:ExpressionIndex) -> ExpressionIndex: + return self.expr(LowLevelILOperation.LLIL_TEST_BIT, a, b, size = size) - def system_call(self) -> LowLevelILExpr: + def system_call(self) -> ExpressionIndex: """ ``system_call`` return a system call expression. :return: a system call expression. - :rtype: LowLevelILExpr + :rtype: ExpressionIndex """ return self.expr(LowLevelILOperation.LLIL_SYSCALL) - def intrinsic(self, outputs:List[Union[ILFlag, LowLevelILExpr]], intrinsic:'architecture.IntrinsicType', - params:List[LowLevelILExpr], flags:'architecture.FlagType'=None): + def intrinsic(self, outputs:List[Union[ILFlag, ExpressionIndex]], intrinsic:'architecture.IntrinsicType', + params:List[ExpressionIndex], flags:'architecture.FlagType'=None): """ ``intrinsic`` return an intrinsic expression. :return: an intrinsic expression. - :rtype: LowLevelILExpr + :rtype: ExpressionIndex """ output_list = [] for output in outputs: if isinstance(output, ILFlag): - output_list.append((1 << 32) | output.index) + output_list.append((1 << 32) | int(output)) else: - output_list.append(output.index) + output_list.append(output) param_list = [] for param in params: - param_list.append(param.index) - call_param = self.expr(LowLevelILOperation.LLIL_CALL_PARAM, len(params), self.add_operand_list(param_list).index) - return self.expr(LowLevelILOperation.LLIL_INTRINSIC, len(outputs), self.add_operand_list(output_list).index, - self.arch.get_intrinsic_index(intrinsic), call_param.index, flags = flags) + param_list.append(param) + call_param = self.expr(LowLevelILOperation.LLIL_CALL_PARAM, len(params), self.add_operand_list(param_list)) + return self.expr(LowLevelILOperation.LLIL_INTRINSIC, len(outputs), self.add_operand_list(output_list), + self.arch.get_intrinsic_index(intrinsic), call_param, flags = flags) - def breakpoint(self) -> LowLevelILExpr: + def breakpoint(self) -> ExpressionIndex: """ ``breakpoint`` returns a processor breakpoint expression. :return: a breakpoint expression. - :rtype: LowLevelILExpr + :rtype: ExpressionIndex """ return self.expr(LowLevelILOperation.LLIL_BP) - def trap(self, value:int) -> LowLevelILExpr: + def trap(self, value:int) -> ExpressionIndex: """ ``trap`` returns a processor trap (interrupt) expression of the given integer ``value``. :param int value: trap (interrupt) number :return: a trap expression. - :rtype: LowLevelILExpr + :rtype: ExpressionIndex """ return self.expr(LowLevelILOperation.LLIL_TRAP, value) - def undefined(self) -> LowLevelILExpr: + def undefined(self) -> ExpressionIndex: """ ``undefined`` returns the undefined expression. This should be used for instructions which perform functions but aren't important for dataflow or partial emulation purposes. :return: the unimplemented expression. - :rtype: LowLevelILExpr + :rtype: ExpressionIndex """ return self.expr(LowLevelILOperation.LLIL_UNDEF) - def unimplemented(self) -> LowLevelILExpr: + def unimplemented(self) -> ExpressionIndex: """ ``unimplemented`` returns the unimplemented expression. This should be used for all instructions which aren't implemented. :return: the unimplemented expression. - :rtype: LowLevelILExpr + :rtype: ExpressionIndex """ return self.expr(LowLevelILOperation.LLIL_UNIMPL) - def unimplemented_memory_ref(self, size:int, addr:LowLevelILExpr) -> LowLevelILExpr: + def unimplemented_memory_ref(self, size:int, addr:ExpressionIndex) -> ExpressionIndex: """ ``unimplemented_memory_ref`` a memory reference to expression ``addr`` of size ``size`` with unimplemented operation. :param int size: size in bytes of the memory reference - :param LowLevelILExpr addr: expression to reference memory + :param ExpressionIndex addr: expression to reference memory :return: the unimplemented memory reference expression. - :rtype: LowLevelILExpr + :rtype: ExpressionIndex """ - return self.expr(LowLevelILOperation.LLIL_UNIMPL_MEM, addr.index, size = size) + return self.expr(LowLevelILOperation.LLIL_UNIMPL_MEM, addr, size = size) - def float_add(self, size:int, a:LowLevelILExpr, b:LowLevelILExpr, flags:'architecture.FlagType'=None) -> LowLevelILExpr: + def float_add(self, size:int, a:ExpressionIndex, b:ExpressionIndex, flags:'architecture.FlagType'=None) -> ExpressionIndex: """ ``float_add`` adds floating point expression ``a`` to expression ``b`` potentially setting flags ``flags`` and returning an expression of ``size`` bytes. :param int size: the size of the result in bytes - :param LowLevelILExpr a: LHS expression - :param LowLevelILExpr b: RHS expression + :param ExpressionIndex a: LHS expression + :param ExpressionIndex b: RHS expression :param str flags: flags to set :return: The expression ``fadd.{}(a, b)`` - :rtype: LowLevelILExpr + :rtype: ExpressionIndex """ - return self.expr(LowLevelILOperation.LLIL_FADD, a.index, b.index, size=size, flags=flags) + return self.expr(LowLevelILOperation.LLIL_FADD, a, b, size=size, flags=flags) - def float_sub(self, size:int, a:LowLevelILExpr, b:LowLevelILExpr, flags:'architecture.FlagType'=None) -> LowLevelILExpr: + def float_sub(self, size:int, a:ExpressionIndex, b:ExpressionIndex, flags:'architecture.FlagType'=None) -> ExpressionIndex: """ ``float_sub`` subtracts floating point expression ``b`` from expression ``a`` potentially setting flags ``flags`` and returning an expression of ``size`` bytes. :param int size: the size of the result in bytes - :param LowLevelILExpr a: LHS expression - :param LowLevelILExpr b: RHS expression + :param ExpressionIndex a: LHS expression + :param ExpressionIndex b: RHS expression :param str flags: flags to set :return: The expression ``fsub.{}(a, b)`` - :rtype: LowLevelILExpr + :rtype: ExpressionIndex """ - return self.expr(LowLevelILOperation.LLIL_FSUB, a.index, b.index, size=size, flags=flags) + return self.expr(LowLevelILOperation.LLIL_FSUB, a, b, size=size, flags=flags) - def float_mult(self, size:int, a:LowLevelILExpr, b:LowLevelILExpr, flags:'architecture.FlagType'=None) -> LowLevelILExpr: + def float_mult(self, size:int, a:ExpressionIndex, b:ExpressionIndex, flags:'architecture.FlagType'=None) -> ExpressionIndex: """ ``float_mult`` multiplies floating point expression ``a`` by expression ``b`` potentially setting flags ``flags`` and returning an expression of ``size`` bytes. :param int size: the size of the result in bytes - :param LowLevelILExpr a: LHS expression - :param LowLevelILExpr b: RHS expression + :param ExpressionIndex a: LHS expression + :param ExpressionIndex b: RHS expression :param str flags: flags to set :return: The expression ``fmul.{}(a, b)`` - :rtype: LowLevelILExpr + :rtype: ExpressionIndex """ - return self.expr(LowLevelILOperation.LLIL_FMUL, a.index, b.index, size=size, flags=flags) + return self.expr(LowLevelILOperation.LLIL_FMUL, a, b, size=size, flags=flags) - def float_div(self, size:int, a:LowLevelILExpr, b:LowLevelILExpr, flags:'architecture.FlagType'=None) -> LowLevelILExpr: + def float_div(self, size:int, a:ExpressionIndex, b:ExpressionIndex, flags:'architecture.FlagType'=None) -> ExpressionIndex: """ ``float_div`` divides floating point expression ``a`` by expression ``b`` potentially setting flags ``flags`` and returning an expression of ``size`` bytes. :param int size: the size of the result in bytes - :param LowLevelILExpr a: LHS expression - :param LowLevelILExpr b: RHS expression + :param ExpressionIndex a: LHS expression + :param ExpressionIndex b: RHS expression :param str flags: flags to set :return: The expression ``fdiv.{}(a, b)`` - :rtype: LowLevelILExpr + :rtype: ExpressionIndex """ - return self.expr(LowLevelILOperation.LLIL_FDIV, a.index, b.index, size=size, flags=flags) + return self.expr(LowLevelILOperation.LLIL_FDIV, a, b, size=size, flags=flags) - def float_sqrt(self, size:int, value:LowLevelILExpr, flags:'architecture.FlagType'=None) -> LowLevelILExpr: + def float_sqrt(self, size:int, value:ExpressionIndex, flags:'architecture.FlagType'=None) -> ExpressionIndex: """ ``float_sqrt`` returns square root of floating point expression ``value`` of size ``size`` potentially setting flags :param int size: the size of the result in bytes - :param LowLevelILExpr value: the expression to negate + :param ExpressionIndex value: the expression to negate :param str flags: optional, flags to set :return: The expression ``sqrt.{}(value)`` - :rtype: LowLevelILExpr + :rtype: ExpressionIndex """ - return self.expr(LowLevelILOperation.LLIL_FSQRT, value.index, size=size, flags=flags) + return self.expr(LowLevelILOperation.LLIL_FSQRT, value, size=size, flags=flags) - def float_neg(self, size:int, value:LowLevelILExpr, flags:'architecture.FlagType'=None) -> LowLevelILExpr: + def float_neg(self, size:int, value:ExpressionIndex, flags:'architecture.FlagType'=None) -> ExpressionIndex: """ ``float_neg`` returns sign negation of floating point expression ``value`` of size ``size`` potentially setting flags :param int size: the size of the result in bytes - :param LowLevelILExpr value: the expression to negate + :param ExpressionIndex value: the expression to negate :param str flags: optional, flags to set :return: The expression ``fneg.{}(value)`` - :rtype: LowLevelILExpr + :rtype: ExpressionIndex """ - return self.expr(LowLevelILOperation.LLIL_FNEG, value.index, size=size, flags=flags) + return self.expr(LowLevelILOperation.LLIL_FNEG, value, size=size, flags=flags) - def float_abs(self, size:int, value:LowLevelILExpr, flags:'architecture.FlagType'=None) -> LowLevelILExpr: + def float_abs(self, size:int, value:ExpressionIndex, flags:'architecture.FlagType'=None) -> ExpressionIndex: """ ``float_abs`` returns absolute value of floating point expression ``value`` of size ``size`` potentially setting flags :param int size: the size of the result in bytes - :param LowLevelILExpr value: the expression to negate + :param ExpressionIndex value: the expression to negate :param str flags: optional, flags to set :return: The expression ``fabs.{}(value)`` - :rtype: LowLevelILExpr + :rtype: ExpressionIndex """ - return self.expr(LowLevelILOperation.LLIL_FABS, value.index, size=size, flags=flags) + return self.expr(LowLevelILOperation.LLIL_FABS, value, size=size, flags=flags) - def float_to_int(self, size:int, value:LowLevelILExpr, flags:'architecture.FlagType'=None) -> LowLevelILExpr: + def float_to_int(self, size:int, value:ExpressionIndex, flags:'architecture.FlagType'=None) -> ExpressionIndex: """ ``float_to_int`` returns integer value of floating point expression ``value`` of size ``size`` potentially setting flags :param int size: the size of the result in bytes - :param LowLevelILExpr value: the expression to negate + :param ExpressionIndex value: the expression to negate :param str flags: optional, flags to set :return: The expression ``int.{}(value)`` - :rtype: LowLevelILExpr + :rtype: ExpressionIndex """ - return self.expr(LowLevelILOperation.LLIL_FLOAT_TO_INT, value.index, size=size, flags=flags) + return self.expr(LowLevelILOperation.LLIL_FLOAT_TO_INT, value, size=size, flags=flags) - def int_to_float(self, size:int, value:LowLevelILExpr, flags:'architecture.FlagType'=None) -> LowLevelILExpr: + def int_to_float(self, size:int, value:ExpressionIndex, flags:'architecture.FlagType'=None) -> ExpressionIndex: """ ``int_to_float`` returns floating point value of integer expression ``value`` of size ``size`` potentially setting flags :param int size: the size of the result in bytes - :param LowLevelILExpr value: the expression to negate + :param ExpressionIndex value: the expression to negate :param str flags: optional, flags to set :return: The expression ``float.{}(value)`` - :rtype: LowLevelILExpr + :rtype: ExpressionIndex """ - return self.expr(LowLevelILOperation.LLIL_INT_TO_FLOAT, value.index, size=size, flags=flags) + return self.expr(LowLevelILOperation.LLIL_INT_TO_FLOAT, value, size=size, flags=flags) - def float_convert(self, size:int, value:LowLevelILExpr, flags:'architecture.FlagType'=None) -> LowLevelILExpr: + def float_convert(self, size:int, value:ExpressionIndex, flags:'architecture.FlagType'=None) -> ExpressionIndex: """ ``int_to_float`` converts floating point value of expression ``value`` to size ``size`` potentially setting flags :param int size: the size of the result in bytes - :param LowLevelILExpr value: the expression to negate + :param ExpressionIndex value: the expression to negate :param str flags: optional, flags to set :return: The expression ``fconvert.{}(value)`` - :rtype: LowLevelILExpr + :rtype: ExpressionIndex """ - return self.expr(LowLevelILOperation.LLIL_FLOAT_CONV, value.index, size=size, flags=flags) + return self.expr(LowLevelILOperation.LLIL_FLOAT_CONV, value, size=size, flags=flags) - def round_to_int(self, size:int, value:LowLevelILExpr, flags:'architecture.FlagType'=None) -> LowLevelILExpr: + def round_to_int(self, size:int, value:ExpressionIndex, flags:'architecture.FlagType'=None) -> ExpressionIndex: """ ``round_to_int`` rounds a floating point value to the nearest integer :param int size: the size of the result in bytes - :param LowLevelILExpr value: the expression to negate + :param ExpressionIndex value: the expression to negate :param str flags: optional, flags to set :return: The expression ``roundint.{}(value)`` - :rtype: LowLevelILExpr + :rtype: ExpressionIndex """ - return self.expr(LowLevelILOperation.LLIL_ROUND_TO_INT, value.index, size=size, flags=flags) + return self.expr(LowLevelILOperation.LLIL_ROUND_TO_INT, value, size=size, flags=flags) - def floor(self, size:int, value:LowLevelILExpr, flags:'architecture.FlagType'=None) -> LowLevelILExpr: + def floor(self, size:int, value:ExpressionIndex, flags:'architecture.FlagType'=None) -> ExpressionIndex: """ ``floor`` rounds a floating point value to an integer towards negative infinity :param int size: the size of the result in bytes - :param LowLevelILExpr value: the expression to negate + :param ExpressionIndex value: the expression to negate :param str flags: optional, flags to set :return: The expression ``roundint.{}(value)`` - :rtype: LowLevelILExpr + :rtype: ExpressionIndex """ - return self.expr(LowLevelILOperation.LLIL_FLOOR, value.index, size=size, flags=flags) + return self.expr(LowLevelILOperation.LLIL_FLOOR, value, size=size, flags=flags) - def ceil(self, size:int, value:LowLevelILExpr, flags:'architecture.FlagType'=None) -> LowLevelILExpr: + def ceil(self, size:int, value:ExpressionIndex, flags:'architecture.FlagType'=None) -> ExpressionIndex: """ ``ceil`` rounds a floating point value to an integer towards positive infinity :param int size: the size of the result in bytes - :param LowLevelILExpr value: the expression to negate + :param ExpressionIndex value: the expression to negate :param str flags: optional, flags to set :return: The expression ``roundint.{}(value)`` - :rtype: LowLevelILExpr + :rtype: ExpressionIndex """ - return self.expr(LowLevelILOperation.LLIL_CEIL, value.index, size=size, flags=flags) + return self.expr(LowLevelILOperation.LLIL_CEIL, value, size=size, flags=flags) - def float_trunc(self, size:int, value:LowLevelILExpr, flags:'architecture.FlagType'=None) -> LowLevelILExpr: + def float_trunc(self, size:int, value:ExpressionIndex, flags:'architecture.FlagType'=None) -> ExpressionIndex: """ ``float_trunc`` rounds a floating point value to an integer towards zero :param int size: the size of the result in bytes - :param LowLevelILExpr value: the expression to negate + :param ExpressionIndex value: the expression to negate :param str flags: optional, flags to set :return: The expression ``roundint.{}(value)`` - :rtype: LowLevelILExpr + :rtype: ExpressionIndex """ - return self.expr(LowLevelILOperation.LLIL_FTRUNC, value.index, size=size, flags=flags) + return self.expr(LowLevelILOperation.LLIL_FTRUNC, value, size=size, flags=flags) - def float_compare_equal(self, size:int, a:LowLevelILExpr, b:LowLevelILExpr) -> LowLevelILExpr: + def float_compare_equal(self, size:int, a:ExpressionIndex, b:ExpressionIndex) -> ExpressionIndex: """ ``float_compare_equal`` returns floating point comparison expression of size ``size`` checking if expression ``a`` is equal to expression ``b`` :param int size: the size of the operands in bytes - :param LowLevelILExpr a: LHS expression - :param LowLevelILExpr b: RHS expression + :param ExpressionIndex a: LHS expression + :param ExpressionIndex b: RHS expression :param str flags: flags to set :return: The expression ``a f== b`` - :rtype: LowLevelILExpr + :rtype: ExpressionIndex """ - return self.expr(LowLevelILOperation.LLIL_FCMP_E, a.index, b.index) + return self.expr(LowLevelILOperation.LLIL_FCMP_E, a, b) - def float_compare_not_equal(self, size:int, a:LowLevelILExpr, b:LowLevelILExpr) -> LowLevelILExpr: + def float_compare_not_equal(self, size:int, a:ExpressionIndex, b:ExpressionIndex) -> ExpressionIndex: """ ``float_compare_not_equal`` returns floating point comparison expression of size ``size`` checking if expression ``a`` is not equal to expression ``b`` :param int size: the size of the operands in bytes - :param LowLevelILExpr a: LHS expression - :param LowLevelILExpr b: RHS expression + :param ExpressionIndex a: LHS expression + :param ExpressionIndex b: RHS expression :param str flags: flags to set :return: The expression ``a f!= b`` - :rtype: LowLevelILExpr + :rtype: ExpressionIndex """ - return self.expr(LowLevelILOperation.LLIL_FCMP_NE, a.index, b.index) + return self.expr(LowLevelILOperation.LLIL_FCMP_NE, a, b) - def float_compare_less_than(self, size:int, a:LowLevelILExpr, b:LowLevelILExpr) -> LowLevelILExpr: + def float_compare_less_than(self, size:int, a:ExpressionIndex, b:ExpressionIndex) -> ExpressionIndex: """ ``float_compare_less_than`` returns floating point comparison expression of size ``size`` checking if expression ``a`` is less than to expression ``b`` :param int size: the size of the operands in bytes - :param LowLevelILExpr a: LHS expression - :param LowLevelILExpr b: RHS expression + :param ExpressionIndex a: LHS expression + :param ExpressionIndex b: RHS expression :param str flags: flags to set :return: The expression ``a f< b`` - :rtype: LowLevelILExpr + :rtype: ExpressionIndex """ - return self.expr(LowLevelILOperation.LLIL_FCMP_LT, a.index, b.index) + return self.expr(LowLevelILOperation.LLIL_FCMP_LT, a, b) - def float_compare_less_equal(self, size:int, a:LowLevelILExpr, b:LowLevelILExpr) -> LowLevelILExpr: + def float_compare_less_equal(self, size:int, a:ExpressionIndex, b:ExpressionIndex) -> ExpressionIndex: """ ``float_compare_less_equal`` returns floating point comparison expression of size ``size`` checking if expression ``a`` is less than or equal to expression ``b`` :param int size: the size of the operands in bytes - :param LowLevelILExpr a: LHS expression - :param LowLevelILExpr b: RHS expression + :param ExpressionIndex a: LHS expression + :param ExpressionIndex b: RHS expression :param str flags: flags to set :return: The expression ``a f<= b`` - :rtype: LowLevelILExpr + :rtype: ExpressionIndex """ - return self.expr(LowLevelILOperation.LLIL_FCMP_LE, a.index, b.index) + return self.expr(LowLevelILOperation.LLIL_FCMP_LE, a, b) - def float_compare_greater_equal(self, size:int, a:LowLevelILExpr, b:LowLevelILExpr) -> LowLevelILExpr: + def float_compare_greater_equal(self, size:int, a:ExpressionIndex, b:ExpressionIndex) -> ExpressionIndex: """ ``float_compare_greater_equal`` returns floating point comparison expression of size ``size`` checking if expression ``a`` is greater than or equal to expression ``b`` :param int size: the size of the operands in bytes - :param LowLevelILExpr a: LHS expression - :param LowLevelILExpr b: RHS expression + :param ExpressionIndex a: LHS expression + :param ExpressionIndex b: RHS expression :param str flags: flags to set :return: The expression ``a f>= b`` - :rtype: LowLevelILExpr + :rtype: ExpressionIndex """ - return self.expr(LowLevelILOperation.LLIL_FCMP_GE, a.index, b.index) + return self.expr(LowLevelILOperation.LLIL_FCMP_GE, a, b) - def float_compare_greater_than(self, size:int, a:LowLevelILExpr, b:LowLevelILExpr) -> LowLevelILExpr: + def float_compare_greater_than(self, size:int, a:ExpressionIndex, b:ExpressionIndex) -> ExpressionIndex: """ ``float_compare_greater_than`` returns floating point comparison expression of size ``size`` checking if expression ``a`` is greater than or equal to expression ``b`` :param int size: the size of the operands in bytes - :param LowLevelILExpr a: LHS expression - :param LowLevelILExpr b: RHS expression + :param ExpressionIndex a: LHS expression + :param ExpressionIndex b: RHS expression :param str flags: flags to set :return: The expression ``a f> b`` - :rtype: LowLevelILExpr + :rtype: ExpressionIndex """ - return self.expr(LowLevelILOperation.LLIL_FCMP_GT, a.index, b.index) + return self.expr(LowLevelILOperation.LLIL_FCMP_GT, a, b) - def float_compare_unordered(self, size:int, a:LowLevelILExpr, b:LowLevelILExpr) -> LowLevelILExpr: + def float_compare_unordered(self, size:int, a:ExpressionIndex, b:ExpressionIndex) -> ExpressionIndex: """ ``float_compare_unordered`` returns floating point comparison expression of size ``size`` checking if expression ``a`` is unordered relative to expression ``b`` :param int size: the size of the operands in bytes - :param LowLevelILExpr a: LHS expression - :param LowLevelILExpr b: RHS expression + :param ExpressionIndex a: LHS expression + :param ExpressionIndex b: RHS expression :param str flags: flags to set :return: The expression ``is_unordered(a, b)`` - :rtype: LowLevelILExpr + :rtype: ExpressionIndex """ - return self.expr(LowLevelILOperation.LLIL_FCMP_UO, a.index, b.index) + return self.expr(LowLevelILOperation.LLIL_FCMP_UO, a, b) - def goto(self, label:LowLevelILLabel) -> LowLevelILExpr: + def goto(self, label:LowLevelILLabel) -> ExpressionIndex: """ ``goto`` returns a goto expression which jumps to the provided LowLevelILLabel. :param LowLevelILLabel label: Label to jump to - :return: the LowLevelILExpr that jumps to the provided label - :rtype: LowLevelILExpr + :return: the ExpressionIndex that jumps to the provided label + :rtype: ExpressionIndex """ - return LowLevelILExpr(core.BNLowLevelILGoto(self.handle, label.handle)) + return ExpressionIndex(core.BNLowLevelILGoto(self.handle, label.handle)) - def if_expr(self, operand:LowLevelILExpr, t:LowLevelILLabel, f:LowLevelILLabel) -> LowLevelILExpr: + def if_expr(self, operand:ExpressionIndex, t:LowLevelILLabel, f:LowLevelILLabel) -> ExpressionIndex: """ ``if_expr`` returns the ``if`` expression which depending on condition ``operand`` jumps to the LowLevelILLabel ``t`` when the condition expression ``operand`` is non-zero and ``f`` when it's zero. - :param LowLevelILExpr operand: comparison expression to evaluate. + :param ExpressionIndex operand: comparison expression to evaluate. :param LowLevelILLabel t: Label for the true branch :param LowLevelILLabel f: Label for the false branch - :return: the LowLevelILExpr for the if expression - :rtype: LowLevelILExpr + :return: the ExpressionIndex for the if expression + :rtype: ExpressionIndex """ - return LowLevelILExpr(core.BNLowLevelILIf(self.handle, operand.index, t.handle, f.handle)) + return ExpressionIndex(core.BNLowLevelILIf(self.handle, operand, t.handle, f.handle)) def mark_label(self, label:LowLevelILLabel) -> None: """ @@ -2689,14 +4120,14 @@ class LowLevelILFunction: """ core.BNLowLevelILMarkLabel(self.handle, label.handle) - def add_label_map(self, labels:Mapping[int, LowLevelILLabel]) -> LowLevelILExpr: + def add_label_map(self, labels:Mapping[int, LowLevelILLabel]) -> ExpressionIndex: """ ``add_label_map`` returns a label list expression for the given list of LowLevelILLabel objects. :param labels: the list of LowLevelILLabel to get a label list expression from :type labels: dict(int, LowLevelILLabel) :return: the label list expression - :rtype: LowLevelILExpr + :rtype: ExpressionIndex """ label_list = (ctypes.POINTER(core.BNLowLevelILLabel) * len(labels))() # type: ignore value_list = (ctypes.POINTER(ctypes.c_ulonglong) * len(labels))() # type: ignore @@ -2704,38 +4135,38 @@ class LowLevelILFunction: value_list[i] = key label_list[i] = value.handle - return LowLevelILExpr(core.BNLowLevelILAddLabelMap(self.handle, value_list, label_list, len(labels))) + return ExpressionIndex(core.BNLowLevelILAddLabelMap(self.handle, value_list, label_list, len(labels))) - def add_operand_list(self, operands:List[Union[ExpressionIndex, LowLevelILExpr]]) -> LowLevelILExpr: + def add_operand_list(self, operands:List[Union[ExpressionIndex, ExpressionIndex]]) -> ExpressionIndex: """ ``add_operand_list`` returns an operand list expression for the given list of integer operands. :param operands: list of operand numbers - :type operands: List(Union[ExpressionIndex, LowLevelILExpr]) + :type operands: List(Union[ExpressionIndex, ExpressionIndex]) :return: an operand list expression - :rtype: LowLevelILExpr + :rtype: ExpressionIndex """ operand_list = (ctypes.c_ulonglong * len(operands))() for i in range(len(operands)): op = operands[i] - if isinstance(op, LowLevelILExpr): - operand_list[i] = op.index + if isinstance(op, ExpressionIndex): + operand_list[i] = op elif isinstance(op, int): operand_list[i] = op else: raise Exception("Invalid operand type") - return LowLevelILExpr(core.BNLowLevelILAddOperandList(self.handle, operand_list, len(operands))) + return ExpressionIndex(core.BNLowLevelILAddOperandList(self.handle, operand_list, len(operands))) - def operand(self, n:int, expr:LowLevelILExpr) -> LowLevelILExpr: + def operand(self, n:int, expr:ExpressionIndex) -> ExpressionIndex: """ ``operand`` sets the operand number of the expression ``expr`` and passes back ``expr`` without modification. :param int n: - :param LowLevelILExpr expr: + :param ExpressionIndex expr: :return: returns the expression ``expr`` unmodified - :rtype: LowLevelILExpr + :rtype: ExpressionIndex """ - core.BNLowLevelILSetExprSourceOperand(self.handle, expr.index, n) + core.BNLowLevelILSetExprSourceOperand(self.handle, expr, n) return expr def finalize(self) -> None: -- cgit v1.3.1