diff options
Diffstat (limited to 'python')
| -rw-r--r-- | python/architecture.py | 2 | ||||
| -rw-r--r-- | python/binaryview.py | 8 | ||||
| -rw-r--r-- | python/debuginfo.py | 2 | ||||
| -rw-r--r-- | python/function.py | 2 | ||||
| -rw-r--r-- | python/platform.py | 117 | ||||
| -rw-r--r-- | python/typearchive.py | 2 | ||||
| -rw-r--r-- | python/typecontainer.py | 2 | ||||
| -rw-r--r-- | python/typeparser.py | 6 | ||||
| -rw-r--r-- | python/typeprinter.py | 12 |
9 files changed, 121 insertions, 32 deletions
diff --git a/python/architecture.py b/python/architecture.py index 3e4a010e..ce8c4e63 100644 --- a/python/architecture.py +++ b/python/architecture.py @@ -566,7 +566,7 @@ class Architecture(metaclass=_ArchitectureMetaClass): def standalone_platform(self) -> 'platform.Platform': """Architecture standalone platform (read-only)""" pl = core.BNGetArchitectureStandalonePlatform(self.handle) - return platform.Platform(self, pl) + return platform.CorePlatform._from_cache(pl) @property def type_libraries(self) -> List['typelibrary.TypeLibrary']: diff --git a/python/binaryview.py b/python/binaryview.py index 154b4f8e..a18f8d8d 100644 --- a/python/binaryview.py +++ b/python/binaryview.py @@ -1381,13 +1381,13 @@ class BinaryViewType(metaclass=_BinaryViewTypeMetaclass): plat = core.BNGetPlatformForViewType(self.handle, ident, arch.handle) if plat is None: return None - return _platform.Platform(handle=plat) + return _platform.CorePlatform._from_cache(handle=plat) def recognize_platform(self, ident, endian: Endianness, view: 'BinaryView', metadata): plat = core.BNRecognizePlatformForViewType(self.handle, ident, endian, view.handle, metadata.handle) if plat is None: return None - return binaryninja.Platform(handle=plat) + return _platform.CorePlatform._from_cache(handle=plat) @staticmethod def add_binaryview_finalized_event(callback: BinaryViewEvent.BinaryViewEventCallback) -> None: @@ -2941,7 +2941,7 @@ class BinaryView: plat = core.BNGetDefaultPlatform(self.handle) if plat is None: return None - self._platform = _platform.Platform(self.arch, handle=plat) + self._platform = _platform.CorePlatform._from_cache(handle=plat) return self._platform @platform.setter @@ -8603,7 +8603,7 @@ to a the type "tagRECT" found in the typelibrary "winX64common" result_name = (core.BNQualifiedName * 1)() if not core.BNLookupImportedTypePlatform(self.handle, name._to_core_struct(), result_platform, result_name): return None - platform = _platform.Platform(arch=self.arch, handle=result_platform[0]) + platform = _platform.CorePlatform._from_cache(handle=result_platform[0]) name = _types.QualifiedName._from_core_struct(result_name[0]) core.BNFreeQualifiedName(result_name) return platform, name diff --git a/python/debuginfo.py b/python/debuginfo.py index 806e61a8..f3172ae2 100644 --- a/python/debuginfo.py +++ b/python/debuginfo.py @@ -351,7 +351,7 @@ class DebugInfo(object): function_type = None if function.platform: - func_platform = _platform.Platform(handle=core.BNNewPlatformReference(function.platform)) + func_platform = _platform.CorePlatform._from_cache(handle=core.BNNewPlatformReference(function.platform)) else: func_platform = None diff --git a/python/function.py b/python/function.py index 3f667b5f..5b447584 100644 --- a/python/function.py +++ b/python/function.py @@ -503,7 +503,7 @@ class Function: plat = core.BNGetFunctionPlatform(self.handle) if plat is None: return None - self._platform = _platform.Platform(handle=plat) + self._platform = _platform.CorePlatform._from_cache(handle=plat) return self._platform @property diff --git a/python/platform.py b/python/platform.py index c0a5ce65..72f08341 100644 --- a/python/platform.py +++ b/python/platform.py @@ -21,6 +21,7 @@ import os import ctypes import traceback +import warnings from typing import List, Dict, Optional, Tuple # Binary Ninja components @@ -44,7 +45,7 @@ class _PlatformMetaClass(type): assert platforms is not None, "core.BNGetPlatformList returned None" try: for i in range(0, count.value): - yield Platform(handle=core.BNNewPlatformReference(platforms[i])) + yield CorePlatform(handle=core.BNNewPlatformReference(platforms[i])) finally: core.BNFreePlatformList(platforms, count.value) @@ -53,7 +54,7 @@ class _PlatformMetaClass(type): platform = core.BNGetPlatformByName(str(value)) if platform is None: raise KeyError("'%s' is not a valid platform" % str(value)) - return Platform(handle=platform) + return CorePlatform(handle=platform) class Platform(metaclass=_PlatformMetaClass): @@ -102,6 +103,10 @@ class Platform(metaclass=_PlatformMetaClass): assert _handle is not None self.__class__._registered_platforms.append(self) else: + if type(self) is Platform: + binaryninja.log_warn( + ":py:func:`Platform(handle=...)` is deprecated, use :py:func:`CorePlatform._from_cache(handle=...)`" + ) _handle = handle _arch = architecture.CoreArchitecture._from_cache(core.BNGetPlatformArchitecture(_handle)) count = ctypes.c_ulonglong() @@ -214,7 +219,10 @@ class Platform(metaclass=_PlatformMetaClass): self._pending_parser_input_lists[source_file_values_ptr.value] = (source_file_values_ptr.value, source_file_values_buf) except: + arguments_out[0] = None arguments_len_out[0] = 0 + source_file_names_out[0] = None + source_file_values_out[0] = None source_files_len_out[0] = 0 traceback.print_exc() @@ -229,19 +237,22 @@ class Platform(metaclass=_PlatformMetaClass): ): try: buf = ctypes.cast(arguments, ctypes.c_void_p) - if buf.value not in self._pending_parser_input_lists: - raise ValueError("freeing arguments list that wasn't allocated") - del self._pending_parser_input_lists[buf.value] + if buf.value is not None: + if buf.value not in self._pending_parser_input_lists: + raise ValueError("freeing arguments list that wasn't allocated") + del self._pending_parser_input_lists[buf.value] buf = ctypes.cast(source_file_names, ctypes.c_void_p) - if buf.value not in self._pending_parser_input_lists: - raise ValueError("freeing source_file_names list that wasn't allocated") - del self._pending_parser_input_lists[buf.value] + if buf.value is not None: + if buf.value not in self._pending_parser_input_lists: + raise ValueError("freeing source_file_names list that wasn't allocated") + del self._pending_parser_input_lists[buf.value] buf = ctypes.cast(source_file_values, ctypes.c_void_p) - if buf.value not in self._pending_parser_input_lists: - raise ValueError("freeing source_file_values list that wasn't allocated") - del self._pending_parser_input_lists[buf.value] + if buf.value is not None: + if buf.value not in self._pending_parser_input_lists: + raise ValueError("freeing source_file_values list that wasn't allocated") + del self._pending_parser_input_lists[buf.value] except: log_error(traceback.format_exc()) @@ -318,7 +329,7 @@ class Platform(metaclass=_PlatformMetaClass): assert platforms is not None, "core.BNGetPlatformListByArchitecture returned None" result = [] for i in range(0, count.value): - result.append(Platform(handle=core.BNNewPlatformReference(platforms[i]))) + result.append(CorePlatform._from_cache(core.BNNewPlatformReference(platforms[i]))) core.BNFreePlatformList(platforms, count.value) return result @@ -533,7 +544,7 @@ class Platform(metaclass=_PlatformMetaClass): result = core.BNGetRelatedPlatform(self.handle, arch.handle) if not result: return None - return Platform(handle=result) + return CorePlatform._from_cache(handle=result) def add_related_platform(self, arch, platform): core.BNAddRelatedPlatform(self.handle, arch.handle, platform.handle) @@ -542,7 +553,7 @@ class Platform(metaclass=_PlatformMetaClass): new_addr = ctypes.c_ulonglong() new_addr.value = addr result = core.BNGetAssociatedPlatformByAddress(self.handle, new_addr) - return Platform(handle=result), new_addr.value + return CorePlatform._from_cache(result), new_addr.value @property def type_container(self) -> 'typecontainer.TypeContainer': @@ -707,3 +718,81 @@ class Platform(metaclass=_PlatformMetaClass): @property def arch(self): return self._arch + + +_platform_cache = {} + + +class CorePlatform(Platform): + def __init__(self, handle: core.BNPlatform): + super(CorePlatform, self).__init__(handle=handle) + if type(self) is CorePlatform: + global _platform_cache + _platform_cache[ctypes.addressof(handle.contents)] = self + + @classmethod + def _from_cache(cls, handle) -> 'Platform': + """ + Look up a platform from a given BNPlatform handle + :param handle: BNPlatform pointer + :return: Platform instance responsible for this handle + """ + global _platform_cache + return _platform_cache.get(ctypes.addressof(handle.contents)) or cls(handle) + + def adjust_type_parser_input( + self, + parser: 'typeparser.TypeParser', + arguments: List[str], + source_files: List[Tuple[str, str]] + ) -> Tuple[List[str], List[Tuple[str, str]]]: + + arguments_in = (ctypes.c_char_p * len(arguments))() + for i, argument in enumerate(arguments): + arguments_in[i] = core.cstr(argument) + + source_file_names_in = (ctypes.c_char_p * len(source_files))() + source_file_names_out = (ctypes.c_char_p * len(source_files))() + source_file_values_in = (ctypes.c_char_p * len(source_files))() + source_file_values_out = (ctypes.c_char_p * len(source_files))() + for i, (name, value) in enumerate(source_files): + source_file_names_in[i] = core.cstr(name) + source_file_values_in[i] = core.cstr(value) + + arguments_out = ctypes.POINTER(ctypes.c_char_p)() + arguments_len_out = (ctypes.c_size_t)() + source_file_names_out = ctypes.POINTER(ctypes.c_char_p)() + source_file_values_out = ctypes.POINTER(ctypes.c_char_p)() + source_files_len_out = (ctypes.c_size_t)() + + core.BNPlatformAdjustTypeParserInput( + self.handle, + parser.handle, + arguments_in, + len(arguments), + source_file_names_in, + source_file_values_in, + len(source_files), + arguments_out, + arguments_len_out, + source_file_names_out, + source_file_values_out, + source_files_len_out + ) + + result_arguments = [] + for i in range(arguments_len_out.value): + result_arguments.append(core.pyNativeStr(arguments_out[i])) + + result_source_files = [] + for i in range(source_files_len_out.value): + result_source_files.append(( + core.pyNativeStr(source_file_names_out[i]), + core.pyNativeStr(source_file_values_out[i]), + )) + + core.BNFreeStringList(arguments_out, arguments_len_out.value) + core.BNFreeStringList(source_file_names_out, source_files_len_out.value) + core.BNFreeStringList(source_file_values_out, source_files_len_out.value) + + return result_arguments, result_source_files diff --git a/python/typearchive.py b/python/typearchive.py index 7b264056..379c7d4c 100644 --- a/python/typearchive.py +++ b/python/typearchive.py @@ -140,7 +140,7 @@ class TypeArchive: """ handle = core.BNGetTypeArchivePlatform(self.handle) assert handle is not None - return platform.Platform(handle=handle) + return platform.CorePlatform._from_cache(handle=handle) @property def current_snapshot_id(self) -> str: diff --git a/python/typecontainer.py b/python/typecontainer.py index 0b3221b8..55ea7666 100644 --- a/python/typecontainer.py +++ b/python/typecontainer.py @@ -108,7 +108,7 @@ class TypeContainer: """ handle = core.BNTypeContainerGetPlatform(self.handle) assert handle is not None - return platform.Platform(handle=handle) + return platform.CorePlatform._from_cache(handle=handle) def add_types(self, types: Mapping['_types.QualifiedNameType', '_types.Type'], progress_func: Optional[ProgressFuncType] = None) -> Optional[Mapping['_types.QualifiedName', str]]: """ diff --git a/python/typeparser.py b/python/typeparser.py index 98c83029..3e58d650 100644 --- a/python/typeparser.py +++ b/python/typeparser.py @@ -266,7 +266,7 @@ class TypeParser(metaclass=_TypeParserMetaclass): try: source_py = core.pyNativeStr(source) file_name_py = core.pyNativeStr(fileName) - platform_py = platform.Platform(handle=core.BNNewPlatformReference(platform_)) + platform_py = platform.CorePlatform._from_cache(handle=core.BNNewPlatformReference(platform_)) existing_types_py = None if existingTypes: @@ -310,7 +310,7 @@ class TypeParser(metaclass=_TypeParserMetaclass): try: source_py = core.pyNativeStr(source) file_name_py = core.pyNativeStr(fileName) - platform_py = platform.Platform(handle=core.BNNewPlatformReference(platform_)) + platform_py = platform.CorePlatform._from_cache(handle=core.BNNewPlatformReference(platform_)) existing_types_py = None if existingTypes: @@ -359,7 +359,7 @@ class TypeParser(metaclass=_TypeParserMetaclass): ) -> bool: try: source_py = core.pyNativeStr(source) - platform_py = platform.Platform(handle=core.BNNewPlatformReference(platform_)) + platform_py = platform.CorePlatform._from_cache(handle=core.BNNewPlatformReference(platform_)) existing_types_py = None if existingTypes: diff --git a/python/typeprinter.py b/python/typeprinter.py index aea598b3..e9e085c6 100644 --- a/python/typeprinter.py +++ b/python/typeprinter.py @@ -117,7 +117,7 @@ class TypePrinter(metaclass=_TypePrinterMetaclass): try: platform_py = None if platform: - platform_py = _platform.Platform(handle=core.BNNewPlatformReference(platform)) + platform_py = _platform.CorePlatform._from_cache(handle=core.BNNewPlatformReference(platform)) result_py = self.get_type_tokens( types.Type.create(handle=core.BNNewTypeReference(type)), platform_py, types.QualifiedName._from_core_struct(name.contents), base_confidence, escaping) @@ -135,7 +135,7 @@ class TypePrinter(metaclass=_TypePrinterMetaclass): try: platform_py = None if platform: - platform_py = _platform.Platform(handle=core.BNNewPlatformReference(platform)) + platform_py = _platform.CorePlatform._from_cache(handle=core.BNNewPlatformReference(platform)) parent_type_py = None if parent_type: parent_type_py = types.Type.create(handle=core.BNNewTypeReference(parent_type)) @@ -156,7 +156,7 @@ class TypePrinter(metaclass=_TypePrinterMetaclass): try: platform_py = None if platform: - platform_py = _platform.Platform(handle=core.BNNewPlatformReference(platform)) + platform_py = _platform.CorePlatform._from_cache(handle=core.BNNewPlatformReference(platform)) parent_type_py = None if parent_type: parent_type_py = types.Type.create(handle=core.BNNewTypeReference(parent_type)) @@ -177,7 +177,7 @@ class TypePrinter(metaclass=_TypePrinterMetaclass): try: platform_py = None if platform: - platform_py = _platform.Platform(handle=core.BNNewPlatformReference(platform)) + platform_py = _platform.CorePlatform._from_cache(handle=core.BNNewPlatformReference(platform)) result_py = self.get_type_string( types.Type.create(handle=core.BNNewTypeReference(type)), platform_py, types.QualifiedName._from_core_struct(name.contents), escaping) @@ -193,7 +193,7 @@ class TypePrinter(metaclass=_TypePrinterMetaclass): try: platform_py = None if platform: - platform_py = _platform.Platform(handle=core.BNNewPlatformReference(platform)) + platform_py = _platform.CorePlatform._from_cache(handle=core.BNNewPlatformReference(platform)) result_py = self.get_type_string_before_name( types.Type.create(handle=core.BNNewTypeReference(type)), platform_py, escaping) @@ -209,7 +209,7 @@ class TypePrinter(metaclass=_TypePrinterMetaclass): try: platform_py = None if platform: - platform_py = _platform.Platform(handle=core.BNNewPlatformReference(platform)) + platform_py = _platform.CorePlatform._from_cache(handle=core.BNNewPlatformReference(platform)) result_py = self.get_type_string_after_name( types.Type.create(handle=core.BNNewTypeReference(type)), platform_py, escaping) |
