Skip to content

Commit 457fb75

Browse files
committed
Add type attribute APIs
1 parent d158e09 commit 457fb75

4 files changed

Lines changed: 164 additions & 1 deletion

File tree

binaryninjaapi.h

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9974,7 +9974,16 @@ namespace BinaryNinja {
99749974
};
99759975

99769976
/*!
9977-
\ingroup types
9977+
\ingroup types
9978+
*/
9979+
struct TypeAttribute
9980+
{
9981+
std::string name;
9982+
std::string value;
9983+
};
9984+
9985+
/*!
9986+
\ingroup types
99789987
*/
99799988
class Type : public CoreRefCountObject<BNType, BNNewTypeReference, BNFreeType>
99809989
{
@@ -10116,6 +10125,9 @@ namespace BinaryNinja {
1011610125
std::string GetPointerSuffixString() const;
1011710126
std::vector<InstructionTextToken> GetPointerSuffixTokens(uint8_t baseConfidence = BN_FULL_CONFIDENCE) const;
1011810127

10128+
std::vector<TypeAttribute> GetAttributes() const;
10129+
std::optional<std::string> GetAttribute(const std::string& name) const;
10130+
1011910131
std::string GetString(Platform* platform = nullptr, BNTokenEscapingType escaping = NoTokenEscapingType) const;
1012010132
std::string GetTypeAndName(const QualifiedName& name, BNTokenEscapingType escaping = NoTokenEscapingType) const;
1012110133
std::string GetStringBeforeName(Platform* platform = nullptr, BNTokenEscapingType escaping = NoTokenEscapingType) const;
@@ -10531,6 +10543,12 @@ namespace BinaryNinja {
1053110543
TypeBuilder& AddPointerSuffix(BNPointerSuffix ps);
1053210544
TypeBuilder& SetPointerSuffix(const std::set<BNPointerSuffix>& suffix);
1053310545

10546+
void SetAttribute(const std::string& name, const std::string& value);
10547+
void SetAttributes(const std::map<std::string, std::string>& attrs);
10548+
void RemoveAttribute(const std::string& name);
10549+
std::vector<TypeAttribute> GetAttributes() const;
10550+
std::optional<std::string> GetAttribute(const std::string& name) const;
10551+
1053410552
std::string GetString(Platform* platform = nullptr) const;
1053510553
std::string GetTypeAndName(const QualifiedName& name) const;
1053610554
std::string GetStringBeforeName(Platform* platform = nullptr) const;

binaryninjacore.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3772,6 +3772,12 @@ extern "C"
37723772
size_t typeRefCount;
37733773
} BNAllTypeFieldReferences;
37743774

3775+
typedef struct BNTypeAttribute
3776+
{
3777+
char* name;
3778+
char* value;
3779+
} BNTypeAttribute;
3780+
37753781
BINARYNINJACOREAPI char* BNAllocString(const char* contents);
37763782
BINARYNINJACOREAPI char* BNAllocStringWithLength(const char* contents, size_t len);
37773783
BINARYNINJACOREAPI void BNFreeString(char* str);
@@ -6693,6 +6699,9 @@ extern "C"
66936699
BINARYNINJACOREAPI BNInstructionTextToken* BNGetTypePointerSuffixTokens(BNType* type, uint8_t baseConfidence, size_t* count);
66946700
BINARYNINJACOREAPI void BNFreePointerSuffixList(BNPointerSuffix* suffix, size_t count);
66956701
BINARYNINJACOREAPI bool BNTypeShouldDisplayReturnType(BNType* type);
6702+
BINARYNINJACOREAPI BNTypeAttribute* BNGetTypeAttributes(BNType* type, size_t* count);
6703+
BINARYNINJACOREAPI char* BNGetTypeAttributeByName(BNType* type, const char* name);
6704+
BINARYNINJACOREAPI void BNFreeTypeAttributeList(BNTypeAttribute* attr, size_t count);
66966705

66976706
BINARYNINJACOREAPI char* BNGetTypeString(BNType* type, BNPlatform* platform, BNTokenEscapingType escaping);
66986707
BINARYNINJACOREAPI char* BNGetTypeStringBeforeName(BNType* type, BNPlatform* platform, BNTokenEscapingType escaping);
@@ -6773,6 +6782,11 @@ extern "C"
67736782
BINARYNINJACOREAPI bool BNTypeBuilderHasTemplateArguments(BNTypeBuilder* type);
67746783
BINARYNINJACOREAPI void BNSetTypeBuilderNameType(BNTypeBuilder* type, BNNameType nameType);
67756784
BINARYNINJACOREAPI void BNSetTypeBuilderHasTemplateArguments(BNTypeBuilder* type, bool hasTemplateArguments);
6785+
BINARYNINJACOREAPI void BNSetTypeBuilderAttribute(BNTypeBuilder* type, const char* name, const char* value);
6786+
BINARYNINJACOREAPI void BNSetTypeBuilderAttributeList(BNTypeBuilder* type, BNTypeAttribute* attrs, size_t count);
6787+
BINARYNINJACOREAPI void BNRemoveTypeBuilderAttribute(BNTypeBuilder* type, const char* name);
6788+
BINARYNINJACOREAPI BNTypeAttribute* BNGetTypeBuilderAttributes(BNTypeBuilder* type, size_t* count);
6789+
BINARYNINJACOREAPI char* BNGetTypeBuilderAttributeByName(BNTypeBuilder* type, const char* name);
67766790

67776791
BINARYNINJACOREAPI char* BNGetTypeBuilderString(BNTypeBuilder* type, BNPlatform* platform);
67786792
BINARYNINJACOREAPI char* BNGetTypeBuilderStringBeforeName(BNTypeBuilder* type, BNPlatform* platform);

python/types.py

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -551,6 +551,26 @@ def __exit__(self, type, value, traceback):
551551
self.container.add_named_type(self.name, self.type.immutable_copy())
552552

553553

554+
class TypeBuilderAttributes(dict):
555+
def __init__(self, builder, *args):
556+
super(TypeBuilderAttributes, self).__init__(*args)
557+
self._builder = builder
558+
559+
def __setitem__(self, key: str, value: str):
560+
if not isinstance(key, str):
561+
raise TypeError("Type attribute key must be a string")
562+
if not isinstance(value, str):
563+
raise TypeError("Type attribute value must be a string")
564+
core.BNSetTypeBuilderAttribute(self._builder._handle, key, value)
565+
super(TypeBuilderAttributes, self).__setitem__(key, value)
566+
567+
def __delitem__(self, key: str):
568+
if not isinstance(key, str):
569+
raise TypeError("Type attribute key must be a string")
570+
core.BNRemoveTypeBuilderAttribute(self._builder._handle, key)
571+
super(TypeBuilderAttributes, self).__delitem__(key)
572+
573+
554574
class TypeBuilder:
555575
"""
556576
All TypeBuilder objects should not be instantiated directly but created via ``.create`` APIs.
@@ -855,6 +875,34 @@ def signed(self, value: BoolWithConfidenceType) -> None:
855875
def children(self) -> List['TypeBuilder']:
856876
return []
857877

878+
@property
879+
def attributes(self) -> Dict[str, str]:
880+
"""Attribute names and their values"""
881+
count = ctypes.c_ulonglong()
882+
attributes = core.BNGetTypeBuilderAttributes(self._handle, count)
883+
result = dict()
884+
for i in range(count.value):
885+
result[attributes[i].name] = attributes[i].value
886+
core.BNFreeTypeAttributeList(attributes, count.value)
887+
return TypeBuilderAttributes(self, result)
888+
889+
@attributes.setter
890+
def attributes(self, values: Dict[str, str]) -> None:
891+
if not isinstance(values, dict):
892+
raise TypeError("Attributes must be a dictionary")
893+
attributes = (core.BNTypeAttribute * len(values))()
894+
i = 0
895+
for name, value in values.items():
896+
if not isinstance(name, str):
897+
raise TypeError("Attribute names must be strings")
898+
if not isinstance(value, str):
899+
raise TypeError("Attribute values must be strings")
900+
attributes[i].name = name
901+
attributes[i].value = value
902+
i += 1
903+
core.BNSetTypeBuilderAttributeList(self._handle, attributes, len(values))
904+
905+
858906
class VoidBuilder(TypeBuilder):
859907
@classmethod
860908
def create(cls, platform: Optional['_platform.Platform'] = None, confidence: int = core.max_confidence) -> 'VoidBuilder':
@@ -1940,6 +1988,17 @@ def altname(self) -> str:
19401988
"""Alternative name for the type object"""
19411989
return core.BNGetTypeAlternateName(self._handle)
19421990

1991+
@property
1992+
def attributes(self) -> Dict[str, str]:
1993+
"""Attribute names and their values"""
1994+
count = ctypes.c_ulonglong()
1995+
attributes = core.BNGetTypeAttributes(self._handle, count)
1996+
result = dict()
1997+
for i in range(count.value):
1998+
result[attributes[i].name] = attributes[i].value
1999+
core.BNFreeTypeAttributeList(attributes, count.value)
2000+
return result
2001+
19432002
def _to_core_struct(self) -> core.BNTypeWithConfidence:
19442003
type_conf = core.BNTypeWithConfidence()
19452004
type_conf.type = self._handle

type.cpp

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -753,6 +753,29 @@ std::vector<InstructionTextToken> Type::GetPointerSuffixTokens(uint8_t baseConfi
753753
}
754754

755755

756+
std::vector<TypeAttribute> Type::GetAttributes() const
757+
{
758+
size_t count = 0;
759+
BNTypeAttribute* attributes = BNGetTypeAttributes(m_object, &count);
760+
std::vector<TypeAttribute> result;
761+
for (size_t i = 0; i < count; i++)
762+
result.emplace_back(attributes[i].name, attributes[i].value);
763+
BNFreeTypeAttributeList(attributes, count);
764+
return result;
765+
}
766+
767+
768+
std::optional<std::string> Type::GetAttribute(const std::string& name) const
769+
{
770+
char* result = BNGetTypeAttributeByName(m_object, name.c_str());
771+
if (!result)
772+
return std::nullopt;
773+
std::string resultStr(result);
774+
BNFreeString(result);
775+
return resultStr;
776+
}
777+
778+
756779
string Type::GetString(Platform* platform, BNTokenEscapingType escaping) const
757780
{
758781
char* str = BNGetTypeString(m_object, platform ? platform->GetObject() : nullptr, escaping);
@@ -2189,6 +2212,55 @@ TypeBuilder& TypeBuilder::SetPointerSuffix(const std::set<BNPointerSuffix>& suff
21892212
}
21902213

21912214

2215+
void TypeBuilder::SetAttribute(const std::string& name, const std::string& value)
2216+
{
2217+
BNSetTypeBuilderAttribute(m_object, name.c_str(), value.c_str());
2218+
}
2219+
2220+
2221+
void TypeBuilder::SetAttributes(const std::map<std::string, std::string>& values)
2222+
{
2223+
BNTypeAttribute* attrs = new BNTypeAttribute[values.size()];
2224+
size_t i = 0;
2225+
for (auto& [name, value] : values)
2226+
{
2227+
attrs[i].name = (char*)name.c_str();
2228+
attrs[i].value = (char*)value.c_str();
2229+
i++;
2230+
}
2231+
BNSetTypeBuilderAttributeList(m_object, attrs, values.size());
2232+
}
2233+
2234+
2235+
void TypeBuilder::RemoveAttribute(const std::string& name)
2236+
{
2237+
BNRemoveTypeBuilderAttribute(m_object, name.c_str());
2238+
}
2239+
2240+
2241+
std::vector<TypeAttribute> TypeBuilder::GetAttributes() const
2242+
{
2243+
size_t count;
2244+
BNTypeAttribute* attributes = BNGetTypeBuilderAttributes(m_object, &count);
2245+
std::vector<TypeAttribute> result;
2246+
for (size_t i = 0; i < count; i++)
2247+
result.emplace_back(attributes[i].name, attributes[i].value);
2248+
BNFreeTypeAttributeList(attributes, count);
2249+
return result;
2250+
}
2251+
2252+
2253+
std::optional<std::string> TypeBuilder::GetAttribute(const std::string& name) const
2254+
{
2255+
char* result = BNGetTypeBuilderAttributeByName(m_object, name.c_str());
2256+
if (!result)
2257+
return std::nullopt;
2258+
std::string resultStr(result);
2259+
BNFreeString(result);
2260+
return resultStr;
2261+
}
2262+
2263+
21922264
QualifiedName TypeBuilder::GetTypeName() const
21932265
{
21942266
BNQualifiedName name = BNTypeBuilderGetTypeName(m_object);

0 commit comments

Comments
 (0)