summaryrefslogtreecommitdiff
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
parentae51b060402a939afcae5b52e30cfebd4944a26e (diff)
typelibrary: minimal api commit
-rw-r--r--binaryninjacore.h60
-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
6 files changed, 360 insertions, 0 deletions
diff --git a/binaryninjacore.h b/binaryninjacore.h
index 9c80cd9b..af26a67b 100644
--- a/binaryninjacore.h
+++ b/binaryninjacore.h
@@ -134,6 +134,8 @@ extern "C"
struct BNLowLevelILFunction;
struct BNMediumLevelILFunction;
struct BNType;
+ struct BNTypeLibrary;
+ struct BNTypeLibraryMapping;
struct BNStructure;
struct BNTagType;
struct BNTag;
@@ -3401,6 +3403,61 @@ extern "C"
BINARYNINJACOREAPI BNTypeWithConfidence BNGetMediumLevelILExprType(BNMediumLevelILFunction* func, size_t expr);
+ // Type Libraries
+ BINARYNINJACOREAPI BNTypeLibrary* BNNewTypeLibrary(BNArchitecture* arch, const char* name);
+ BINARYNINJACOREAPI BNTypeLibrary* BNNewTypeLibraryReference(BNTypeLibrary* lib);
+ BINARYNINJACOREAPI BNTypeLibrary* BNDuplicateTypeLibrary(BNTypeLibrary* lib);
+ BINARYNINJACOREAPI BNTypeLibrary* BNLoadTypeLibraryFromFile(const char* path);
+ BINARYNINJACOREAPI void BNFreeTypeLibrary(BNTypeLibrary* lib);
+
+ BINARYNINJACOREAPI BNTypeLibrary* BNLookupTypeLibraryByName(BNArchitecture* arch, const char* name);
+ BINARYNINJACOREAPI BNTypeLibrary* BNLookupTypeLibraryByGuid(BNArchitecture* arch, const char* guid);
+
+ BINARYNINJACOREAPI BNTypeLibrary** BNGetArchitectureTypeLibraries(BNArchitecture* arch, size_t* count);
+ BINARYNINJACOREAPI void BNFreeTypeLibraryList(BNTypeLibrary** lib, size_t count);
+
+ BINARYNINJACOREAPI void BNFinalizeTypeLibrary(BNTypeLibrary* lib);
+
+ BINARYNINJACOREAPI BNArchitecture* BNGetTypeLibraryArchitecture(BNTypeLibrary* lib);
+
+ BINARYNINJACOREAPI void BNSetTypeLibraryName(BNTypeLibrary* lib, const char* name);
+ BINARYNINJACOREAPI char* BNGetTypeLibraryName(BNTypeLibrary* lib);
+
+ BINARYNINJACOREAPI void BNAddTypeLibraryAlternateName(BNTypeLibrary* lib, const char* name);
+ BINARYNINJACOREAPI char** BNGetTypeLibraryAlternateNames(BNTypeLibrary* lib, size_t* count); // BNFreeStringList
+
+ BINARYNINJACOREAPI void BNSetTypeLibraryDependencyName(BNTypeLibrary* lib, const char* name);
+ BINARYNINJACOREAPI char* BNGetTypeLibraryDependencyName(BNTypeLibrary* lib);
+
+ BINARYNINJACOREAPI void BNSetTypeLibraryGuid(BNTypeLibrary* lib, const char* name);
+ BINARYNINJACOREAPI char* BNGetTypeLibraryGuid(BNTypeLibrary* lib);
+
+ BINARYNINJACOREAPI void BNClearTypeLibraryPlatforms(BNTypeLibrary* lib);
+ BINARYNINJACOREAPI void BNAddTypeLibraryPlatform(BNTypeLibrary* lib, BNPlatform* platform);
+ BINARYNINJACOREAPI char** BNGetTypeLibraryPlatforms(BNTypeLibrary* lib, size_t* count); // BNFreeStringList
+
+ BINARYNINJACOREAPI void BNTypeLibraryStoreMetadata(BNTypeLibrary* lib, const char* key, BNMetadata* value);
+ BINARYNINJACOREAPI BNMetadata* BNTypeLibraryQueryMetadata(BNTypeLibrary* lib, const char* key);
+ BINARYNINJACOREAPI void BNTypeLibraryRemoveMetadata(BNTypeLibrary* lib, const char* key);
+
+ BINARYNINJACOREAPI void BNAddTypeLibraryNamedObject(BNTypeLibrary* lib, BNQualifiedName* name, BNType* type);
+ BINARYNINJACOREAPI void BNAddTypeLibraryNamedType(BNTypeLibrary* lib, BNQualifiedName* name, BNType* type);
+
+ BINARYNINJACOREAPI BNType* BNGetTypeLibraryNamedObject(BNTypeLibrary* lib, BNQualifiedName* name);
+ BINARYNINJACOREAPI BNType* BNGetTypeLibraryNamedType(BNTypeLibrary* lib, BNQualifiedName* name);
+
+ BINARYNINJACOREAPI BNQualifiedNameAndType* BNGetTypeLibraryNamedObjects(BNTypeLibrary* lib, size_t* count);
+ BINARYNINJACOREAPI BNQualifiedNameAndType* BNGetTypeLibraryNamedTypes(BNTypeLibrary* lib, size_t* count);
+
+ BINARYNINJACOREAPI void BNWriteTypeLibraryToFile(BNTypeLibrary* lib, const char* path);
+
+ BINARYNINJACOREAPI void BNBinaryViewAddTypeLibrary(BNBinaryView* view, BNTypeLibrary* lib);
+ BINARYNINJACOREAPI BNTypeLibrary* BNBinaryViewGetTypeLibrary(BNBinaryView* view, const char* name);
+ BINARYNINJACOREAPI BNTypeLibrary** BNBinaryViewGetTypeLibraries(BNBinaryView* view, size_t* count);
+
+ BINARYNINJACOREAPI BNType* BNBinaryViewImportLibraryType(BNBinaryView* view, BNTypeLibrary* lib, BNQualifiedName* name);
+ BINARYNINJACOREAPI BNType* BNBinaryViewImportLibraryObject(BNBinaryView* view, BNTypeLibrary* lib, BNQualifiedName* name);
+
// Types
BINARYNINJACOREAPI bool BNTypesEqual(BNType* a, BNType* b);
BINARYNINJACOREAPI bool BNTypesNotEqual(BNType* a, BNType* b);
@@ -3695,6 +3752,9 @@ extern "C"
BINARYNINJACOREAPI char* BNGetPlatformSystemCallName(BNPlatform* platform, uint32_t number);
BINARYNINJACOREAPI BNType* BNGetPlatformSystemCallType(BNPlatform* platform, uint32_t number);
+ BINARYNINJACOREAPI BNTypeLibrary** BNGetPlatformTypeLibraries(BNPlatform* platform, size_t* count);
+ BINARYNINJACOREAPI BNTypeLibrary** BNGetPlatformTypeLibrariesByName(BNPlatform* platform, char* depName, size_t* count);
+
//Demangler
BINARYNINJACOREAPI bool BNDemangleMS(BNArchitecture* arch,
const char* mangledName,
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
+