From bc5c0977dc5b4087e8f39cc67089bb5709aac04e Mon Sep 17 00:00:00 2001 From: Peter LaFosse Date: Wed, 23 Jun 2021 20:20:50 -0400 Subject: type hints for highlevelil.py, mediumlevelil.py and lowlevelil.py, workflow.py Fix linter error in scriptingprovider.py Update workflow.py using updated paradigms and type hints --- python/basicblock.py | 5 +- python/binaryview.py | 50 +++--- python/bncompleter.py | 6 +- python/callingconvention.py | 49 +++--- python/demangle.py | 4 +- python/filemetadata.py | 16 +- python/flowgraph.py | 17 +- python/function.py | 5 +- python/generator.cpp | 2 +- python/highlevelil.py | 384 ++++++++++++++++++++++---------------------- python/lowlevelil.py | 28 ++-- python/mediumlevelil.py | 309 +++++++++++++++++------------------ python/platform.py | 7 +- python/scriptingprovider.py | 6 +- python/types.py | 28 +--- python/workflow.py | 148 +++++++++-------- 16 files changed, 532 insertions(+), 532 deletions(-) (limited to 'python') diff --git a/python/basicblock.py b/python/basicblock.py index 7104f418..4aca6de5 100644 --- a/python/basicblock.py +++ b/python/basicblock.py @@ -51,7 +51,8 @@ class BasicBlockEdge: class BasicBlock: def __init__(self, handle:core.BNBasicBlockHandle, view:Optional['binaryninja.binaryview.BinaryView']=None): self._view = view - self.handle = core.handle_of_type(handle, core.BNBasicBlock) + _handle = core.BNBasicBlockHandle + self.handle:core.BNBasicBlockHandle = ctypes.cast(handle, _handle) self._arch = None self._func = None self._instStarts:Optional[List[int]] = None @@ -144,7 +145,7 @@ class BasicBlock: self._instStarts.append(start) start += length - def _create_instance(self, handle:core.BNBasicBlock, view:'binaryninja.binaryview.BinaryView') -> 'BasicBlock': + def _create_instance(self, handle:core.BNBasicBlockHandle, view:'binaryninja.binaryview.BinaryView') -> 'BasicBlock': """Internal method used to instantiate child instances""" return BasicBlock(handle, view) diff --git a/python/binaryview.py b/python/binaryview.py index 53cc308a..4c57131e 100644 --- a/python/binaryview.py +++ b/python/binaryview.py @@ -705,10 +705,11 @@ class _BinaryViewTypeMetaclass(type): class BinaryViewType(metaclass=_BinaryViewTypeMetaclass): - def __init__(self, handle:core.BNBinaryViewType): + def __init__(self, handle:core.BNBinaryViewTypeHandle): # Used to force Python callback objects to not get garbage collected _platform_recognizers = {} - self.handle = core.handle_of_type(handle, core.BNBinaryViewType) + _handle = core.BNBinaryViewTypeHandle + self.handle = ctypes.cast(handle, _handle) def __repr__(self): return f"" @@ -1340,10 +1341,9 @@ class BinaryView: registered_view_type = None _associated_data = {} _registered_instances = [] - def __init__(self, file_metadata:'filemetadata.FileMetadata'=None, parent_view:'BinaryView'=None, handle:'ctypes.pointer[core.BNBinaryView]'=None): + def __init__(self, file_metadata:'filemetadata.FileMetadata'=None, parent_view:'BinaryView'=None, handle:core.BNBinaryViewHandle=None): if handle is not None: - self.handle = core.handle_of_type(handle, core.BNBinaryView) - assert self.handle is not None, "core.handle_of_type returned None" + _handle = handle if file_metadata is None: self._file = filemetadata.FileMetadata(handle=core.BNGetFileForView(handle)) else: @@ -1352,8 +1352,7 @@ class BinaryView: binaryninja._init_plugins() if file_metadata is None: file_metadata = filemetadata.FileMetadata() - self.handle = core.BNCreateBinaryDataView(file_metadata.handle) - assert self.handle is not None, "core.BNCreateBinaryDataView returned None" + _handle = core.BNCreateBinaryDataView(file_metadata.handle) self._file = filemetadata.FileMetadata(handle=core.BNNewFileReference(file_metadata.handle)) else: binaryninja._init_plugins() @@ -1388,9 +1387,10 @@ class BinaryView: _parent_view = None if parent_view is not None: _parent_view = parent_view.handle - self.handle = core.BNCreateCustomBinaryView(self.__class__.name, file_metadata.handle, _parent_view, self._cb) - assert self.handle is not None, "core.BNCreateCustomBinaryView returned None" - assert self.handle is not None + _handle = core.BNCreateCustomBinaryView(self.__class__.name, file_metadata.handle, _parent_view, self._cb) + + assert _handle is not None + self.handle = _handle self._notifications = {} self._parse_only = False @@ -1423,8 +1423,6 @@ class BinaryView: def __eq__(self, other): if not isinstance(other, self.__class__): return NotImplemented - assert self.handle is not None - assert other.handle is not None return ctypes.addressof(self.handle.contents) == ctypes.addressof(other.handle.contents) def __ne__(self, other): @@ -1433,7 +1431,6 @@ class BinaryView: return not (self == other) def __hash__(self): - assert self.handle is not None return hash(ctypes.addressof(self.handle.contents)) def __iter__(self) -> Generator['_function.Function', None, None]: @@ -2052,7 +2049,7 @@ class BinaryView: """Dictionary object where plugins can store arbitrary data associated with the view""" # TODO: # assert isinstance(self.handle, int), "session_data called with no BinaryView.handle" - handle = ctypes.cast(self.handle, ctypes.c_void_p) + handle = ctypes.cast(self.handle, ctypes.c_void_p) # type: ignore if handle.value not in BinaryView._associated_data: obj = _BinaryViewAssociatedDataStore() BinaryView._associated_data[handle.value] = obj @@ -2086,7 +2083,6 @@ class BinaryView: @property def relocation_ranges(self): """List of relocation range tuples (read-only)""" - count = ctypes.c_ulonglong() ranges = core.BNGetRelocationRanges(self.handle, count) assert ranges is not None, "core.BNGetRelocationRanges returned None" @@ -3215,7 +3211,7 @@ class BinaryView: result = [func for func in result if func.platform == plat] return result - def get_functions_by_name(self, name, plat=None, ordered_filter=[SymbolType.FunctionSymbol, SymbolType.ImportedFunctionSymbol, SymbolType.LibraryFunctionSymbol]): + def get_functions_by_name(self, name, plat=None, ordered_filter=None): """``get_functions_by_name`` returns a list of Function objects function with a Symbol of ``name``. @@ -3230,6 +3226,10 @@ class BinaryView: >>> """ + if ordered_filter is not None: + ordered_filter = [SymbolType.FunctionSymbol, + SymbolType.ImportedFunctionSymbol, + SymbolType.LibraryFunctionSymbol] if plat == None: plat = self.platform syms = self.get_symbols_by_name(name, ordered_filter=ordered_filter) @@ -4019,7 +4019,7 @@ class BinaryView: return None return _types.Symbol(None, None, None, handle = sym) - def get_symbols_by_name(self, name, namespace=None, ordered_filter=[SymbolType.FunctionSymbol, SymbolType.ImportedFunctionSymbol, SymbolType.LibraryFunctionSymbol, SymbolType.DataSymbol, SymbolType.ImportedDataSymbol, SymbolType.ImportAddressSymbol, SymbolType.ExternalSymbol]): + def get_symbols_by_name(self, name, namespace=None, ordered_filter=None): """ ``get_symbols_by_name`` retrieves a list of Symbol objects for the given symbol name and ordered filter @@ -4035,6 +4035,14 @@ class BinaryView: [] >>> """ + if ordered_filter is None: + ordered_filter = [SymbolType.FunctionSymbol, + SymbolType.ImportedFunctionSymbol, + SymbolType.LibraryFunctionSymbol, + SymbolType.DataSymbol, + SymbolType.ImportedDataSymbol, + SymbolType.ImportAddressSymbol, + SymbolType.ExternalSymbol] if isinstance(namespace, str): namespace = _types.NameSpace(namespace) if isinstance(namespace, _types.NameSpace): @@ -5523,9 +5531,9 @@ class BinaryView: core.free_string(errors) raise SyntaxError(error_str) - type_dict = {} - variables = {} - functions = {} + type_dict:Mapping[_types.QualifiedName, _types.Type] = {} + variables:Mapping[_types.QualifiedName, _types.Type] = {} + functions:Mapping[_types.QualifiedName, _types.Type] = {} for i in range(0, parse.typeCount): name = _types.QualifiedName._from_core_struct(parse.types[i].name) type_dict[name] = _types.Type(core.BNNewTypeReference(parse.types[i].type), platform = self.platform) @@ -7267,7 +7275,7 @@ class StructuredDataValue: return ' '.join(["{:02x}".format(x) for x in struct.unpack(decode_str, self._value)]) def __repr__(self): - return "".format(str(self._type), str(self)) + return f"" def __int__(self): if self._type.width == 1: diff --git a/python/bncompleter.py b/python/bncompleter.py index 62641a2a..330cf0d0 100644 --- a/python/bncompleter.py +++ b/python/bncompleter.py @@ -146,10 +146,10 @@ class Completer: word = word + ' ' matches.append(word) #Not sure why in the console builtins becomes a dict but this works for now. - if hasattr(__builtins__, '__dict__'): - builtins = __builtins__.__dict__ + if hasattr(__builtins__, '__dict__'): # type: ignore remove this ignore > pyright 1.1.149 + builtins = __builtins__.__dict__ # type: ignore remove this ignore > pyright 1.1.149 else: - builtins = __builtins__ + builtins = __builtins__ # type: ignore remove this ignore > pyright 1.1.149 for nspace in [self.namespace, builtins]: for word, val in nspace.items(): if word[:n] == text and word not in seen: diff --git a/python/callingconvention.py b/python/callingconvention.py index f4d7682e..d17cc6e6 100644 --- a/python/callingconvention.py +++ b/python/callingconvention.py @@ -20,6 +20,7 @@ import traceback import ctypes +from typing import Optional # Binary Ninja components from . import _binaryninjacore as core @@ -49,10 +50,9 @@ class CallingConvention: _registered_calling_conventions = [] - def __init__(self, arch=None, name=None, handle=None, confidence=core.max_confidence): + def __init__(self, arch:'architecture.Architecture'=None, name:str=None, handle=None, confidence:int=core.max_confidence): if handle is None: if arch is None or name is None: - self.handle = None raise ValueError("Must specify either handle or architecture and name") self._arch = arch self._pending_reg_lists = {} @@ -77,20 +77,20 @@ class CallingConvention: self._cb.getIncomingFlagValue = self._cb.getIncomingFlagValue.__class__(self._get_incoming_flag_value) self._cb.getIncomingVariableForParameterVariable = self._cb.getIncomingVariableForParameterVariable.__class__(self._get_incoming_var_for_parameter_var) self._cb.getParameterVariableForIncomingVariable = self._cb.getParameterVariableForIncomingVariable.__class__(self._get_parameter_var_for_incoming_var) - self.handle = core.BNCreateCallingConvention(arch.handle, name, self._cb) + _handle = core.BNCreateCallingConvention(arch.handle, name, self._cb) self.__class__._registered_calling_conventions.append(self) else: - self.handle = handle - self.arch = architecture.CoreArchitecture._from_cache(core.BNGetCallingConventionArchitecture(self.handle)) - self.__dict__["name"] = core.BNGetCallingConventionName(self.handle) - self.__dict__["arg_regs_share_index"] = core.BNAreArgumentRegistersSharedIndex(self.handle) - self.__dict__["arg_regs_for_varargs"] = core.BNAreArgumentRegistersUsedForVarArgs(self.handle) - self.__dict__["stack_reserved_for_arg_regs"] = core.BNIsStackReservedForArgumentRegisters(self.handle) - self.__dict__["stack_adjusted_on_return"] = core.BNIsStackAdjustedOnReturn(self.handle) - self.__dict__["eligible_for_heuristics"] = core.BNIsEligibleForHeuristics(self.handle) + _handle = handle + self.arch = architecture.CoreArchitecture._from_cache(core.BNGetCallingConventionArchitecture(_handle)) + self.__dict__["name"] = core.BNGetCallingConventionName(_handle) + self.__dict__["arg_regs_share_index"] = core.BNAreArgumentRegistersSharedIndex(_handle) + self.__dict__["arg_regs_for_varargs"] = core.BNAreArgumentRegistersUsedForVarArgs(_handle) + self.__dict__["stack_reserved_for_arg_regs"] = core.BNIsStackReservedForArgumentRegisters(_handle) + self.__dict__["stack_adjusted_on_return"] = core.BNIsStackAdjustedOnReturn(_handle) + self.__dict__["eligible_for_heuristics"] = core.BNIsEligibleForHeuristics(_handle) count = ctypes.c_ulonglong() - regs = core.BNGetCallerSavedRegisters(self.handle, count) + regs = core.BNGetCallerSavedRegisters(_handle, count) assert regs is not None, "core.BNGetCallerSavedRegisters returned None" result = [] arch = self.arch @@ -100,7 +100,7 @@ class CallingConvention: self.__dict__["caller_saved_regs"] = result count = ctypes.c_ulonglong() - regs = core.BNGetCalleeSavedRegisters(self.handle, count) + regs = core.BNGetCalleeSavedRegisters(_handle, count) assert regs is not None, "core.BNGetCalleeSavedRegisters returned None" result = [] arch = self.arch @@ -110,7 +110,7 @@ class CallingConvention: self.__dict__["callee_saved_regs"] = result count = ctypes.c_ulonglong() - regs = core.BNGetIntegerArgumentRegisters(self.handle, count) + regs = core.BNGetIntegerArgumentRegisters(_handle, count) assert regs is not None, "core.BNGetIntegerArgumentRegisters returned None" result = [] arch = self.arch @@ -120,7 +120,7 @@ class CallingConvention: self.__dict__["int_arg_regs"] = result count = ctypes.c_ulonglong() - regs = core.BNGetFloatArgumentRegisters(self.handle, count) + regs = core.BNGetFloatArgumentRegisters(_handle, count) assert regs is not None, "core.BNGetFloatArgumentRegisters returned None" result = [] arch = self.arch @@ -129,32 +129,32 @@ class CallingConvention: core.BNFreeRegisterList(regs, count.value) self.__dict__["float_arg_regs"] = result - reg = core.BNGetIntegerReturnValueRegister(self.handle) + reg = core.BNGetIntegerReturnValueRegister(_handle) if reg == 0xffffffff: self.__dict__["int_return_reg"] = None else: self.__dict__["int_return_reg"] = self.arch.get_reg_name(reg) - reg = core.BNGetHighIntegerReturnValueRegister(self.handle) + reg = core.BNGetHighIntegerReturnValueRegister(_handle) if reg == 0xffffffff: self.__dict__["high_int_return_reg"] = None else: self.__dict__["high_int_return_reg"] = self.arch.get_reg_name(reg) - reg = core.BNGetFloatReturnValueRegister(self.handle) + reg = core.BNGetFloatReturnValueRegister(_handle) if reg == 0xffffffff: self.__dict__["float_return_reg"] = None else: self.__dict__["float_return_reg"] = self.arch.get_reg_name(reg) - reg = core.BNGetGlobalPointerRegister(self.handle) + reg = core.BNGetGlobalPointerRegister(_handle) if reg == 0xffffffff: self.__dict__["global_pointer_reg"] = None else: self.__dict__["global_pointer_reg"] = self.arch.get_reg_name(reg) count = ctypes.c_ulonglong() - regs = core.BNGetImplicitlyDefinedRegisters(self.handle, count) + regs = core.BNGetImplicitlyDefinedRegisters(_handle, count) assert regs is not None, "core.BNGetImplicitlyDefinedRegisters returned None" result = [] arch = self.arch @@ -162,7 +162,8 @@ class CallingConvention: result.append(arch.get_reg_name(regs[i])) core.BNFreeRegisterList(regs, count.value) self.__dict__["implicitly_defined_regs"] = result - + assert _handle is not None + self.handle = _handle self.confidence = confidence def __del__(self): @@ -178,8 +179,6 @@ class CallingConvention: def __eq__(self, other): if not isinstance(other, self.__class__): return NotImplemented - assert self.handle is not None - assert other.handle is not None return ctypes.addressof(self.handle.contents) == ctypes.addressof(other.handle.contents) def __ne__(self, other): @@ -188,7 +187,6 @@ class CallingConvention: return not (self == other) def __hash__(self): - assert self.handle is not None return hash(ctypes.addressof(self.handle.contents)) def _get_caller_saved_regs(self, ctxt, count): @@ -297,6 +295,9 @@ class CallingConvention: def _get_int_return_reg(self, ctxt): try: + if not isinstance(self.__class__.int_return_reg, str): + log.log_error(traceback.format_exc()) + return False return self.arch.regs[self.__class__.int_return_reg].index except: log.log_error(traceback.format_exc()) diff --git a/python/demangle.py b/python/demangle.py index db0bde1d..105ee889 100644 --- a/python/demangle.py +++ b/python/demangle.py @@ -68,7 +68,7 @@ def demangle_ms(arch, mangled_name, options = False): (isinstance(options, bool) and core.BNDemangleMS(arch.handle, mangled_name, ctypes.byref(handle), ctypes.byref(outName), ctypes.byref(outSize), options)) or \ (options is None and core.BNDemangleMSWithOptions(arch.handle, mangled_name, ctypes.byref(handle), ctypes.byref(outName), ctypes.byref(outSize), None)): for i in range(outSize.value): - names.append(outName[i].decode('utf8')) + names.append(outName[i].decode('utf8')) # type: ignore core.BNFreeDemangledName(ctypes.byref(outName), outSize.value) return (types.Type(handle), names) return (None, mangled_name) @@ -93,7 +93,7 @@ def demangle_gnu3(arch, mangled_name, options = None): (isinstance(options, bool) and core.BNDemangleGNU3(arch.handle, mangled_name, ctypes.byref(handle), ctypes.byref(outName), ctypes.byref(outSize), options)) or \ (options is None and core.BNDemangleGNU3WithOptions(arch.handle, mangled_name, ctypes.byref(handle), ctypes.byref(outName), ctypes.byref(outSize), None)): for i in range(outSize.value): - names.append(outName[i].decode('utf8')) + names.append(outName[i].decode('utf8')) # type: ignore core.BNFreeDemangledName(ctypes.byref(outName), outSize.value) if not handle: return (None, names) diff --git a/python/filemetadata.py b/python/filemetadata.py index 954467d7..06e7324a 100644 --- a/python/filemetadata.py +++ b/python/filemetadata.py @@ -120,7 +120,7 @@ class FileMetadata: _associated_data = {} - def __init__(self, filename = None, handle = None): + def __init__(self, filename:Optional[str]=None, handle:Optional[core.BNFileMetadataHandle]=None): """ Instantiates a new FileMetadata class. @@ -128,13 +128,16 @@ class FileMetadata: :param handle: A handle to the underlying C FileMetadata object. Defaults to None. """ if handle is not None: - self.handle = core.handle_of_type(handle, core.BNFileMetadata) + _type = core.BNFileMetadataHandle + _handle = ctypes.cast(handle, _type) else: binaryninja._init_plugins() - self.handle = core.BNCreateFileMetadata() + _handle = core.BNCreateFileMetadata() if filename is not None: - core.BNSetFilename(self.handle, str(filename)) + core.BNSetFilename(_handle, str(filename)) self._nav:Optional[NavigationHandler] = None + assert _handle is not None + self.handle = _handle def __repr__(self): return "" % self.filename @@ -147,8 +150,6 @@ class FileMetadata: def __eq__(self, other): if not isinstance(other, self.__class__): return NotImplemented - assert self.handle is not None - assert other.handle is not None return ctypes.addressof(self.handle.contents) == ctypes.addressof(other.handle.contents) def __ne__(self, other): @@ -157,7 +158,6 @@ class FileMetadata: return not (self == other) def __hash__(self): - assert self.handle is not None return hash(ctypes.addressof(self.handle.contents)) @property @@ -270,7 +270,7 @@ class FileMetadata: def session_data(self) -> Any: """Dictionary object where plugins can store arbitrary data associated with the file""" assert self.handle is not None, "Attempting to set session_data when handle is None" - handle = ctypes.cast(self.handle, ctypes.c_void_p) + handle = ctypes.cast(self.handle, ctypes.c_void_p) # type: ignore if handle.value not in FileMetadata._associated_data: obj = _FileMetadataAssociatedDataStore() FileMetadata._associated_data[handle.value] = obj diff --git a/python/flowgraph.py b/python/flowgraph.py index 0fd2ae09..0a0faae9 100644 --- a/python/flowgraph.py +++ b/python/flowgraph.py @@ -84,13 +84,13 @@ class EdgeStyle: class FlowGraphNode: def __init__(self, graph = None, handle = None): - if handle is None: + _handle = handle + if _handle is None: if graph is None: - self.handle = None raise ValueError("flow graph node must be associated with a graph") - handle = core.BNCreateFlowGraphNode(graph.handle) - self.handle = handle - assert self.handle is not None, "core.BNCreateFlowGraphNode returned None" + _handle = core.BNCreateFlowGraphNode(graph.handle) + assert _handle is not None + self.handle = _handle self._graph = graph if self._graph is None: self._graph = FlowGraph(handle = core.BNGetFlowGraphNodeOwner(self.handle)) @@ -112,9 +112,6 @@ class FlowGraphNode: def __eq__(self, other): if not isinstance(other, self.__class__): return NotImplemented - - assert self.handle is not None - assert other.handle is not None return ctypes.addressof(self.handle.contents) == ctypes.addressof(other.handle.contents) def __ne__(self, other): @@ -123,7 +120,6 @@ class FlowGraphNode: return not (self == other) def __hash__(self): - assert self.handle is not None return hash(ctypes.addressof(self.handle.contents)) def __iter__(self): @@ -411,6 +407,7 @@ class FlowGraph: self._ext_cb.externalRefTaken = self._ext_cb.externalRefTaken.__class__(self._external_ref_taken) self._ext_cb.externalRefReleased = self._ext_cb.externalRefReleased.__class__(self._external_ref_released) handle = core.BNCreateCustomFlowGraph(self._ext_cb) + assert handle is not None self.handle = handle def __del__(self): @@ -425,8 +422,6 @@ class FlowGraph: def __eq__(self, other): if not isinstance(other, self.__class__): return NotImplemented - assert self.handle is not None - assert other.handle is not None return ctypes.addressof(self.handle.contents) == ctypes.addressof(other.handle.contents) def __ne__(self, other): diff --git a/python/function.py b/python/function.py index 36ecc52f..3aba76f2 100644 --- a/python/function.py +++ b/python/function.py @@ -253,7 +253,8 @@ class Function: def __init__(self, view:Optional['binaryview.BinaryView']=None, handle:Optional[core.BNFunction]=None): self._advanced_analysis_requests = 0 assert handle is not None, "creation of standalone 'Function' objects is not implemented" - self.handle = core.handle_of_type(handle, core.BNFunction) + FunctionHandle = ctypes.POINTER(core.BNFunction) + self.handle = ctypes.cast(handle, FunctionHandle) if view is None: self._view = binaryview.BinaryView(handle = core.BNGetFunctionData(self.handle)) else: @@ -930,7 +931,7 @@ class Function: @property def session_data(self) -> Any: """Dictionary object where plugins can store arbitrary data associated with the function""" - handle = ctypes.cast(self.handle, ctypes.c_void_p) + handle = ctypes.cast(self.handle, ctypes.c_void_p) # type: ignore if handle.value not in Function._associated_data: obj = _FunctionAssociatedDataStore() Function._associated_data[handle.value] = obj diff --git a/python/generator.cpp b/python/generator.cpp index 8b7b202c..5541f017 100644 --- a/python/generator.cpp +++ b/python/generator.cpp @@ -249,7 +249,7 @@ int main(int argc, char* argv[]) if (!stringField) fprintf(out, "\tpass\n"); - fprintf(out, "%sPointer = ctypes.POINTER(%s)\n", name.c_str(), name.c_str()); + fprintf(out, "%sHandle = ctypes.POINTER(%s)\n", name.c_str(), name.c_str()); } else if (i.second->GetClass() == EnumerationTypeClass) { diff --git a/python/highlevelil.py b/python/highlevelil.py index 7f78ece7..348468be 100644 --- a/python/highlevelil.py +++ b/python/highlevelil.py @@ -466,18 +466,19 @@ class HighLevelILInstruction: finally: core.BNHighLevelILFreeOperandList(operand_list) - def get_expr_list(self, operand_index1:int, operand_index2:int) -> List[variable.Variable]: + def get_expr_list(self, operand_index1:int, operand_index2:int) -> List['HighLevelILInstruction']: count = ctypes.c_ulonglong() operand_list = core.BNHighLevelILGetOperandList(self.function.handle, self.expr_index, operand_index1, count) assert operand_list is not None, "core.BNHighLevelILGetOperandList returned None" - value:List[variable.Variable] = [] + value:List[HighLevelILInstruction] = [] try: for j in range(count.value): - value.append(variable.Variable.from_identifier(self.function.source_function, operand_list[j])) + value.append(HighLevelILInstruction.create(self.function, operand_list[j], self.as_ast)) return value finally: core.BNHighLevelILFreeOperandList(operand_list) + def get_var_ssa_list(self, operand_index1:int, _:int) -> List['mediumlevelil.SSAVariable']: count = ctypes.c_ulonglong() operand_list = core.BNHighLevelILGetOperandList(self.function.handle, self.expr_index, operand_index1, count) @@ -644,27 +645,28 @@ class HighLevelILBlock(HighLevelILInstruction): operand_names = tuple(["body"]) @property - def body(self): + def body(self) -> List[HighLevelILInstruction]: return self.get_expr_list(0, 1) - def __iter__(self): + def __iter__(self) -> Generator['HighLevelILInstruction', None, None]: for expr in self.body: yield expr + @dataclass(frozen=True, repr=False) class HighLevelILIf(ControlFlow): operand_names = tuple(["condition", "true", "false"]) @property - def condition(self): + def condition(self) -> HighLevelILInstruction: return self.get_expr(0) @property - def true(self): + def true(self) -> HighLevelILInstruction: return self.get_expr(1) @property - def false(self): + def false(self) -> HighLevelILInstruction: return self.get_expr(2) @@ -673,11 +675,11 @@ class HighLevelILWhile(Loop): operand_names = tuple(["condition", "body"]) @property - def condition(self): + def condition(self) -> HighLevelILInstruction: return self.get_expr(0) @property - def body(self): + def body(self) -> HighLevelILInstruction: return self.get_expr(1) @@ -686,15 +688,15 @@ class HighLevelILWhile_ssa(Loop, SSA): operand_names = tuple(["condition_phi", "condition", "body"]) @property - def condition_phi(self): + def condition_phi(self) -> HighLevelILInstruction: return self.get_expr(0) @property - def condition(self): + def condition(self) -> HighLevelILInstruction: return self.get_expr(1) @property - def body(self): + def body(self) -> HighLevelILInstruction: return self.get_expr(2) @@ -703,11 +705,11 @@ class HighLevelILDo_while(Loop): operand_names = tuple(["body", "condition"]) @property - def body(self): + def body(self) -> HighLevelILInstruction: return self.get_expr(0) @property - def condition(self): + def condition(self) -> HighLevelILInstruction: return self.get_expr(1) @@ -716,15 +718,15 @@ class HighLevelILDo_while_ssa(Loop, SSA): operand_names = tuple(["body", "condition_phi", "condition"]) @property - def body(self): + def body(self) -> HighLevelILInstruction: return self.get_expr(0) @property - def condition_phi(self): + def condition_phi(self) -> HighLevelILInstruction: return self.get_expr(1) @property - def condition(self): + def condition(self) -> HighLevelILInstruction: return self.get_expr(2) @@ -733,19 +735,19 @@ class HighLevelILFor(Loop): operand_names = tuple(["init", "condition", "update", "body"]) @property - def init(self): + def init(self) -> HighLevelILInstruction: return self.get_expr(0) @property - def condition(self): + def condition(self) -> HighLevelILInstruction: return self.get_expr(1) @property - def update(self): + def update(self) -> HighLevelILInstruction: return self.get_expr(2) @property - def body(self): + def body(self) -> HighLevelILInstruction: return self.get_expr(3) @@ -754,23 +756,23 @@ class HighLevelILFor_ssa(Loop, SSA): operand_names = tuple(["init", "condition_phi", "condition", "update"]) @property - def init(self): + def init(self) -> HighLevelILInstruction: return self.get_expr(0) @property - def condition_phi(self): + def condition_phi(self) -> HighLevelILInstruction: return self.get_expr(1) @property - def condition(self): + def condition(self) -> HighLevelILInstruction: return self.get_expr(2) @property - def update(self): + def update(self) -> HighLevelILInstruction: return self.get_expr(3) @property - def body(self): + def body(self) -> HighLevelILInstruction: return self.get_expr(3) @@ -779,15 +781,15 @@ class HighLevelILSwitch(ControlFlow): operand_names = tuple(["condition", "default", "cases"]) @property - def condition(self): + def condition(self) -> HighLevelILInstruction: return self.get_expr(0) @property - def default(self): + def default(self) -> HighLevelILInstruction: return self.get_expr(1) @property - def cases(self): + def cases(self) -> List[HighLevelILInstruction]: return self.get_expr_list(2, 3) @@ -796,11 +798,11 @@ class HighLevelILCase(HighLevelILInstruction): operand_names = tuple(["values", "body"]) @property - def values(self): + def values(self) -> List[HighLevelILInstruction]: return self.get_expr_list(0, 1) @property - def body(self): + def body(self) -> HighLevelILInstruction: return self.get_expr(2) @@ -819,7 +821,7 @@ class HighLevelILJump(Terminal): operand_names = tuple(["dest"]) @property - def dest(self): + def dest(self) -> HighLevelILInstruction: return self.get_expr(0) @@ -828,7 +830,7 @@ class HighLevelILRet(ControlFlow): operand_names = tuple(["src"]) @property - def src(self): + def src(self) -> List[HighLevelILInstruction]: return self.get_expr_list(0, 1) @@ -842,7 +844,7 @@ class HighLevelILGoto(Terminal): operand_names = tuple(["target"]) @property - def target(self): + def target(self) -> GotoLabel: return self.get_label(0) @@ -851,7 +853,7 @@ class HighLevelILLabel(HighLevelILInstruction): operand_names = tuple(["target"]) @property - def target(self): + def target(self) -> GotoLabel: return self.get_label(0) @@ -860,7 +862,7 @@ class HighLevelILVar_declare(HighLevelILInstruction): operand_names = tuple(["var"]) @property - def var(self): + def var(self) -> variable.Variable: return self.get_var(0) @@ -869,11 +871,11 @@ class HighLevelILVar_init(HighLevelILInstruction): operand_names = tuple(["dest", "src"]) @property - def dest(self): + def dest(self) -> variable.Variable: return self.get_var(0) @property - def src(self): + def src(self) -> HighLevelILInstruction: return self.get_expr(1) @@ -882,11 +884,11 @@ class HighLevelILVar_init_ssa(SSA): operand_names = tuple(["dest", "src"]) @property - def dest(self): + def dest(self) -> 'mediumlevelil.SSAVariable': return self.get_var_ssa(0, 1) @property - def src(self): + def src(self) -> HighLevelILInstruction: return self.get_expr(2) @@ -895,11 +897,11 @@ class HighLevelILAssign(HighLevelILInstruction): operand_names = tuple(["dest", "src"]) @property - def dest(self): + def dest(self) -> HighLevelILInstruction: return self.get_expr(0) @property - def src(self): + def src(self) -> HighLevelILInstruction: return self.get_expr(1) @@ -908,11 +910,11 @@ class HighLevelILAssign_unpack(HighLevelILInstruction): operand_names = tuple(["dest", "src"]) @property - def dest(self): + def dest(self) -> List[HighLevelILInstruction]: return self.get_expr_list(0, 1) @property - def src(self): + def src(self) -> HighLevelILInstruction: return self.get_expr(2) @@ -921,19 +923,19 @@ class HighLevelILAssign_mem_ssa(SSA): operand_names = tuple(["dest", "dest_memory", "src", "src_memory"]) @property - def dest(self): + def dest(self) -> HighLevelILInstruction: return self.get_expr(0) @property - def dest_memory(self): + def dest_memory(self) -> int: return self.get_int(1) @property - def src(self): + def src(self) -> HighLevelILInstruction: return self.get_expr(2) @property - def src_memory(self): + def src_memory(self) -> int: return self.get_int(3) @@ -942,19 +944,19 @@ class HighLevelILAssign_unpack_mem_ssa(SSA): operand_names = tuple(["dest", "dest_memory", "src", "src_memory"]) @property - def dest(self): + def dest(self) -> List[HighLevelILInstruction]: return self.get_expr_list(0, 1) @property - def dest_memory(self): + def dest_memory(self) -> int: return self.get_int(2) @property - def src(self): + def src(self) -> HighLevelILInstruction: return self.get_expr(3) @property - def src_memory(self): + def src_memory(self) -> int: return self.get_int(4) @@ -963,7 +965,7 @@ class HighLevelILVar(HighLevelILInstruction): operand_names = tuple(["var"]) @property - def var(self): + def var(self) -> variable.Variable: return self.get_var(0) @@ -972,7 +974,7 @@ class HighLevelILVar_ssa(SSA): operand_names = tuple(["var"]) @property - def var(self): + def var(self) -> 'mediumlevelil.SSAVariable': return self.get_var_ssa(0, 1) @@ -981,11 +983,11 @@ class HighLevelILVar_phi(SSA): operand_names = tuple(["dest", "src"]) @property - def dest(self): + def dest(self) -> 'mediumlevelil.SSAVariable': return self.get_var_ssa(0, 1) @property - def src(self): + def src(self) -> List['mediumlevelil.SSAVariable']: return self.get_var_ssa_list(2, 3) @@ -994,11 +996,11 @@ class HighLevelILMem_phi(Memory): operand_names = tuple(["dest", "src"]) @property - def dest(self): + def dest(self) -> int: return self.get_int(0) @property - def src(self): + def src(self) -> List[int]: return self.get_int_list(1) @@ -1007,15 +1009,15 @@ class HighLevelILStruct_field(HighLevelILInstruction): operand_names = tuple(["src", "offset", "member_index"]) @property - def src(self): + def src(self) -> HighLevelILInstruction: return self.get_expr(0) @property - def offset(self): + def offset(self) -> int: return self.get_int(1) @property - def member_index(self): + def member_index(self) -> Optional[int]: return self.get_member_index(2) @@ -1024,11 +1026,11 @@ class HighLevelILArray_index(HighLevelILInstruction): operand_names = tuple(["src", "index"]) @property - def src(self): + def src(self) -> HighLevelILInstruction: return self.get_expr(0) @property - def index(self): + def index(self) -> HighLevelILInstruction: return self.get_expr(1) @@ -1037,15 +1039,15 @@ class HighLevelILArray_index_ssa(SSA): operand_names = tuple(["src", "src_memory", "index"]) @property - def src(self): + def src(self) -> HighLevelILInstruction: return self.get_expr(0) @property - def src_memory(self): + def src_memory(self) -> int: return self.get_int(1) @property - def index(self): + def index(self) -> HighLevelILInstruction: return self.get_expr(2) @@ -1054,11 +1056,11 @@ class HighLevelILSplit(HighLevelILInstruction): operand_names = tuple(["high", "low"]) @property - def high(self): + def high(self) -> HighLevelILInstruction: return self.get_expr(0) @property - def low(self): + def low(self) -> HighLevelILInstruction: return self.get_expr(1) @@ -1067,7 +1069,7 @@ class HighLevelILDeref(HighLevelILInstruction): operand_names = tuple(["src"]) @property - def src(self): + def src(self) -> HighLevelILInstruction: return self.get_expr(0) @@ -1076,15 +1078,15 @@ class HighLevelILDeref_field(HighLevelILInstruction): operand_names = tuple(["src", "offset", "member_index"]) @property - def src(self): + def src(self) -> HighLevelILInstruction: return self.get_expr(0) @property - def offset(self): + def offset(self) -> int: return self.get_int(1) @property - def member_index(self): + def member_index(self) -> Optional[int]: return self.get_member_index(2) @@ -1093,11 +1095,11 @@ class HighLevelILDeref_ssa(SSA): operand_names = tuple(["src", "src_memory"]) @property - def src(self): + def src(self) -> HighLevelILInstruction: return self.get_expr(0) @property - def src_memory(self): + def src_memory(self) -> int: return self.get_int(1) @@ -1106,19 +1108,19 @@ class HighLevelILDeref_field_ssa(SSA): operand_names = tuple(["src", "src_memory", "offset", "member_index"]) @property - def src(self): + def src(self) -> HighLevelILInstruction: return self.get_expr(0) @property - def src_memory(self): + def src_memory(self) -> int: return self.get_int(1) @property - def offset(self): + def offset(self) -> int: return self.get_int(2) @property - def member_index(self): + def member_index(self) -> Optional[int]: return self.get_member_index(3) @@ -1127,7 +1129,7 @@ class HighLevelILAddress_of(HighLevelILInstruction): operand_names = tuple(["src"]) @property - def src(self): + def src(self) -> HighLevelILInstruction: return self.get_expr(0) @@ -1136,7 +1138,7 @@ class HighLevelILConst(Constant): operand_names = tuple(["constant"]) @property - def constant(self): + def constant(self) -> int: return self.get_int(0) @@ -1145,7 +1147,7 @@ class HighLevelILConst_ptr(Constant): operand_names = tuple(["constant"]) @property - def constant(self): + def constant(self) -> int: return self.get_int(0) @@ -1154,11 +1156,11 @@ class HighLevelILExtern_ptr(Constant): operand_names = tuple(["constant", "offset"]) @property - def constant(self): + def constant(self) -> int: return self.get_int(0) @property - def offset(self): + def offset(self) -> int: return self.get_int(1) @@ -1167,7 +1169,7 @@ class HighLevelILFloat_const(Constant): operand_names = tuple(["constant"]) @property - def constant(self): + def constant(self) -> float: return self.get_float(0) @@ -1176,7 +1178,7 @@ class HighLevelILImport(Constant): operand_names = tuple(["constant"]) @property - def constant(self): + def constant(self) -> int: return self.get_int(0) @@ -1240,15 +1242,15 @@ class HighLevelILRlc(Arithmetic, BinaryOperation): operand_names = tuple(["left", "right", "carry"]) @property - def left(self): + def left(self) -> HighLevelILInstruction: return self.get_expr(0) @property - def right(self): + def right(self) -> HighLevelILInstruction: return self.get_expr(1) @property - def carry(self): + def carry(self) -> HighLevelILInstruction: return self.get_expr(2) @@ -1272,11 +1274,11 @@ class HighLevelILMulu_dp(BinaryOperation, DoublePrecision): operand_names = tuple(["left", "right"]) @property - def left(self): + def left(self) -> HighLevelILInstruction: return self.get_expr(0) @property - def right(self): + def right(self) -> HighLevelILInstruction: return self.get_expr(1) @@ -1285,11 +1287,11 @@ class HighLevelILMuls_dp(Signed, BinaryOperation, DoublePrecision): operand_names = tuple(["left", "right"]) @property - def left(self): + def left(self) -> HighLevelILInstruction: return self.get_expr(0) @property - def right(self): + def right(self) -> HighLevelILInstruction: return self.get_expr(1) @@ -1303,11 +1305,11 @@ class HighLevelILDivu_dp(BinaryOperation, DoublePrecision): operand_names = tuple(["left", "right"]) @property - def left(self): + def left(self) -> HighLevelILInstruction: return self.get_expr(0) @property - def right(self): + def right(self) -> HighLevelILInstruction: return self.get_expr(1) @@ -1321,11 +1323,11 @@ class HighLevelILDivs_dp(Signed, BinaryOperation, DoublePrecision): operand_names = tuple(["left", "right"]) @property - def left(self): + def left(self) -> HighLevelILInstruction: return self.get_expr(0) @property - def right(self): + def right(self) -> HighLevelILInstruction: return self.get_expr(1) @@ -1339,11 +1341,11 @@ class HighLevelILModu_dp(BinaryOperation, DoublePrecision): operand_names = tuple(["left", "right"]) @property - def left(self): + def left(self) -> HighLevelILInstruction: return self.get_expr(0) @property - def right(self): + def right(self) -> HighLevelILInstruction: return self.get_expr(1) @@ -1357,11 +1359,11 @@ class HighLevelILMods_dp(Signed, BinaryOperation, DoublePrecision): operand_names = tuple(["left", "right"]) @property - def left(self): + def left(self) -> HighLevelILInstruction: return self.get_expr(0) @property - def right(self): + def right(self) -> HighLevelILInstruction: return self.get_expr(1) @@ -1370,7 +1372,7 @@ class HighLevelILNeg(Arithmetic, UnaryOperation): operand_names = tuple(["src"]) @property - def src(self): + def src(self) -> HighLevelILInstruction: return self.get_expr(0) @@ -1379,7 +1381,7 @@ class HighLevelILNot(Arithmetic, UnaryOperation): operand_names = tuple(["src"]) @property - def src(self): + def src(self) -> HighLevelILInstruction: return self.get_expr(0) @@ -1388,7 +1390,7 @@ class HighLevelILSx(Arithmetic, UnaryOperation): operand_names = tuple(["src"]) @property - def src(self): + def src(self) -> HighLevelILInstruction: return self.get_expr(0) @@ -1397,7 +1399,7 @@ class HighLevelILZx(Arithmetic, UnaryOperation): operand_names = tuple(["src"]) @property - def src(self): + def src(self) -> HighLevelILInstruction: return self.get_expr(0) @@ -1406,7 +1408,7 @@ class HighLevelILLow_part(Arithmetic, UnaryOperation): operand_names = tuple(["src"]) @property - def src(self): + def src(self) -> HighLevelILInstruction: return self.get_expr(0) @@ -1415,11 +1417,11 @@ class HighLevelILCall(Call): operand_names = tuple(["dest", "params"]) @property - def dest(self): + def dest(self) -> HighLevelILInstruction: return self.get_expr(0) @property - def params(self): + def params(self) -> List[HighLevelILInstruction]: return self.get_expr_list(1, 2) @@ -1428,19 +1430,19 @@ class HighLevelILCall_ssa(Call, SSA): operand_names = tuple(["dest", "params", "dest_memory", "src_memory"]) @property - def dest(self): + def dest(self) -> HighLevelILInstruction: return self.get_expr(0) @property - def params(self): + def params(self) -> List[HighLevelILInstruction]: return self.get_expr_list(1, 2) @property - def dest_memory(self): + def dest_memory(self) -> int: return self.get_int(3) @property - def src_memory(self): + def src_memory(self) -> int: return self.get_int(4) @@ -1449,11 +1451,11 @@ class HighLevelILCmp_e(Comparison): operand_names = tuple(["left", "right"]) @property - def left(self): + def left(self) -> HighLevelILInstruction: return self.get_expr(0) @property - def right(self): + def right(self) -> HighLevelILInstruction: return self.get_expr(1) @@ -1462,11 +1464,11 @@ class HighLevelILCmp_ne(Comparison): operand_names = tuple(["left", "right"]) @property - def left(self): + def left(self) -> HighLevelILInstruction: return self.get_expr(0) @property - def right(self): + def right(self) -> HighLevelILInstruction: return self.get_expr(1) @@ -1475,11 +1477,11 @@ class HighLevelILCmp_slt(Comparison, Signed): operand_names = tuple(["left", "right"]) @property - def left(self): + def left(self) -> HighLevelILInstruction: return self.get_expr(0) @property - def right(self): + def right(self) -> HighLevelILInstruction: return self.get_expr(1) @@ -1488,11 +1490,11 @@ class HighLevelILCmp_ult(Comparison): operand_names = tuple(["left", "right"]) @property - def left(self): + def left(self) -> HighLevelILInstruction: return self.get_expr(0) @property - def right(self): + def right(self) -> HighLevelILInstruction: return self.get_expr(1) @@ -1501,11 +1503,11 @@ class HighLevelILCmp_sle(Comparison, Signed): operand_names = tuple(["left", "right"]) @property - def left(self): + def left(self) -> HighLevelILInstruction: return self.get_expr(0) @property - def right(self): + def right(self) -> HighLevelILInstruction: return self.get_expr(1) @@ -1514,11 +1516,11 @@ class HighLevelILCmp_ule(Comparison): operand_names = tuple(["left", "right"]) @property - def left(self): + def left(self) -> HighLevelILInstruction: return self.get_expr(0) @property - def right(self): + def right(self) -> HighLevelILInstruction: return self.get_expr(1) @@ -1527,11 +1529,11 @@ class HighLevelILCmp_sge(Comparison, Signed): operand_names = tuple(["left", "right"]) @property - def left(self): + def left(self) -> HighLevelILInstruction: return self.get_expr(0) @property - def right(self): + def right(self) -> HighLevelILInstruction: return self.get_expr(1) @@ -1540,11 +1542,11 @@ class HighLevelILCmp_uge(Comparison): operand_names = tuple(["left", "right"]) @property - def left(self): + def left(self) -> HighLevelILInstruction: return self.get_expr(0) @property - def right(self): + def right(self) -> HighLevelILInstruction: return self.get_expr(1) @@ -1553,11 +1555,11 @@ class HighLevelILCmp_sgt(Comparison, Signed): operand_names = tuple(["left", "right"]) @property - def left(self): + def left(self) -> HighLevelILInstruction: return self.get_expr(0) @property - def right(self): + def right(self) -> HighLevelILInstruction: return self.get_expr(1) @@ -1566,11 +1568,11 @@ class HighLevelILCmp_ugt(Comparison): operand_names = tuple(["left", "right"]) @property - def left(self): + def left(self) -> HighLevelILInstruction: return self.get_expr(0) @property - def right(self): + def right(self) -> HighLevelILInstruction: return self.get_expr(1) @@ -1579,11 +1581,11 @@ class HighLevelILTest_bit(Comparison): operand_names = tuple(["left", "right"]) @property - def left(self): + def left(self) -> HighLevelILInstruction: return self.get_expr(0) @property - def right(self): + def right(self) -> HighLevelILInstruction: return self.get_expr(1) @@ -1592,7 +1594,7 @@ class HighLevelILBool_to_int(HighLevelILInstruction): operand_names = tuple(["src"]) @property - def src(self): + def src(self) -> HighLevelILInstruction: return self.get_expr(0) @@ -1606,7 +1608,7 @@ class HighLevelILSyscall(Call): operand_names = tuple(["params"]) @property - def params(self): + def params(self) -> List[HighLevelILInstruction]: return self.get_expr_list(0, 1) @@ -1615,15 +1617,15 @@ class HighLevelILSyscall_ssa(Call, SSA): operand_names = tuple(["params", "dest_memory", "src_memory"]) @property - def params(self): + def params(self) -> List[HighLevelILInstruction]: return self.get_expr_list(0, 1) @property - def dest_memory(self): + def dest_memory(self) -> int: return self.get_int(2) @property - def src_memory(self): + def src_memory(self) -> int: return self.get_int(3) @@ -1632,11 +1634,11 @@ class HighLevelILTailcall(Tailcall): operand_names = tuple(["dest", "params"]) @property - def dest(self): + def dest(self) -> HighLevelILInstruction: return self.get_expr(0) @property - def params(self): + def params(self) -> List[HighLevelILInstruction]: return self.get_expr_list(1, 2) @@ -1650,7 +1652,7 @@ class HighLevelILTrap(Terminal): operand_names = tuple(["vector"]) @property - def vector(self): + def vector(self) -> int: return self.get_int(0) @@ -1659,11 +1661,11 @@ class HighLevelILIntrinsic(HighLevelILInstruction): operand_names = tuple(["intrinsic", "params"]) @property - def intrinsic(self): + def intrinsic(self) -> 'lowlevelil.ILIntrinsic': return self.get_intrinsic(0) @property - def params(self): + def params(self) -> List[HighLevelILInstruction]: return self.get_expr_list(1, 2) @@ -1672,19 +1674,19 @@ class HighLevelILIntrinsic_ssa(SSA): operand_names = tuple(["intrinsic", "params", "dest_memory", "src_memory"]) @property - def intrinsic(self): + def intrinsic(self) -> 'lowlevelil.ILIntrinsic': return self.get_intrinsic(0) @property - def params(self): + def params(self) -> List[HighLevelILInstruction]: return self.get_expr_list(1, 2) @property - def dest_memory(self): + def dest_memory(self) -> int: return self.get_int(2) @property - def src_memory(self): + def src_memory(self) -> int: return self.get_int(3) @@ -1703,7 +1705,7 @@ class HighLevelILUnimpl_mem(Memory): operand_names = tuple(["src"]) @property - def src(self): + def src(self) -> HighLevelILInstruction: return self.get_expr(0) @@ -1712,11 +1714,11 @@ class HighLevelILFadd(FloatingPoint): operand_names = tuple(["left", "right"]) @property - def left(self): + def left(self) -> HighLevelILInstruction: return self.get_expr(0) @property - def right(self): + def right(self) -> HighLevelILInstruction: return self.get_expr(1) @@ -1725,11 +1727,11 @@ class HighLevelILFsub(FloatingPoint): operand_names = tuple(["left", "right"]) @property - def left(self): + def left(self) -> HighLevelILInstruction: return self.get_expr(0) @property - def right(self): + def right(self) -> HighLevelILInstruction: return self.get_expr(1) @@ -1738,11 +1740,11 @@ class HighLevelILFmul(FloatingPoint): operand_names = tuple(["left", "right"]) @property - def left(self): + def left(self) -> HighLevelILInstruction: return self.get_expr(0) @property - def right(self): + def right(self) -> HighLevelILInstruction: return self.get_expr(1) @@ -1751,11 +1753,11 @@ class HighLevelILFdiv(FloatingPoint): operand_names = tuple(["left", "right"]) @property - def left(self): + def left(self) -> HighLevelILInstruction: return self.get_expr(0) @property - def right(self): + def right(self) -> HighLevelILInstruction: return self.get_expr(1) @@ -1764,7 +1766,7 @@ class HighLevelILFsqrt(FloatingPoint): operand_names = tuple(["src"]) @property - def src(self): + def src(self) -> HighLevelILInstruction: return self.get_expr(0) @@ -1773,7 +1775,7 @@ class HighLevelILFneg(FloatingPoint): operand_names = tuple(["src"]) @property - def src(self): + def src(self) -> HighLevelILInstruction: return self.get_expr(0) @@ -1782,7 +1784,7 @@ class HighLevelILFabs(FloatingPoint): operand_names = tuple(["src"]) @property - def src(self): + def src(self) -> HighLevelILInstruction: return self.get_expr(0) @@ -1791,7 +1793,7 @@ class HighLevelILFloat_to_int(FloatingPoint): operand_names = tuple(["src"]) @property - def src(self): + def src(self) -> HighLevelILInstruction: return self.get_expr(0) @@ -1800,7 +1802,7 @@ class HighLevelILInt_to_float(FloatingPoint): operand_names = tuple(["src"]) @property - def src(self): + def src(self) -> HighLevelILInstruction: return self.get_expr(0) @@ -1809,7 +1811,7 @@ class HighLevelILFloat_conv(FloatingPoint): operand_names = tuple(["src"]) @property - def src(self): + def src(self) -> HighLevelILInstruction: return self.get_expr(0) @@ -1818,7 +1820,7 @@ class HighLevelILRound_to_int(FloatingPoint): operand_names = tuple(["src"]) @property - def src(self): + def src(self) -> HighLevelILInstruction: return self.get_expr(0) @@ -1827,7 +1829,7 @@ class HighLevelILFloor(FloatingPoint): operand_names = tuple(["src"]) @property - def src(self): + def src(self) -> HighLevelILInstruction: return self.get_expr(0) @@ -1836,7 +1838,7 @@ class HighLevelILCeil(FloatingPoint): operand_names = tuple(["src"]) @property - def src(self): + def src(self) -> HighLevelILInstruction: return self.get_expr(0) @@ -1845,7 +1847,7 @@ class HighLevelILFtrunc(FloatingPoint): operand_names = tuple(["src"]) @property - def src(self): + def src(self) -> HighLevelILInstruction: return self.get_expr(0) @@ -1854,11 +1856,11 @@ class HighLevelILFcmp_e(FloatingPoint, Comparison): operand_names = tuple(["left", "right"]) @property - def left(self): + def left(self) -> HighLevelILInstruction: return self.get_expr(0) @property - def right(self): + def right(self) -> HighLevelILInstruction: return self.get_expr(1) @@ -1867,11 +1869,11 @@ class HighLevelILFcmp_ne(FloatingPoint, Comparison): operand_names = tuple(["left", "right"]) @property - def left(self): + def left(self) -> HighLevelILInstruction: return self.get_expr(0) @property - def right(self): + def right(self) -> HighLevelILInstruction: return self.get_expr(1) @@ -1880,11 +1882,11 @@ class HighLevelILFcmp_lt(FloatingPoint, Comparison): operand_names = tuple(["left", "right"]) @property - def left(self): + def left(self) -> HighLevelILInstruction: return self.get_expr(0) @property - def right(self): + def right(self) -> HighLevelILInstruction: return self.get_expr(1) @@ -1893,11 +1895,11 @@ class HighLevelILFcmp_le(FloatingPoint, Comparison): operand_names = tuple(["left", "right"]) @property - def left(self): + def left(self) -> HighLevelILInstruction: return self.get_expr(0) @property - def right(self): + def right(self) -> HighLevelILInstruction: return self.get_expr(1) @@ -1906,11 +1908,11 @@ class HighLevelILFcmp_ge(FloatingPoint, Comparison): operand_names = tuple(["left", "right"]) @property - def left(self): + def left(self) -> HighLevelILInstruction: return self.get_expr(0) @property - def right(self): + def right(self) -> HighLevelILInstruction: return self.get_expr(1) @@ -1919,11 +1921,11 @@ class HighLevelILFcmp_gt(FloatingPoint, Comparison): operand_names = tuple(["left", "right"]) @property - def left(self): + def left(self) -> HighLevelILInstruction: return self.get_expr(0) @property - def right(self): + def right(self) -> HighLevelILInstruction: return self.get_expr(1) @@ -1932,11 +1934,11 @@ class HighLevelILFcmp_o(FloatingPoint, Comparison): operand_names = tuple(["left", "right"]) @property - def left(self): + def left(self) -> HighLevelILInstruction: return self.get_expr(0) @property - def right(self): + def right(self) -> HighLevelILInstruction: return self.get_expr(1) @@ -1945,11 +1947,11 @@ class HighLevelILFcmp_uo(FloatingPoint, Comparison): operand_names = tuple(["left", "right"]) @property - def left(self): + def left(self) -> HighLevelILInstruction: return self.get_expr(0) @property - def right(self): + def right(self) -> HighLevelILInstruction: return self.get_expr(1) @@ -2101,23 +2103,25 @@ class HighLevelILFunction: self._arch = arch self._source_function = source_func if handle is not None: - self.handle = core.handle_of_type(handle, core.BNHighLevelILFunction) + HLILHandle = ctypes.POINTER(core.BNHighLevelILFunction) + _handle = ctypes.cast(handle, HLILHandle) if self._source_function is None: - self._source_function = function.Function(handle = core.BNGetHighLevelILOwnerFunction(self.handle)) + self._source_function = function.Function(handle = core.BNGetHighLevelILOwnerFunction(_handle)) if self._arch is None: self._arch = self._source_function.arch else: if self._source_function is None: - self.handle = None raise ValueError("IL functions must be created with an associated function") if self._arch is None: self._arch = self._source_function.arch if self._arch is None: raise ValueError("IL functions must be created with an associated Architecture") func_handle = self._source_function.handle - self.handle = core.BNCreateHighLevelILFunction(self._arch.handle, func_handle) + _handle = core.BNCreateHighLevelILFunction(self._arch.handle, func_handle) assert self._source_function is not None assert self._arch is not None + assert _handle is not None + self.handle = _handle def __del__(self): if self.handle is not None: @@ -2133,8 +2137,6 @@ class HighLevelILFunction: def __eq__(self, other): if not isinstance(other, self.__class__): return NotImplemented - assert self.handle is not None - assert other.handle is not None return ctypes.addressof(self.handle.contents) == ctypes.addressof(other.handle.contents) def __ne__(self, other): @@ -2487,7 +2489,7 @@ class HighLevelILFunction: class HighLevelILBasicBlock(basicblock.BasicBlock): - def __init__(self, view:Optional['binaryview.BinaryView'], handle:core.BNBasicBlock, owner:HighLevelILFunction): + def __init__(self, view:Optional['binaryview.BinaryView'], handle:core.BNBasicBlockHandle, owner:HighLevelILFunction): super(HighLevelILBasicBlock, self).__init__(handle, view) self._il_function = owner @@ -2506,7 +2508,7 @@ class HighLevelILBasicBlock(basicblock.BasicBlock): else: return self.il_function[self.end + idx] - def _create_instance(self, handle:core.BNBasicBlock, view:'binaryview.BinaryView'): + def _create_instance(self, handle:core.BNBasicBlockHandle, view:'binaryview.BinaryView'): """Internal method by super to instantiate child instances""" return HighLevelILBasicBlock(view, handle, self.il_function) diff --git a/python/lowlevelil.py b/python/lowlevelil.py index 21b12909..28be0df6 100644 --- a/python/lowlevelil.py +++ b/python/lowlevelil.py @@ -399,7 +399,7 @@ class LowLevelILInstruction: view = self.function.source_function.view core_block = core.BNGetLowLevelILBasicBlockForInstruction(self.function.handle, self.instr_index) assert core_block is not None, "BNGetLowLevelILBasicBlockForInstruction returned None" - return LowLevelILBasicBlock(view, core_block, self.function) + return LowLevelILBasicBlock(core_block, self.function, view) @property def ssa_form(self) -> 'LowLevelILInstruction': @@ -2417,10 +2417,10 @@ class LowLevelILFunction: self._arch = arch self._source_function = source_func if handle is not None: - self.handle = core.handle_of_type(handle, core.BNLowLevelILFunction) - assert self.handle is not None + LLILHandle = ctypes.POINTER(core.BNLowLevelILFunction) + _handle = ctypes.cast(handle, LLILHandle) if self._source_function is None: - source_handle = core.BNGetLowLevelILOwnerFunction(self.handle) + source_handle = core.BNGetLowLevelILOwnerFunction(_handle) if source_handle: self._source_function = function.Function(handle = source_handle) else: @@ -2439,8 +2439,9 @@ class LowLevelILFunction: func_handle = None else: func_handle = self._source_function.handle - self.handle = core.BNCreateLowLevelILFunction(self._arch.handle, func_handle) - assert self.handle is not None + _handle = core.BNCreateLowLevelILFunction(self._arch.handle, func_handle) + assert _handle is not None + self.handle = _handle assert self._arch is not None assert self._source_function is not None @@ -2462,8 +2463,6 @@ class LowLevelILFunction: def __eq__(self, other): if not isinstance(other, self.__class__): return NotImplemented - assert self.handle is not None - assert other.handle is not None return ctypes.addressof(self.handle.contents) == ctypes.addressof(other.handle.contents) def __ne__(self, other): @@ -2472,7 +2471,6 @@ class LowLevelILFunction: return not (self == other) def __hash__(self): - assert self.handle is not None return hash(ctypes.addressof(self.handle.contents)) def __getitem__(self, i): @@ -2497,8 +2495,8 @@ class LowLevelILFunction: try: for i in range(0, count.value): core_block = core.BNNewBasicBlockReference(blocks[i]) - assert core_block is not None - yield LowLevelILBasicBlock(view, core_block, self) + assert core_block is not None, "core.BNNewBasicBlockReference returned None" + yield LowLevelILBasicBlock(core_block, self, view) finally: core.BNFreeBasicBlockList(blocks, count.value) @@ -2541,8 +2539,8 @@ class LowLevelILFunction: try: for i in range(0, count.value): core_block = core.BNNewBasicBlockReference(blocks[i]) - assert core_block is not None - yield LowLevelILBasicBlock(view, core_block, self) + assert core_block is not None, "core.BNNewBasicBlockReference returned None" + yield LowLevelILBasicBlock(core_block, self, view) finally: core.BNFreeBasicBlockList(blocks, count.value) @@ -4356,7 +4354,7 @@ class LowLevelILFunction: class LowLevelILBasicBlock(basicblock.BasicBlock): - def __init__(self, view:Optional['binaryview.BinaryView'], handle:core.BNBasicBlock, owner:'LowLevelILFunction'): + def __init__(self, handle:core.BNBasicBlockHandle, owner:LowLevelILFunction, view:Optional['binaryview.BinaryView']): super(LowLevelILBasicBlock, self).__init__(handle, view) self._il_function = owner @@ -4392,7 +4390,7 @@ class LowLevelILBasicBlock(basicblock.BasicBlock): def _create_instance(self, handle, view): """Internal method by super to instantiate child instances""" - return LowLevelILBasicBlock(view, handle, self._il_function) + return LowLevelILBasicBlock(handle, self._il_function, view) @property def instruction_count(self) -> int: diff --git a/python/mediumlevelil.py b/python/mediumlevelil.py index 681902b5..27f165d2 100644 --- a/python/mediumlevelil.py +++ b/python/mediumlevelil.py @@ -26,7 +26,7 @@ from dataclasses import dataclass # Binary Ninja components from . import _binaryninjacore as core from .enums import MediumLevelILOperation, ILBranchDependence, DataFlowQueryOption -from . import basicblock #required for MediumLevelILBasicBlock argument +from . import basicblock from . import function from . import types from . import lowlevelil @@ -672,7 +672,7 @@ class UnaryOperation(MediumLevelILInstruction): operand_names = tuple(["src"]) @property - def src(self): + def src(self) -> MediumLevelILInstruction: return self.get_expr(0) @@ -681,11 +681,11 @@ class BinaryOperation(MediumLevelILInstruction): operand_names = tuple(["left", "right"]) @property - def left(self): + def left(self) -> MediumLevelILInstruction: return self.get_expr(0) @property - def right(self): + def right(self) -> MediumLevelILInstruction: return self.get_expr(1) @@ -694,15 +694,15 @@ class Carry(Arithmetic): operand_names = tuple(["left", "right", "carry"]) @property - def left(self): + def left(self) -> MediumLevelILInstruction: return self.get_expr(0) @property - def right(self): + def right(self) -> MediumLevelILInstruction: return self.get_expr(1) @property - def carry(self): + def carry(self) -> MediumLevelILInstruction: return self.get_expr(2) @@ -836,7 +836,7 @@ class MediumLevelILLoad(Load): operand_names = tuple(["src"]) @property - def src(self): + def src(self) -> MediumLevelILInstruction: return self.get_expr(0) @@ -845,7 +845,7 @@ class MediumLevelILVar(MediumLevelILInstruction): operand_names = tuple(["src"]) @property - def src(self): + def src(self) -> variable.Variable: return self.get_var(0) @@ -854,7 +854,7 @@ class MediumLevelILAddress_of(MediumLevelILInstruction): operand_names = tuple(["src"]) @property - def src(self): + def src(self) -> variable.Variable: return self.get_var(0) @@ -863,7 +863,7 @@ class MediumLevelILConst(Constant): operand_names = tuple(["constant"]) @property - def constant(self): + def constant(self) -> int: return self.get_int(0) @@ -872,7 +872,7 @@ class MediumLevelILConst_ptr(Constant): operand_names = tuple(["constant"]) @property - def constant(self): + def constant(self) -> int: return self.get_int(0) @@ -881,7 +881,7 @@ class MediumLevelILFloat_const(Constant, FloatingPoint): operand_names = tuple(["constant"]) @property - def constant(self): + def constant(self) -> float: return self.get_float(0) @@ -890,7 +890,7 @@ class MediumLevelILImport(Constant): operand_names = tuple(["constant"]) @property - def constant(self): + def constant(self) -> int: return self.get_int(0) @@ -924,7 +924,7 @@ class MediumLevelILJump(Terminal): operand_names = tuple(["dest"]) @property - def dest(self): + def dest(self) -> MediumLevelILInstruction: return self.get_expr(0) @@ -933,7 +933,7 @@ class MediumLevelILRet_hint(ControlFlow): operand_names = tuple(["dest"]) @property - def dest(self): + def dest(self) -> MediumLevelILInstruction: return self.get_expr(0) @@ -955,7 +955,7 @@ class MediumLevelILCall_param(MediumLevelILInstruction): operand_names = tuple(["src"]) @property - def src(self): + def src(self) -> List[variable.Variable]: return self.get_var_list(0, 1) @@ -964,7 +964,7 @@ class MediumLevelILRet(Return): operand_names = tuple(["src"]) @property - def src(self): + def src(self) -> List[MediumLevelILInstruction]: return self.get_expr_list(0, 1) @@ -973,7 +973,7 @@ class MediumLevelILGoto(Terminal): operand_names = tuple(["dest"]) @property - def dest(self): + def dest(self) -> int: return self.get_int(0) @@ -982,7 +982,7 @@ class MediumLevelILBool_to_int(MediumLevelILInstruction): operand_names = tuple(["src"]) @property - def src(self): + def src(self) -> MediumLevelILInstruction: return self.get_expr(0) @@ -991,7 +991,7 @@ class MediumLevelILFree_var_slot(RegisterStack): operand_names = tuple(["dest"]) @property - def dest(self): + def dest(self) -> variable.Variable: return self.get_var(0) @@ -1000,7 +1000,7 @@ class MediumLevelILTrap(Terminal): operand_names = tuple(["vector"]) @property - def vector(self): + def vector(self) -> int: return self.get_int(0) @@ -1009,11 +1009,11 @@ class MediumLevelILFree_var_slot_ssa(RegisterStack): operand_names = tuple(["dest", "prev"]) @property - def dest(self): + def dest(self) -> SSAVariable: return self.get_var_ssa_dest_and_src(0, 1) @property - def prev(self): + def prev(self) -> SSAVariable: return self.get_var_ssa_dest_and_src(0, 2) @@ -1022,7 +1022,7 @@ class MediumLevelILUnimpl_mem(Memory): operand_names = tuple(["src"]) @property - def src(self): + def src(self) -> MediumLevelILInstruction: return self.get_expr(0) @@ -1080,7 +1080,7 @@ class MediumLevelILVar_ssa(SSA): operand_names = tuple(["src"]) @property - def src(self): + def src(self) -> SSAVariable: return self.get_var_ssa(0, 1) @@ -1089,7 +1089,7 @@ class MediumLevelILVar_aliased(SSA): operand_names = tuple(["src"]) @property - def src(self): + def src(self) -> SSAVariable: return self.get_var_ssa(0, 1) @@ -1098,11 +1098,11 @@ class MediumLevelILSet_var(SetVar): operand_names = tuple(["dest", "src"]) @property - def dest(self): + def dest(self) -> variable.Variable: return self.get_var(0) @property - def src(self): + def src(self) -> MediumLevelILInstruction: return self.get_expr(1) @@ -1111,11 +1111,11 @@ class MediumLevelILLoad_struct(Load): operand_names = tuple(["src", "offset"]) @property - def src(self): + def src(self) -> MediumLevelILInstruction: return self.get_expr(0) @property - def offset(self): + def offset(self) -> int: return self.get_int(1) @@ -1124,11 +1124,11 @@ class MediumLevelILStore(Store): operand_names = tuple(["dest", "src"]) @property - def dest(self): + def dest(self) -> MediumLevelILInstruction: return self.get_expr(0) @property - def src(self): + def src(self) -> MediumLevelILInstruction: return self.get_expr(1) @@ -1137,11 +1137,11 @@ class MediumLevelILVar_field(MediumLevelILInstruction): operand_names = tuple(["src", "offset"]) @property - def src(self): + def src(self) -> variable.Variable: return self.get_var(0) @property - def offset(self): + def offset(self) -> int: return self.get_int(1) @@ -1150,11 +1150,11 @@ class MediumLevelILVar_split(MediumLevelILInstruction): operand_names = tuple(["high", "low"]) @property - def high(self): + def high(self) -> variable.Variable: return self.get_var(0) @property - def low(self): + def low(self) -> variable.Variable: return self.get_var(1) @@ -1163,11 +1163,11 @@ class MediumLevelILAddress_of_field(MediumLevelILInstruction): operand_names = tuple(["src", "offset"]) @property - def src(self): + def src(self) -> variable.Variable: return self.get_var(0) @property - def offset(self): + def offset(self) -> int: return self.get_int(1) @@ -1176,11 +1176,11 @@ class MediumLevelILExtern_ptr(Constant): operand_names = tuple(["constant", "offset"]) @property - def constant(self): + def constant(self) -> int: return self.get_int(0) @property - def offset(self): + def offset(self) -> int: return self.get_int(1) @@ -1351,11 +1351,11 @@ class MediumLevelILSyscall(Syscall): operand_names = tuple(["output", "params"]) @property - def output(self): + def output(self) -> List[variable.Variable]: return self.get_var_list(0, 1) @property - def params(self): + def params(self) -> List[MediumLevelILInstruction]: return self.get_expr_list(2, 3) @@ -1364,11 +1364,11 @@ class MediumLevelILVar_ssa_field(SSA): operand_names = tuple(["src", "offset"]) @property - def src(self): + def src(self) -> SSAVariable: return self.get_var_ssa(0, 1) @property - def offset(self): + def offset(self) -> int: return self.get_int(2) @@ -1377,11 +1377,11 @@ class MediumLevelILVar_aliased_field(SSA): operand_names = tuple(["src", "offset"]) @property - def src(self): + def src(self) -> SSAVariable: return self.get_var_ssa(0, 1) @property - def offset(self): + def offset(self) -> int: return self.get_int(2) @@ -1390,11 +1390,11 @@ class MediumLevelILVar_split_ssa(SSA): operand_names = tuple(["high", "low"]) @property - def high(self): + def high(self) -> SSAVariable: return self.get_var_ssa(0, 1) @property - def low(self): + def low(self) -> SSAVariable: return self.get_var_ssa(2, 3) @@ -1403,7 +1403,7 @@ class MediumLevelILCall_output_ssa(SSA): operand_names = tuple(["dest_memory", "dest"]) @property - def dest_memory(self): + def dest_memory(self) -> int: return self.get_int(0) @property @@ -1420,11 +1420,11 @@ class MediumLevelILCall_param_ssa(SSA): operand_names = tuple(["src_memory", "src"]) @property - def src_memory(self): + def src_memory(self) -> int: return self.get_int(0) @property - def src(self): + def src(self) -> List[SSAVariable]: return self.get_var_ssa_list(1, 2) @@ -1433,11 +1433,11 @@ class MediumLevelILLoad_ssa(Load, SSA): operand_names = tuple(["src", "src_memory"]) @property - def src(self): + def src(self) -> MediumLevelILInstruction: return self.get_expr(0) @property - def src_memory(self): + def src_memory(self) -> int: return self.get_int(1) @@ -1446,11 +1446,11 @@ class MediumLevelILVar_phi(Phi, SetVar, SSA): operand_names = tuple(["dest", "src"]) @property - def dest(self): + def dest(self) -> SSAVariable: return self.get_var_ssa(0, 1) @property - def src(self): + def src(self) -> List[SSAVariable]: return self.get_var_ssa_list(2, 3) @@ -1459,11 +1459,11 @@ class MediumLevelILMem_phi(Memory, Phi): operand_names = tuple(["dest_memory", "src_memory"]) @property - def dest_memory(self): + def dest_memory(self) -> int: return self.get_int(0) @property - def src_memory(self): + def src_memory(self) -> List[int]: return self.get_int_list(1) @@ -1472,11 +1472,11 @@ class MediumLevelILSet_var_ssa(SetVar): operand_names = tuple(["dest", "src"]) @property - def dest(self): + def dest(self) -> SSAVariable: return self.get_var_ssa(0, 1) @property - def src(self): + def src(self) -> MediumLevelILInstruction: return self.get_expr(2) @@ -1545,7 +1545,7 @@ class MediumLevelILJump_to(Terminal): operand_names = tuple(["dest", "targets"]) @property - def dest(self): + def dest(self) -> MediumLevelILInstruction: return self.get_expr(0) @property @@ -1558,15 +1558,15 @@ class MediumLevelILSet_var_aliased(SetVar, SSA): operand_names = tuple(["dest", "prev", "src"]) @property - def dest(self): + def dest(self) -> SSAVariable: return self.get_var_ssa_dest_and_src(0, 1) @property - def prev(self): + def prev(self) -> SSAVariable: return self.get_var_ssa_dest_and_src(0, 2) @property - def src(self): + def src(self) -> MediumLevelILInstruction: return self.get_expr(3) @@ -1581,7 +1581,7 @@ class MediumLevelILSyscall_untyped(Syscall): return inst.dest @property - def dest(self): + def dest(self) -> MediumLevelILInstruction: return self.get_expr(1) @property @@ -1591,7 +1591,7 @@ class MediumLevelILSyscall_untyped(Syscall): return inst.src @property - def stack(self): + def stack(self) -> MediumLevelILInstruction: return self.get_expr(2) @@ -1600,15 +1600,15 @@ class MediumLevelILIntrinsic(MediumLevelILInstruction): operand_names = tuple(["output", "intrinsic", "params"]) @property - def output(self): + def output(self) -> List[variable.Variable]: return self.get_var_list(0, 1) @property - def intrinsic(self): + def intrinsic(self) -> 'lowlevelil.ILIntrinsic': return self.get_intrinsic(2) @property - def params(self): + def params(self) -> List[MediumLevelILInstruction]: return self.get_expr_list(3, 4) @property @@ -1629,15 +1629,15 @@ class MediumLevelILIntrinsic_ssa(SSA): operand_names = tuple(["output", "intrinsic", "params"]) @property - def output(self): + def output(self) -> List[SSAVariable]: return self.get_var_ssa_list(0, 1) @property - def intrinsic(self): + def intrinsic(self) -> 'lowlevelil.ILIntrinsic': return self.get_intrinsic(2) @property - def params(self): + def params(self) -> List[MediumLevelILInstruction]: return self.get_expr_list(3, 4) @property @@ -1657,19 +1657,19 @@ class MediumLevelILSet_var_ssa_field(SetVar): operand_names = tuple(["dest", "prev", "offset", "src"]) @property - def dest(self): + def dest(self) -> SSAVariable: return self.get_var_ssa_dest_and_src(0, 1) @property - def prev(self): + def prev(self) -> SSAVariable: return self.get_var_ssa_dest_and_src(0, 2) @property - def offset(self): + def offset(self) -> int: return self.get_int(3) @property - def src(self): + def src(self) -> MediumLevelILInstruction: return self.get_expr(4) @property @@ -1682,15 +1682,15 @@ class MediumLevelILSet_var_split_ssa(SetVar): operand_names = tuple(["high", "low", "src"]) @property - def high(self): + def high(self) -> SSAVariable: return self.get_var_ssa(0, 1) @property - def low(self): + def low(self) -> SSAVariable: return self.get_var_ssa(2, 3) @property - def src(self): + def src(self) -> MediumLevelILInstruction: return self.get_expr(4) @property @@ -1703,19 +1703,19 @@ class MediumLevelILSet_var_aliased_field(SetVar, SSA): operand_names = tuple(["dest", "prev", "offset", "src"]) @property - def dest(self): + def dest(self) -> SSAVariable: return self.get_var_ssa_dest_and_src(0, 1) @property - def prev(self): + def prev(self) -> SSAVariable: return self.get_var_ssa_dest_and_src(0, 2) @property - def offset(self): + def offset(self) -> int: return self.get_int(3) @property - def src(self): + def src(self) -> MediumLevelILInstruction: return self.get_expr(4) @property @@ -1728,23 +1728,23 @@ class MediumLevelILSyscall_ssa(Syscall, SSA): operand_names = tuple(["output", "params", "src_memory"]) @property - def output(self): + def output(self) -> List[SSAVariable]: inst = self.get_expr(0) assert isinstance(inst, MediumLevelILCall_output_ssa), "MediumLevelILSyscall_ssa return bad type for output" return inst.dest @property - def output_dest_memory(self): + def output_dest_memory(self) -> int: inst = self.get_expr(0) assert isinstance(inst, MediumLevelILCall_output_ssa), "MediumLevelILSyscall_ssa return bad type for output" return inst.dest_memory @property - def params(self): + def params(self) -> List[MediumLevelILInstruction]: return self.get_expr_list(1, 2) @property - def src_memory(self): + def src_memory(self) -> int: return self.get_int(3) @@ -1753,31 +1753,31 @@ class MediumLevelILSyscall_untyped_ssa(Syscall, SSA): operand_names = tuple(["output", "params", "stack"]) @property - def output(self): + def output(self) -> List[SSAVariable]: inst = self.get_expr(0) assert isinstance(inst, MediumLevelILCall_output_ssa), "MediumLevelILSyscall_untyped_ssa return bad type for 'output'" return inst.dest @property - def output_dest_memory(self): + def output_dest_memory(self) -> int: inst = self.get_expr(0) assert isinstance(inst, MediumLevelILCall_output_ssa), "MediumLevelILSyscall_untyped_ssa return bad type for 'output_dest_memory'" return inst.dest_memory @property - def params(self): + def params(self) -> List[SSAVariable]: inst = self.get_expr(1) assert isinstance(inst, MediumLevelILCall_param_ssa), "MediumLevelILSyscall_untyped_ssa return bad type for 'params'" return inst.src @property - def params_src_memory(self): + def params_src_memory(self) -> int: inst = self.get_expr(1) assert isinstance(inst, MediumLevelILCall_param_ssa), "MediumLevelILSyscall_untyped_ssa return bad type for 'params_src_memory'" return inst.src_memory @property - def stack(self): + def stack(self) -> MediumLevelILInstruction: return self.get_expr(2) @@ -1786,15 +1786,15 @@ class MediumLevelILLoad_struct_ssa(Load, SSA): operand_names = tuple(["src", "offset", "src_memory"]) @property - def src(self): + def src(self) -> MediumLevelILInstruction: return self.get_expr(0) @property - def offset(self): + def offset(self) -> int: return self.get_int(1) @property - def src_memory(self): + def src_memory(self) -> int: return self.get_int(2) @@ -1803,15 +1803,15 @@ class MediumLevelILSet_var_field(SetVar): operand_names = tuple(["dest", "offset", "src"]) @property - def dest(self): + def dest(self) -> variable.Variable: return self.get_var(0) @property - def offset(self): + def offset(self) -> int: return self.get_int(1) @property - def src(self): + def src(self) -> MediumLevelILInstruction: return self.get_expr(2) @@ -1820,15 +1820,15 @@ class MediumLevelILSet_var_split(SetVar): operand_names = tuple(["high", "low", "src"]) @property - def high(self): + def high(self) -> variable.Variable: return self.get_var(0) @property - def low(self): + def low(self) -> variable.Variable: return self.get_var(1) @property - def src(self): + def src(self) -> MediumLevelILInstruction: return self.get_expr(2) @property @@ -1841,15 +1841,15 @@ class MediumLevelILStore_struct(Store): operand_names = tuple(["dest", "offset", "src"]) @property - def dest(self): + def dest(self) -> MediumLevelILInstruction: return self.get_expr(0) @property - def offset(self): + def offset(self) -> int: return self.get_int(1) @property - def src(self): + def src(self) -> MediumLevelILInstruction: return self.get_expr(2) @@ -1878,15 +1878,15 @@ class MediumLevelILCall(Call): operand_names = tuple(["output", "dest", "params"]) @property - def output(self): + def output(self) -> List[variable.Variable]: return self.get_var_list(0, 1) @property - def dest(self): + def dest(self) -> MediumLevelILInstruction: return self.get_expr(2) @property - def params(self): + def params(self) -> List[MediumLevelILInstruction]: return self.get_expr_list(3, 4) @@ -1895,15 +1895,15 @@ class MediumLevelILIf(Terminal): operand_names = tuple(["condition", "true", "false"]) @property - def condition(self): + def condition(self) -> MediumLevelILInstruction: return self.get_expr(0) @property - def true(self): + def true(self) -> int: return self.get_int(1) @property - def false(self): + def false(self) -> int: return self.get_int(2) @@ -1912,23 +1912,23 @@ class MediumLevelILTailcall_untyped(Tailcall): operand_names = tuple(["output", "dest", "params", "stack"]) @property - def output(self): + def output(self) -> List[variable.Variable]: inst = self.get_expr(0) assert isinstance(inst, MediumLevelILCall_output), "MediumLevelILTailcall_untyped return bad type for 'output'" return inst.dest @property - def dest(self): + def dest(self) -> MediumLevelILInstruction: return self.get_expr(1) @property - def params(self): + def params(self) -> List[variable.Variable]: inst = self.get_expr(2) assert isinstance(inst, MediumLevelILCall_param), "MediumLevelILTailcall_untyped return bad type for 'params'" return inst.src @property - def stack(self): + def stack(self) -> MediumLevelILInstruction: return self.get_expr(3) @@ -1937,27 +1937,27 @@ class MediumLevelILCall_ssa(Call, SSA): operand_names = tuple(["output", "dest", "params", "src_memory"]) @property - def output(self): + def output(self) -> List[SSAVariable]: inst = self.get_expr(0) assert isinstance(inst, MediumLevelILCall_output_ssa), "MediumLevelILCall_ssa return bad type for output" return inst.dest @property - def output_dest_memory(self): + def output_dest_memory(self) -> int: inst = self.get_expr(0) assert isinstance(inst, MediumLevelILCall_output_ssa), "MediumLevelILCall_ssa return bad type for output" return inst.dest_memory @property - def dest(self): + def dest(self) -> MediumLevelILInstruction: return self.get_expr(1) @property - def params(self): + def params(self) -> List[MediumLevelILInstruction]: return self.get_expr_list(2, 3) @property - def src_memory(self): + def src_memory(self) -> int: return self.get_int(4) @@ -1966,23 +1966,23 @@ class MediumLevelILCall_untyped_ssa(Call, SSA): operand_names = tuple(["output", "dest", "params", "stack"]) @property - def output(self): + def output(self) -> List[SSAVariable]: inst = self.get_expr(0) assert isinstance(inst, MediumLevelILCall_output_ssa), "MediumLevelILCall_untyped_ssa return bad type for output" return inst.dest @property - def output_dest_memory(self): + def output_dest_memory(self) -> int: inst = self.get_expr(0) assert isinstance(inst, MediumLevelILCall_output_ssa), "MediumLevelILCall_untyped_ssa return bad type for output" return inst.dest_memory @property - def dest(self): + def dest(self) -> MediumLevelILInstruction: return self.get_expr(1) @property - def params(self): + def params(self) -> List[SSAVariable]: inst = self.get_expr(2) assert isinstance(inst, MediumLevelILCall_param_ssa), "MediumLevelILCall_untyped_ssa return bad type for 'params'" return inst.src @@ -1994,7 +1994,7 @@ class MediumLevelILCall_untyped_ssa(Call, SSA): return inst.src_memory @property - def stack(self): + def stack(self) -> MediumLevelILInstruction: return self.get_expr(3) @@ -2003,15 +2003,15 @@ class MediumLevelILTailcall(Tailcall): operand_names = tuple(["output", "dest", "params"]) @property - def output(self): + def output(self) -> List[variable.Variable]: return self.get_var_list(0, 1) @property - def dest(self): + def dest(self) -> MediumLevelILInstruction: return self.get_expr(2) @property - def params(self): + def params(self) -> List[MediumLevelILInstruction]: return self.get_expr_list(3, 4) @@ -2020,27 +2020,27 @@ class MediumLevelILTailcall_ssa(Tailcall, SSA): operand_names = tuple(["output", "dest", "params", "src_memory"]) @property - def output(self): + def output(self) -> List[SSAVariable]: inst = self.get_expr(0) assert isinstance(inst, MediumLevelILCall_output_ssa), "MediumLevelILTailcall_ssa return bad type for output" return inst.dest @property - def output_dest_memory(self): + def output_dest_memory(self) -> int: inst = self.get_expr(0) assert isinstance(inst, MediumLevelILCall_output_ssa), "MediumLevelILTailcall_ssa return bad type for output" return inst.dest_memory @property - def dest(self): + def dest(self) -> MediumLevelILInstruction: return self.get_expr(1) @property - def params(self): + def params(self) -> List[MediumLevelILInstruction]: return self.get_expr_list(2, 3) @property - def src_memory(self): + def src_memory(self) -> int: return self.get_int(4) @@ -2049,27 +2049,27 @@ class MediumLevelILTailcall_untyped_ssa(Tailcall, SSA): operand_names = tuple(["output", "dest", "params", "stack"]) @property - def output(self): + def output(self) -> List[SSAVariable]: inst = self.get_expr(0) assert isinstance(inst, MediumLevelILCall_output_ssa), "MediumLevelILTailcall_untyped_ssa return bad type for 'output'" return inst.dest @property - def output_dest_memory(self): + def output_dest_memory(self) -> int: inst = self.get_expr(0) assert isinstance(inst, MediumLevelILCall_output_ssa), "MediumLevelILTailcall_untyped_ssa return bad type for 'output'" return inst.dest_memory @property - def dest(self): + def dest(self) -> MediumLevelILInstruction: return self.get_expr(1) @property - def params(self): + def params(self) -> MediumLevelILInstruction: return self.get_expr(2) @property - def stack(self): + def stack(self) -> MediumLevelILInstruction: return self.get_expr(3) @@ -2078,19 +2078,19 @@ class MediumLevelILStore_ssa(Store, SSA): operand_names = tuple(["dest", "dest_memory", "src_memory", "src"]) @property - def dest(self): + def dest(self) -> MediumLevelILInstruction: return self.get_expr(0) @property - def dest_memory(self): + def dest_memory(self) -> int: return self.get_int(1) @property - def src_memory(self): + def src_memory(self) -> int: return self.get_int(2) @property - def src(self): + def src(self) -> MediumLevelILInstruction: return self.get_expr(3) @@ -2099,23 +2099,23 @@ class MediumLevelILCall_untyped(Call): operand_names = tuple(["output", "dest", "params", "stack"]) @property - def output(self): + def output(self) -> List[variable.Variable]: inst = self.get_expr(0) assert isinstance(inst, MediumLevelILCall_output), "MediumLevelILCall_untyped return bad type for 'output'" return inst.dest @property - def dest(self): + def dest(self) -> MediumLevelILInstruction: return self.get_expr(1) @property - def params(self): + def params(self) -> List[variable.Variable]: inst = self.get_expr(2) assert isinstance(inst, MediumLevelILCall_param), "MediumLevelILCall_untyped return bad type for 'params'" return inst.src @property - def stack(self): + def stack(self) -> MediumLevelILInstruction: return self.get_expr(3) @@ -2124,23 +2124,23 @@ class MediumLevelILStore_struct_ssa(Store, SSA): operand_names = tuple(["dest", "offset", "dest_memory", "src_memory", "src"]) @property - def dest(self): + def dest(self) -> MediumLevelILInstruction: return self.get_expr(0) @property - def offset(self): + def offset(self) -> int: return self.get_int(1) @property - def dest_memory(self): + def dest_memory(self) -> int: return self.get_int(2) @property - def src_memory(self): + def src_memory(self) -> int: return self.get_int(3) @property - def src(self): + def src(self) -> MediumLevelILInstruction: return self.get_expr(4) ILInstruction = { @@ -2307,7 +2307,8 @@ class MediumLevelILFunction: _arch = arch _source_function = source_func if handle is not None: - _handle = core.handle_of_type(handle, core.BNMediumLevelILFunction) + MLILHandle = ctypes.POINTER(core.BNMediumLevelILFunction) + _handle = ctypes.cast(handle, MLILHandle) if _source_function is None: _source_function = function.Function(handle = core.BNGetMediumLevelILOwnerFunction(_handle)) if _arch is None: @@ -2782,7 +2783,7 @@ class MediumLevelILFunction: class MediumLevelILBasicBlock(basicblock.BasicBlock): - def __init__(self, handle:core.BNBasicBlock, owner:MediumLevelILFunction, view:Optional['binaryview.BinaryView']=None): + def __init__(self, handle:core.BNBasicBlockHandle, owner:MediumLevelILFunction, view:Optional['binaryview.BinaryView']=None): super(MediumLevelILBasicBlock, self).__init__(handle, view) self._il_function = owner @@ -2797,7 +2798,7 @@ class MediumLevelILBasicBlock(basicblock.BasicBlock): for idx in range(self.start, self.end): yield self._il_function[idx] - def __getitem__(self, idx): + def __getitem__(self, idx) -> 'MediumLevelILInstruction': size = self.end - self.start if isinstance(idx, slice): return [self[index] for index in range(*idx.indices(size))] @@ -2819,7 +2820,7 @@ class MediumLevelILBasicBlock(basicblock.BasicBlock): else: return False - def _create_instance(self, handle:core.BNBasicBlock, view:'binaryview.BinaryView') -> 'MediumLevelILBasicBlock': + def _create_instance(self, handle:core.BNBasicBlockHandle, view:'binaryview.BinaryView') -> 'MediumLevelILBasicBlock': """Internal method by super to instantiate child instances""" return MediumLevelILBasicBlock(handle, self.il_function, view) diff --git a/python/platform.py b/python/platform.py index 882b4acb..2dacf7a6 100644 --- a/python/platform.py +++ b/python/platform.py @@ -20,6 +20,7 @@ import os import ctypes +from typing import Mapping # Binary Ninja components import binaryninja @@ -425,9 +426,9 @@ class Platform(metaclass=_PlatformMetaClass): core.free_string(errors) if not result: raise SyntaxError(error_str) - type_dict = {} - variables = {} - functions = {} + type_dict:Mapping[types.QualifiedName, types.Type] = {} + variables:Mapping[types.QualifiedName, types.Type] = {} + functions:Mapping[types.QualifiedName, types.Type] = {} for i in range(0, parse.typeCount): name = types.QualifiedName._from_core_struct(parse.types[i].name) type_dict[name] = types.Type(core.BNNewTypeReference(parse.types[i].type), platform = self) diff --git a/python/scriptingprovider.py b/python/scriptingprovider.py index b1012c42..d3b2c23c 100644 --- a/python/scriptingprovider.py +++ b/python/scriptingprovider.py @@ -806,10 +806,10 @@ class PythonScriptingProvider(ScriptingProvider): python_bin, status = self._get_executable_for_libpython(python_lib, python_bin_override) return python_bin - def _load_module(self, ctx, repo_path, module, force): + def _load_module(self, ctx, _repo_path:bytes, _module:bytes, force:bool): + repo_path = _repo_path.decode("utf-8") + module = _module.decode("utf-8") try: - repo_path = repo_path.decode("utf-8") - module = module.decode("utf-8") repo = RepositoryManager()[repo_path] plugin = repo[module] diff --git a/python/types.py b/python/types.py index 0e5f7562..d3f6294d 100644 --- a/python/types.py +++ b/python/types.py @@ -258,7 +258,8 @@ class Symbol: """ def __init__(self, sym_type, addr, short_name, full_name=None, raw_name=None, handle=None, binding=None, namespace=None, ordinal=0): if handle is not None: - _handle = core.handle_of_type(handle, core.BNSymbol) + SymbolPointer = ctypes.POINTER(core.BNSymbol) + _handle = ctypes.cast(handle, SymbolPointer) else: if isinstance(sym_type, str): sym_type = SymbolType[sym_type] @@ -1093,7 +1094,7 @@ class StructureMember: if len(self.name) == 0: return f"" return f"<{self.type.get_string_before_name()} {self.name}{self.type.get_string_after_name()}" + \ - ", offset {self.offset:#x}>" + f", offset {self.offset:#x}>" class Structure: def __init__(self, handle=None): @@ -1395,28 +1396,7 @@ class TypeParserResult: return "" % (self.types, self.variables, self.functions) - @types.setter - def types(self, value): - self._types = value - - @property - def variables(self): - return self._variables - - @variables.setter - def variables(self, value): - self._variables = value - - @property - def functions(self): - return self._functions - - @functions.setter - def functions(self, value): - self._functions = value - - -def preprocess_source(source, filename=None, include_dirs=[]): +def preprocess_source(source:str, filename:str=None, include_dirs:List[str]=[]) -> Tuple[Optional[str], str]: """ ``preprocess_source`` run the C preprocessor on the given source or source filename. diff --git a/python/workflow.py b/python/workflow.py index d74b8184..45ef97f9 100644 --- a/python/workflow.py +++ b/python/workflow.py @@ -19,48 +19,45 @@ # IN THE SOFTWARE. import ctypes -import json -import random +import traceback +from typing import List, Union, Callable, Optional, Any # Binary Ninja components import binaryninja -from binaryninja import _binaryninjacore as core -from binaryninja import BranchType -from binaryninja.flowgraph import EdgeStyle, EdgePenStyle, FlowGraph, FlowGraphNode, ThemeColor -from typing import List, Union +from . import log +from . import _binaryninjacore as core +from .flowgraph import FlowGraph, CoreFlowGraph -# 2-3 compatibility -from binaryninja import range -from binaryninja import pyNativeStr - -_action_callbacks = {} +ActivityType = Union['Activity', str] class Activity(object): """ :class:`Activity` """ - def __init__(self, name = "", handle = None, action = None): + _action_callbacks = {} + def __init__(self, name:str = "", handle:Optional[core.BNActivityHandle] = None, action:Optional[Callable[[Any], None]] = None): if handle is None: #cls._notify(ac, callback) action_callback = ctypes.CFUNCTYPE(None, ctypes.c_void_p, ctypes.POINTER(core.BNAnalysisContext))(lambda ctxt, ac: self._action(ac)) - self.handle = core.BNCreateActivity(name, None, action_callback) + _handle = core.BNCreateActivity(name, None, action_callback) self.action = action - global _action_callbacks - _action_callbacks[len(_action_callbacks)] = action_callback + self.__class__._action_callbacks[len(self.__class__._action_callbacks)] = action_callback else: - self.handle = handle - self.__dict__["name"] = name + _handle = handle + assert _handle is not None, "Activity instantiation failed" + self.handle = _handle + self._name = name - def _action(self, ac): + def _action(self, ac:Any): try: if self.action is not None: self.action(ac) except: - binaryninja.log.log_error(traceback.format_exc()) + log.log_error(traceback.format_exc()) def __del__(self): - binaryninja.log.log_error("Activity DEL called!") + log.log_error("Activity DEL called!") if self.handle is not None: core.BNFreeActivity(self.handle) @@ -81,35 +78,44 @@ class Activity(object): return not (self == other) def __hash__(self): - return hash((self.instance_id, ctypes.addressof(self.handle.contents))) + return hash(ctypes.addressof(self.handle.contents)) @property def name(self): """Activity name (read-only)""" + if self._name != "": + return self._name return core.BNActivityGetName(self.handle) class _WorkflowMetaclass(type): - @property - def list(self): + def list(self) -> List['Workflow']: """List all Workflows (read-only)""" binaryninja._init_plugins() count = ctypes.c_ulonglong() workflows = core.BNGetWorkflowList(count) + assert workflows is not None, "core.BNGetWorkflowList returned None" result = [] - for i in range(0, count.value): - result.append(Workflow(handle = core.BNNewWorkflowReference(workflows[i]))) - core.BNFreeWorkflowList(workflows, count.value) - return result + try: + for i in range(0, count.value): + handle = core.BNNewWorkflowReference(workflows[i]) + assert handle is not None, "core.BNNewWorkflowReference returned None" + result.append(Workflow(handle = handle)) + return result + finally: + core.BNFreeWorkflowList(workflows, count.value) def __iter__(self): binaryninja._init_plugins() count = ctypes.c_ulonglong() workflows = core.BNGetWorkflowList(count) + assert workflows is not None, "core.BNGetWorkflowList returned None" try: for i in range(0, count.value): - yield Workflow(handle = core.BNNewWorkflowReference(workflows[i])) + handle = core.BNNewWorkflowReference(workflows[i]) + assert handle is not None, "core.BNNewWorkflowReference returned None" + yield Workflow(handle = handle) finally: core.BNFreeWorkflowList(workflows, count.value) @@ -118,14 +124,8 @@ class _WorkflowMetaclass(type): workflow = core.BNWorkflowInstance(str(value)) return Workflow(handle = workflow) - def __setattr__(self, name, value): - try: - type.__setattr__(self, name, value) - except AttributeError: - raise AttributeError("attribute '%s' is read only" % name) - -class Workflow(object, metaclass=_WorkflowMetaclass): +class Workflow(metaclass=_WorkflowMetaclass): """ :class:`Workflow` A Binary Ninja Workflow is an abstraction of a computational binary analysis pipeline and it provides the extensibility \ mechanism needed for tailored binary analysis and decompilation. More specifically, a Workflow is a repository of activities along with a \ @@ -158,7 +158,7 @@ class Workflow(object, metaclass=_WorkflowMetaclass): >>> pwf = Workflow().clone("PythonLogWarnWorkflow") >>> pwf.show_topology() - >>> pwf.register_activity(Activity("PythonLogWarn", action=lambda analysis_context: binaryninja.log.log_warn("PythonLogWarn Called!"))) + >>> pwf.register_activity(Activity("PythonLogWarn", action=lambda analysis_context: log.log_warn("PythonLogWarn Called!"))) >>> pwf.insert("core.function.basicBlockAnalysis", ["PythonLogWarn"]) >>> pwf.register() @@ -167,15 +167,17 @@ class Workflow(object, metaclass=_WorkflowMetaclass): >>> Workflow().show_documentation() """ - def __init__(self, name = "", handle = None, query_registry = True): + def __init__(self, name:str = "", handle:core.BNWorkflowHandle = None, query_registry:bool = True): if handle is None: if query_registry: - self.handle = core.BNWorkflowInstance(str(name)) + _handle = core.BNWorkflowInstance(str(name)) else: - self.handle = core.BNCreateWorkflow(name) + _handle = core.BNCreateWorkflow(name) else: - self.handle = handle - self.__dict__["name"] = core.BNGetWorkflowName(self.handle) + _handle = handle + assert _handle is not None + self.handle = _handle + self._name = core.BNGetWorkflowName(self.handle) def __del__(self): if self.handle is not None: @@ -193,6 +195,10 @@ class Workflow(object, metaclass=_WorkflowMetaclass): def __str__(self): return self.name + @property + def name(self) -> str: + return self._name + def __eq__(self, other): if not isinstance(other, self.__class__): return NotImplemented @@ -204,9 +210,9 @@ class Workflow(object, metaclass=_WorkflowMetaclass): return not (self == other) def __hash__(self): - return hash((self.instance_id, ctypes.addressof(self.handle.contents))) + return hash(ctypes.addressof(self.handle.contents)) - def register(self, description = "") -> bool: + def register(self, description:str = "") -> bool: """ ``register`` Register this Workflow, making it immutable and available for use. @@ -216,7 +222,7 @@ class Workflow(object, metaclass=_WorkflowMetaclass): """ return core.BNRegisterWorkflow(self.handle, str(description)) - def clone(self, name, activity = "") -> "Workflow": + def clone(self, name:str, activity:ActivityType = "") -> "Workflow": """ ``clone`` Clone a new Workflow, copying all Activities and the execution strategy. @@ -228,7 +234,7 @@ class Workflow(object, metaclass=_WorkflowMetaclass): workflow = core.BNWorkflowClone(self.handle, str(name), str(activity)) return Workflow(handle = workflow) - def register_activity(self, activity, subactivities = [], description = "") -> bool: + def register_activity(self, activity:Activity, subactivities:List[ActivityType] = [], description:str = "") -> Optional[bool]: """ ``register_activity`` Register an Activity with this Workflow. @@ -245,21 +251,21 @@ class Workflow(object, metaclass=_WorkflowMetaclass): input_list[i] = binaryninja.cstr(str(subactivities[i])) return core.BNWorkflowRegisterActivity(self.handle, activity.handle, input_list, len(subactivities), str(description)) - def contains(self, activity) -> bool: + def contains(self, activity:ActivityType) -> bool: """ ``contains`` Determine if an Activity exists in this Workflow. - :param str activity: the Activity name + :param ActivityType activity: the Activity name :return: True if the Activity exists, False otherwise :rtype: bool """ - return core.BNWorkflowContains(self.handle, str(name)) + return core.BNWorkflowContains(self.handle, str(activity)) - def configuration(self, activity = "") -> str: + def configuration(self, activity:ActivityType = "") -> str: """ ``configuration`` Retrieve the configuration as an adjacency list in JSON for the Workflow, or if specified just for the given ``activity``. - :param str activity: if specified, return the configuration for the ``activity`` + :param ActivityType activity: if specified, return the configuration for the ``activity`` :return: an adjacency list representation of the configuration in JSON :rtype: str """ @@ -274,7 +280,7 @@ class Workflow(object, metaclass=_WorkflowMetaclass): """ return core.BNWorkflowIsRegistered(self.handle) - def get_activity(self, activity) -> Union[None, Activity]: + def get_activity(self, activity:ActivityType) -> Optional[Activity]: """ ``get_activity`` Retrieve the Activity object for the specified ``activity``. @@ -285,9 +291,9 @@ class Workflow(object, metaclass=_WorkflowMetaclass): handle = core.BNWorkflowGetActivity(self.handle, str(activity)) if handle is None: return None - return Activity(activity, handle) + return Activity(str(activity), handle) - def activity_roots(self, activity = "") -> List[str]: + def activity_roots(self, activity:ActivityType = "") -> List[str]: """ ``activity_roots`` Retrieve the list of activity roots for the Workflow, or if specified just for the given ``activity``. @@ -297,13 +303,16 @@ class Workflow(object, metaclass=_WorkflowMetaclass): """ length = ctypes.c_ulonglong() result = core.BNWorkflowGetActivityRoots(self.handle, str(activity), ctypes.byref(length)) + assert result is not None, "core.BNWorkflowGetActivityRoots returned None" out_list = [] - for i in range(length.value): - out_list.append(pyNativeStr(result[i])) - core.BNFreeStringList(result, length) - return out_list + try: + for i in range(length.value): + out_list.append(result[i].decode('utf-8')) + return out_list + finally: + core.BNFreeStringList(result, length) - def subactivities(self, activity = "", immediate = True) -> List[str]: + def subactivities(self, activity:ActivityType = "", immediate:bool = True) -> List[str]: """ ``subactivities`` Retrieve the list of all activities, or optionally a filtered list. @@ -314,13 +323,16 @@ class Workflow(object, metaclass=_WorkflowMetaclass): """ length = ctypes.c_ulonglong() result = core.BNWorkflowGetSubactivities(self.handle, str(activity), immediate, ctypes.byref(length)) + assert result is not None, "core.BNWorkflowGetSubactivities returned None" out_list = [] - for i in range(length.value): - out_list.append(pyNativeStr(result[i])) - core.BNFreeStringList(result, length) - return out_list + try: + for i in range(length.value): + out_list.append(result[i].decode('utf-8')) + return out_list + finally: + core.BNFreeStringList(result, length) - def assign_subactivities(self, activity, activities) -> bool: + def assign_subactivities(self, activity:Activity, activities:List[str]) -> bool: """ ``assign_subactivities`` Assign the list of ``activities`` as the new set of children for the specified ``activity``. @@ -343,7 +355,7 @@ class Workflow(object, metaclass=_WorkflowMetaclass): """ return core.BNWorkflowClear(self.handle) - def insert(self, activity, activities) -> bool: + def insert(self, activity:ActivityType, activities:List[str]) -> bool: """ ``insert`` Insert the list of ``activities`` before the specified ``activity`` and at the same level. @@ -357,7 +369,7 @@ class Workflow(object, metaclass=_WorkflowMetaclass): input_list[i] = binaryninja.cstr(str(activities[i])) return core.BNWorkflowInsert(self.handle, str(activity), input_list, len(activities)) - def remove(self, activity) -> bool: + def remove(self, activity:ActivityType) -> bool: """ ``remove`` Remove the specified ``activity``. @@ -367,7 +379,7 @@ class Workflow(object, metaclass=_WorkflowMetaclass): """ return core.BNWorkflowRemove(self.handle, str(activity)) - def replace(self, activity, new_activity) -> bool: + def replace(self, activity:ActivityType, new_activity:List[str]) -> bool: """ ``replace`` Replace the specified ``activity``. @@ -378,7 +390,7 @@ class Workflow(object, metaclass=_WorkflowMetaclass): """ return core.BNWorkflowReplace(self.handle, str(activity), str(new_activity)) - def graph(self, activity = "", sequential = False, show = True) -> Union[None, FlowGraph]: + def graph(self, activity:ActivityType = "", sequential:bool = False, show:bool = True) -> Optional[FlowGraph]: """ ``graph`` Generate a FlowGraph object for the current Workflow and optionally show it in the UI. @@ -391,7 +403,7 @@ class Workflow(object, metaclass=_WorkflowMetaclass): graph = core.BNWorkflowGetGraph(self.handle, str(activity), sequential) if not graph: return None - graph = binaryninja.flowgraph.CoreFlowGraph(graph) + graph = CoreFlowGraph(graph) if show: core.BNShowGraphReport(None, f'{self.name} <{activity}>' if activity else self.name, graph.handle) return graph -- cgit v1.3.1