summaryrefslogtreecommitdiff
path: root/python
diff options
context:
space:
mode:
authorRyan Snyder <ryan@vector35.com>2021-08-04 11:17:40 -0400
committerRyan Snyder <ryan@vector35.com>2021-08-20 04:34:14 -0400
commitcc1e85a4a8b2001f9fd6cf91b93fb39abef3a0e2 (patch)
tree45fdf52d2bdb8e09f57fc76079a3a91b6528f4a1 /python
parentc1e526ea39d97c4c374de4cf8c211dc39ebbb538 (diff)
platforms: specify platform types and add bvt platform callbacks
Diffstat (limited to 'python')
-rw-r--r--python/binaryview.py29
-rw-r--r--python/platform.py10
2 files changed, 37 insertions, 2 deletions
diff --git a/python/binaryview.py b/python/binaryview.py
index 092cceec..e2bae443 100644
--- a/python/binaryview.py
+++ b/python/binaryview.py
@@ -302,7 +302,6 @@ class BinaryViewEvent(object):
except:
binaryninja.log.log_error(traceback.format_exc())
-
class ActiveAnalysisInfo(object):
def __init__(self, func, analysis_time, update_count, submit_count):
self._func = func
@@ -787,6 +786,10 @@ class _BinaryViewTypeMetaclass(type):
return BinaryViewType(view_type)
+
+# Used to force Python callback objects to not get garbage collected
+_platform_recognizers = {}
+
class BinaryViewType(with_metaclass(_BinaryViewTypeMetaclass, object)):
def __init__(self, handle):
@@ -1042,12 +1045,36 @@ class BinaryViewType(with_metaclass(_BinaryViewTypeMetaclass, object)):
def register_default_platform(self, arch, plat):
core.BNRegisterDefaultPlatformForViewType(self.handle, arch.handle, plat.handle)
+ def register_platform_recognizer(self, ident, endian, cb):
+ def callback(cb, view, meta):
+ try:
+ file_metadata = binaryninja.filemetadata.FileMetadata(handle = core.BNGetFileForView(view))
+ view_obj = binaryninja.binaryview.BinaryView(file_metadata = file_metadata, handle = core.BNNewViewReference(view))
+ meta_obj = binaryninja.metadata.Metadata(handle = core.BNNewMetadataReference(meta))
+ plat = cb(view_obj, meta_obj)
+ if plat:
+ return ctypes.cast(core.BNNewPlatformReference(plat.handle), ctypes.c_void_p).value
+ except:
+ binaryninja.log.log_error(traceback.format_exc())
+ return None
+
+ callback_obj = ctypes.CFUNCTYPE(ctypes.c_void_p, ctypes.c_void_p, ctypes.POINTER(core.BNBinaryView), ctypes.POINTER(core.BNMetadata))(lambda ctxt, view, meta: callback(cb, view, meta))
+ core.BNRegisterPlatformRecognizerForViewType(self.handle, ident, endian, callback_obj, None)
+ global _platform_recognizers
+ _platform_recognizers[len(_platform_recognizers)] = callback_obj
+
def get_platform(self, ident, arch):
plat = core.BNGetPlatformForViewType(self.handle, ident, arch.handle)
if plat is None:
return None
return binaryninja.platform.Platform(handle = plat)
+ def recognize_platform(self, ident, endian, view, metadata):
+ plat = core.BNRecognizePlatformForViewType(self.handle, ident, endian, view.handle, metadata.handle)
+ if plat is None:
+ return None
+ return binaryninja.platform.Platform(handle = plat)
+
@staticmethod
def add_binaryview_finalized_event(callback):
"""
diff --git a/python/platform.py b/python/platform.py
index 4983adff..5039f1ca 100644
--- a/python/platform.py
+++ b/python/platform.py
@@ -94,6 +94,8 @@ class Platform(with_metaclass(_PlatformMetaClass, object)):
calling conventions used.
"""
name = None
+ type_file_path = None # path to platform types file
+ type_include_dirs = [] # list of directories available to #include from type_file_path
def __init__(self, arch = None, handle = None):
if handle is None:
@@ -101,7 +103,13 @@ class Platform(with_metaclass(_PlatformMetaClass, object)):
self.handle = None
raise ValueError("platform must have an associated architecture")
self._arch = arch
- self.handle = core.BNCreatePlatform(arch.handle, self.__class__.name)
+ if self.__class__.type_file_path is None:
+ self.handle = core.BNCreatePlatform(arch.handle, self.__class__.name)
+ else:
+ dir_buf = (ctypes.c_char_p * len(self.__class__.type_include_dirs))()
+ for (i, dir) in enumerate(self.__class__.type_include_dirs):
+ dir_buf[i] = dir.encode('charmap')
+ self.handle = core.BNCreatePlatformWithTypes(arch.handle, self.__class__.name, self.__class__.type_file_path, dir_buf, len(self.__class__.type_include_dirs))
else:
self.handle = handle
self.__dict__["name"] = core.BNGetPlatformName(self.handle)