summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--architecture.cpp16
-rw-r--r--binaryninjaapi.h315
-rw-r--r--binaryninjacore.h23
-rw-r--r--binaryview.cpp93
-rw-r--r--platform.cpp32
-rw-r--r--python/binaryview.py56
-rw-r--r--typelibrary.cpp241
-rw-r--r--ui/uitypes.h1
8 files changed, 766 insertions, 11 deletions
diff --git a/architecture.cpp b/architecture.cpp
index ab12e3ed..ba6f94b3 100644
--- a/architecture.cpp
+++ b/architecture.cpp
@@ -1369,6 +1369,22 @@ Ref<Platform> Architecture::GetStandalonePlatform()
}
+vector<Ref<TypeLibrary>> Architecture::GetTypeLibraries()
+{
+ size_t count;
+ BNTypeLibrary** libs = BNGetArchitectureTypeLibraries(m_object, &count);
+
+ vector<Ref<TypeLibrary>> result;
+ for (size_t i = 0; i < count; ++i)
+ {
+ result.push_back(new TypeLibrary(BNNewTypeLibraryReference(libs[i])));
+ }
+
+ BNFreeTypeLibraryList(libs, count);
+ return result;
+}
+
+
void Architecture::AddArchitectureRedirection(Architecture* from, Architecture* to)
{
BNAddArchitectureRedirection(m_object, from->GetObject(), to->GetObject());
diff --git a/binaryninjaapi.h b/binaryninjaapi.h
index ccf72b0a..70f7b97e 100644
--- a/binaryninjaapi.h
+++ b/binaryninjaapi.h
@@ -2809,6 +2809,7 @@ namespace BinaryNinja {
struct TypeParserResult;
class Component;
class DebugInfo;
+ class TypeLibrary;
class QueryMetadataException : public std::exception
{
@@ -4459,6 +4460,91 @@ namespace BinaryNinja {
void RegisterPlatformTypes(Platform* platform);
+ /*! Make the contents of a type library available for type/import resolution
+
+ \param lib library to register with the view
+ */
+ void AddTypeLibrary(TypeLibrary* lib);
+ /*! Get the type library with the given name
+
+ \param name Library name to lookup
+ \return The Type Library object, or nullptr if one has not been added with this name
+ */
+ Ref<TypeLibrary> GetTypeLibrary(const std::string& name);
+ /*! Get the list of imported type libraries
+
+ \return All imported type libraries
+ */
+ std::vector<Ref<TypeLibrary>> GetTypeLibraries();
+
+ /*! Recursively imports a type from the specified type library, or, if no library was explicitly provided,
+ the first type library associated with the current `BinaryView` that provides the name requested.
+
+ This may have the impact of loading other type libraries as dependencies on other type libraries are lazily resolved
+ when references to types provided by them are first encountered.
+
+ Note that the name actually inserted into the view may not match the name as it exists in the type library in
+ the event of a name conflict. To aid in this, the `Type` object returned is a `NamedTypeReference` to
+ the deconflicted name used.
+
+ \param lib
+ \param name
+ \return A `NamedTypeReference` to the type, taking into account any renaming performed
+ */
+ Ref<Type> ImportTypeLibraryType(Ref<TypeLibrary>& lib, const QualifiedName& name);
+ /*! Recursively imports an object from the specified type library, or, if no library was explicitly provided,
+ the first type library associated with the current `BinaryView` that provides the name requested.
+
+ This may have the impact of loading other type libraries as dependencies on other type libraries are lazily resolved
+ when references to types provided by them are first encountered.
+
+ .. note:: If you are implementing a custom BinaryView and use this method to import object types,
+ you should then call ``RecordImportedObjectLibrary`` with the details of where the object is located.
+
+ \param lib
+ \param name
+ \return The object type, with any interior `NamedTypeReferences` renamed as necessary to be appropriate for the current view
+ */
+ Ref<Type> ImportTypeLibraryObject(Ref<TypeLibrary>& lib, const QualifiedName& name);
+
+ /*! Recursively exports ``type`` into ``lib`` as a type with name ``name``
+
+ As other referenced types are encountered, they are either copied into the destination type library or
+ else the type library that provided the referenced type is added as a dependency for the destination library.
+
+ \param lib
+ \param name
+ \param type
+ */
+ void ExportTypeToTypeLibrary(TypeLibrary* lib, const QualifiedName& name, Type* type);
+ /*! Recursively exports ``type`` into ``lib`` as an object with name ``name``
+
+ As other referenced types are encountered, they are either copied into the destination type library or
+ else the type library that provided the referenced type is added as a dependency for the destination library.
+
+ \param lib
+ \param name
+ \param type
+ */
+ void ExportObjectToTypeLibrary(TypeLibrary* lib, const QualifiedName& name, Type* type);
+
+ /*! Should be called by custom `BinaryView` implementations when they have successfully imported an object
+ from a type library (eg a symbol's type). Values recorded with this function will then be queryable via ``LookupImportedObjectLibrary``.
+
+ \param tgtPlatform Platform of symbol at import site
+ \param tgtAddr Address of symbol at import site
+ \param lib Type Library containing the imported type
+ \param name Name of the object in the type library
+ */
+ void RecordImportedObjectLibrary(Platform* tgtPlatform, uint64_t tgtAddr, TypeLibrary* lib, const QualifiedName& name);
+ /*! Gives you details of which type library and name was used to determine the type of a symbol at a given address.
+
+ \param tgtPlatform Platform of symbol at import site
+ \param tgtAddr Address of symbol at import site
+ \return A pair with the library and name used, or std::nullopt if it was not imported
+ */
+ std::optional<std::pair<Ref<TypeLibrary>, QualifiedName>> LookupImportedObjectLibrary(Platform* tgtPlatform, uint64_t tgtAddr);
+
bool FindNextData(
uint64_t start, const DataBuffer& data, uint64_t& result, BNFindFlag flags = FindCaseSensitive);
bool FindNextText(uint64_t start, const std::string& data, uint64_t& result, Ref<DisassemblySettings> settings,
@@ -6203,6 +6289,9 @@ namespace BinaryNinja {
\return Architecture standalone platform
*/
Ref<Platform> GetStandalonePlatform();
+
+ std::vector<Ref<TypeLibrary>> GetTypeLibraries();
+
void AddArchitectureRedirection(Architecture* from, Architecture* to);
};
@@ -11495,6 +11584,12 @@ namespace BinaryNinja {
\return A list of system calls for this platform
*/
std::map<uint32_t, QualifiedNameAndType> GetSystemCalls();
+
+ std::vector<Ref<TypeLibrary>> GetTypeLibraries();
+
+ std::vector<Ref<TypeLibrary>> GetTypeLibrariesByName(const std::string& name);
+
+
Ref<Type> GetTypeByName(const QualifiedName& name);
Ref<Type> GetVariableByName(const QualifiedName& name);
Ref<Type> GetFunctionByName(const QualifiedName& name, bool exactMatch = false);
@@ -13456,4 +13551,224 @@ namespace BinaryNinja {
std::vector<DataVariable> GetReferencedDataVariables();
};
+ class TypeLibrary: public CoreRefCountObject<BNTypeLibrary, BNNewTypeLibraryReference, BNFreeTypeLibrary>
+ {
+ public:
+ TypeLibrary(BNTypeLibrary* handle);
+
+ /*! Creates an empty type library object with a random GUID and the provided name.
+
+ \param arch
+ \param name
+ */
+ TypeLibrary(Ref<Architecture> arch, const std::string& name);
+
+ /*! Loads a finalized type library instance from file
+
+ \param path
+ \return
+ */
+ static Ref<TypeLibrary> LoadFromFile(const std::string& path);
+
+ /*! Looks up the first type library found with a matching name. Keep in mind that names are
+ not necessarily unique.
+
+ \param arch
+ \param name
+ \return
+ */
+ static Ref<TypeLibrary> LookupByName(Ref<Architecture> arch, const std::string& name);
+
+ /*! Attempts to grab a type library associated with the provided Architecture and GUID pair
+
+ \param arch
+ \param guid
+ \return
+ */
+ static Ref<TypeLibrary> LookupByGuid(Ref<Architecture> arch, const std::string& guid);
+
+ /*! Saves a finalized type library instance to file
+
+ \param path
+ */
+ void WriteToFile(const std::string& path);
+
+ /*! The Architecture this type library is associated with
+
+ \return
+ */
+ Ref<Architecture> GetArchitecture();
+
+ /*! Returns the GUID associated with the type library
+
+ \return
+ */
+ std::string GetGuid();
+
+ /*! The primary name associated with this type library
+
+ \return
+ */
+ std::string GetName();
+
+ /*! A list of extra names that will be considered a match by ``Platform::GetTypeLibrariesByName``
+
+ \return
+ */
+ std::set<std::string> GetAlternateNames();
+
+ /*! The dependency name of a library is the name used to record dependencies across
+ type libraries. This allows, for example, a library with the name "musl_libc" to have
+ dependencies on it recorded as "libc_generic", allowing a type library to be used across
+ multiple platforms where each has a specific libc that also provides the name "libc_generic"
+ as an `alternate_name`.
+
+ \return
+ */
+ std::string GetDependencyName();
+
+ /*! Returns a list of all platform names that this type library will register with during platform
+ type registration.
+
+ This returns strings, not Platform objects, as type libraries can be distributed with support for
+ Platforms that may not be present.
+
+ \return
+ */
+ std::set<std::string> GetPlatformNames();
+
+ /*! Retrieves a metadata associated with the given key stored in the type library
+
+ \param key Key to query
+ \return Metadata associated with the key
+ */
+ Ref<Metadata> QueryMetadata(const std::string& key);
+
+ /*! Sets the GUID of a type library instance that has not been finalized
+
+ \param guid
+ */
+ void SetGuid(const std::string& guid);
+
+ /*! Direct extracts a reference to a contained object -- when attempting to extract types from a library
+ into a BinaryView, consider using BinaryView::ImportLibraryObject instead.
+
+ \param name
+ \return
+ */
+ Ref<Type> GetNamedObject(const QualifiedName& name);
+
+ /*! Direct extracts a reference to a contained type -- when attempting to extract types from a library
+ into a BinaryView, consider using BinaryView.ImportLibraryType>` instead.
+
+ \param name
+ \return
+ */
+ Ref<Type> GetNamedType(const QualifiedName& name);
+
+ /*! A list containing all named objects (functions, exported variables) provided by a type library
+
+ \return
+ */
+ std::vector<QualifiedNameAndType> GetNamedObjects();
+
+ /*! A list containing all named types provided by a type library
+
+ \return
+ */
+ std::vector<QualifiedNameAndType> GetNamedTypes();
+
+ /*! Sets the name of a type library instance that has not been finalized
+
+ \param name
+ */
+ void SetName(const std::string& name);
+
+ /*! Adds an extra name to this type library used during library lookups and dependency resolution
+
+ \param alternate
+ */
+ void AddAlternateName(const std::string& alternate);
+
+ /*! Sets the dependency name of a type library instance that has not been finalized
+
+ \param depName
+ */
+ void SetDependencyName(const std::string& depName);
+
+ /*! Clears the list of platforms associated with a type library instance that has not been finalized
+
+ */
+ void ClearPlatforms();
+
+ /*! Associate a platform with a type library instance that has not been finalized.
+
+ This will cause the library to be searchable by Platform::GetTypeLibrariesByName when loaded.
+
+ This does not have side affects until finalization of the type library.
+
+ \param platform
+ */
+ void AddPlatform(Ref<Platform> platform);
+
+ /*! Stores an object for the given key in the current type library. Objects stored using StoreMetadata can be
+ retrieved from any reference to the library.
+
+ This is primarily intended as a way to store Platform specific information relevant to BinaryView implementations;
+ for example the PE BinaryViewType uses type library metadata to retrieve ordinal information, when available.
+
+ \param key Key value to associate the Metadata object with
+ \param value Object to store.
+ */
+ void StoreMetadata(const std::string& key, Ref<Metadata> value);
+
+ /*! Removes the metadata associated with key from the current type library.
+
+ \param key Key associated with metadata
+ */
+ void RemoveMetadata(const std::string& key);
+
+ /*! Directly inserts a named object into the type library's object store.
+ This is not done recursively, so care should be taken that types referring to other types
+ through NamedTypeReferences are already appropriately prepared.
+
+ To add types and objects from an existing BinaryView, it is recommended to use
+ BinaryView::ExportObjectToLibrary, which will automatically pull in all referenced types and record
+ additional dependencies as needed.
+
+ \param name
+ \param type
+ */
+ void AddNamedObject(const QualifiedName& name, Ref<Type> type);
+
+ /*! Directly inserts a named object into the type library's object store.
+ This is not done recursively, so care should be taken that types referring to other types
+ through NamedTypeReferences are already appropriately prepared.
+
+ To add types and objects from an existing BinaryView, it is recommended to use
+ BinaryView::ExportTypeToLibrary, which will automatically pull in all referenced types and record
+ additional dependencies as needed.
+
+ \param name
+ \param type
+ */
+ void AddNamedType(const QualifiedName& name, Ref<Type> type);
+
+ /*! Manually flag NamedTypeReferences to the given QualifiedName as originating from another source
+ TypeLibrary with the given dependency name.
+
+ \warning Use this api with extreme caution.
+
+ \param name
+ \param source
+ */
+ void AddNamedTypeSource(const QualifiedName& name, const std::string& source);
+
+ /*! Flags a newly created type library instance as finalized and makes it available for Platform and Architecture
+ type library searches
+
+ */
+ void Finalize();
+ };
+
} // namespace BinaryNinja
diff --git a/binaryninjacore.h b/binaryninjacore.h
index d5655a09..0849a35d 100644
--- a/binaryninjacore.h
+++ b/binaryninjacore.h
@@ -150,13 +150,13 @@
#else
#define BN_HAVE_ATTRIBUTE(x) 0
#endif
-
-#if BN_HAVE_ATTRIBUTE(format) || (defined(__GNUC__) && !defined(__clang__))
- #define BN_PRINTF_ATTRIBUTE(string_index, first_to_check) \
- __attribute__((format(__printf__, string_index, first_to_check)))
-#else
+//
+//#if BN_HAVE_ATTRIBUTE(format) || (defined(__GNUC__) && !defined(__clang__))
+// #define BN_PRINTF_ATTRIBUTE(string_index, first_to_check) \
+// __attribute__((format(__printf__, string_index, first_to_check)))
+//#else
#define BN_PRINTF_ATTRIBUTE(string_index, first_to_check)
-#endif
+//#endif
#ifdef __cplusplus
@@ -5200,15 +5200,20 @@ extern "C"
BINARYNINJACOREAPI BNTypeLibrary** BNGetBinaryViewTypeLibraries(BNBinaryView* view, size_t* count);
BINARYNINJACOREAPI BNType* BNBinaryViewImportTypeLibraryType(
- BNBinaryView* view, BNTypeLibrary* lib, BNQualifiedName* name);
+ BNBinaryView* view, BNTypeLibrary** lib, BNQualifiedName* name);
BINARYNINJACOREAPI BNType* BNBinaryViewImportTypeLibraryObject(
- BNBinaryView* view, BNTypeLibrary* lib, BNQualifiedName* name);
+ BNBinaryView* view, BNTypeLibrary** lib, BNQualifiedName* name);
BINARYNINJACOREAPI void BNBinaryViewExportTypeToTypeLibrary(
BNBinaryView* view, BNTypeLibrary* lib, BNQualifiedName* name, BNType* type);
BINARYNINJACOREAPI void BNBinaryViewExportObjectToTypeLibrary(
BNBinaryView* view, BNTypeLibrary* lib, BNQualifiedName* name, BNType* type);
+ BINARYNINJACOREAPI void BNBinaryViewRecordImportedObjectLibrary(
+ BNBinaryView* view, BNPlatform* tgtPlatform, uint64_t tgtAddr, BNTypeLibrary* lib, BNQualifiedName* name);
+ BINARYNINJACOREAPI bool BNBinaryViewLookupImportedObjectLibrary(
+ BNBinaryView* view, BNPlatform* tgtPlatform, uint64_t tgtAddr, BNTypeLibrary** lib, BNQualifiedName* name);
+
// Language Representation
BINARYNINJACOREAPI BNLanguageRepresentationFunction* BNCreateLanguageRepresentationFunction(
BNArchitecture* arch, BNFunction* func);
@@ -5766,7 +5771,7 @@ extern "C"
BINARYNINJACOREAPI BNTypeLibrary** BNGetPlatformTypeLibraries(BNPlatform* platform, size_t* count);
BINARYNINJACOREAPI BNTypeLibrary** BNGetPlatformTypeLibrariesByName(
- BNPlatform* platform, char* depName, size_t* count);
+ BNPlatform* platform, const char* depName, size_t* count);
// Demangler
BINARYNINJACOREAPI bool BNDemangleMS(BNArchitecture* arch, const char* mangledName, BNType** outType,
diff --git a/binaryview.cpp b/binaryview.cpp
index f1b5b3b5..1eb96e51 100644
--- a/binaryview.cpp
+++ b/binaryview.cpp
@@ -3639,6 +3639,99 @@ void BinaryView::RegisterPlatformTypes(Platform* platform)
}
+void BinaryView::AddTypeLibrary(TypeLibrary* lib)
+{
+ BNAddBinaryViewTypeLibrary(m_object, lib->GetObject());
+}
+
+
+Ref<TypeLibrary> BinaryView::GetTypeLibrary(const std::string& name)
+{
+ BNTypeLibrary* lib = BNGetBinaryViewTypeLibrary(m_object, name.c_str());
+ if (!lib)
+ return nullptr;
+ return new TypeLibrary(lib);
+}
+
+
+std::vector<Ref<TypeLibrary>> BinaryView::GetTypeLibraries()
+{
+ size_t count;
+ BNTypeLibrary** libs = BNGetBinaryViewTypeLibraries(m_object, &count);
+
+ vector<Ref<TypeLibrary>> result;
+ for (size_t i = 0; i < count; ++i)
+ {
+ result.push_back(new TypeLibrary(BNNewTypeLibraryReference(libs[i])));
+ }
+
+ BNFreeTypeLibraryList(libs, count);
+ return result;
+}
+
+
+Ref<Type> BinaryView::ImportTypeLibraryType(Ref<TypeLibrary>& lib, const QualifiedName& name)
+{
+ BNQualifiedName apiName = name.GetAPIObject();
+ BNTypeLibrary* apiLib = lib ? lib->GetObject() : nullptr;
+ BNType* result = BNBinaryViewImportTypeLibraryType(m_object, &apiLib, &apiName);
+ lib = apiLib ? new TypeLibrary(apiLib) : nullptr;
+ QualifiedName::FreeAPIObject(&apiName);
+ if (!result)
+ return nullptr;
+ return new Type(result);
+}
+
+
+Ref<Type> BinaryView::ImportTypeLibraryObject(Ref<TypeLibrary>& lib, const QualifiedName& name)
+{
+ BNQualifiedName apiName = name.GetAPIObject();
+ BNTypeLibrary* apiLib = lib ? lib->GetObject() : nullptr;
+ BNType* result = BNBinaryViewImportTypeLibraryObject(m_object, &apiLib, &apiName);
+ lib = apiLib ? new TypeLibrary(apiLib) : nullptr;
+ QualifiedName::FreeAPIObject(&apiName);
+ if (!result)
+ return nullptr;
+ return new Type(result);
+}
+
+
+void BinaryView::ExportTypeToTypeLibrary(TypeLibrary* lib, const QualifiedName& name, Type* type)
+{
+ BNQualifiedName apiName = name.GetAPIObject();
+ BNBinaryViewExportTypeToTypeLibrary(m_object, lib->GetObject(), &apiName, type->GetObject());
+ QualifiedName::FreeAPIObject(&apiName);
+}
+
+
+void BinaryView::ExportObjectToTypeLibrary(TypeLibrary* lib, const QualifiedName& name, Type* type)
+{
+ BNQualifiedName apiName = name.GetAPIObject();
+ BNBinaryViewExportObjectToTypeLibrary(m_object, lib->GetObject(), &apiName, type->GetObject());
+ QualifiedName::FreeAPIObject(&apiName);
+}
+
+
+void BinaryView::RecordImportedObjectLibrary(Platform* tgtPlatform, uint64_t tgtAddr, TypeLibrary* lib, const QualifiedName& name)
+{
+ BNQualifiedName apiName = name.GetAPIObject();
+ BNBinaryViewRecordImportedObjectLibrary(m_object, tgtPlatform->m_object, tgtAddr, lib->GetObject(), &apiName);
+ QualifiedName::FreeAPIObject(&apiName);
+}
+
+
+std::optional<std::pair<Ref<TypeLibrary>, QualifiedName>> BinaryView::LookupImportedObjectLibrary(Platform* tgtPlatform, uint64_t tgtAddr)
+{
+ BNTypeLibrary* resultLib;
+ BNQualifiedName resultName;
+ if (!BNBinaryViewLookupImportedObjectLibrary(m_object, tgtPlatform->m_object, tgtAddr, &resultLib, &resultName))
+ return std::nullopt;
+ QualifiedName name = QualifiedName::FromAPIObject(&resultName);
+ BNFreeQualifiedName(&resultName);
+ return std::make_pair(new TypeLibrary(resultLib), name);
+}
+
+
bool BinaryView::FindNextData(uint64_t start, const DataBuffer& data, uint64_t& result, BNFindFlag flags)
{
return BNFindNextData(m_object, start, data.GetBufferObject(), &result, flags);
diff --git a/platform.cpp b/platform.cpp
index b3ec68e8..06d65539 100644
--- a/platform.cpp
+++ b/platform.cpp
@@ -342,6 +342,38 @@ map<uint32_t, QualifiedNameAndType> Platform::GetSystemCalls()
}
+vector<Ref<TypeLibrary>> Platform::GetTypeLibraries()
+{
+ size_t count;
+ BNTypeLibrary** libs = BNGetPlatformTypeLibraries(m_object, &count);
+
+ vector<Ref<TypeLibrary>> result;
+ for (size_t i = 0; i < count; ++i)
+ {
+ result.push_back(new TypeLibrary(BNNewTypeLibraryReference(libs[i])));
+ }
+
+ BNFreeTypeLibraryList(libs, count);
+ return result;
+}
+
+
+vector<Ref<TypeLibrary>> Platform::GetTypeLibrariesByName(const std::string& name)
+{
+ size_t count;
+ BNTypeLibrary** libs = BNGetPlatformTypeLibrariesByName(m_object, name.c_str(), &count);
+
+ vector<Ref<TypeLibrary>> result;
+ for (size_t i = 0; i < count; ++i)
+ {
+ result.push_back(new TypeLibrary(BNNewTypeLibraryReference(libs[i])));
+ }
+
+ BNFreeTypeLibraryList(libs, count);
+ return result;
+}
+
+
Ref<Type> Platform::GetTypeByName(const QualifiedName& name)
{
BNQualifiedName nameObj = name.GetAPIObject();
diff --git a/python/binaryview.py b/python/binaryview.py
index 35be7068..b60259f3 100644
--- a/python/binaryview.py
+++ b/python/binaryview.py
@@ -6930,8 +6930,10 @@ class BinaryView:
:rtype: Type
"""
_name = _types.QualifiedName(name)
+ _lib = ctypes.POINTER(core.BNTypeLibrary)()
+ _lib.contents = None if lib is None else lib.handle
handle = core.BNBinaryViewImportTypeLibraryType(
- self.handle, None if lib is None else lib.handle, _name._to_core_struct()
+ self.handle, _lib, _name._to_core_struct()
)
if handle is None:
return None
@@ -6946,14 +6948,19 @@ class BinaryView:
This may have the impact of loading other type libraries as dependencies on other type libraries are lazily resolved
when references to types provided by them are first encountered.
+ .. note:: If you are implementing a custom BinaryView and use this method to import object types,
+ you should then call ``record_imported_object`` with the details of where the object is located.
+
:param QualifiedName name:
:param TypeLibrary lib:
:return: the object type, with any interior `NamedTypeReferences` renamed as necessary to be appropriate for the current view
:rtype: Type
"""
_name = _types.QualifiedName(name)
+ _lib = ctypes.POINTER(core.BNTypeLibrary)()
+ _lib.contents = None if lib is None else lib.handle
handle = core.BNBinaryViewImportTypeLibraryObject(
- self.handle, None if lib is None else lib.handle, _name._to_core_struct()
+ self.handle, _lib, _name._to_core_struct()
)
if handle is None:
return None
@@ -7016,6 +7023,51 @@ class BinaryView:
raise ValueError("name can only be None if named type is derived from string passed to type_obj")
core.BNBinaryViewExportObjectToTypeLibrary(self.handle, lib.handle, _name._to_core_struct(), type_obj.handle)
+ def record_imported_object_library(
+ self, lib: typelibrary.TypeLibrary, name: str, addr: int, platform: Optional['_platform.Platform'] = None
+ ) -> None:
+ """
+ ``record_imported_object_library`` should be called by custom py:Class:`BinaryView` implementations
+ when they have successfully imported an object from a type library (eg a symbol's type).
+ Values recorded with this function will then be queryable via ``lookup_imported_object_library``.
+
+ :param lib: Type Library containing the imported type
+ :param name: Name of the object in the type library
+ :param addr: Address of symbol at import site
+ :param platform: Platform of symbol at import site
+ :rtype: None
+ """
+
+ if platform is None:
+ platform = self.platform
+
+ core.BNBinaryViewRecordImportedObjectLibrary(self.handle, platform.handle, addr, lib.handle, _types.QualifiedName(name)._to_core_struct())
+
+ def lookup_imported_object_library(
+ self, addr: int, platform: Optional['_platform.Platform'] = None
+ ) -> Optional[Tuple[typelibrary.TypeLibrary, str]]:
+ """
+ ``lookup_imported_object_library`` gives you details of which type library and name was used to determine
+ the type of a symbol at a given address
+
+ :param addr: Address of symbol at import site
+ :param platform: Platform of symbol at import site
+ :return: A tuple of [TypeLibrary, str] with the library and name used, or None if it was not imported
+ :rtype: Tuple[TypeLibrary, str]
+ """
+
+ if platform is None:
+ platform = self.platform
+
+ result_lib = (ctypes.POINTER(core.BNTypeLibrary) * 1)()
+ result_name = (core.BNQualifiedName * 1)()
+ if not core.BNBinaryViewLookupImportedObjectLibrary(self.handle, platform.handle, addr, result_lib, result_name):
+ return None
+ lib = typelibrary.TypeLibrary(result_lib[0])
+ name = _types.QualifiedName._from_core_struct(result_name[0])
+ core.BNFreeQualifiedName(result_name)
+ return lib, name
+
def register_platform_types(self, platform: '_platform.Platform') -> None:
"""
``register_platform_types`` ensures that the platform-specific types for a :py:Class:`Platform` are available
diff --git a/typelibrary.cpp b/typelibrary.cpp
new file mode 100644
index 00000000..4a794805
--- /dev/null
+++ b/typelibrary.cpp
@@ -0,0 +1,241 @@
+#include "binaryninjaapi.h"
+
+using namespace BinaryNinja;
+
+TypeLibrary::TypeLibrary(BNTypeLibrary* handle)
+{
+ m_object = handle;
+}
+
+
+TypeLibrary::TypeLibrary(Ref<Architecture> arch, const std::string& name)
+{
+ m_object = BNNewTypeLibrary(arch->GetObject(), name.c_str());
+}
+
+
+Ref<TypeLibrary> TypeLibrary::LoadFromFile(const std::string& path)
+{
+ return new TypeLibrary(BNLoadTypeLibraryFromFile(path.c_str()));
+}
+
+
+Ref<TypeLibrary> TypeLibrary::LookupByName(Ref<Architecture> arch, const std::string& name)
+{
+ return new TypeLibrary(BNLookupTypeLibraryByName(arch->GetObject(), name.c_str()));
+}
+
+
+Ref<TypeLibrary> TypeLibrary::LookupByGuid(Ref<Architecture> arch, const std::string& guid)
+{
+ return new TypeLibrary(BNLookupTypeLibraryByGuid(arch->GetObject(), guid.c_str()));
+}
+
+
+void TypeLibrary::WriteToFile(const std::string& path)
+{
+ BNWriteTypeLibraryToFile(m_object, path.c_str());
+}
+
+
+Ref<Architecture> TypeLibrary::GetArchitecture()
+{
+ return new CoreArchitecture(BNGetTypeLibraryArchitecture(m_object));
+}
+
+
+std::string TypeLibrary::GetGuid()
+{
+ char* str = BNGetTypeLibraryGuid(m_object);
+ std::string result = str;
+ BNFreeString(str);
+ return result;
+}
+
+
+std::string TypeLibrary::GetName()
+{
+ char* str = BNGetTypeLibraryName(m_object);
+ std::string result = str;
+ BNFreeString(str);
+ return result;
+}
+
+
+std::set<std::string> TypeLibrary::GetAlternateNames()
+{
+ size_t count;
+ char** strs = BNGetTypeLibraryAlternateNames(m_object, &count);
+ std::set<std::string> result;
+ for (size_t i = 0; i < count; i++)
+ {
+ result.insert(strs[i]);
+ }
+ BNFreeStringList(strs, count);
+ return result;
+
+}
+
+
+std::string TypeLibrary::GetDependencyName()
+{
+ char* str = BNGetTypeLibraryDependencyName(m_object);
+ std::string result = str;
+ BNFreeString(str);
+ return result;
+}
+
+
+std::set<std::string> TypeLibrary::GetPlatformNames()
+{
+ size_t count = 0;
+ char** strs = BNGetTypeLibraryPlatforms(m_object, &count);
+ std::set<std::string> result;
+ for (size_t i = 0; i < count; i++)
+ {
+ result.insert(strs[i]);
+ }
+ BNFreeStringList(strs, count);
+ return result;
+}
+
+
+Ref<Metadata> TypeLibrary::QueryMetadata(const std::string& key)
+{
+ BNMetadata* result = BNTypeLibraryQueryMetadata(m_object, key.c_str());
+ if (!result)
+ return nullptr;
+ return new Metadata(result);
+}
+
+
+void TypeLibrary::SetGuid(const std::string& guid)
+{
+ BNSetTypeLibraryGuid(m_object, guid.c_str());
+}
+
+
+Ref<Type> TypeLibrary::GetNamedObject(const QualifiedName& name)
+{
+ BNQualifiedName qname = name.GetAPIObject();
+ BNType* result = BNGetTypeLibraryNamedObject(m_object, &qname);
+ QualifiedName::FreeAPIObject(&qname);
+ if (!result)
+ return nullptr;
+ return new Type(result);
+}
+
+
+Ref<Type> TypeLibrary::GetNamedType(const QualifiedName& name)
+{
+ BNQualifiedName qname = name.GetAPIObject();
+ BNType* result = BNGetTypeLibraryNamedType(m_object, &qname);
+ QualifiedName::FreeAPIObject(&qname);
+ if (!result)
+ return nullptr;
+ return new Type(result);
+}
+
+
+std::vector<QualifiedNameAndType> TypeLibrary::GetNamedObjects()
+{
+ size_t count = 0;
+ BNQualifiedNameAndType* objects = BNGetTypeLibraryNamedObjects(m_object, &count);
+ std::vector<QualifiedNameAndType> result;
+ for (size_t i = 0; i < count; i ++)
+ {
+ QualifiedNameAndType qnat;
+ qnat.name = QualifiedName::FromAPIObject(&objects[i].name);
+ qnat.type = new Type(BNNewTypeReference(objects[i].type));
+ }
+ BNFreeQualifiedNameAndTypeArray(objects, count);
+ return result;
+}
+
+
+std::vector<QualifiedNameAndType> TypeLibrary::GetNamedTypes()
+{
+ size_t count = 0;
+ BNQualifiedNameAndType* types = BNGetTypeLibraryNamedTypes(m_object, &count);
+ std::vector<QualifiedNameAndType> result;
+ for (size_t i = 0; i < count; i ++)
+ {
+ QualifiedNameAndType qnat;
+ qnat.name = QualifiedName::FromAPIObject(&types[i].name);
+ qnat.type = new Type(BNNewTypeReference(types[i].type));
+ }
+ BNFreeQualifiedNameAndTypeArray(types, count);
+ return result;
+}
+
+
+void TypeLibrary::SetName(const std::string& name)
+{
+ BNSetTypeLibraryName(m_object, name.c_str());
+}
+
+
+void TypeLibrary::AddAlternateName(const std::string& alternate)
+{
+ BNAddTypeLibraryAlternateName(m_object, alternate.c_str());
+}
+
+
+void TypeLibrary::SetDependencyName(const std::string& depName)
+{
+ BNSetTypeLibraryDependencyName(m_object, depName.c_str());
+}
+
+
+void TypeLibrary::ClearPlatforms()
+{
+ BNClearTypeLibraryPlatforms(m_object);
+}
+
+
+void TypeLibrary::AddPlatform(Ref<Platform> platform)
+{
+ BNAddTypeLibraryPlatform(m_object, platform->m_object);
+}
+
+
+void TypeLibrary::StoreMetadata(const std::string& key, Ref<Metadata> value)
+{
+ BNTypeLibraryStoreMetadata(m_object, key.c_str(), value->m_object);
+}
+
+
+void TypeLibrary::RemoveMetadata(const std::string& key)
+{
+ BNTypeLibraryRemoveMetadata(m_object, key.c_str());
+}
+
+
+void TypeLibrary::AddNamedObject(const QualifiedName& name, Ref<Type> type)
+{
+ BNQualifiedName qname = name.GetAPIObject();
+ BNAddTypeLibraryNamedObject(m_object, &qname, type->m_object);
+ QualifiedName::FreeAPIObject(&qname);
+}
+
+
+void TypeLibrary::AddNamedType(const QualifiedName& name, Ref<Type> type)
+{
+ BNQualifiedName qname = name.GetAPIObject();
+ BNAddTypeLibraryNamedType(m_object, &qname, type->m_object);
+ QualifiedName::FreeAPIObject(&qname);
+}
+
+
+void TypeLibrary::AddNamedTypeSource(const QualifiedName& name, const std::string& source)
+{
+ BNQualifiedName qname = name.GetAPIObject();
+ BNAddTypeLibraryNamedTypeSource(m_object, &qname, source.c_str());
+ QualifiedName::FreeAPIObject(&qname);
+}
+
+
+void TypeLibrary::Finalize()
+{
+ BNFinalizeTypeLibrary(m_object);
+}
diff --git a/ui/uitypes.h b/ui/uitypes.h
index 9c1dadd3..b512c8f0 100644
--- a/ui/uitypes.h
+++ b/ui/uitypes.h
@@ -100,6 +100,7 @@ typedef BinaryNinja::Ref<BinaryNinja::TagType> TagTypeRef;
typedef BinaryNinja::Ref<BinaryNinja::TemporaryFile> TemporaryFileRef;
typedef BinaryNinja::Ref<BinaryNinja::Transform> TransformRef;
typedef BinaryNinja::Ref<BinaryNinja::Type> TypeRef;
+typedef BinaryNinja::Ref<BinaryNinja::TypeLibrary> TypeLibraryRef;
typedef BinaryNinja::Ref<BinaryNinja::WebsocketClient> WebsocketClientRef;
typedef BinaryNinja::Ref<BinaryNinja::WebsocketProvider> WebsocketProviderRef;
typedef BinaryNinja::Ref<BinaryNinja::RepoPlugin> RepoPluginRef;