diff options
| author | KyleMiles <krm504@nyu.edu> | 2021-11-01 23:15:54 -0400 |
|---|---|---|
| committer | KyleMiles <krm504@nyu.edu> | 2021-11-11 16:16:36 -0500 |
| commit | 53640fb603ef58baf02bb43746046f9f62603f30 (patch) | |
| tree | 557cd5fce36d10ebb03066c5548f20108e3aa940 /python/variable.py | |
| parent | f125e6c97df72d391615d823e46c411be78a853a (diff) | |
Resolves #2748; Variable.ssa_versions; Fixes some type annotations
Diffstat (limited to 'python/variable.py')
| -rw-r--r-- | python/variable.py | 49 |
1 files changed, 42 insertions, 7 deletions
diff --git a/python/variable.py b/python/variable.py index d345e4b0..3ce7e437 100644 --- a/python/variable.py +++ b/python/variable.py @@ -26,7 +26,13 @@ from dataclasses import dataclass, field import binaryninja from . import _binaryninjacore as core from . import decorators -from .enums import RegisterValueType, VariableSourceType, DeadStoreElimination +from .enums import RegisterValueType, VariableSourceType, DeadStoreElimination, FunctionGraphType + +FunctionOrILFunction = Union["binaryninja.function.Function", + "binaryninja.lowlevelil.LowLevelILFunction", + "binaryninja.mediumlevelil.MediumLevelILFunction", + "binaryninja.highlevelil.HighLevelILFunction"] + @dataclass(frozen=True) class LookupTableEntry: @@ -624,24 +630,29 @@ class VariableNameAndType(CoreVariable): class Variable(CoreVariable): - def __init__(self, func:'binaryninja.function.Function', source_type:VariableSourceType, index:int, storage:int): + def __init__(self, func:FunctionOrILFunction, source_type:VariableSourceType, index:int, storage:int): super(Variable, self).__init__(source_type, index, storage) - self._function = func + if isinstance(func, binaryninja.function.Function): + self._function = func + self._il_function = None + else: + self._function = func.source_function + self._il_function = func @classmethod - def from_variable_name_and_type(cls, func:'binaryninja.function.Function', var:VariableNameAndType): + def from_variable_name_and_type(cls, func:FunctionOrILFunction, var:VariableNameAndType): return cls(func, VariableSourceType(var.type), var.index, var.storage) @classmethod - def from_core_variable(cls, func:'binaryninja.function.Function', var:CoreVariable): + def from_core_variable(cls, func:FunctionOrILFunction, var:CoreVariable): return cls(func, var.source_type, var.index, var.storage) @classmethod - def from_BNVariable(cls, func:'binaryninja.function.Function', var:core.BNVariable): + def from_BNVariable(cls, func:FunctionOrILFunction, var:core.BNVariable): return cls(func, var.type, var.index, var.storage) @classmethod - def from_identifier(cls, func:'binaryninja.function.Function', identifier:int): + def from_identifier(cls, func:FunctionOrILFunction, identifier:int): var = core.BNFromVariableIdentifier(identifier) return cls(func, VariableSourceType(var.type), var.index, var.storage) @@ -716,6 +727,30 @@ class Variable(CoreVariable): self._function.create_user_var(self, new_type, self.name) @property + def ssa_versions(self) -> Generator[int, None, None]: + """Returns the SSA versions associated with this variable. Doesn't return anything for aliased variables.""" + if self._il_function is None: + raise NotImplementedError("No IL function associated with variable") + + version_count = ctypes.c_ulonglong() + versions = None + if self._il_function.il_form in [FunctionGraphType.MediumLevelILFunctionGraph, FunctionGraphType.MediumLevelILSSAFormFunctionGraph]: + versions = core.BNGetMediumLevelILVariableSSAVersions(self._il_function.handle, self.to_BNVariable(), version_count) + elif self._il_function.il_form in [FunctionGraphType.HighLevelILFunctionGraph, FunctionGraphType.HighLevelILSSAFormFunctionGraph]: + versions = core.BNGetHighLevelILVariableSSAVersions(self._il_function.handle, self.to_BNVariable(), version_count) + else: + raise NotImplementedError("Unsupported IL form") + + if versions is None: + raise NotImplementedError("No SSA versions; is this an aliased variable?") + + try: + for version_i in range(version_count.value): + yield versions[version_i] + finally: + core.BNFreeILInstructionList(versions) + + @property def dead_store_elimination(self): return DeadStoreElimination(core.BNGetFunctionVariableDeadStoreElimination(self._function.handle, self.to_BNVariable())) |
