summaryrefslogtreecommitdiff
path: root/python
diff options
context:
space:
mode:
Diffstat (limited to 'python')
-rw-r--r--python/architecture.py2
-rw-r--r--python/binaryview.py8
-rw-r--r--python/debuginfo.py2
-rw-r--r--python/function.py2
-rw-r--r--python/platform.py117
-rw-r--r--python/typearchive.py2
-rw-r--r--python/typecontainer.py2
-rw-r--r--python/typeparser.py6
-rw-r--r--python/typeprinter.py12
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)