diff options
| -rw-r--r-- | architecture.cpp | 16 | ||||
| -rw-r--r-- | binaryninjaapi.h | 315 | ||||
| -rw-r--r-- | binaryninjacore.h | 23 | ||||
| -rw-r--r-- | binaryview.cpp | 93 | ||||
| -rw-r--r-- | platform.cpp | 32 | ||||
| -rw-r--r-- | python/binaryview.py | 56 | ||||
| -rw-r--r-- | typelibrary.cpp | 241 | ||||
| -rw-r--r-- | ui/uitypes.h | 1 |
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; |
