diff options
Diffstat (limited to 'python')
| -rw-r--r-- | python/function.py | 44 | ||||
| -rw-r--r-- | python/mediumlevelil.py | 16 |
2 files changed, 60 insertions, 0 deletions
diff --git a/python/function.py b/python/function.py index 06a9beb5..93ed8b49 100644 --- a/python/function.py +++ b/python/function.py @@ -1397,6 +1397,21 @@ class Function: core.BNFreeMergedVariableList(data, count.value) return result + @property + def split_vars(self) -> List['variable.Variable']: + """ + Set of variables that have been split with ``split_var``. These variables correspond + to those unique to each definition site and are obtained by using + ``MediumLevelILInstruction.get_split_var_for_definition`` at the definitions. + """ + count = ctypes.c_ulonglong() + data = core.BNGetSplitVariables(self.handle, count) + result = [] + for i in range(count.value): + result.append(Variable.from_BNVariable(self, data[i])) + core.BNFreeVariableList(data) + return result + def mark_recent_use(self) -> None: core.BNMarkFunctionAsRecentlyUsed(self.handle) @@ -3374,6 +3389,35 @@ class Function: source_list[i].storage = sources[i].storage core.BNUnmergeVariables(self.handle, target.to_BNVariable(), source_list, len(sources)) + def split_var(self, var: 'variable.Variable') -> None: + """ + ``split_var`` splits a varible at the definition site. The given ``var`` must be the + variable unique to the definition and should be obtained by using + ``MediumLevelILInstruction.get_split_var_for_definition`` at the definition site. + + This function is not meant to split variables that have been previously merged. Use + ``unmerge_vars`` to split previously merged variables. + + .. warning:: Binary Ninja automatically splits all variables that the analysis determines \ + to be safely splittable. Splitting a variable manually with ``split_var`` can cause \ + IL and decompilation to be incorrect. There are some patterns where variables can be safely \ + split semantically but analysis cannot determine that it is safe. This function is provided \ + to allow variable splitting to be performed in these cases by plugins or by the user. + + :param Variable var: variable to split + """ + core.BNSplitVariable(self.handle, var.to_BNVariable()) + + def unsplit_var(self, var: 'variable.Variable') -> None: + """ + ``unsplit_var`` undoes varible splitting performed with ``split_var``. The given ``var`` + must be the variable unique to the definition and should be obtained by using + ``MediumLevelILInstruction.get_split_var_for_definition`` at the definition site. + + :param Variable var: variable to unsplit + """ + core.BNUnsplitVariable(self.handle, var.to_BNVariable()) + class AdvancedFunctionAnalysisDataRequestor: def __init__(self, func: 'Function' = None): diff --git a/python/mediumlevelil.py b/python/mediumlevelil.py index 06298e6e..47e7e2e1 100644 --- a/python/mediumlevelil.py +++ b/python/mediumlevelil.py @@ -730,6 +730,22 @@ class MediumLevelILInstruction(BaseILInstruction): core.BNGetMediumLevelILBranchDependence(self.function.handle, self.instr_index, branch_instr) ) + def get_split_var_for_definition(self, var: variable.Variable) -> variable.Variable: + """ + Gets the unique variable for a definition instruction. This unique variable can be passed + to ``Function.split_var`` to split a variable at a definition. The given ``var`` is the + assigned variable to query. + + :param Variable var: variable to query + :rtype: Variable + """ + return variable.Variable( + self.function.source_function, var.source_type, + core.BNGetDefaultIndexForMediumLevelILVariableDefinition( + self.function.handle, var.to_BNVariable(), self.instr_index + ), var.storage + ) + @property def operation(self) -> MediumLevelILOperation: return self.instr.operation |
