summaryrefslogtreecommitdiff
path: root/python
diff options
context:
space:
mode:
authorGlenn Smith <glenn@vector35.com>2024-03-07 21:32:43 -0500
committerGlenn Smith <glenn@vector35.com>2024-03-07 21:32:43 -0500
commit4620519194636807511824023284542848735054 (patch)
tree79f124def81e468f1e83a305174725ca1ff34fa0 /python
parent72cc84aabd188e4add6e5012df86414b65d95bc8 (diff)
Python: More IL expr functions
- XLILFunction.get_expr: Get an expr by index - XLILFunction.copy_expr: Copy an IL expr to a new expr - XLILInstruction.raw_operands: the straight integers from the core - Extra accessors on XLILLabel
Diffstat (limited to 'python')
-rw-r--r--python/highlevelil.py42
-rw-r--r--python/lowlevelil.py58
-rw-r--r--python/mediumlevelil.py58
3 files changed, 154 insertions, 4 deletions
diff --git a/python/highlevelil.py b/python/highlevelil.py
index 7efbcbb8..2b4d9153 100644
--- a/python/highlevelil.py
+++ b/python/highlevelil.py
@@ -767,6 +767,11 @@ class HighLevelILInstruction(BaseILInstruction):
return GotoLabel(self.function, self.core_instr.operands[operand_index])
@property
+ def raw_operands(self) -> OperandsType:
+ """Raw operand expression indices as specified by the core structure (read-only)"""
+ return self.instr.operands
+
+ @property
def operands(self) -> List[HighLevelILOperandType]:
"""Operands for the instruction"""
return list(map(lambda x: x[1], self.detailed_operands))
@@ -2783,6 +2788,43 @@ class HighLevelILFunction:
operation_value = operation.value
return ExpressionIndex(core.BNHighLevelILAddExpr(self.handle, operation_value, size, a, b, c, d, e))
+ def get_expr_count(self) -> int:
+ """
+ ``get_expr_count`` gives a the total number of expressions in this IL function
+
+ You can use this to enumerate all expressions in conjunction with :py:func:`get_expr`
+
+ .. warning :: Not all IL expressions are valid, even if their index is within the bounds of the function,
+ they might not be used by the function and might not contain properly structured data.
+
+ :return: The number of expressions in the function
+ """
+ return core.BNGetHighLevelILExprCount(self.handle)
+
+ def get_expr(self, index: ExpressionIndex) -> Optional[HighLevelILInstruction]:
+ """
+ ``get_expr`` retrieves the IL expression at a given expression index in the function.
+
+ .. warning :: Not all IL expressions are valid, even if their index is within the bounds of the function,
+ they might not be used by the function and might not contain properly structured data.
+
+ :param index: Index of desired expression in function
+ :return: A HighLevelILInstruction object for the expression, if it exists. Otherwise, None
+ """
+ if index >= self.get_expr_count():
+ return None
+
+ return HighLevelILInstruction.create(self, index)
+
+ def copy_expr(self, original: HighLevelILInstruction) -> ExpressionIndex:
+ """
+ ``copy_expr`` adds an expression to the function which is equivalent to the given expression
+
+ :param HighLevelILInstruction original: the original IL Instruction you want to copy
+ :return: The index of the newly copied expression
+ """
+ return self.expr(original.operation, original.raw_operands[0], original.raw_operands[1], original.raw_operands[2], original.raw_operands[3], original.raw_operands[4], original.size)
+
def replace_expr(self, original: InstructionOrExpression, new: InstructionOrExpression) -> None:
"""
``replace_expr`` allows modification of HLIL expressions
diff --git a/python/lowlevelil.py b/python/lowlevelil.py
index 16ffbd88..02586113 100644
--- a/python/lowlevelil.py
+++ b/python/lowlevelil.py
@@ -69,6 +69,26 @@ class LowLevelILLabel:
else:
self.handle = handle
+ @property
+ def ref(self) -> bool:
+ return self.handle[0].ref
+
+ @ref.setter
+ def ref(self, value):
+ self.handle[0].ref = value
+
+ @property
+ def resolved(self) -> bool:
+ return self.handle[0].resolved
+
+ @property
+ def operand(self) -> InstructionIndex:
+ return InstructionIndex(self.handle[0].operand)
+
+ @operand.setter
+ def operand(self, value: InstructionIndex):
+ self.handle[0].operand = int(value)
+
@dataclass(frozen=True)
class ILRegister:
@@ -671,6 +691,11 @@ class LowLevelILInstruction(BaseILInstruction):
return result
@property
+ def raw_operands(self) -> OperandsType:
+ """Raw operand expression indices as specified by the core structure (read-only)"""
+ return self.instr.operands
+
+ @property
def operands(self) -> List[LowLevelILOperandType]:
"""Operands for the instruction"""
return list(map(lambda x: x[1], self.detailed_operands))
@@ -3232,7 +3257,7 @@ class LowLevelILFunction:
def __hash__(self):
return hash(ctypes.addressof(self.handle.contents))
- def __getitem__(self, i:ExpressionIndex) -> LowLevelILInstruction:
+ def __getitem__(self, i: InstructionIndex) -> LowLevelILInstruction:
if isinstance(i, slice) or isinstance(i, tuple):
raise IndexError("expected integer instruction index")
if i < -len(self) or i >= len(self):
@@ -3725,10 +3750,39 @@ class LowLevelILFunction:
"""
``get_expr_count`` gives a the total number of expressions in this IL function
- You can use this to enumerate all expressions in conjunction with LowLevelILInstruction.create()
+ You can use this to enumerate all expressions in conjunction with :py:func:`get_expr`
+
+ .. warning :: Not all IL expressions are valid, even if their index is within the returned value from this,
+ they might not be used by the function and might not contain properly structured data.
+
+ :return: The number of expressions in the function
"""
return core.BNGetLowLevelILExprCount(self.handle)
+ def get_expr(self, index: ExpressionIndex) -> Optional[LowLevelILInstruction]:
+ """
+ ``get_expr`` retrieves the IL expression at a given expression index in the function.
+
+ .. warning :: Not all IL expressions are valid, even if their index is within the bounds of the function,
+ they might not be used by the function and might not contain properly structured data.
+
+ :param index: Index of desired expression in function
+ :return: A LowLevelILInstruction object for the expression, if it exists. Otherwise, None
+ """
+ if index >= self.get_expr_count():
+ return None
+
+ return LowLevelILInstruction.create(self, index)
+
+ def copy_expr(self, original: LowLevelILInstruction) -> ExpressionIndex:
+ """
+ ``copy_expr`` adds an expression to the function which is equivalent to the given expression
+
+ :param LowLevelILInstruction original: the original IL Instruction you want to copy
+ :return: The index of the newly copied expression
+ """
+ return self.expr(original.operation, original.raw_operands[0], original.raw_operands[1], original.raw_operands[2], original.raw_operands[3], original.size, original.flags)
+
def replace_expr(self, original: InstructionOrExpression, new: InstructionOrExpression) -> None:
"""
``replace_expr`` allows modification of expressions but ONLY during lifting.
diff --git a/python/mediumlevelil.py b/python/mediumlevelil.py
index 159299c7..e857920f 100644
--- a/python/mediumlevelil.py
+++ b/python/mediumlevelil.py
@@ -109,6 +109,26 @@ class MediumLevelILLabel:
else:
self.handle = handle
+ @property
+ def ref(self) -> bool:
+ return self.handle[0].ref
+
+ @ref.setter
+ def ref(self, value):
+ self.handle[0].ref = value
+
+ @property
+ def resolved(self) -> bool:
+ return self.handle[0].resolved
+
+ @property
+ def operand(self) -> InstructionIndex:
+ return InstructionIndex(self.handle[0].operand)
+
+ @operand.setter
+ def operand(self, value: InstructionIndex):
+ self.handle[0].operand = int(value)
+
@dataclass(frozen=True, repr=False)
class MediumLevelILOperationAndSize:
@@ -423,6 +443,11 @@ class MediumLevelILInstruction(BaseILInstruction):
return list(map(lambda x: x[1], self.detailed_operands))
@property
+ def raw_operands(self) -> OperandsType:
+ """Raw operand expression indices as specified by the core structure (read-only)"""
+ return self.instr.operands
+
+ @property
def detailed_operands(self) -> List[Tuple[str, MediumLevelILOperandType, str]]:
"""
Returns a list of tuples containing the name of the operand, the operand, and the type of the operand.
@@ -3394,9 +3419,38 @@ class MediumLevelILFunction:
"""
``get_expr_count`` gives a the total number of expressions in this IL function
- You can use this to enumerate all expressions in conjunction with MediumLevelILInstruction.create()
+ You can use this to enumerate all expressions in conjunction with :py:func:`get_expr`
+
+ .. warning :: Not all IL expressions are valid, even if their index is within the bounds of the function,
+ they might not be used by the function and might not contain properly structured data.
+
+ :return: The number of expressions in the function
+ """
+ return core.BNGetMediumLevelILExprCount(self.handle)
+
+ def get_expr(self, index: ExpressionIndex) -> Optional[MediumLevelILInstruction]:
+ """
+ ``get_expr`` retrieves the IL expression at a given expression index in the function.
+
+ .. warning :: Not all IL expressions are valid, even if their index is within the bounds of the function,
+ they might not be used by the function and might not contain properly structured data.
+
+ :param index: Index of desired expression in function
+ :return: A MediumLevelILInstruction object for the expression, if it exists. Otherwise, None
+ """
+ if index >= self.get_expr_count():
+ return None
+
+ return MediumLevelILInstruction.create(self, index)
+
+ def copy_expr(self, original: MediumLevelILInstruction) -> ExpressionIndex:
+ """
+ ``copy_expr`` adds an expression to the function which is equivalent to the given expression
+
+ :param MediumLevelILInstruction original: the original IL Instruction you want to copy
+ :return: The index of the newly copied expression
"""
- return core.BNGeMediumLevelILExprCount(self.handle)
+ return self.expr(original.operation, original.raw_operands[0], original.raw_operands[1], original.raw_operands[2], original.raw_operands[3], original.raw_operands[4], original.size)
def replace_expr(self, original: InstructionOrExpression, new: InstructionOrExpression) -> None:
"""