summaryrefslogtreecommitdiff
path: root/python/lowlevelil.py
diff options
context:
space:
mode:
authorGlenn Smith <glenn@vector35.com>2025-03-06 17:14:55 -0500
committerGlenn Smith <glenn@vector35.com>2025-03-06 17:16:20 -0500
commit5192206454838298978583761915446906174711 (patch)
tree883ab60668b09be7bacb1836e0f5a5b7a36d70ee /python/lowlevelil.py
parent5736062338006550996756091378670665643994 (diff)
Python: Add LLILFunction.translate and sample workflow using it
Diffstat (limited to 'python/lowlevelil.py')
-rw-r--r--python/lowlevelil.py31
1 files changed, 31 insertions, 0 deletions
diff --git a/python/lowlevelil.py b/python/lowlevelil.py
index b8fe0b94..f37e53a2 100644
--- a/python/lowlevelil.py
+++ b/python/lowlevelil.py
@@ -4126,6 +4126,37 @@ class LowLevelILFunction:
raise NotImplementedError(f"unknown expr operation {expr.operation} in copy_expr_to")
+ def translate(
+ self, expr_handler: Callable[['LowLevelILFunction', 'LowLevelILBasicBlock', 'LowLevelILInstruction'], ExpressionIndex]
+ ) -> 'LowLevelILFunction':
+ """
+ ``translate`` clones an IL function and modifies its expressions as specified by
+ a given ``expr_handler``, returning the updated IL function.
+
+ :param expr_handler: Function to modify an expression and copy it to the new function.
+ The function should have the following signature:
+
+ .. function:: expr_handler(new_func: LowLevelILFunction, old_block: LowLevelILBasicBlock, old_instr: LowLevelILInstruction) -> ExpressionIndex
+
+ Where:
+ - **new_func** (*LowLevelILFunction*): New function to receive translated instructions
+ - **old_block** (*LowLevelILBasicBlock*): Original block containing old_instr
+ - **old_instr** (*LowLevelILInstruction*): Original instruction
+ - **returns** (*ExpressionIndex*): Expression index of newly created instruction in ``new_func``
+ :return: Cloned IL function with modifications
+ """
+
+ propagated_func = LowLevelILFunction(self.arch, source_func=self.source_function)
+ propagated_func.prepare_to_copy_function(self)
+ for block in self.basic_blocks:
+ propagated_func.prepare_to_copy_block(block)
+ for instr_index in range(block.start, block.end):
+ instr: LowLevelILInstruction = self[InstructionIndex(instr_index)]
+ propagated_func.set_current_address(instr.address, block.arch)
+ propagated_func.append(expr_handler(propagated_func, block, instr))
+
+ return propagated_func
+
def set_expr_attributes(self, expr: InstructionOrExpression, value: ILInstructionAttributeSet):
"""
``set_expr_attributes`` allows modification of instruction attributes but ONLY during lifting.