summaryrefslogtreecommitdiff
path: root/python
diff options
context:
space:
mode:
authorRyan Snyder <ryan@vector35.com>2019-09-11 21:03:56 -0400
committerRyan Snyder <ryan@vector35.com>2019-09-24 10:42:12 -0400
commitc5bd94376017e9d9d98a4dba2fac6b49572cda6d (patch)
treef81ed6dad33b591013cffcf63866627a02f468bb /python
parentae51b060402a939afcae5b52e30cfebd4944a26e (diff)
typelibrary: minimal api commit
Diffstat (limited to 'python')
-rw-r--r--python/__init__.py2
-rw-r--r--python/architecture.py13
-rw-r--r--python/binaryview.py56
-rw-r--r--python/platform.py19
-rw-r--r--python/typelibrary.py210
5 files changed, 300 insertions, 0 deletions
diff --git a/python/__init__.py b/python/__init__.py
index 1ae4d5d9..284f3116 100644
--- a/python/__init__.py
+++ b/python/__init__.py
@@ -46,6 +46,7 @@ from binaryninja.log import *
from binaryninja.lowlevelil import *
from binaryninja.mediumlevelil import *
from binaryninja.types import *
+from binaryninja.typelibrary import *
from binaryninja.functionrecognizer import *
from binaryninja.update import *
from binaryninja.plugin import *
@@ -253,3 +254,4 @@ def get_memory_usage_info():
result[info[i].name] = info[i].value
core.BNFreeMemoryUsageInfo(info, count.value)
return result
+
diff --git a/python/architecture.py b/python/architecture.py
index 5fe2aec9..296bdab9 100644
--- a/python/architecture.py
+++ b/python/architecture.py
@@ -31,6 +31,7 @@ import binaryninja
from binaryninja import log
from binaryninja import lowlevelil
from binaryninja import types
+from binaryninja import typelibrary
from binaryninja import databuffer
from binaryninja import platform
from binaryninja import callingconvention
@@ -430,6 +431,18 @@ class Architecture(with_metaclass(_ArchitectureMetaClass, object)):
pl = core.BNGetArchitectureStandalonePlatform(self.handle)
return platform.Platform(self, pl)
+ @property
+ def type_libraries(self):
+ """Architecture type libraries"""
+ count = ctypes.c_ulonglong(0)
+ result = []
+ handles = core.BNGetArchitectureTypeLibraries(self.handle, count)
+ for i in range(0, count.value):
+ result.append(typelibrary.TypeLibrary(core.BNNewTypeLibraryReference(handles[i])))
+ core.BNFreeTypeLibraryList(handles, count.value)
+ return result
+
+
def __setattr__(self, name, value):
if ((name == "name") or (name == "endianness") or (name == "address_size") or
(name == "default_int_size") or (name == "regs") or (name == "get_max_instruction_length") or
diff --git a/python/binaryview.py b/python/binaryview.py
index 6d29b469..fe3d7dbe 100644
--- a/python/binaryview.py
+++ b/python/binaryview.py
@@ -36,6 +36,7 @@ import binaryninja
from binaryninja import associateddatastore # required for _BinaryViewAssociatedDataStore
from binaryninja import log
from binaryninja import types
+from binaryninja import typelibrary
from binaryninja import fileaccessor
from binaryninja import databuffer
from binaryninja import basicblock
@@ -1615,6 +1616,19 @@ class BinaryView(object):
core.BNFreeTypeNameList(name_list, count.value)
return result
+
+ @property
+ def type_libraries(self):
+ """List of imported type libraries (read-only)"""
+ count = ctypes.c_ulonglong(0)
+ libraries = core.BNBinaryViewGetTypeLibraries(self.handle, count)
+ result = []
+ for i in range(0, count.value):
+ result.append(typelibrary.TypeLibrary(core.BNNewTypeLibraryReference(libraries[i])))
+ core.BNFreeTypeLibraryList(libraries, count.value)
+ return result
+
+
@property
def segments(self):
"""List of segments (read-only)"""
@@ -4477,6 +4491,32 @@ class BinaryView(object):
name = types.QualifiedName(name)._get_core_struct()
return core.BNGetAnalysisTypeId(self.handle, name)
+ def add_type_library(self, lib):
+ """
+ ``add_type_library`` make the contents of a type library available for type/import resolution
+
+ :param TypeLibrary lib: library to register with the view
+ :rtype: None
+ """
+ if not isinstance(lib, typelibrary.TypeLibrary):
+ raise ValueError("must pass in a TypeLibrary object")
+ core.BNBinaryViewAddTypeLibrary(self.handle, lib.handle)
+
+ def get_type_library(self, name):
+ """
+ ``get_type_library`` returns the TypeLibrary
+
+ :param str name: Library name to lookup
+ :return: The Type Library object, if any
+ :rtype: TypeLibrary or None
+ :Example:
+
+ """
+ handle = core.BNBinaryViewGetTypeLibrary(self.handle, name)
+ if handle is None:
+ return None
+ return typelibrary.TypeLibrary(handle)
+
def is_type_auto_defined(self, name):
"""
``is_type_auto_defined`` queries the user type list of name. If name is not in the *user* type list then the name
@@ -4597,6 +4637,22 @@ class BinaryView(object):
new_name = types.QualifiedName(new_name)._get_core_struct()
core.BNRenameAnalysisType(self.handle, old_name, new_name)
+ def import_library_type(self, name, lib = None):
+ if not isinstance(name, types.QualifiedName):
+ name = types.QualifiedName(name)
+ handle = core.BNBinaryViewImportLibraryType(self.handle, None if lib is None else lib.handle, name._get_core_struct())
+ if handle is None:
+ return None
+ return types.Type(handle, platform = self.platform)
+
+ def import_library_object(self, name, lib = None):
+ if not isinstance(name, types.QualifiedName):
+ name = types.QualifiedName(name)
+ handle = core.BNBinaryViewImportLibraryObject(self.handle, None if lib is None else lib.handle, name._get_core_struct())
+ if handle is None:
+ return None
+ return types.Type(handle, platform = self.platform)
+
def register_platform_types(self, platform):
"""
``register_platform_types`` ensures that the platform-specific types for a :py:Class:`Platform` are available
diff --git a/python/platform.py b/python/platform.py
index 543e7c54..2d061172 100644
--- a/python/platform.py
+++ b/python/platform.py
@@ -286,6 +286,25 @@ class Platform(with_metaclass(_PlatformMetaClass, object)):
core.BNFreeSystemCallList(call_list, count.value)
return result
+ @property
+ def type_libraries(self):
+ count = ctypes.c_ulonglong(0)
+ libs = core.BNGetPlatformTypeLibraries(self.handle, count)
+ result = []
+ for i in range(0, count.value):
+ result.append(binaryninja.TypeLibrary(core.BNNewTypeLibraryReference(libs[i])))
+ core.BNFreeTypeLibraryList(libs, count.value)
+ return result
+
+ def type_libraries_by_name(self, name):
+ count = ctypes.c_ulonglong(0)
+ libs = core.BNGetPlatformTypeLibrariesByName(self.handle, name, count)
+ result = []
+ for i in range(0, count.value):
+ result.append(binaryninja.TypeLibrary(core.BNNewTypeLibraryReference(libs[i])))
+ core.BNFreeTypeLibraryList(libs, count.value)
+ return result
+
def __setattr__(self, name, value):
try:
object.__setattr__(self, name, value)
diff --git a/python/typelibrary.py b/python/typelibrary.py
new file mode 100644
index 00000000..8a340928
--- /dev/null
+++ b/python/typelibrary.py
@@ -0,0 +1,210 @@
+# Copyright (c) 2015-2019 Vector 35 Inc
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to
+# deal in the Software without restriction, including without limitation the
+# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+# sell copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+# IN THE SOFTWARE.
+
+import struct
+import traceback
+import ctypes
+import abc
+import numbers
+
+# Binary Ninja components
+from binaryninja import _binaryninjacore as core
+import binaryninja
+from binaryninja import log
+from binaryninja import types
+from binaryninja import metadata
+from binaryninja import platform
+from binaryninja import architecture
+
+# 2-3 compatibility
+from binaryninja import range
+from binaryninja import with_metaclass
+
+class TypeLibrary(object):
+ def __init__(self, handle):
+ self.handle = core.handle_of_type(handle, core.BNTypeLibrary)
+
+ def __del__(self):
+ core.BNFreeTypeLibrary(self.handle)
+
+ def __repr__(self):
+ return "<typelib '{}':{}>".format(self.name, self.arch.name)
+
+ @classmethod
+ def new(cls, arch, name):
+ handle = core.BNNewTypeLibrary(arch.handle, name)
+ return TypeLibrary(handle)
+
+ @classmethod
+ def load_from_file(cls, path):
+ handle = core.BNLoadTypeLibraryFromFile(path)
+ if handle is None:
+ return None
+ return TypeLibrary(handle)
+
+ def write_to_file(self, path):
+ core.BNWriteTypeLibraryToFile(self.handle, path)
+
+ @classmethod
+ def from_name(cls, arch, name):
+ handle = core.BNLookupTypeLibraryByName(arch.handle, name)
+ if handle is None:
+ return None
+ return TypeLibrary(handle)
+
+ @classmethod
+ def from_guid(cls, arch, guid):
+ handle = core.BNLookupTypeLibraryByGuid(arch.handle, guid)
+ if handle is None:
+ return None
+ return TypeLibrary(handle)
+
+ @property
+ def arch(self):
+ arch = core.BNGetTypeLibraryArchitecture(self.handle)
+ if arch is None:
+ return None
+ return binaryninja.architecture.CoreArchitecture._from_cache(handle=arch)
+
+ @property
+ def name(self):
+ name = core.BNGetTypeLibraryName(self.handle)
+ return name
+
+ @name.setter
+ def name(self, value):
+ core.BNSetTypeLibraryName(self.handle, value)
+
+ @property
+ def dependency_name(self):
+ return core.BNGetTypeLibraryDependencyName(self.handle)
+
+ @dependency_name.setter
+ def dependency_name(self, value):
+ core.BNSetTypeLibraryDependencyName(self.handle, value)
+
+ @property
+ def guid(self):
+ return core.BNGetTypeLibraryGuid(self.handle)
+
+ @guid.setter
+ def guid(self, value):
+ core.BNSetTypeLibraryGuid(self.handle, value)
+
+ @property
+ def alternate_names(self):
+ count = ctypes.c_ulonglong(0)
+ result = []
+ names = core.BNGetTypeLibraryAlternateNames(self.handle, count)
+ for i in range(0, count.value):
+ result.append(names[i])
+ core.BNFreeStringList(names, count.value)
+ return result
+
+ def add_alternate_name(self, name):
+ core.BNAddTypeLibraryAlternateName(self.handle, name)
+
+ @property
+ def platform_names(self):
+ count = ctypes.c_ulonglong(0)
+ result = []
+ platforms = core.BNGetTypeLibraryPlatforms(self.handle, count)
+ for i in range(0, count.value):
+ result.append(platforms[i])
+ core.BNFreeStringList(platforms, count.value)
+ return result
+
+ def add_platform(self, plat):
+ if not isinstance(plat, platform.Platform):
+ raise ValueError("plat must be a Platform object")
+ core.BNAddTypeLibraryPlatform(self.handle, plat.handle)
+
+ def clear_platforms(self):
+ core.BNClearTypeLibraryPlatforms(self.handle)
+
+ def finalize(self):
+ core.BNFinalizeTypeLibrary(self.handle)
+
+ def query_metadata(self, key):
+ md_handle = core.BNTypeLibraryQueryMetadata(self.handle, key)
+ if md_handle is None:
+ return None
+ return metadata.Metadata(handle=md_handle).value
+
+ def store_metadata(self, key, md):
+ if not isinstance(md, metadata.Metadata):
+ md = metadata.Metadata(md)
+ core.BNTypeLibraryStoreMetadata(self.handle, key, md.handle)
+
+ def remove_metadata(self, key):
+ core.BNTypeLibraryRemoveMetadata(self.handle, key)
+
+ def add_named_object(self, name, t):
+ if not isinstance(name, types.QualifiedName):
+ name = types.QualifiedName(name)
+ if not isinstance(t, types.Type):
+ raise ValueError("t must be a Type")
+ core.BNAddTypeLibraryNamedObject(self.handle, name._get_core_struct(), t.handle)
+
+ def add_named_type(self, name, t):
+ if not isinstance(name, types.QualifiedName):
+ name = types.QualifiedName(name)
+ if not isinstance(t, types.Type):
+ raise ValueError("t must be a Type")
+ core.BNAddTypeLibraryNamedType(self.handle, name._get_core_struct(), t.handle)
+
+ def get_named_object(self, name):
+ if not isinstance(name, types.QualifiedName):
+ name = types.QualifiedName(name)
+ t = core.BNGetTypeLibraryNamedObject(self.handle, name._get_core_struct())
+ if t is None:
+ return None
+ return types.Type(t)
+
+ def get_named_type(self, name):
+ if not isinstance(name, types.QualifiedName):
+ name = types.QualifiedName(name)
+ t = core.BNGetTypeLibraryNamedType(self.handle, name._get_core_struct())
+ if t is None:
+ return None
+ return types.Type(t)
+
+ @property
+ def named_objects(self):
+ count = ctypes.c_ulonglong(0)
+ result = {}
+ named_types = core.BNGetTypeLibraryNamedObjects(self.handle, count)
+ for i in range(0, count.value):
+ name = types.QualifiedName._from_core_struct(named_types[i].name)
+ result[name] = types.Type(core.BNNewTypeReference(named_types[i].type))
+ core.BNFreeQualifiedNameAndTypeArray(named_types, count.value)
+ return result
+
+ @property
+ def named_types(self):
+ count = ctypes.c_ulonglong(0)
+ result = {}
+ named_types = core.BNGetTypeLibraryNamedTypes(self.handle, count)
+ for i in range(0, count.value):
+ name = types.QualifiedName._from_core_struct(named_types[i].name)
+ result[name] = types.Type(core.BNNewTypeReference(named_types[i].type))
+ core.BNFreeQualifiedNameAndTypeArray(named_types, count.value)
+ return result
+