diff options
| author | Peter LaFosse <peter@vector35.com> | 2024-01-12 16:55:19 -0500 |
|---|---|---|
| committer | Peter LaFosse <peter@vector35.com> | 2024-01-15 08:50:51 -0500 |
| commit | ecfc518d025359e7d2cf7e5da30f856916bf48b4 (patch) | |
| tree | 1142480ecbd1ddabe3c2e1893441226619749e50 | |
| parent | 0747711195517010294963997446673189669493 (diff) | |
Add APIs for getting the the base Metadata object for BinaryViews and TypeLibraries
| -rw-r--r-- | binaryninjaapi.h | 8 | ||||
| -rw-r--r-- | binaryninjacore.h | 5 | ||||
| -rw-r--r-- | binaryview.cpp | 12 | ||||
| -rw-r--r-- | python/binaryview.py | 58 | ||||
| -rw-r--r-- | python/metadata.py | 8 | ||||
| -rw-r--r-- | python/typelibrary.py | 20 | ||||
| -rw-r--r-- | typelibrary.cpp | 6 |
7 files changed, 114 insertions, 3 deletions
diff --git a/binaryninjaapi.h b/binaryninjaapi.h index 5f7e8cc2..5b92a2e5 100644 --- a/binaryninjaapi.h +++ b/binaryninjaapi.h @@ -5852,6 +5852,8 @@ namespace BinaryNinja { void StoreMetadata(const std::string& key, Ref<Metadata> value, bool isAuto = false); Ref<Metadata> QueryMetadata(const std::string& key); void RemoveMetadata(const std::string& key); + Ref<Metadata> GetMetadata(); + Ref<Metadata> GetAutoMetadata(); std::string GetStringMetadata(const std::string& key); std::vector<uint8_t> GetRawMetadata(const std::string& key); uint64_t GetUIntMetadata(const std::string& key); @@ -16086,6 +16088,12 @@ namespace BinaryNinja { */ void RemoveMetadata(const std::string& key); + /*! Returns a base Metadata object associated with the current type library. + + \return Metadata object associated with the type library + */ + Ref<Metadata> GetMetadata(); + /*! 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. diff --git a/binaryninjacore.h b/binaryninjacore.h index a1da4493..0fdba060 100644 --- a/binaryninjacore.h +++ b/binaryninjacore.h @@ -37,7 +37,7 @@ // Current ABI version for linking to the core. This is incremented any time // there are changes to the API that affect linking, including new functions, // new types, or modifications to existing functions or types. -#define BN_CURRENT_CORE_ABI_VERSION 45 +#define BN_CURRENT_CORE_ABI_VERSION 46 // Minimum ABI version that is supported for loading of plugins. Plugins that // are linked to an ABI version less than this will not be able to load and @@ -5356,6 +5356,7 @@ extern "C" BINARYNINJACOREAPI void BNTypeLibraryStoreMetadata(BNTypeLibrary* lib, const char* key, BNMetadata* value); BINARYNINJACOREAPI BNMetadata* BNTypeLibraryQueryMetadata(BNTypeLibrary* lib, const char* key); + BINARYNINJACOREAPI BNMetadata* BNTypeLibraryGetMetadata(BNTypeLibrary* lib); BINARYNINJACOREAPI void BNTypeLibraryRemoveMetadata(BNTypeLibrary* lib, const char* key); BINARYNINJACOREAPI BNTypeContainer* BNGetTypeLibraryTypeContainer(BNTypeLibrary* lib); @@ -6483,6 +6484,8 @@ extern "C" BNBinaryView* view, const char* key, BNMetadata* value, bool isAuto); BINARYNINJACOREAPI BNMetadata* BNBinaryViewQueryMetadata(BNBinaryView* view, const char* key); BINARYNINJACOREAPI void BNBinaryViewRemoveMetadata(BNBinaryView* view, const char* key); + BINARYNINJACOREAPI BNMetadata* BNBinaryViewGetMetadata(BNBinaryView* view); + BINARYNINJACOREAPI BNMetadata* BNBinaryViewGetAutoMetadata(BNBinaryView* view); BINARYNINJACOREAPI char** BNBinaryViewGetLoadSettingsTypeNames(BNBinaryView* view, size_t* count); BINARYNINJACOREAPI BNSettings* BNBinaryViewGetLoadSettings(BNBinaryView* view, const char* typeName); diff --git a/binaryview.cpp b/binaryview.cpp index dba5bbc7..7d79a839 100644 --- a/binaryview.cpp +++ b/binaryview.cpp @@ -4543,6 +4543,18 @@ void BinaryView::RemoveMetadata(const std::string& key) } +Ref<Metadata> BinaryView::GetMetadata() +{ + return new Metadata(BNBinaryViewGetMetadata(m_object)); +} + + +Ref<Metadata> BinaryView::GetAutoMetadata() +{ + return new Metadata(BNBinaryViewGetAutoMetadata(m_object)); +} + + string BinaryView::GetStringMetadata(const string& key) { auto data = QueryMetadata(key); diff --git a/python/binaryview.py b/python/binaryview.py index 2446f04f..0c475445 100644 --- a/python/binaryview.py +++ b/python/binaryview.py @@ -7458,6 +7458,30 @@ class BinaryView: return None return _types.Type.create(handle, platform=self.platform) + def import_com_type_for_guid(self, guid: Union[str, uuid.UUID]) -> Optional['_types.Type']: + """ + ``import_com_type_for_guid`` recursively imports a com interface given its GUID. + + .. note:: This method is only available on Windows. + + :param str guid: GUID of the COM interface to import + :return: the object type, with any interior `NamedTypeReferences` renamed as necessary to be appropriate for the current view + :rtype: Type + """ + if not isinstance(guid, str): + guid = str(guid) + + tl = self.get_type_library("win32common") + if tl is None: + return None + + type_name = tl.metadata.get("com_interface_guids", {}) + assert isinstance(type_name, dict) + type_name = type_name.get(guid, None) + if type_name is None: + return None + return self.import_library_type(type_name, tl) + def import_library_object(self, name: str, lib: Optional[typelibrary.TypeLibrary] = None) -> Optional['_types.Type']: """ ``import_library_object`` recursively imports an object from the specified type library, or, if \ @@ -8463,6 +8487,40 @@ class BinaryView: """ core.BNBinaryViewRemoveMetadata(self.handle, key) + @property + def metadata(self) -> Dict[str, 'metadata.MetadataValueType']: + """ + `metadata` retrieves the metadata associated with the current BinaryView. + + :rtype: metadata associated with the BinaryView + :Example: + + >>> bv.metadata + <metadata: {}> + """ + md_handle = core.BNBinaryViewGetMetadata(self.handle) + assert md_handle is not None, "core.BNBinaryViewGetMetadata returned None" + value = metadata.Metadata(handle=md_handle).value + assert isinstance(value, dict), "core.BNBinaryViewGetMetadata did not return a dict" + return value + + @property + def auto_metadata(self) -> Dict[str, 'metadata.MetadataValueType']: + """ + `metadata` retrieves the metadata associated with the current BinaryView. + + :rtype: metadata associated with the BinaryView + :Example: + + >>> bv.metadata + <metadata: {}> + """ + md_handle = core.BNBinaryViewGetAutoMetadata(self.handle) + assert md_handle is not None, "core.BNBinaryViewGetAutoMetadata returned None" + value = metadata.Metadata(handle=md_handle).value + assert isinstance(value, dict), "core.BNBinaryViewGetAutoMetadata did not return a dict" + return value + def get_load_settings_type_names(self) -> List[str]: """ ``get_load_settings_type_names`` retrieve a list :py:class:`BinaryViewType` names for which load settings exist in \ diff --git a/python/metadata.py b/python/metadata.py index e2483749..e87c5cbb 100644 --- a/python/metadata.py +++ b/python/metadata.py @@ -19,7 +19,7 @@ # IN THE SOFTWARE. import ctypes -from typing import Union, Optional, List, Tuple +from typing import Union, Optional, List, Tuple, Any # Binary Ninja components from . import _binaryninjacore as core @@ -184,6 +184,12 @@ class Metadata: raise ValueError("Metadata object is not boolean type") return core.BNMetadataGetBoolean(self.handle) + def get(self, key:str, default:Any=None) -> Any: + try: + return self[key] + except (KeyError, IndexError, ValueError, NotImplementedError): + return default + @property def value(self): if self.is_integer: diff --git a/python/typelibrary.py b/python/typelibrary.py index db22ee22..c9ddd37b 100644 --- a/python/typelibrary.py +++ b/python/typelibrary.py @@ -20,6 +20,7 @@ import ctypes from typing import Optional, List, Dict, Union +import uuid # Binary Ninja components import binaryninja @@ -283,6 +284,24 @@ class TypeLibrary: core.BNTypeLibraryRemoveMetadata(self.handle, key) @property + def metadata(self) -> Dict[str, 'metadata.MetadataValueType']: + """ + `metadata` retrieves the metadata associated with the current type library. + + :rtype: Metadata object + :Example: + + >>> lib.store_metadata("integer", 1337) + >>> lib.metadata["integer"] + 1337 + """ + md_handle = core.BNTypeLibraryGetMetadata(self.handle) + assert md_handle is not None, "core.BNTypeLibraryGetMetadata returned None" + value = metadata.Metadata(handle=md_handle).value + assert isinstance(value, dict), "core.BNTypeLibraryGetMetadata returned non-dict" + return value + + @property def type_container(self) -> 'typecontainer.TypeContainer': """ Type Container for all TYPES within the Type Library. Objects are not included. @@ -407,4 +426,3 @@ class TypeLibrary: return result finally: core.BNFreeQualifiedNameAndTypeArray(named_types, count.value) - diff --git a/typelibrary.cpp b/typelibrary.cpp index 2e7c15d1..b3c1293b 100644 --- a/typelibrary.cpp +++ b/typelibrary.cpp @@ -225,6 +225,12 @@ void TypeLibrary::RemoveMetadata(const std::string& key) } +Ref<Metadata> TypeLibrary::GetMetadata() +{ + return new Metadata(BNTypeLibraryGetMetadata(m_object)); +} + + void TypeLibrary::AddNamedObject(const QualifiedName& name, Ref<Type> type) { BNQualifiedName qname = name.GetAPIObject(); |
