Skip to content

Commit 2490182

Browse files
committed
Python: MLILFunction translate() and instr copy_to
1 parent 0486354 commit 2490182

File tree

1 file changed

+47
-0
lines changed

1 file changed

+47
-0
lines changed

python/mediumlevelil.py

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -406,6 +406,22 @@ def create(
406406
instr = CoreMediumLevelILInstruction.from_BNMediumLevelILInstruction(inst)
407407
return ILInstruction[instr.operation](func, expr_index, instr, instr_index) # type: ignore
408408

409+
def copy_to(
410+
self, dest: 'MediumLevelILFunction',
411+
sub_expr_handler: Optional[Callable[['MediumLevelILInstruction'], ExpressionIndex]] = None
412+
) -> ExpressionIndex:
413+
"""
414+
``copy_to`` deep copies an expression into a new IL function.
415+
If provided, the function ``sub_expr_handler`` will be called on every copied sub-expression
416+
417+
.. warning:: This function should ONLY be called as a part of a lifter or workflow. It will otherwise not do anything useful as analysis will not be running.
418+
419+
:param MediumLevelILFunction dest: Function to copy the expression to
420+
:param sub_expr_handler: Optional function to call on every copied sub-expression
421+
:return: Index of the copied expression in the target function
422+
"""
423+
return self.function.copy_expr_to(self, dest, sub_expr_handler)
424+
409425
def __str__(self):
410426
tokens = self.tokens
411427
if tokens is None:
@@ -3901,6 +3917,37 @@ def do_copy(
39013917
dest.set_expr_type(new_index, self.get_expr_type(expr.expr_index))
39023918
return new_index
39033919

3920+
def translate(
3921+
self, expr_handler: Callable[['MediumLevelILFunction', 'MediumLevelILBasicBlock', 'MediumLevelILInstruction'], ExpressionIndex]
3922+
) -> 'MediumLevelILFunction':
3923+
"""
3924+
``translate`` clones an IL function and modifies its expressions as specified by
3925+
a given ``expr_handler``, returning the updated IL function.
3926+
3927+
:param expr_handler: Function to modify an expression and copy it to the new function.
3928+
The function should have the following signature:
3929+
3930+
.. function:: expr_handler(new_func: MediumLevelILFunction, old_block: MediumLevelILBasicBlock, old_instr: MediumLevelILInstruction) -> ExpressionIndex
3931+
3932+
Where:
3933+
- **new_func** (*MediumLevelILFunction*): New function to receive translated instructions
3934+
- **old_block** (*MediumLevelILBasicBlock*): Original block containing old_instr
3935+
- **old_instr** (*MediumLevelILInstruction*): Original instruction
3936+
- **returns** (*ExpressionIndex*): Expression index of newly created instruction in ``new_func``
3937+
:return: Cloned IL function with modifications
3938+
"""
3939+
3940+
propagated_func = MediumLevelILFunction(self.arch, low_level_il=self.low_level_il)
3941+
propagated_func.prepare_to_copy_function(self)
3942+
for block in self.basic_blocks:
3943+
propagated_func.prepare_to_copy_block(block)
3944+
for instr_index in range(block.start, block.end):
3945+
instr: MediumLevelILInstruction = self[InstructionIndex(instr_index)]
3946+
propagated_func.set_current_address(instr.address, block.arch)
3947+
propagated_func.append(expr_handler(propagated_func, block, instr))
3948+
3949+
return propagated_func
3950+
39043951
def set_expr_attributes(self, expr: InstructionOrExpression, value: ILInstructionAttributeSet):
39053952
"""
39063953
``set_expr_attributes`` allows modification of instruction attributes but ONLY during lifting.

0 commit comments

Comments
 (0)