summaryrefslogtreecommitdiff
path: root/python
diff options
context:
space:
mode:
Diffstat (limited to 'python')
-rw-r--r--python/highlevelil.py490
-rw-r--r--python/lowlevelil.py643
-rw-r--r--python/mediumlevelil.py45
3 files changed, 896 insertions, 282 deletions
diff --git a/python/highlevelil.py b/python/highlevelil.py
index 1784c806..a267101f 100644
--- a/python/highlevelil.py
+++ b/python/highlevelil.py
@@ -20,7 +20,7 @@
import ctypes
import struct
-from typing import Optional, Generator, List, Union, NewType, Tuple, ClassVar, Mapping, Set
+from typing import Optional, Generator, List, Union, NewType, Tuple, ClassVar, Mapping, Set, Callable
from dataclasses import dataclass
from enum import Enum
@@ -59,10 +59,11 @@ OperandsType = Tuple[ExpressionIndex, ExpressionIndex, ExpressionIndex, Expressi
HighLevelILOperandType = Union['HighLevelILInstruction', 'lowlevelil.ILIntrinsic', 'variable.Variable',
'mediumlevelil.SSAVariable', List[int], List['variable.Variable'],
List['mediumlevelil.SSAVariable'], List['HighLevelILInstruction'], Optional[int], float,
- 'GotoLabel', databuffer.DataBuffer]
+ 'GotoLabel', variable.ConstantData, databuffer.DataBuffer]
VariablesList = List[Union['mediumlevelil.SSAVariable', 'variable.Variable']]
StringOrType = Union[str, '_types.Type', '_types.TypeBuilder']
ILInstructionAttributeSet = Union[Set[ILInstructionAttribute], List[ILInstructionAttribute]]
+HighLevelILVisitorCallback = Callable[[str, HighLevelILOperandType, str, Optional['HighLevelILInstruction']], bool]
class VariableReferenceType(Enum):
@@ -768,8 +769,86 @@ class HighLevelILInstruction(BaseILInstruction):
@property
def operands(self) -> List[HighLevelILOperandType]:
+ """Operands for the instruction"""
+ return list(map(lambda x: x[1], self.detailed_operands))
+
+ @property
+ def detailed_operands(self) -> List[Tuple[str, HighLevelILOperandType, str]]:
+ """
+ Returns a list of tuples containing the name of the operand, the operand, and the type of the operand.
+ Useful for iterating over all operands of an instruction and sub-instructions.
+ """
return []
+ def visit_all(self, cb: HighLevelILVisitorCallback,
+ name: str = "root", parent: Optional['HighLevelILInstruction'] = None) -> bool:
+ """
+ Visits all operands of this instruction and all operands of any sub-instructions.
+ Using pre-order traversal.
+
+ :param HighLevelILVisitorCallback cb: Callback function that takes the name of the operand, the operand, operand type, and parent instruction
+ :return: True if all instructions were visited, False if the callback returned False
+ """
+ if cb(name, self, "HighLevelILInstruction", parent) == False:
+ return False
+ for name, op, opType in self.detailed_operands:
+ if opType == "HighLevelILInstruction":
+ assert isinstance(op, HighLevelILInstruction)
+ if not op.visit_all(cb, name, self):
+ return False
+ elif opType == "List[HighLevelILInstruction]":
+ assert isinstance(op, list) and all(isinstance(i, HighLevelILInstruction) for i in op)
+ for i in op:
+ if not i.visit_all(cb, name, self): # type: ignore
+ return False
+ elif cb(name, op, opType, self) == False:
+ return False
+ return True
+
+ def visit_operands(self, cb: HighLevelILVisitorCallback,
+ name: str = "root", parent: Optional['HighLevelILInstruction'] = None) -> bool:
+ """
+ Visits all leaf operands of this instruction and any sub-instructions.
+
+ :param HighLevelILVisitorCallback cb: Callback function that takes the name of the operand, the operand, operand type, and parent instruction
+ :return: True if all instructions were visited, False if the callback returned False
+ """
+ for name, op, opType in self.detailed_operands:
+ if opType == "HighLevelILInstruction":
+ assert isinstance(op, HighLevelILInstruction)
+ if not op.visit_operands(cb, name, self):
+ return False
+ elif opType == "List[HighLevelILInstruction]":
+ assert isinstance(op, list) and all(isinstance(i, HighLevelILInstruction) for i in op)
+ for i in op:
+ if not i.visit_operands(cb, name, self): # type: ignore
+ return False
+ elif cb(name, op, opType, self) == False:
+ return False
+ return True
+
+ def visit(self, cb: HighLevelILVisitorCallback,
+ name: str = "root", parent: Optional['HighLevelILInstruction'] = None) -> bool:
+ """
+ Visits all HighLevelILInstructions in the operands of this instruction and any sub-instructions.
+
+ :param HighLevelILVisitorCallback cb: Callback function that takes the name of the operand, the operand, operand type, and parent instruction
+ :return: True if all instructions were visited, False if the callback returned False
+ """
+ if cb(name, self, "HighLevelILInstruction", parent) == False:
+ return False
+ for name, op, opType in self.detailed_operands:
+ if opType == "HighLevelILInstruction":
+ assert isinstance(op, HighLevelILInstruction)
+ if not op.visit(cb, name, self):
+ return False
+ elif opType == "List[HighLevelILInstruction]":
+ assert isinstance(op, list) and all(isinstance(i, HighLevelILInstruction) for i in op)
+ for i in op:
+ if not i.visit(cb, name, self): # type: ignore
+ return False
+ return True
+
@dataclass(frozen=True, repr=False, eq=False)
class HighLevelILUnaryBase(HighLevelILInstruction, UnaryOperation):
@@ -778,8 +857,10 @@ class HighLevelILUnaryBase(HighLevelILInstruction, UnaryOperation):
return self.get_expr(0)
@property
- def operands(self) -> List[HighLevelILOperandType]:
- return [self.src]
+ def detailed_operands(self) -> List[Tuple[str, HighLevelILOperandType, str]]:
+ return [
+ ("src", self.src, "HighLevelILInstruction"),
+ ]
@dataclass(frozen=True, repr=False, eq=False)
@@ -793,8 +874,11 @@ class HighLevelILBinaryBase(HighLevelILInstruction, BinaryOperation):
return self.get_expr(1)
@property
- def operands(self) -> List[HighLevelILOperandType]:
- return [self.left, self.right]
+ def detailed_operands(self) -> List[Tuple[str, HighLevelILOperandType, str]]:
+ return [
+ ("left", self.left, "HighLevelILInstruction"),
+ ("right", self.right, "HighLevelILInstruction"),
+ ]
@dataclass(frozen=True, repr=False, eq=False)
@@ -817,8 +901,12 @@ class HighLevelILCarryBase(HighLevelILInstruction, Arithmetic):
return self.get_expr(2)
@property
- def operands(self) -> List[HighLevelILOperandType]:
- return [self.left, self.right, self.carry]
+ def detailed_operands(self) -> List[Tuple[str, HighLevelILOperandType, str]]:
+ return [
+ ("left", self.left, "HighLevelILInstruction"),
+ ("right", self.right, "HighLevelILInstruction"),
+ ("carry", self.carry, "HighLevelILInstruction"),
+ ]
@dataclass(frozen=True, repr=False, eq=False)
@@ -836,6 +924,12 @@ class HighLevelILBlock(HighLevelILInstruction):
for expr in self.body:
yield expr
+ @property
+ def detailed_operands(self) -> List[Tuple[str, HighLevelILOperandType, str]]:
+ return [
+ ("body", self.body, "List[HighLevelILInstruction]"),
+ ]
+
@dataclass(frozen=True, repr=False, eq=False)
class HighLevelILIf(HighLevelILInstruction, ControlFlow):
@@ -852,8 +946,12 @@ class HighLevelILIf(HighLevelILInstruction, ControlFlow):
return self.get_expr(2)
@property
- def operands(self) -> List[HighLevelILOperandType]:
- return [self.condition]
+ def detailed_operands(self) -> List[Tuple[str, HighLevelILOperandType, str]]:
+ return [
+ ("condition", self.condition, "HighLevelILInstruction"),
+ ("true", self.true, "HighLevelILInstruction"),
+ ("false", self.false, "HighLevelILInstruction"),
+ ]
@dataclass(frozen=True, repr=False, eq=False)
@@ -867,8 +965,11 @@ class HighLevelILWhile(HighLevelILInstruction, Loop):
return self.get_expr(1)
@property
- def operands(self) -> List[HighLevelILOperandType]:
- return [self.condition]
+ def detailed_operands(self) -> List[Tuple[str, HighLevelILOperandType, str]]:
+ return [
+ ("condition", self.condition, "HighLevelILInstruction"),
+ ("body", self.body, "HighLevelILInstruction"),
+ ]
@dataclass(frozen=True, repr=False, eq=False)
@@ -886,8 +987,12 @@ class HighLevelILWhileSsa(HighLevelILInstruction, Loop, SSA):
return self.get_expr(2)
@property
- def operands(self) -> List[HighLevelILOperandType]:
- return [self.condition_phi, self.condition]
+ def detailed_operands(self) -> List[Tuple[str, HighLevelILOperandType, str]]:
+ return [
+ ("condition_phi", self.condition_phi, "HighLevelILInstruction"),
+ ("condition", self.condition, "HighLevelILInstruction"),
+ ("body", self.body, "HighLevelILInstruction"),
+ ]
@dataclass(frozen=True, repr=False, eq=False)
@@ -901,8 +1006,11 @@ class HighLevelILDoWhile(HighLevelILInstruction, Loop):
return self.get_expr(1)
@property
- def operands(self) -> List[HighLevelILOperandType]:
- return [self.condition]
+ def detailed_operands(self) -> List[Tuple[str, HighLevelILOperandType, str]]:
+ return [
+ ("body", self.body, "HighLevelILInstruction"),
+ ("condition", self.condition, "HighLevelILInstruction"),
+ ]
@dataclass(frozen=True, repr=False, eq=False)
@@ -920,8 +1028,12 @@ class HighLevelILDoWhileSsa(HighLevelILInstruction, Loop, SSA):
return self.get_expr(2)
@property
- def operands(self) -> List[HighLevelILOperandType]:
- return [self.condition_phi, self.condition]
+ def detailed_operands(self) -> List[Tuple[str, HighLevelILOperandType, str]]:
+ return [
+ ("body", self.body, "HighLevelILInstruction"),
+ ("condition_phi", self.condition_phi, "HighLevelILInstruction"),
+ ("condition", self.condition, "HighLevelILInstruction"),
+ ]
@dataclass(frozen=True, repr=False, eq=False)
@@ -943,8 +1055,13 @@ class HighLevelILFor(HighLevelILInstruction, Loop):
return self.get_expr(3)
@property
- def operands(self) -> List[HighLevelILOperandType]:
- return [self.init, self.condition, self.update]
+ def detailed_operands(self) -> List[Tuple[str, HighLevelILOperandType, str]]:
+ return [
+ ("init", self.init, "HighLevelILInstruction"),
+ ("condition", self.condition, "HighLevelILInstruction"),
+ ("update", self.update, "HighLevelILInstruction"),
+ ("body", self.body, "HighLevelILInstruction"),
+ ]
@dataclass(frozen=True, repr=False, eq=False)
@@ -970,8 +1087,14 @@ class HighLevelILForSsa(HighLevelILInstruction, Loop, SSA):
return self.get_expr(3)
@property
- def operands(self) -> List[HighLevelILOperandType]:
- return [self.init, self.condition_phi, self.condition, self.update]
+ def detailed_operands(self) -> List[Tuple[str, HighLevelILOperandType, str]]:
+ return [
+ ("init", self.init, "HighLevelILInstruction"),
+ ("condition_phi", self.condition_phi, "HighLevelILInstruction"),
+ ("condition", self.condition, "HighLevelILInstruction"),
+ ("update", self.update, "HighLevelILInstruction"),
+ ("body", self.body, "HighLevelILInstruction"),
+ ]
@dataclass(frozen=True, repr=False, eq=False)
@@ -989,8 +1112,12 @@ class HighLevelILSwitch(HighLevelILInstruction, ControlFlow):
return self.get_expr_list(2, 3)
@property
- def operands(self) -> List[HighLevelILOperandType]:
- return [self.condition]
+ def detailed_operands(self) -> List[Tuple[str, HighLevelILOperandType, str]]:
+ return [
+ ("condition", self.condition, "HighLevelILInstruction"),
+ ("default", self.default, "HighLevelILInstruction"),
+ ("cases", self.cases, "List[HighLevelILInstruction]"),
+ ]
@dataclass(frozen=True, repr=False, eq=False)
@@ -1004,8 +1131,11 @@ class HighLevelILCase(HighLevelILInstruction):
return self.get_expr(2)
@property
- def operands(self) -> List[HighLevelILOperandType]:
- return [self.values]
+ def detailed_operands(self) -> List[Tuple[str, HighLevelILOperandType, str]]:
+ return [
+ ("values", self.values, "List[HighLevelILInstruction]"),
+ ("body", self.body, "HighLevelILInstruction"),
+ ]
@dataclass(frozen=True, repr=False, eq=False)
@@ -1025,8 +1155,10 @@ class HighLevelILJump(HighLevelILInstruction, Terminal):
return self.get_expr(0)
@property
- def operands(self) -> List[HighLevelILOperandType]:
- return [self.dest]
+ def detailed_operands(self) -> List[Tuple[str, HighLevelILOperandType, str]]:
+ return [
+ ("dest", self.dest, "HighLevelILInstruction"),
+ ]
@dataclass(frozen=True, repr=False, eq=False)
@@ -1036,8 +1168,10 @@ class HighLevelILRet(HighLevelILInstruction, Return):
return self.get_expr_list(0, 1)
@property
- def operands(self) -> List[HighLevelILInstruction]:
- return self.src
+ def detailed_operands(self) -> List[Tuple[str, HighLevelILOperandType, str]]:
+ return [
+ ("src", self.src, "List[HighLevelILInstruction]"),
+ ]
@dataclass(frozen=True, repr=False, eq=False)
@@ -1057,8 +1191,10 @@ class HighLevelILGoto(HighLevelILInstruction, Terminal):
return self.get_label(0)
@property
- def operands(self) -> List[HighLevelILOperandType]:
- return [self.target]
+ def detailed_operands(self) -> List[Tuple[str, HighLevelILOperandType, str]]:
+ return [
+ ("target", self.target, "GotoLabel"),
+ ]
@dataclass(frozen=True, repr=False, eq=False)
@@ -1068,8 +1204,10 @@ class HighLevelILLabel(HighLevelILInstruction):
return self.get_label(0)
@property
- def operands(self) -> List[HighLevelILOperandType]:
- return [self.target]
+ def detailed_operands(self) -> List[Tuple[str, HighLevelILOperandType, str]]:
+ return [
+ ("target", self.target, "GotoLabel"),
+ ]
@dataclass(frozen=True, repr=False, eq=False)
@@ -1079,8 +1217,10 @@ class HighLevelILVarDeclare(HighLevelILInstruction):
return self.get_var(0)
@property
- def operands(self) -> List[HighLevelILOperandType]:
- return [self.var]
+ def detailed_operands(self) -> List[Tuple[str, HighLevelILOperandType, str]]:
+ return [
+ ("var", self.var, "Variable"),
+ ]
@dataclass(frozen=True, repr=False, eq=False)
@@ -1094,12 +1234,15 @@ class HighLevelILVarInit(HighLevelILInstruction):
return self.get_expr(1)
@property
- def vars_written(self) -> VariablesList:
- return [self.dest]
+ def detailed_operands(self) -> List[Tuple[str, HighLevelILOperandType, str]]:
+ return [
+ ("dest", self.dest, "Variable"),
+ ("src", self.src, "HighLevelILInstruction"),
+ ]
@property
- def operands(self) -> List[HighLevelILOperandType]:
- return [self.dest, self.src]
+ def vars_written(self) -> VariablesList:
+ return [self.dest]
@dataclass(frozen=True, repr=False, eq=False)
@@ -1113,12 +1256,15 @@ class HighLevelILVarInitSsa(HighLevelILInstruction, SSA):
return self.get_expr(2)
@property
- def vars_written(self) -> VariablesList:
- return [self.dest]
+ def detailed_operands(self) -> List[Tuple[str, HighLevelILOperandType, str]]:
+ return [
+ ("dest", self.dest, "SSAVariable"),
+ ("src", self.src, "HighLevelILInstruction"),
+ ]
@property
- def operands(self) -> List[HighLevelILOperandType]:
- return [self.dest, self.src]
+ def vars_written(self) -> VariablesList:
+ return [self.dest]
@dataclass(frozen=True, repr=False, eq=False)
@@ -1132,6 +1278,13 @@ class HighLevelILAssign(HighLevelILInstruction):
return self.get_expr(1)
@property
+ def detailed_operands(self) -> List[Tuple[str, HighLevelILOperandType, str]]:
+ return [
+ ("dest", self.dest, "HighLevelILInstruction"),
+ ("src", self.src, "HighLevelILInstruction"),
+ ]
+
+ @property
def vars_written(self) -> VariablesList:
if isinstance(self.dest, (HighLevelILSplit, HighLevelILVar)):
return [*self.dest.vars, *self.src.vars_written]
@@ -1140,10 +1293,6 @@ class HighLevelILAssign(HighLevelILInstruction):
else:
return [*self.dest.vars_written, *self.src.vars_written]
- @property
- def operands(self) -> List[HighLevelILOperandType]:
- return [self.dest, self.src]
-
@dataclass(frozen=True, repr=False, eq=False)
class HighLevelILAssignUnpack(HighLevelILInstruction):
@@ -1156,6 +1305,13 @@ class HighLevelILAssignUnpack(HighLevelILInstruction):
return self.get_expr(2)
@property
+ def detailed_operands(self) -> List[Tuple[str, HighLevelILOperandType, str]]:
+ return [
+ ("dest", self.dest, "List[HighLevelILInstruction]"),
+ ("src", self.src, "HighLevelILInstruction"),
+ ]
+
+ @property
def vars_written(self) -> VariablesList:
result = []
for i in self.dest:
@@ -1165,10 +1321,6 @@ class HighLevelILAssignUnpack(HighLevelILInstruction):
result.extend(i.vars_written)
return result
- @property
- def operands(self) -> List[HighLevelILOperandType]:
- return [self.dest, self.src]
-
@dataclass(frozen=True, repr=False, eq=False)
class HighLevelILAssignMemSsa(HighLevelILInstruction, SSA):
@@ -1189,8 +1341,13 @@ class HighLevelILAssignMemSsa(HighLevelILInstruction, SSA):
return self.get_int(3)
@property
- def operands(self) -> List[HighLevelILOperandType]:
- return [self.dest, self.dest_memory, self.src, self.src_memory]
+ def detailed_operands(self) -> List[Tuple[str, HighLevelILOperandType, str]]:
+ return [
+ ("dest", self.dest, "HighLevelILInstruction"),
+ ("dest_memory", self.dest_memory, "int"),
+ ("src", self.src, "HighLevelILInstruction"),
+ ("src_memory", self.src_memory, "int"),
+ ]
@dataclass(frozen=True, repr=False, eq=False)
@@ -1212,8 +1369,13 @@ class HighLevelILAssignUnpackMemSsa(HighLevelILInstruction, SSA, Memory):
return self.get_int(4)
@property
- def operands(self) -> List[HighLevelILOperandType]:
- return [self.dest, self.dest_memory, self.src, self.src_memory]
+ def detailed_operands(self) -> List[Tuple[str, HighLevelILOperandType, str]]:
+ return [
+ ("dest", self.dest, "List[HighLevelILInstruction]"),
+ ("dest_memory", self.dest_memory, "int"),
+ ("src", self.src, "HighLevelILInstruction"),
+ ("src_memory", self.src_memory, "int"),
+ ]
@dataclass(frozen=True, repr=False, eq=False)
@@ -1223,8 +1385,10 @@ class HighLevelILVar(HighLevelILInstruction):
return self.get_var(0)
@property
- def operands(self) -> List[HighLevelILOperandType]:
- return [self.var]
+ def detailed_operands(self) -> List[Tuple[str, HighLevelILOperandType, str]]:
+ return [
+ ("var", self.var, "Variable"),
+ ]
@dataclass(frozen=True, repr=False, eq=False)
@@ -1234,8 +1398,10 @@ class HighLevelILVarSsa(HighLevelILInstruction, SSA):
return self.get_var_ssa(0, 1)
@property
- def operands(self) -> List[HighLevelILOperandType]:
- return [self.var]
+ def detailed_operands(self) -> List[Tuple[str, HighLevelILOperandType, str]]:
+ return [
+ ("var", self.var, "SSAVariable"),
+ ]
@dataclass(frozen=True, repr=False, eq=False)
@@ -1253,8 +1419,11 @@ class HighLevelILVarPhi(HighLevelILInstruction, Phi):
return [self.dest]
@property
- def operands(self) -> List[HighLevelILOperandType]:
- return [self.dest, self.src]
+ def detailed_operands(self) -> List[Tuple[str, HighLevelILOperandType, str]]:
+ return [
+ ("dest", self.dest, "SSAVariable"),
+ ("src", self.src, "List[SSAVariable]"),
+ ]
@dataclass(frozen=True, repr=False, eq=False)
@@ -1268,8 +1437,11 @@ class HighLevelILMemPhi(HighLevelILInstruction, Memory, Phi):
return self.get_int_list(1)
@property
- def operands(self) -> List[HighLevelILOperandType]:
- return [self.dest, self.src]
+ def detailed_operands(self) -> List[Tuple[str, HighLevelILOperandType, str]]:
+ return [
+ ("dest", self.dest, "int"),
+ ("src", self.src, "List[int]"),
+ ]
@dataclass(frozen=True, repr=False, eq=False)
@@ -1287,8 +1459,12 @@ class HighLevelILStructField(HighLevelILInstruction):
return self.get_member_index(2)
@property
- def operands(self) -> List[HighLevelILOperandType]:
- return [self.src, self.offset, self.member_index]
+ def detailed_operands(self) -> List[Tuple[str, HighLevelILOperandType, str]]:
+ return [
+ ("src", self.src, "HighLevelILInstruction"),
+ ("offset", self.offset, "int"),
+ ("member_index", self.member_index, "Optional[int]"),
+ ]
@dataclass(frozen=True, repr=False, eq=False)
@@ -1302,8 +1478,11 @@ class HighLevelILArrayIndex(HighLevelILInstruction):
return self.get_expr(1)
@property
- def operands(self) -> List[HighLevelILOperandType]:
- return [self.src, self.index]
+ def detailed_operands(self) -> List[Tuple[str, HighLevelILOperandType, str]]:
+ return [
+ ("src", self.src, "HighLevelILInstruction"),
+ ("index", self.index, "HighLevelILInstruction"),
+ ]
@dataclass(frozen=True, repr=False, eq=False)
@@ -1321,8 +1500,12 @@ class HighLevelILArrayIndexSsa(HighLevelILInstruction, SSA):
return self.get_expr(2)
@property
- def operands(self) -> List[HighLevelILOperandType]:
- return [self.src, self.src_memory, self.index]
+ def detailed_operands(self) -> List[Tuple[str, HighLevelILOperandType, str]]:
+ return [
+ ("src", self.src, "HighLevelILInstruction"),
+ ("src_memory", self.src_memory, "int"),
+ ("index", self.index, "HighLevelILInstruction"),
+ ]
@dataclass(frozen=True, repr=False, eq=False)
@@ -1336,8 +1519,11 @@ class HighLevelILSplit(HighLevelILInstruction):
return self.get_expr(1)
@property
- def operands(self) -> List[HighLevelILOperandType]:
- return [self.high, self.low]
+ def detailed_operands(self) -> List[Tuple[str, HighLevelILOperandType, str]]:
+ return [
+ ("high", self.high, "HighLevelILInstruction"),
+ ("low", self.low, "HighLevelILInstruction"),
+ ]
@dataclass(frozen=True, repr=False, eq=False)
@@ -1360,8 +1546,12 @@ class HighLevelILDerefField(HighLevelILInstruction):
return self.get_member_index(2)
@property
- def operands(self) -> List[HighLevelILOperandType]:
- return [self.src, self.offset, self.member_index]
+ def detailed_operands(self) -> List[Tuple[str, HighLevelILOperandType, str]]:
+ return [
+ ("src", self.src, "HighLevelILInstruction"),
+ ("offset", self.offset, "int"),
+ ("member_index", self.member_index, "Optional[int]"),
+ ]
@dataclass(frozen=True, repr=False, eq=False)
@@ -1375,8 +1565,11 @@ class HighLevelILDerefSsa(HighLevelILInstruction, SSA):
return self.get_int(1)
@property
- def operands(self) -> List[HighLevelILOperandType]:
- return [self.src, self.src_memory]
+ def detailed_operands(self) -> List[Tuple[str, HighLevelILOperandType, str]]:
+ return [
+ ("src", self.src, "HighLevelILInstruction"),
+ ("src_memory", self.src_memory, "int"),
+ ]
@dataclass(frozen=True, repr=False, eq=False)
@@ -1398,8 +1591,13 @@ class HighLevelILDerefFieldSsa(HighLevelILInstruction, SSA):
return self.get_member_index(3)
@property
- def operands(self) -> List[HighLevelILOperandType]:
- return [self.src, self.src_memory, self.offset, self.member_index]
+ def detailed_operands(self) -> List[Tuple[str, HighLevelILOperandType, str]]:
+ return [
+ ("src", self.src, "HighLevelILInstruction"),
+ ("src_memory", self.src_memory, "int"),
+ ("offset", self.offset, "int"),
+ ("member_index", self.member_index, "Optional[int]"),
+ ]
@dataclass(frozen=True, repr=False, eq=False)
@@ -1420,8 +1618,10 @@ class HighLevelILConst(HighLevelILInstruction, Constant):
return self.get_int(0)
@property
- def operands(self) -> List[HighLevelILOperandType]:
- return [self.constant]
+ def detailed_operands(self) -> List[Tuple[str, HighLevelILOperandType, str]]:
+ return [
+ ("constant", self.constant, "int"),
+ ]
@dataclass(frozen=True, repr=False, eq=False)
@@ -1431,8 +1631,10 @@ class HighLevelILConstPtr(HighLevelILInstruction, Constant):
return self.get_int(0)
@property
- def operands(self) -> List[HighLevelILOperandType]:
- return [self.constant]
+ def detailed_operands(self) -> List[Tuple[str, HighLevelILOperandType, str]]:
+ return [
+ ("constant", self.constant, "int"),
+ ]
@dataclass(frozen=True, repr=False, eq=False)
@@ -1446,8 +1648,11 @@ class HighLevelILExternPtr(HighLevelILInstruction, Constant):
return self.get_int(1)
@property
- def operands(self) -> List[HighLevelILOperandType]:
- return [self.constant, self.offset]
+ def detailed_operands(self) -> List[Tuple[str, HighLevelILOperandType, str]]:
+ return [
+ ("constant", self.constant, "int"),
+ ("offset", self.offset, "int"),
+ ]
@dataclass(frozen=True, repr=False, eq=False)
@@ -1457,8 +1662,10 @@ class HighLevelILFloatConst(HighLevelILInstruction, Constant):
return self.get_float(0)
@property
- def operands(self) -> List[HighLevelILOperandType]:
- return [self.constant]
+ def detailed_operands(self) -> List[Tuple[str, HighLevelILOperandType, str]]:
+ return [
+ ("constant", self.constant, "float"),
+ ]
@dataclass(frozen=True, repr=False, eq=False)
@@ -1468,8 +1675,10 @@ class HighLevelILImport(HighLevelILInstruction, Constant):
return self.get_int(0)
@property
- def operands(self) -> List[HighLevelILOperandType]:
- return [self.constant]
+ def detailed_operands(self) -> List[Tuple[str, HighLevelILOperandType, str]]:
+ return [
+ ("constant", self.constant, "int"),
+ ]
@dataclass(frozen=True, repr=False, eq=False)
@@ -1479,8 +1688,10 @@ class HighLevelILConstData(HighLevelILInstruction, Constant):
return self.get_constant_data(0, 1)
@property
- def operands(self) -> List[HighLevelILOperandType]:
- return [self.constant_data]
+ def detailed_operands(self) -> List[Tuple[str, HighLevelILOperandType, str]]:
+ return [
+ ("constant_data", self.constant_data, "ConstantData"),
+ ]
@dataclass(frozen=True, repr=False, eq=False)
@@ -1644,8 +1855,11 @@ class HighLevelILCall(HighLevelILInstruction, Localcall):
return self.get_expr_list(1, 2)
@property
- def operands(self) -> List[HighLevelILOperandType]:
- return [self.dest, self.params]
+ def detailed_operands(self) -> List[Tuple[str, HighLevelILOperandType, str]]:
+ return [
+ ("dest", self.dest, "HighLevelILInstruction"),
+ ("params", self.params, "List[HighLevelILInstruction]"),
+ ]
@dataclass(frozen=True, repr=False, eq=False)
@@ -1667,8 +1881,13 @@ class HighLevelILCallSsa(HighLevelILInstruction, Localcall, SSA):
return self.get_int(4)
@property
- def operands(self) -> List[HighLevelILOperandType]:
- return [self.dest, self.params, self.dest_memory, self.src_memory]
+ def detailed_operands(self) -> List[Tuple[str, HighLevelILOperandType, str]]:
+ return [
+ ("dest", self.dest, "HighLevelILInstruction"),
+ ("params", self.params, "List[HighLevelILInstruction]"),
+ ("dest_memory", self.dest_memory, "int"),
+ ("src_memory", self.src_memory, "int"),
+ ]
@dataclass(frozen=True, repr=False, eq=False)
@@ -1743,8 +1962,10 @@ class HighLevelILSyscall(HighLevelILInstruction, Syscall):
return self.get_expr_list(0, 1)
@property
- def operands(self) -> List[HighLevelILInstruction]:
- return self.params
+ def detailed_operands(self) -> List[Tuple[str, HighLevelILOperandType, str]]:
+ return [
+ ("params", self.params, "List[HighLevelILInstruction]"),
+ ]
@dataclass(frozen=True, repr=False, eq=False)
@@ -1762,8 +1983,12 @@ class HighLevelILSyscallSsa(HighLevelILInstruction, Syscall, SSA):
return self.get_int(3)
@property
- def operands(self) -> List[HighLevelILOperandType]:
- return [self.params, self.dest_memory, self.src_memory]
+ def detailed_operands(self) -> List[Tuple[str, HighLevelILOperandType, str]]:
+ return [
+ ("params", self.params, "List[HighLevelILInstruction]"),
+ ("dest_memory", self.dest_memory, "int"),
+ ("src_memory", self.src_memory, "int"),
+ ]
@dataclass(frozen=True, repr=False, eq=False)
@@ -1777,8 +2002,11 @@ class HighLevelILTailcall(HighLevelILInstruction, Tailcall):
return self.get_expr_list(1, 2)
@property
- def operands(self) -> List[HighLevelILOperandType]:
- return [self.dest, self.params]
+ def detailed_operands(self) -> List[Tuple[str, HighLevelILOperandType, str]]:
+ return [
+ ("dest", self.dest, "HighLevelILInstruction"),
+ ("params", self.params, "List[HighLevelILInstruction]"),
+ ]
@dataclass(frozen=True, repr=False, eq=False)
@@ -1793,8 +2021,10 @@ class HighLevelILTrap(HighLevelILInstruction, Terminal):
return self.get_int(0)
@property
- def operands(self) -> List[HighLevelILOperandType]:
- return [self.vector]
+ def detailed_operands(self) -> List[Tuple[str, HighLevelILOperandType, str]]:
+ return [
+ ("vector", self.vector, "int"),
+ ]
@dataclass(frozen=True, repr=False, eq=False)
@@ -1808,8 +2038,11 @@ class HighLevelILIntrinsic(HighLevelILInstruction, Intrinsic):
return self.get_expr_list(1, 2)
@property
- def operands(self) -> List[HighLevelILOperandType]:
- return [self.intrinsic, self.params]
+ def detailed_operands(self) -> List[Tuple[str, HighLevelILOperandType, str]]:
+ return [
+ ("intrinsic", self.intrinsic, "ILIntrinsic"),
+ ("params", self.params, "List[HighLevelILInstruction]"),
+ ]
@dataclass(frozen=True, repr=False, eq=False)
@@ -1831,8 +2064,13 @@ class HighLevelILIntrinsicSsa(HighLevelILInstruction, SSA):
return self.get_int(3)
@property
- def operands(self) -> List[HighLevelILOperandType]:
- return [self.intrinsic, self.params, self.dest_memory, self.src_memory]
+ def detailed_operands(self) -> List[Tuple[str, HighLevelILOperandType, str]]:
+ return [
+ ("intrinsic", self.intrinsic, "ILIntrinsic"),
+ ("params", self.params, "List[HighLevelILInstruction]"),
+ ("dest_memory", self.dest_memory, "int"),
+ ("src_memory", self.src_memory, "int"),
+ ]
@dataclass(frozen=True, repr=False, eq=False)
@@ -2270,6 +2508,46 @@ class HighLevelILFunction:
return HighLevelILBasicBlock(block, self, view)
+
+ def visit(self, cb: HighLevelILVisitorCallback) -> bool:
+ """
+ Iterates over all the instructions in the function and calls the callback function
+ for each instruction and each sub-instruction.
+
+ :param HighLevelILVisitorCallback cb: Callback function that takes the name of the operand, the operand, operand type, and parent instruction
+ :return: True if all instructions were visited, False if the callback function returned False.
+ """
+ for instr in self.instructions:
+ if not instr.visit(cb):
+ return False
+ return True
+
+ def visit_all(self, cb: HighLevelILVisitorCallback) -> bool:
+ """
+ Iterates over all the instructions in the function and calls the callback function for each instruction and their operands.
+
+ :param HighLevelILVisitorCallback cb: Callback function that takes the name of the operand, the operand, operand type, and parent instruction
+ :return: True if all instructions were visited, False if the callback function returned False.
+ """
+ for instr in self.instructions:
+ if not instr.visit_all(cb):
+ return False
+ return True
+
+ def visit_operands(self, cb: HighLevelILVisitorCallback) -> bool:
+ """
+ Iterates over all the instructions in the function and calls the callback function for each operand and
+ the operands of each sub-instruction.
+
+ :param HighLevelILVisitorCallback cb: Callback function that takes the name of the operand, the operand, operand type, and parent instruction
+ :return: True if all instructions were visited, False if the callback function returned False.
+ """
+ for instr in self.instructions:
+ if not instr.visit_operands(cb):
+ return False
+ return True
+
+
@property
def instructions(self) -> Generator[HighLevelILInstruction, None, None]:
"""A generator of hlil instructions of the current function"""
diff --git a/python/lowlevelil.py b/python/lowlevelil.py
index 23830acb..5942de6d 100644
--- a/python/lowlevelil.py
+++ b/python/lowlevelil.py
@@ -20,7 +20,7 @@
import ctypes
import struct
-from typing import Generator, List, Optional, Dict, Union, Tuple, NewType, ClassVar, Set
+from typing import Generator, List, Optional, Dict, Union, Tuple, NewType, ClassVar, Set, Callable
from dataclasses import dataclass
# Binary Ninja components
@@ -57,6 +57,7 @@ LowLevelILOperandType = Union['LowLevelILOperationAndSize', 'ILRegister', 'ILFla
List['LowLevelILInstruction'], List[Union['ILFlag', 'ILRegister']], List['SSARegister'],
List['SSARegisterStack'], List['SSAFlag'], List['SSARegisterOrFlag'], None]
ILInstructionAttributeSet = Union[Set[ILInstructionAttribute], List[ILInstructionAttribute]]
+LowLevelILVisitorCallback = Callable[[str, LowLevelILOperandType, str, Optional['LowLevelILInstruction']], bool]
class LowLevelILLabel:
@@ -660,8 +661,88 @@ class LowLevelILInstruction(BaseILInstruction):
@property
def operands(self) -> List[LowLevelILOperandType]:
+ """Operands for the instruction"""
+ return list(map(lambda x: x[1], self.detailed_operands))
+
+ @property
+ def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
+ """
+ Returns a list of tuples containing the name of the operand, the operand, and the type of the operand.
+ Useful for iterating over all operands of an instruction and sub-instructions.
+ """
return []
+
+ def visit_all(self, cb: LowLevelILVisitorCallback,
+ name: str = "root", parent: Optional['LowLevelILInstruction'] = None) -> bool:
+ """
+ Visits all operands of this instruction and all operands of any sub-instructions.
+ Using pre-order traversal.
+
+ :param LowLevelILVisitorCallback cb: Callback function that takes the name of the operand, the operand, operand type, and parent instruction
+ :return: True if all instructions were visited, False if the callback returned False
+ """
+ if cb(name, self, "LowLevelILInstruction", parent) == False:
+ return False
+ for name, op, opType in self.detailed_operands:
+ if opType == "LowLevelILInstruction":
+ assert isinstance(op, LowLevelILInstruction)
+ if not op.visit_all(cb, name, self):
+ return False
+ elif opType == "List[LowLevelILInstruction]":
+ assert isinstance(op, list) and all(isinstance(i, LowLevelILInstruction) for i in op)
+ for i in op:
+ if not i.visit_all(cb, name, self): # type: ignore
+ return False
+ elif cb(name, op, opType, self) == False:
+ return False
+ return True
+
+ def visit_operands(self, cb: LowLevelILVisitorCallback,
+ name: str = "root", parent: Optional['LowLevelILInstruction'] = None) -> bool:
+ """
+ Visits all leaf operands of this instruction and any sub-instructions.
+
+ :param LowLevelILVisitorCallback cb: Callback function that takes the name of the operand, the operand, operand type, and parent instruction
+ :return: True if all instructions were visited, False if the callback returned False
+ """
+ for name, op, opType in self.detailed_operands:
+ if opType == "LowLevelILInstruction":
+ assert isinstance(op, LowLevelILInstruction)
+ if not op.visit_operands(cb, name, self):
+ return False
+ elif opType == "List[LowLevelILInstruction]":
+ assert isinstance(op, list) and all(isinstance(i, LowLevelILInstruction) for i in op)
+ for i in op:
+ if not i.visit_operands(cb, name, self): # type: ignore
+ return False
+ elif cb(name, op, opType, self) == False:
+ return False
+ return True
+
+ def visit(self, cb: LowLevelILVisitorCallback,
+ name: str = "root", parent: Optional['LowLevelILInstruction'] = None) -> bool:
+ """
+ Visits all LowLevelILInstructions in the operands of this instruction and any sub-instructions.
+
+ :param LowLevelILVisitorCallback cb: Callback function that takes the name of the operand, the operand, operand type, and parent instruction
+ :return: True if all instructions were visited, False if the callback returned False
+ """
+ if cb(name, self, "LowLevelILInstruction", parent) == False:
+ return False
+ for name, op, opType in self.detailed_operands:
+ if opType == "LowLevelILInstruction":
+ assert isinstance(op, LowLevelILInstruction)
+ if not op.visit(cb, name, self):
+ return False
+ elif opType == "List[LowLevelILInstruction]":
+ assert isinstance(op, list) and all(isinstance(i, LowLevelILInstruction) for i in op)
+ for i in op:
+ if not i.visit(cb, name, self): # type: ignore
+ return False
+ return True
+
+
@property
def prefix_operands(self) -> List[LowLevelILOperandType]:
"""All operands in the expression tree in prefix order"""
@@ -1036,8 +1117,11 @@ class LowLevelILBinaryBase(LowLevelILInstruction, BinaryOperation):
return self._get_expr(1)
@property
- def operands(self) -> List[LowLevelILOperandType]:
- return [self.left, self.right]
+ def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
+ return [
+ ("left", self.left, "LowLevelILInstruction"),
+ ("right", self.right, "LowLevelILInstruction"),
+ ]
@dataclass(frozen=True, repr=False, eq=False)
@@ -1060,8 +1144,12 @@ class LowLevelILCarryBase(LowLevelILInstruction, Carry):
return self._get_expr(2)
@property
- def operands(self) -> List[LowLevelILOperandType]:
- return [self.left, self.right, self.carry]
+ def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
+ return [
+ ("left", self.left, "LowLevelILInstruction"),
+ ("right", self.right, "LowLevelILInstruction"),
+ ("carry", self.carry, "LowLevelILInstruction"),
+ ]
@dataclass(frozen=True, repr=False, eq=False)
@@ -1071,8 +1159,10 @@ class LowLevelILUnaryBase(LowLevelILInstruction, UnaryOperation):
return self._get_expr(0)
@property
- def operands(self) -> List[LowLevelILOperandType]:
- return [self.src]
+ def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
+ return [
+ ("src", self.src, "LowLevelILInstruction"),
+ ]
@dataclass(frozen=True, repr=False, eq=False)
@@ -1121,8 +1211,10 @@ class LowLevelILConstantBase(LowLevelILInstruction, Constant):
return self._get_int(0)
@property
- def operands(self) -> List[LowLevelILOperandType]:
- return [self.constant]
+ def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
+ return [
+ ("constant", self.constant, "int"),
+ ]
@dataclass(frozen=True, repr=False, eq=False)
@@ -1192,8 +1284,10 @@ class LowLevelILJump(LowLevelILInstruction, Terminal):
return self._get_expr(0)
@property
- def operands(self) -> List[LowLevelILOperandType]:
- return [self.dest]
+ def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
+ return [
+ ("dest", self.dest, "LowLevelILInstruction"),
+ ]
@dataclass(frozen=True, repr=False, eq=False)
@@ -1203,8 +1297,10 @@ class LowLevelILCall(LowLevelILInstruction, Localcall):
return self._get_expr(0)
@property
- def operands(self) -> List[LowLevelILOperandType]:
- return [self.dest]
+ def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
+ return [
+ ("dest", self.dest, "LowLevelILInstruction"),
+ ]
@dataclass(frozen=True, repr=False, eq=False)
@@ -1214,8 +1310,10 @@ class LowLevelILTailcall(LowLevelILInstruction, Tailcall):
return self._get_expr(0)
@property
- def operands(self) -> List[LowLevelILOperandType]:
- return [self.dest]
+ def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
+ return [
+ ("dest", self.dest, "LowLevelILInstruction"),
+ ]
@dataclass(frozen=True, repr=False, eq=False)
@@ -1225,8 +1323,10 @@ class LowLevelILRet(LowLevelILInstruction, Return):
return self._get_expr(0)
@property
- def operands(self) -> List[LowLevelILOperandType]:
- return [self.dest]
+ def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
+ return [
+ ("dest", self.dest, "LowLevelILInstruction"),
+ ]
@dataclass(frozen=True, repr=False, eq=False)
@@ -1236,8 +1336,10 @@ class LowLevelILUnimplMem(LowLevelILInstruction, Memory):
return self._get_expr(0)
@property
- def operands(self) -> List[LowLevelILOperandType]:
- return [self.src]
+ def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
+ return [
+ ("src", self.src, "LowLevelILInstruction"),
+ ]
@dataclass(frozen=True, repr=False, eq=False)
@@ -1247,8 +1349,10 @@ class LowLevelILFsqrt(LowLevelILInstruction, FloatingPoint, Arithmetic):
return self._get_expr(0)
@property
- def operands(self) -> List[LowLevelILOperandType]:
- return [self.src]
+ def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
+ return [
+ ("src", self.src, "LowLevelILInstruction"),
+ ]
@dataclass(frozen=True, repr=False, eq=False)
@@ -1258,8 +1362,10 @@ class LowLevelILFneg(LowLevelILInstruction, FloatingPoint, Arithmetic):
return self._get_expr(0)
@property
- def operands(self) -> List[LowLevelILOperandType]:
- return [self.src]
+ def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
+ return [
+ ("src", self.src, "LowLevelILInstruction"),
+ ]
@dataclass(frozen=True, repr=False, eq=False)
@@ -1269,8 +1375,10 @@ class LowLevelILFabs(LowLevelILInstruction, FloatingPoint, Arithmetic):
return self._get_expr(0)
@property
- def operands(self) -> List[LowLevelILOperandType]:
- return [self.src]
+ def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
+ return [
+ ("src", self.src, "LowLevelILInstruction"),
+ ]
@dataclass(frozen=True, repr=False, eq=False)
@@ -1280,8 +1388,10 @@ class LowLevelILFloatToInt(LowLevelILInstruction, FloatingPoint, Arithmetic):
return self._get_expr(0)
@property
- def operands(self) -> List[LowLevelILOperandType]:
- return [self.src]
+ def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
+ return [
+ ("src", self.src, "LowLevelILInstruction"),
+ ]
@dataclass(frozen=True, repr=False, eq=False)
@@ -1291,8 +1401,10 @@ class LowLevelILIntToFloat(LowLevelILInstruction, FloatingPoint, Arithmetic):
return self._get_expr(0)
@property
- def operands(self) -> List[LowLevelILOperandType]:
- return [self.src]
+ def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
+ return [
+ ("src", self.src, "LowLevelILInstruction"),
+ ]
@dataclass(frozen=True, repr=False, eq=False)
@@ -1302,8 +1414,10 @@ class LowLevelILFloatConv(LowLevelILInstruction, FloatingPoint, Arithmetic):
return self._get_expr(0)
@property
- def operands(self) -> List[LowLevelILOperandType]:
- return [self.src]
+ def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
+ return [
+ ("src", self.src, "LowLevelILInstruction"),
+ ]
@dataclass(frozen=True, repr=False, eq=False)
@@ -1313,8 +1427,10 @@ class LowLevelILRoundToInt(LowLevelILInstruction, FloatingPoint, Arithmetic):
return self._get_expr(0)
@property
- def operands(self) -> List[LowLevelILOperandType]:
- return [self.src]
+ def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
+ return [
+ ("src", self.src, "LowLevelILInstruction"),
+ ]
@dataclass(frozen=True, repr=False, eq=False)
@@ -1324,8 +1440,10 @@ class LowLevelILFloor(LowLevelILInstruction, FloatingPoint, Arithmetic):
return self._get_expr(0)
@property
- def operands(self) -> List[LowLevelILOperandType]:
- return [self.src]
+ def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
+ return [
+ ("src", self.src, "LowLevelILInstruction"),
+ ]
@dataclass(frozen=True, repr=False, eq=False)
@@ -1335,8 +1453,10 @@ class LowLevelILCeil(LowLevelILInstruction, FloatingPoint, Arithmetic):
return self._get_expr(0)
@property
- def operands(self) -> List[LowLevelILOperandType]:
- return [self.src]
+ def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
+ return [
+ ("src", self.src, "LowLevelILInstruction"),
+ ]
@dataclass(frozen=True, repr=False, eq=False)
@@ -1346,8 +1466,10 @@ class LowLevelILFtrunc(LowLevelILInstruction, FloatingPoint, Arithmetic):
return self._get_expr(0)
@property
- def operands(self) -> List[LowLevelILOperandType]:
- return [self.src]
+ def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
+ return [
+ ("src", self.src, "LowLevelILInstruction"),
+ ]
@dataclass(frozen=True, repr=False, eq=False)
@@ -1357,8 +1479,10 @@ class LowLevelILLoad(LowLevelILInstruction, Load):
return self._get_expr(0)
@property
- def operands(self) -> List[LowLevelILOperandType]:
- return [self.src]
+ def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
+ return [
+ ("src", self.src, "LowLevelILInstruction"),
+ ]
@dataclass(frozen=True, repr=False, eq=False)
@@ -1368,8 +1492,10 @@ class LowLevelILPush(LowLevelILInstruction, StackOperation):
return self._get_expr(0)
@property
- def operands(self) -> List[LowLevelILOperandType]:
- return [self.src]
+ def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
+ return [
+ ("src", self.src, "LowLevelILInstruction"),
+ ]
@dataclass(frozen=True, repr=False, eq=False)
@@ -1379,8 +1505,10 @@ class LowLevelILReg(LowLevelILInstruction):
return self._get_reg(0)
@property
- def operands(self) -> List[LowLevelILOperandType]:
- return [self.src]
+ def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
+ return [
+ ("src", self.src, "ILRegister"),
+ ]
@dataclass(frozen=True, repr=False, eq=False)
@@ -1390,8 +1518,10 @@ class LowLevelILRegStackPop(LowLevelILInstruction, RegisterStack):
return self._get_reg_stack(0)
@property
- def operands(self) -> List[LowLevelILOperandType]:
- return [self.stack]
+ def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
+ return [
+ ("stack", self.stack, "ILRegisterStack"),
+ ]
@dataclass(frozen=True, repr=False, eq=False)
@@ -1401,8 +1531,10 @@ class LowLevelILRegStackFreeReg(LowLevelILInstruction, RegisterStack):
return self._get_reg(0)
@property
- def operands(self) -> List[LowLevelILOperandType]:
- return [self.dest]
+ def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
+ return [
+ ("dest", self.dest, "ILRegister"),
+ ]
@dataclass(frozen=True, repr=False, eq=False)
@@ -1422,8 +1554,10 @@ class LowLevelILFloatConst(LowLevelILConstantBase, FloatingPoint):
return self._get_float(0)
@property
- def operands(self) -> List[LowLevelILOperandType]:
- return [self.constant]
+ def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
+ return [
+ ("constant", self.constant, "Union[int, float]"),
+ ]
@dataclass(frozen=True, repr=False, eq=False)
@@ -1433,8 +1567,10 @@ class LowLevelILFlag(LowLevelILInstruction):
return self._get_flag(0)
@property
- def operands(self) -> List[LowLevelILOperandType]:
- return [self.src]
+ def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
+ return [
+ ("src", self.src, "ILFlag"),
+ ]
@dataclass(frozen=True, repr=False, eq=False)
@@ -1444,8 +1580,10 @@ class LowLevelILGoto(LowLevelILInstruction, Terminal):
return self._get_int(0)
@property
- def operands(self) -> List[LowLevelILOperandType]:
- return [self.dest]
+ def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
+ return [
+ ("dest", self.dest, "int"),
+ ]
@dataclass(frozen=True, repr=False, eq=False)
@@ -1455,8 +1593,10 @@ class LowLevelILFlagGroup(LowLevelILInstruction):
return self._get_sem_group(0)
@property
- def operands(self) -> List[LowLevelILOperandType]:
- return [self.semantic_group]
+ def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
+ return [
+ ("semantic_group", self.semantic_group, "ILSemanticFlagGroup"),
+ ]
@dataclass(frozen=True, repr=False, eq=False)
@@ -1466,8 +1606,10 @@ class LowLevelILBoolToInt(LowLevelILInstruction):
return self._get_expr(0)
@property
- def operands(self) -> List[LowLevelILOperandType]:
- return [self.src]
+ def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
+ return [
+ ("src", self.src, "LowLevelILInstruction"),
+ ]
@dataclass(frozen=True, repr=False, eq=False)
@@ -1477,8 +1619,10 @@ class LowLevelILTrap(LowLevelILInstruction, Terminal):
return self._get_int(0)
@property
- def operands(self) -> List[LowLevelILOperandType]:
- return [self.vector]
+ def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
+ return [
+ ("vector", self.vector, "int"),
+ ]
@dataclass(frozen=True, repr=False, eq=False)
@@ -1488,8 +1632,10 @@ class LowLevelILRegSplitDestSsa(LowLevelILInstruction, SSA):
return self._get_reg_ssa(0, 1)
@property
- def operands(self) -> List[LowLevelILOperandType]:
- return [self.dest]
+ def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
+ return [
+ ("dest", self.dest, "SSARegister"),
+ ]
@dataclass(frozen=True, repr=False, eq=False)
@@ -1503,8 +1649,11 @@ class LowLevelILRegStackDestSsa(LowLevelILInstruction, RegisterStack, SSA):
return self._get_reg_stack_ssa(0, 2)
@property
- def operands(self) -> List[LowLevelILOperandType]:
- return [self.dest, self.src]
+ def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
+ return [
+ ("dest", self.dest, "SSARegisterStack"),
+ ("src", self.src, "SSARegisterStack"),
+ ]
@dataclass(frozen=True, repr=False, eq=False)
@@ -1514,8 +1663,10 @@ class LowLevelILRegSsa(LowLevelILInstruction, SSA):
return self._get_reg_ssa(0, 1)
@property
- def operands(self) -> List[LowLevelILOperandType]:
- return [self.src]
+ def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
+ return [
+ ("src", self.src, "SSARegister"),
+ ]
@dataclass(frozen=True, repr=False, eq=False)
@@ -1525,8 +1676,10 @@ class LowLevelILFlagSsa(LowLevelILInstruction, SSA):
return self._get_flag_ssa(0, 1)
@property
- def operands(self) -> List[LowLevelILOperandType]:
- return [self.src]
+ def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
+ return [
+ ("src", self.src, "SSAFlag"),
+ ]
@dataclass(frozen=True, repr=False, eq=False)
@@ -1536,8 +1689,10 @@ class LowLevelILCallParam(LowLevelILInstruction, SSA):
return self._get_expr_list(0)
@property
- def operands(self) -> List[LowLevelILOperandType]:
- return [self.src]
+ def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
+ return [
+ ("src", self.src, "List[LowLevelILInstruction]"),
+ ]
@dataclass(frozen=True, repr=False, eq=False)
@@ -1551,8 +1706,11 @@ class LowLevelILMemPhi(LowLevelILInstruction, Memory, Phi):
return self._get_int_list(1)
@property
- def operands(self) -> List[LowLevelILOperandType]:
- return [self.dest_memory, self.src_memory]
+ def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
+ return [
+ ("dest_memory", self.dest_memory, "int"),
+ ("src_memory", self.src_memory, "List[int]"),
+ ]
@dataclass(frozen=True, repr=False, eq=False)
@@ -1566,8 +1724,11 @@ class LowLevelILSetReg(LowLevelILInstruction, SetReg):
return self._get_expr(1)
@property
- def operands(self) -> List[LowLevelILOperandType]:
- return [self.dest, self.src]
+ def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
+ return [
+ ("dest", self.dest, "ILRegister"),
+ ("src", self.src, "LowLevelILInstruction"),
+ ]
@dataclass(frozen=True, repr=False, eq=False)
@@ -1581,8 +1742,11 @@ class LowLevelILRegStackPush(LowLevelILInstruction, RegisterStack):
return self._get_expr(1)
@property
- def operands(self) -> List[LowLevelILOperandType]:
- return [self.stack, self.src]
+ def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
+ return [
+ ("stack", self.stack, "ILRegisterStack"),
+ ("src", self.src, "LowLevelILInstruction"),
+ ]
@dataclass(frozen=True, repr=False, eq=False)
@@ -1596,8 +1760,11 @@ class LowLevelILSetFlag(LowLevelILInstruction):
return self._get_expr(1)
@property
- def operands(self) -> List[LowLevelILOperandType]:
- return [self.dest, self.src]
+ def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
+ return [
+ ("dest", self.dest, "ILFlag"),
+ ("src", self.src, "LowLevelILInstruction"),
+ ]
@dataclass(frozen=True, repr=False, eq=False)
@@ -1611,8 +1778,11 @@ class LowLevelILStore(LowLevelILInstruction, Store):
return self._get_expr(1)
@property
- def operands(self) -> List[LowLevelILOperandType]:
- return [self.dest, self.src]
+ def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
+ return [
+ ("dest", self.dest, "LowLevelILInstruction"),
+ ("src", self.src, "LowLevelILInstruction"),
+ ]
@dataclass(frozen=True, repr=False, eq=False)
@@ -1626,8 +1796,11 @@ class LowLevelILRegSplit(LowLevelILInstruction):
return self._get_reg(1)
@property
- def operands(self) -> List[LowLevelILOperandType]:
- return [self.hi, self.lo]
+ def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
+ return [
+ ("hi", self.hi, "ILRegister"),
+ ("lo", self.lo, "ILRegister"),
+ ]
@dataclass(frozen=True, repr=False, eq=False)
@@ -1641,8 +1814,11 @@ class LowLevelILRegStackRel(LowLevelILInstruction, RegisterStack):
return self._get_expr(1)
@property
- def operands(self) -> List[LowLevelILOperandType]:
- return [self.stack, self.src]
+ def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
+ return [
+ ("stack", self.stack, "ILRegisterStack"),
+ ("src", self.src, "LowLevelILInstruction"),
+ ]
@dataclass(frozen=True, repr=False, eq=False)
@@ -1656,8 +1832,11 @@ class LowLevelILRegStackFreeRel(LowLevelILInstruction, RegisterStack):
return self._get_expr(1)
@property
- def operands(self) -> List[LowLevelILOperandType]:
- return [self.stack, self.dest]
+ def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
+ return [
+ ("stack", self.stack, "ILRegisterStack"),
+ ("dest", self.dest, "LowLevelILInstruction"),
+ ]
@dataclass(frozen=True, repr=False, eq=False)
@@ -1671,8 +1850,11 @@ class LowLevelILExternPtr(LowLevelILConstantBase):
return self._get_int(1)
@property
- def operands(self) -> List[LowLevelILOperandType]:
- return [self.constant, self.offset]
+ def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
+ return [
+ ("constant", self.constant, "int"),
+ ("offset", self.offset, "int"),
+ ]
@dataclass(frozen=True, repr=False, eq=False)
@@ -1686,8 +1868,11 @@ class LowLevelILFlagBit(LowLevelILInstruction):
return self._get_int(1)
@property
- def operands(self) -> List[LowLevelILOperandType]:
- return [self.src, self.bit]
+ def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
+ return [
+ ("src", self.src, "ILFlag"),
+ ("bit", self.bit, "int"),
+ ]
@dataclass(frozen=True, repr=False, eq=False)
@@ -1921,8 +2106,11 @@ class LowLevelILJumpTo(LowLevelILInstruction):
return self._get_target_map(1)
@property
- def operands(self) -> List[LowLevelILOperandType]:
- return [self.dest, self.targets]
+ def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
+ return [
+ ("dest", self.dest, "LowLevelILInstruction"),
+ ("targets", self.targets, "Dict[int, int]"),
+ ]
@dataclass(frozen=True, repr=False, eq=False)
@@ -1936,8 +2124,11 @@ class LowLevelILFlagCond(LowLevelILInstruction):
return self._get_sem_class(1)
@property
- def operands(self) -> List[LowLevelILOperandType]:
- return [self.condition, self.semantic_class]
+ def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
+ return [
+ ("condition", self.condition, "LowLevelILFlagCondition"),
+ ("semantic_class", self.semantic_class, "Optional[ILSemanticFlagClass]"),
+ ]
@dataclass(frozen=True, repr=False, eq=False)
@@ -1956,8 +2147,11 @@ class LowLevelILSetRegSsa(LowLevelILInstruction, SetReg, SSA):
return self._get_expr(2)
@property
- def operands(self) -> List[LowLevelILOperandType]:
- return [self.dest, self.src]
+ def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
+ return [
+ ("dest", self.dest, "SSARegister"),
+ ("src", self.src, "LowLevelILInstruction"),
+ ]
@dataclass(frozen=True, repr=False, eq=False)
@@ -1971,8 +2165,11 @@ class LowLevelILRegSsaPartial(LowLevelILInstruction, SetReg, SSA):
return self._get_reg(2)
@property
- def operands(self) -> List[LowLevelILOperandType]:
- return [self.full_reg, self.src]
+ def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
+ return [
+ ("full_reg", self.full_reg, "SSARegister"),
+ ("src", self.src, "ILRegister"),
+ ]
@dataclass(frozen=True, repr=False, eq=False)
@@ -1986,8 +2183,11 @@ class LowLevelILRegSplitSsa(LowLevelILInstruction, SetReg, SSA):
return self._get_reg_ssa(2, 3)
@property
- def operands(self) -> List[LowLevelILOperandType]:
- return [self.hi, self.lo]
+ def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
+ return [
+ ("hi", self.hi, "SSARegister"),
+ ("lo", self.lo, "SSARegister"),
+ ]
@dataclass(frozen=True, repr=False, eq=False)
@@ -2001,9 +2201,11 @@ class LowLevelILRegStackAbsSsa(LowLevelILInstruction, RegisterStack, SSA):
return self._get_reg(2)
@property
- def operands(self) -> List[LowLevelILOperandType]:
- return [self.stack, self.src]
-
+ def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
+ return [
+ ("stack", self.stack, "SSARegisterStack"),
+ ("src", self.src, "ILRegister"),
+ ]
@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILRegStackFreeAbsSsa(LowLevelILInstruction, RegisterStack):
@@ -2016,8 +2218,11 @@ class LowLevelILRegStackFreeAbsSsa(LowLevelILInstruction, RegisterStack):
return self._get_reg(1)
@property
- def operands(self) -> List[LowLevelILOperandType]:
- return [self.stack, self.dest]
+ def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
+ return [
+ ("stack", self.stack, "LowLevelILInstruction"),
+ ("dest", self.dest, "ILRegister"),
+ ]
@dataclass(frozen=True, repr=False, eq=False)
@@ -2031,8 +2236,11 @@ class LowLevelILSetFlagSsa(LowLevelILInstruction, SSA):
return self._get_expr(2)
@property
- def operands(self) -> List[LowLevelILOperandType]:
- return [self.dest, self.src]
+ def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
+ return [
+ ("dest", self.dest, "SSAFlag"),
+ ("src", self.src, "LowLevelILInstruction"),
+ ]
@dataclass(frozen=True, repr=False, eq=False)
@@ -2046,8 +2254,11 @@ class LowLevelILFlagBitSsa(LowLevelILInstruction, SSA):
return self._get_int(2)
@property
- def operands(self) -> List[LowLevelILOperandType]:
- return [self.src, self.bit]
+ def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
+ return [
+ ("src", self.src, "SSAFlag"),
+ ("bit", self.bit, "int"),
+ ]
@dataclass(frozen=True, repr=False, eq=False)
@@ -2061,8 +2272,11 @@ class LowLevelILCallOutputSsa(LowLevelILInstruction, SSA):
return self._get_reg_ssa_list(1)
@property
- def operands(self) -> List[LowLevelILOperandType]:
- return [self.dest_memory, self.dest]
+ def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
+ return [
+ ("dest_memory", self.dest_memory, "int"),
+ ("dest", self.dest, "List[SSARegister]"),
+ ]
@dataclass(frozen=True, repr=False, eq=False)
@@ -2076,8 +2290,11 @@ class LowLevelILCallStackSsa(LowLevelILInstruction, SSA):
return self._get_int(2)
@property
- def operands(self) -> List[LowLevelILOperandType]:
- return [self.src, self.src_memory]
+ def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
+ return [
+ ("src", self.src, "SSARegister"),
+ ("src_memory", self.src_memory, "int"),
+ ]
@dataclass(frozen=True, repr=False, eq=False)
@@ -2091,8 +2308,11 @@ class LowLevelILLoadSsa(LowLevelILInstruction, Load, SSA):
return self._get_int(1)
@property
- def operands(self) -> List[LowLevelILOperandType]:
- return [self.src, self.src_memory]
+ def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
+ return [
+ ("src", self.src, "LowLevelILInstruction"),
+ ("src_memory", self.src_memory, "int"),
+ ]
@dataclass(frozen=True, repr=False, eq=False)
@@ -2106,8 +2326,11 @@ class LowLevelILRegPhi(LowLevelILInstruction, Phi):
return self._get_reg_ssa_list(2)
@property
- def operands(self) -> List[LowLevelILOperandType]:
- return [self.dest, self.src]
+ def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
+ return [
+ ("dest", self.dest, "SSARegister"),
+ ("src", self.src, "List[SSARegister]"),
+ ]
@dataclass(frozen=True, repr=False, eq=False)
@@ -2121,8 +2344,11 @@ class LowLevelILRegStackPhi(LowLevelILInstruction, RegisterStack, Phi):
return self._get_reg_stack_ssa_list(2)
@property
- def operands(self) -> List[LowLevelILOperandType]:
- return [self.dest, self.src]
+ def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
+ return [
+ ("dest", self.dest, "SSARegisterStack"),
+ ("src", self.src, "List[SSARegisterStack]"),
+ ]
@dataclass(frozen=True, repr=False, eq=False)
@@ -2136,8 +2362,11 @@ class LowLevelILFlagPhi(LowLevelILInstruction, Phi):
return self._get_flag_ssa_list(2)
@property
- def operands(self) -> List[LowLevelILOperandType]:
- return [self.dest, self.src]
+ def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
+ return [
+ ("dest", self.dest, "SSAFlag"),
+ ("src", self.src, "List[SSAFlag]"),
+ ]
@dataclass(frozen=True, repr=False, eq=False)
@@ -2155,8 +2384,12 @@ class LowLevelILSetRegSplit(LowLevelILInstruction, SetReg):
return self._get_expr(2)
@property
- def operands(self) -> List[LowLevelILOperandType]:
- return [self.hi, self.lo, self.src]
+ def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
+ return [
+ ("hi", self.hi, "ILRegister"),
+ ("lo", self.lo, "ILRegister"),
+ ("src", self.src, "LowLevelILInstruction"),
+ ]
@dataclass(frozen=True, repr=False, eq=False)
@@ -2174,8 +2407,12 @@ class LowLevelILSetRegStackRel(LowLevelILInstruction, RegisterStack):
return self._get_expr(2)
@property
- def operands(self) -> List[LowLevelILOperandType]:
- return [self.stack, self.dest, self.src]
+ def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
+ return [
+ ("stack", self.stack, "ILRegisterStack"),
+ ("dest", self.dest, "LowLevelILInstruction"),
+ ("src", self.src, "LowLevelILInstruction"),
+ ]
@dataclass(frozen=True, repr=False, eq=False)
@@ -2213,8 +2450,12 @@ class LowLevelILCallStackAdjust(LowLevelILInstruction, Localcall):
return self._get_reg_stack_adjust(2)
@property
- def operands(self) -> List[LowLevelILOperandType]:
- return [self.dest, self.stack_adjustment, self.reg_stack_adjustments]
+ def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
+ return [
+ ("dest", self.dest, "LowLevelILInstruction"),
+ ("stack_adjustment", self.stack_adjustment, "int"),
+ ("reg_stack_adjustments", self.reg_stack_adjustments, "Dict[RegisterStackName, int]"),
+ ]
@dataclass(frozen=True, repr=False, eq=False)
@@ -2232,8 +2473,12 @@ class LowLevelILIf(LowLevelILInstruction, ControlFlow):
return self._get_int(2)
@property
- def operands(self) -> List[LowLevelILOperandType]:
- return [self.condition, self.true, self.false]
+ def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
+ return [
+ ("condition", self.condition, "LowLevelILInstruction"),
+ ("true", self.true, "int"),
+ ("false", self.false, "int"),
+ ]
@dataclass(frozen=True, repr=False, eq=False)
@@ -2251,8 +2496,12 @@ class LowLevelILIntrinsic(LowLevelILInstruction, Intrinsic):
return self._get_expr(3)
@property
- def operands(self) -> List[LowLevelILOperandType]:
- return [self.output, self.intrinsic, self.param]
+ def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
+ return [
+ ("output", self.output, "List[Union[ILFlag, ILRegister]]"),
+ ("intrinsic", self.intrinsic, "ILIntrinsic"),
+ ("param", self.param, "LowLevelILInstruction"),
+ ]
@dataclass(frozen=True, repr=False, eq=False)
@@ -2270,8 +2519,12 @@ class LowLevelILIntrinsicSsa(LowLevelILInstruction, SSA):
return self._get_expr(3)
@property
- def operands(self) -> List[LowLevelILOperandType]:
- return [self.output, self.intrinsic, self.param]
+ def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
+ return [
+ ("output", self.output, "List[SSARegisterOrFlag]"),
+ ("intrinsic", self.intrinsic, "ILIntrinsic"),
+ ("param", self.param, "LowLevelILInstruction"),
+ ]
@dataclass(frozen=True, repr=False, eq=False)
@@ -2289,8 +2542,12 @@ class LowLevelILSetRegSsaPartial(LowLevelILInstruction, SetReg, SSA):
return self._get_expr(3)
@property
- def operands(self) -> List[LowLevelILOperandType]:
- return [self.full_reg, self.dest, self.src]
+ def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
+ return [
+ ("full_reg", self.full_reg, "SSARegister"),
+ ("dest", self.dest, "ILRegister"),
+ ("src", self.src, "LowLevelILInstruction"),
+ ]
@dataclass(frozen=True, repr=False, eq=False)
@@ -2308,8 +2565,12 @@ class LowLevelILSetRegSplitSsa(LowLevelILInstruction, SetReg, SSA):
return self._get_expr(2)
@property
- def operands(self) -> List[LowLevelILOperandType]:
- return [self.hi, self.lo, self.src]
+ def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
+ return [
+ ("hi", self.hi, "LowLevelILInstruction"),
+ ("lo", self.lo, "LowLevelILInstruction"),
+ ("src", self.src, "LowLevelILInstruction"),
+ ]
@dataclass(frozen=True, repr=False, eq=False)
@@ -2327,8 +2588,12 @@ class LowLevelILSetRegStackAbsSsa(LowLevelILInstruction, RegisterStack, SSA):
return self._get_expr(2)
@property
- def operands(self) -> List[LowLevelILOperandType]:
- return [self.stack, self.dest, self.src]
+ def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
+ return [
+ ("stack", self.stack, "LowLevelILInstruction"),
+ ("dest", self.dest, "ILRegister"),
+ ("src", self.src, "LowLevelILInstruction"),
+ ]
@dataclass(frozen=True, repr=False, eq=False)
@@ -2346,8 +2611,12 @@ class LowLevelILRegStackRelSsa(LowLevelILInstruction, RegisterStack, SSA):
return self._get_expr(3)
@property
- def operands(self) -> List[LowLevelILOperandType]:
- return [self.stack, self.src, self.top]
+ def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
+ return [
+ ("stack", self.stack, "SSARegisterStack"),
+ ("src", self.src, "LowLevelILInstruction"),
+ ("top", self.top, "LowLevelILInstruction"),
+ ]
@dataclass(frozen=True, repr=False, eq=False)
@@ -2365,8 +2634,12 @@ class LowLevelILRegStackFreeRelSsa(LowLevelILInstruction, RegisterStack, SSA):
return self._get_expr(2)
@property
- def operands(self) -> List[LowLevelILOperandType]:
- return [self.stack, self.dest, self.top]
+ def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
+ return [
+ ("stack", self.stack, "LowLevelILInstruction"),
+ ("dest", self.dest, "LowLevelILInstruction"),
+ ("top", self.top, "LowLevelILInstruction"),
+ ]
@dataclass(frozen=True, repr=False, eq=False)
@@ -2384,8 +2657,12 @@ class LowLevelILSyscallSsa(LowLevelILInstruction, Syscall, SSA):
return self._get_expr(2)
@property
- def operands(self) -> List[LowLevelILOperandType]:
- return [self.output, self.stack, self.param]
+ def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
+ return [
+ ("output", self.output, "LowLevelILInstruction"),
+ ("stack", self.stack, "LowLevelILInstruction"),
+ ("param", self.param, "LowLevelILInstruction"),
+ ]
@dataclass(frozen=True, repr=False, eq=False)
@@ -2407,8 +2684,13 @@ class LowLevelILSetRegStackRelSsa(LowLevelILInstruction, RegisterStack, SSA):
return self._get_expr(3)
@property
- def operands(self) -> List[LowLevelILOperandType]:
- return [self.stack, self.dest, self.top, self.src]
+ def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
+ return [
+ ("stack", self.stack, "LowLevelILInstruction"),
+ ("dest", self.dest, "LowLevelILInstruction"),
+ ("top", self.top, "LowLevelILInstruction"),
+ ("src", self.src, "LowLevelILInstruction"),
+ ]
@dataclass(frozen=True, repr=False, eq=False)
@@ -2430,8 +2712,13 @@ class LowLevelILCallSsa(LowLevelILInstruction, Localcall, SSA):
return self._get_expr(3)
@property
- def operands(self) -> List[LowLevelILOperandType]:
- return [self.output, self.dest, self.stack, self.param]
+ def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
+ return [
+ ("output", self.output, "LowLevelILInstruction"),
+ ("dest", self.dest, "LowLevelILInstruction"),
+ ("stack", self.stack, "LowLevelILInstruction"),
+ ("param", self.param, "LowLevelILInstruction"),
+ ]
@dataclass(frozen=True, repr=False, eq=False)
@@ -2453,8 +2740,13 @@ class LowLevelILTailcallSsa(LowLevelILInstruction, Tailcall, SSA, Terminal):
return self._get_expr(3)
@property
- def operands(self) -> List[LowLevelILOperandType]:
- return [self.output, self.dest, self.stack, self.param]
+ def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
+ return [
+ ("output", self.output, "LowLevelILInstruction"),
+ ("dest", self.dest, "LowLevelILInstruction"),
+ ("stack", self.stack, "LowLevelILInstruction"),
+ ("param", self.param, "LowLevelILInstruction"),
+ ]
@dataclass(frozen=True, repr=False, eq=False)
@@ -2476,8 +2768,13 @@ class LowLevelILStoreSsa(LowLevelILInstruction, Store, SSA):
return self._get_expr(3)
@property
- def operands(self) -> List[LowLevelILOperandType]:
- return [self.dest, self.dest_memory, self.src_memory, self.src]
+ def detailed_operands(self) -> List[Tuple[str, LowLevelILOperandType, str]]:
+ return [
+ ("dest", self.dest, "LowLevelILInstruction"),
+ ("dest_memory", self.dest_memory, "int"),
+ ("src_memory", self.src_memory, "int"),
+ ("src", self.src, "LowLevelILInstruction"),
+ ]
ILInstruction:Dict[LowLevelILOperation, LowLevelILInstruction] = { # type: ignore
@@ -2821,6 +3118,44 @@ class LowLevelILFunction:
for block in self.basic_blocks:
yield from block
+ def visit(self, cb: LowLevelILVisitorCallback) -> bool:
+ """
+ Iterates over all the instructions in the function and calls the callback function
+ for each instruction and each sub-instruction.
+
+ :param LowLevelILVisitorCallback cb: Callback function that takes the name of the operand, the operand, operand type, and parent instruction
+ :return: True if all instructions were visited, False if the callback function returned False.
+ """
+ for instr in self.instructions:
+ if not instr.visit(cb):
+ return False
+ return True
+
+ def visit_all(self, cb: LowLevelILVisitorCallback) -> bool:
+ """
+ Iterates over all the instructions in the function and calls the callback function for each instruction and their operands.
+
+ :param LowLevelILVisitorCallback cb: Callback function that takes the name of the operand, the operand, operand type, and parent instruction
+ :return: True if all instructions were visited, False if the callback function returned False.
+ """
+ for instr in self.instructions:
+ if not instr.visit_all(cb):
+ return False
+ return True
+
+ def visit_operands(self, cb: LowLevelILVisitorCallback) -> bool:
+ """
+ Iterates over all the instructions in the function and calls the callback function for each operand and
+ the operands of each sub-instruction.
+
+ :param LowLevelILVisitorCallback cb: Callback function that takes the name of the operand, the operand, operand type, and parent instruction
+ :return: True if all instructions were visited, False if the callback function returned False.
+ """
+ for instr in self.instructions:
+ if not instr.visit_operands(cb):
+ return False
+ return True
+
@property
def ssa_form(self) -> 'LowLevelILFunction':
"""Low level IL in SSA form (read-only)"""
diff --git a/python/mediumlevelil.py b/python/mediumlevelil.py
index 89eefea3..94311f13 100644
--- a/python/mediumlevelil.py
+++ b/python/mediumlevelil.py
@@ -1237,12 +1237,13 @@ class MediumLevelILCallOutput(MediumLevelILInstruction):
return self._get_var_list(0, 1)
@property
+ def detailed_operands(self) -> List[Tuple[str, MediumLevelILOperandType, str]]:
+ return [("dest", self.dest, "List[Variable]")]
+
+ @property
def vars_written(self) -> List[variable.Variable]:
return self.dest
- @property
- def detailed_operands(self) -> List[Tuple[str, MediumLevelILOperandType, str]]:
- return [("dest", self.dest, "List[Variable]")]
@dataclass(frozen=True, repr=False, eq=False)
@@ -1724,7 +1725,7 @@ class MediumLevelILSyscall(MediumLevelILInstruction, Syscall):
@property
def detailed_operands(self) -> List[Tuple[str, MediumLevelILOperandType, str]]:
return [
- ('output', self.output, 'List[variable.Variable]'),
+ ('output', self.output, 'List[Variable]'),
('params', self.params, 'List[MediumLevelILInstruction]'),
]
@@ -1794,16 +1795,16 @@ class MediumLevelILCallOutputSsa(MediumLevelILInstruction, SSA):
return self._get_var_ssa_list(1, 2)
@property
- def vars_written(self) -> List[SSAVariable]:
- return self.dest
-
- @property
def detailed_operands(self) -> List[Tuple[str, MediumLevelILOperandType, str]]:
return [
('dest_memory', self.dest_memory, 'int'),
('dest', self.dest, 'List[SSAVariable]'),
]
+ @property
+ def vars_written(self) -> List[SSAVariable]:
+ return self.dest
+
@dataclass(frozen=True, repr=False, eq=False)
class MediumLevelILCallParamSsa(MediumLevelILInstruction, SSA):
@@ -2041,8 +2042,8 @@ class MediumLevelILSyscallUntyped(MediumLevelILCallBase, Syscall):
@property
def detailed_operands(self) -> List[Tuple[str, MediumLevelILOperandType, str]]:
return [
- ('output', self.output, 'List[variable.Variable]'),
- ('params', self.params, 'List[variable.Variable]'),
+ ('output', self.output, 'List[Variable]'),
+ ('params', self.params, 'List[Variable]'),
('stack', self.stack, 'MediumLevelILInstruction'),
]
@@ -2064,8 +2065,8 @@ class MediumLevelILIntrinsic(MediumLevelILInstruction, Intrinsic):
@property
def detailed_operands(self) -> List[Tuple[str, MediumLevelILOperandType, str]]:
return [
- ('output', self.output, 'List[variable.Variable]'),
- ('intrinsic', self.intrinsic, "'lowlevelil.ILIntrinsic'"),
+ ('output', self.output, 'List[Variable]'),
+ ('intrinsic', self.intrinsic, "ILIntrinsic"),
('params', self.params, 'List[MediumLevelILInstruction]'),
]
@@ -2099,7 +2100,7 @@ class MediumLevelILIntrinsicSsa(MediumLevelILInstruction, SSA):
def detailed_operands(self) -> List[Tuple[str, MediumLevelILOperandType, str]]:
return [
('output', self.output, 'List[SSAVariable]'),
- ('intrinsic', self.intrinsic, "lowlevelil.ILIntrinsic"),
+ ('intrinsic', self.intrinsic, 'ILIntrinsic'),
('params', self.params, 'List[MediumLevelILInstruction]'),
]
@@ -2334,7 +2335,7 @@ class MediumLevelILSetVarField(MediumLevelILInstruction, SetVar):
@property
def detailed_operands(self) -> List[Tuple[str, MediumLevelILOperandType, str]]:
return [
- ('dest', self.dest, 'variable.Variable'),
+ ('dest', self.dest, 'Variable'),
('offset', self.offset, 'int'),
('src', self.src, 'MediumLevelILInstruction'),
]
@@ -2357,8 +2358,8 @@ class MediumLevelILSetVarSplit(MediumLevelILInstruction, SetVar):
@property
def detailed_operands(self) -> List[Tuple[str, MediumLevelILOperandType, str]]:
return [
- ('high', self.high, 'variable.Variable'),
- ('low', self.low, 'variable.Variable'),
+ ('high', self.high, 'Variable'),
+ ('low', self.low, 'Variable'),
('src', self.src, 'MediumLevelILInstruction'),
]
@@ -2428,7 +2429,7 @@ class MediumLevelILCall(MediumLevelILCallBase, Localcall):
@property
def detailed_operands(self) -> List[Tuple[str, MediumLevelILOperandType, str]]:
return [
- ('output', self.output, 'List[variable.Variable]'),
+ ('output', self.output, 'List[Variable]'),
('dest', self.dest, 'MediumLevelILInstruction'),
('params', self.params, 'List[MediumLevelILInstruction]'),
]
@@ -2482,9 +2483,9 @@ class MediumLevelILTailcallUntyped(MediumLevelILCallBase, Tailcall):
@property
def detailed_operands(self) -> List[Tuple[str, MediumLevelILOperandType, str]]:
return [
- ('output', self.output, 'List[variable.Variable]'),
+ ('output', self.output, 'List[Variable]'),
('dest', self.dest, 'MediumLevelILInstruction'),
- ('params', self.params, 'List[variable.Variable]'),
+ ('params', self.params, 'List[Variable]'),
('stack', self.stack, 'MediumLevelILInstruction'),
]
@@ -2591,7 +2592,7 @@ class MediumLevelILTailcall(MediumLevelILCallBase, Tailcall):
@property
def detailed_operands(self) -> List[Tuple[str, MediumLevelILOperandType, str]]:
return [
- ('output', self.output, 'List[variable.Variable]'),
+ ('output', self.output, 'List[Variable]'),
('dest', self.dest, 'MediumLevelILInstruction'),
('params', self.params, 'List[MediumLevelILInstruction]'),
]
@@ -2732,9 +2733,9 @@ class MediumLevelILCallUntyped(MediumLevelILCallBase, Localcall):
@property
def detailed_operands(self) -> List[Tuple[str, MediumLevelILOperandType, str]]:
return [
- ('output', self.output, 'List[variable.Variable]'),
+ ('output', self.output, 'List[Variable]'),
('dest', self.dest, 'MediumLevelILInstruction'),
- ('params', self.params, 'List[variable.Variable]'),
+ ('params', self.params, 'List[Variable]'),
('stack', self.stack, 'MediumLevelILInstruction'),
]