summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--binaryninjaapi.h20
-rw-r--r--binaryninjacore.h14
-rw-r--r--python/types.py59
-rw-r--r--type.cpp72
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
diff --git a/type.cpp b/type.cpp
index 9dccede1..6ee0e1cb 100644
--- a/type.cpp
+++ b/type.cpp
@@ -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);