diff options
| author | Ryan Snyder <ryan@vector35.com> | 2019-09-11 21:03:56 -0400 |
|---|---|---|
| committer | Ryan Snyder <ryan@vector35.com> | 2019-09-24 10:42:12 -0400 |
| commit | c5bd94376017e9d9d98a4dba2fac6b49572cda6d (patch) | |
| tree | f81ed6dad33b591013cffcf63866627a02f468bb | |
| parent | ae51b060402a939afcae5b52e30cfebd4944a26e (diff) | |
typelibrary: minimal api commit
| -rw-r--r-- | binaryninjacore.h | 60 | ||||
| -rw-r--r-- | python/__init__.py | 2 | ||||
| -rw-r--r-- | python/architecture.py | 13 | ||||
| -rw-r--r-- | python/binaryview.py | 56 | ||||
| -rw-r--r-- | python/platform.py | 19 | ||||
| -rw-r--r-- | python/typelibrary.py | 210 |
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 + |
