diff options
| -rw-r--r-- | binaryninjaapi.h | 20 | ||||
| -rw-r--r-- | binaryninjacore.h | 14 | ||||
| -rw-r--r-- | python/types.py | 59 | ||||
| -rw-r--r-- | type.cpp | 72 |
4 files changed, 164 insertions, 1 deletions
diff --git a/binaryninjaapi.h b/binaryninjaapi.h index f7896a45..a71d8fc0 100644 --- a/binaryninjaapi.h +++ b/binaryninjaapi.h @@ -10066,7 +10066,16 @@ namespace BinaryNinja { }; /*! - \ingroup types + \ingroup types + */ + struct TypeAttribute + { + std::string name; + std::string value; + }; + + /*! + \ingroup types */ class Type : public CoreRefCountObject<BNType, BNNewTypeReference, BNFreeType> { @@ -10208,6 +10217,9 @@ namespace BinaryNinja { std::string GetPointerSuffixString() const; std::vector<InstructionTextToken> GetPointerSuffixTokens(uint8_t baseConfidence = BN_FULL_CONFIDENCE) const; + std::vector<TypeAttribute> GetAttributes() const; + std::optional<std::string> GetAttribute(const std::string& name) const; + std::string GetString(Platform* platform = nullptr, BNTokenEscapingType escaping = NoTokenEscapingType) const; std::string GetTypeAndName(const QualifiedName& name, BNTokenEscapingType escaping = NoTokenEscapingType) const; std::string GetStringBeforeName(Platform* platform = nullptr, BNTokenEscapingType escaping = NoTokenEscapingType) const; @@ -10623,6 +10635,12 @@ namespace BinaryNinja { TypeBuilder& AddPointerSuffix(BNPointerSuffix ps); TypeBuilder& SetPointerSuffix(const std::set<BNPointerSuffix>& suffix); + void SetAttribute(const std::string& name, const std::string& value); + void SetAttributes(const std::map<std::string, std::string>& attrs); + void RemoveAttribute(const std::string& name); + std::vector<TypeAttribute> GetAttributes() const; + std::optional<std::string> GetAttribute(const std::string& name) const; + std::string GetString(Platform* platform = nullptr) const; std::string GetTypeAndName(const QualifiedName& name) const; std::string GetStringBeforeName(Platform* platform = nullptr) const; diff --git a/binaryninjacore.h b/binaryninjacore.h index fb2e8ae8..3ea122bd 100644 --- a/binaryninjacore.h +++ b/binaryninjacore.h @@ -3792,6 +3792,12 @@ extern "C" size_t typeRefCount; } BNAllTypeFieldReferences; + typedef struct BNTypeAttribute + { + char* name; + char* value; + } BNTypeAttribute; + BINARYNINJACOREAPI char* BNAllocString(const char* contents); BINARYNINJACOREAPI char* BNAllocStringWithLength(const char* contents, size_t len); BINARYNINJACOREAPI void BNFreeString(char* str); @@ -6768,6 +6774,9 @@ extern "C" BINARYNINJACOREAPI BNInstructionTextToken* BNGetTypePointerSuffixTokens(BNType* type, uint8_t baseConfidence, size_t* count); BINARYNINJACOREAPI void BNFreePointerSuffixList(BNPointerSuffix* suffix, size_t count); BINARYNINJACOREAPI bool BNTypeShouldDisplayReturnType(BNType* type); + BINARYNINJACOREAPI BNTypeAttribute* BNGetTypeAttributes(BNType* type, size_t* count); + BINARYNINJACOREAPI char* BNGetTypeAttributeByName(BNType* type, const char* name); + BINARYNINJACOREAPI void BNFreeTypeAttributeList(BNTypeAttribute* attr, size_t count); BINARYNINJACOREAPI char* BNGetTypeString(BNType* type, BNPlatform* platform, BNTokenEscapingType escaping); BINARYNINJACOREAPI char* BNGetTypeStringBeforeName(BNType* type, BNPlatform* platform, BNTokenEscapingType escaping); @@ -6848,6 +6857,11 @@ extern "C" BINARYNINJACOREAPI bool BNTypeBuilderHasTemplateArguments(BNTypeBuilder* type); BINARYNINJACOREAPI void BNSetTypeBuilderNameType(BNTypeBuilder* type, BNNameType nameType); BINARYNINJACOREAPI void BNSetTypeBuilderHasTemplateArguments(BNTypeBuilder* type, bool hasTemplateArguments); + BINARYNINJACOREAPI void BNSetTypeBuilderAttribute(BNTypeBuilder* type, const char* name, const char* value); + BINARYNINJACOREAPI void BNSetTypeBuilderAttributeList(BNTypeBuilder* type, BNTypeAttribute* attrs, size_t count); + BINARYNINJACOREAPI void BNRemoveTypeBuilderAttribute(BNTypeBuilder* type, const char* name); + BINARYNINJACOREAPI BNTypeAttribute* BNGetTypeBuilderAttributes(BNTypeBuilder* type, size_t* count); + BINARYNINJACOREAPI char* BNGetTypeBuilderAttributeByName(BNTypeBuilder* type, const char* name); BINARYNINJACOREAPI char* BNGetTypeBuilderString(BNTypeBuilder* type, BNPlatform* platform); BINARYNINJACOREAPI char* BNGetTypeBuilderStringBeforeName(BNTypeBuilder* type, BNPlatform* platform); diff --git a/python/types.py b/python/types.py index 860fba78..853d0836 100644 --- a/python/types.py +++ b/python/types.py @@ -551,6 +551,26 @@ class MutableTypeBuilder(Generic[TB]): self.container.add_named_type(self.name, self.type.immutable_copy()) +class TypeBuilderAttributes(dict): + def __init__(self, builder, *args): + super(TypeBuilderAttributes, self).__init__(*args) + self._builder = builder + + def __setitem__(self, key: str, value: str): + if not isinstance(key, str): + raise TypeError("Type attribute key must be a string") + if not isinstance(value, str): + raise TypeError("Type attribute value must be a string") + core.BNSetTypeBuilderAttribute(self._builder._handle, key, value) + super(TypeBuilderAttributes, self).__setitem__(key, value) + + def __delitem__(self, key: str): + if not isinstance(key, str): + raise TypeError("Type attribute key must be a string") + core.BNRemoveTypeBuilderAttribute(self._builder._handle, key) + super(TypeBuilderAttributes, self).__delitem__(key) + + class TypeBuilder: """ All TypeBuilder objects should not be instantiated directly but created via ``.create`` APIs. @@ -855,6 +875,34 @@ class TypeBuilder: def children(self) -> List['TypeBuilder']: return [] + @property + def attributes(self) -> Dict[str, str]: + """Attribute names and their values""" + count = ctypes.c_ulonglong() + attributes = core.BNGetTypeBuilderAttributes(self._handle, count) + result = dict() + for i in range(count.value): + result[attributes[i].name] = attributes[i].value + core.BNFreeTypeAttributeList(attributes, count.value) + return TypeBuilderAttributes(self, result) + + @attributes.setter + def attributes(self, values: Dict[str, str]) -> None: + if not isinstance(values, dict): + raise TypeError("Attributes must be a dictionary") + attributes = (core.BNTypeAttribute * len(values))() + i = 0 + for name, value in values.items(): + if not isinstance(name, str): + raise TypeError("Attribute names must be strings") + if not isinstance(value, str): + raise TypeError("Attribute values must be strings") + attributes[i].name = name + attributes[i].value = value + i += 1 + core.BNSetTypeBuilderAttributeList(self._handle, attributes, len(values)) + + class VoidBuilder(TypeBuilder): @classmethod def create(cls, platform: Optional['_platform.Platform'] = None, confidence: int = core.max_confidence) -> 'VoidBuilder': @@ -1940,6 +1988,17 @@ class Type: """Alternative name for the type object""" return core.BNGetTypeAlternateName(self._handle) + @property + def attributes(self) -> Dict[str, str]: + """Attribute names and their values""" + count = ctypes.c_ulonglong() + attributes = core.BNGetTypeAttributes(self._handle, count) + result = dict() + for i in range(count.value): + result[attributes[i].name] = attributes[i].value + core.BNFreeTypeAttributeList(attributes, count.value) + return result + def _to_core_struct(self) -> core.BNTypeWithConfidence: type_conf = core.BNTypeWithConfidence() type_conf.type = self._handle @@ -753,6 +753,29 @@ std::vector<InstructionTextToken> Type::GetPointerSuffixTokens(uint8_t baseConfi } +std::vector<TypeAttribute> Type::GetAttributes() const +{ + size_t count = 0; + BNTypeAttribute* attributes = BNGetTypeAttributes(m_object, &count); + std::vector<TypeAttribute> result; + for (size_t i = 0; i < count; i++) + result.emplace_back(attributes[i].name, attributes[i].value); + BNFreeTypeAttributeList(attributes, count); + return result; +} + + +std::optional<std::string> Type::GetAttribute(const std::string& name) const +{ + char* result = BNGetTypeAttributeByName(m_object, name.c_str()); + if (!result) + return std::nullopt; + std::string resultStr(result); + BNFreeString(result); + return resultStr; +} + + string Type::GetString(Platform* platform, BNTokenEscapingType escaping) const { char* str = BNGetTypeString(m_object, platform ? platform->GetObject() : nullptr, escaping); @@ -2189,6 +2212,55 @@ TypeBuilder& TypeBuilder::SetPointerSuffix(const std::set<BNPointerSuffix>& suff } +void TypeBuilder::SetAttribute(const std::string& name, const std::string& value) +{ + BNSetTypeBuilderAttribute(m_object, name.c_str(), value.c_str()); +} + + +void TypeBuilder::SetAttributes(const std::map<std::string, std::string>& values) +{ + BNTypeAttribute* attrs = new BNTypeAttribute[values.size()]; + size_t i = 0; + for (auto& [name, value] : values) + { + attrs[i].name = (char*)name.c_str(); + attrs[i].value = (char*)value.c_str(); + i++; + } + BNSetTypeBuilderAttributeList(m_object, attrs, values.size()); +} + + +void TypeBuilder::RemoveAttribute(const std::string& name) +{ + BNRemoveTypeBuilderAttribute(m_object, name.c_str()); +} + + +std::vector<TypeAttribute> TypeBuilder::GetAttributes() const +{ + size_t count; + BNTypeAttribute* attributes = BNGetTypeBuilderAttributes(m_object, &count); + std::vector<TypeAttribute> result; + for (size_t i = 0; i < count; i++) + result.emplace_back(attributes[i].name, attributes[i].value); + BNFreeTypeAttributeList(attributes, count); + return result; +} + + +std::optional<std::string> TypeBuilder::GetAttribute(const std::string& name) const +{ + char* result = BNGetTypeBuilderAttributeByName(m_object, name.c_str()); + if (!result) + return std::nullopt; + std::string resultStr(result); + BNFreeString(result); + return resultStr; +} + + QualifiedName TypeBuilder::GetTypeName() const { BNQualifiedName name = BNTypeBuilderGetTypeName(m_object); |
