Skip to content

Commit dc1094f

Browse files
committed
Add type attribute APIs
1 parent 4833f8b commit dc1094f

File tree

4 files changed

+164
-1
lines changed

4 files changed

+164
-1
lines changed

binaryninjaapi.h

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

1006810068
/*!
10069-
\ingroup types
10069+
\ingroup types
10070+
*/
10071+
struct TypeAttribute
10072+
{
10073+
std::string name;
10074+
std::string value;
10075+
};
10076+
10077+
/*!
10078+
\ingroup types
1007010079
*/
1007110080
class Type : public CoreRefCountObject<BNType, BNNewTypeReference, BNFreeType>
1007210081
{
@@ -10208,6 +10217,9 @@ namespace BinaryNinja {
1020810217
std::string GetPointerSuffixString() const;
1020910218
std::vector<InstructionTextToken> GetPointerSuffixTokens(uint8_t baseConfidence = BN_FULL_CONFIDENCE) const;
1021010219

10220+
std::vector<TypeAttribute> GetAttributes() const;
10221+
std::optional<std::string> GetAttribute(const std::string& name) const;
10222+
1021110223
std::string GetString(Platform* platform = nullptr, BNTokenEscapingType escaping = NoTokenEscapingType) const;
1021210224
std::string GetTypeAndName(const QualifiedName& name, BNTokenEscapingType escaping = NoTokenEscapingType) const;
1021310225
std::string GetStringBeforeName(Platform* platform = nullptr, BNTokenEscapingType escaping = NoTokenEscapingType) const;
@@ -10623,6 +10635,12 @@ namespace BinaryNinja {
1062310635
TypeBuilder& AddPointerSuffix(BNPointerSuffix ps);
1062410636
TypeBuilder& SetPointerSuffix(const std::set<BNPointerSuffix>& suffix);
1062510637

10638+
void SetAttribute(const std::string& name, const std::string& value);
10639+
void SetAttributes(const std::map<std::string, std::string>& attrs);
10640+
void RemoveAttribute(const std::string& name);
10641+
std::vector<TypeAttribute> GetAttributes() const;
10642+
std::optional<std::string> GetAttribute(const std::string& name) const;
10643+
1062610644
std::string GetString(Platform* platform = nullptr) const;
1062710645
std::string GetTypeAndName(const QualifiedName& name) const;
1062810646
std::string GetStringBeforeName(Platform* platform = nullptr) const;

binaryninjacore.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3792,6 +3792,12 @@ extern "C"
37923792
size_t typeRefCount;
37933793
} BNAllTypeFieldReferences;
37943794

3795+
typedef struct BNTypeAttribute
3796+
{
3797+
char* name;
3798+
char* value;
3799+
} BNTypeAttribute;
3800+
37953801
BINARYNINJACOREAPI char* BNAllocString(const char* contents);
37963802
BINARYNINJACOREAPI char* BNAllocStringWithLength(const char* contents, size_t len);
37973803
BINARYNINJACOREAPI void BNFreeString(char* str);
@@ -6768,6 +6774,9 @@ extern "C"
67686774
BINARYNINJACOREAPI BNInstructionTextToken* BNGetTypePointerSuffixTokens(BNType* type, uint8_t baseConfidence, size_t* count);
67696775
BINARYNINJACOREAPI void BNFreePointerSuffixList(BNPointerSuffix* suffix, size_t count);
67706776
BINARYNINJACOREAPI bool BNTypeShouldDisplayReturnType(BNType* type);
6777+
BINARYNINJACOREAPI BNTypeAttribute* BNGetTypeAttributes(BNType* type, size_t* count);
6778+
BINARYNINJACOREAPI char* BNGetTypeAttributeByName(BNType* type, const char* name);
6779+
BINARYNINJACOREAPI void BNFreeTypeAttributeList(BNTypeAttribute* attr, size_t count);
67716780

67726781
BINARYNINJACOREAPI char* BNGetTypeString(BNType* type, BNPlatform* platform, BNTokenEscapingType escaping);
67736782
BINARYNINJACOREAPI char* BNGetTypeStringBeforeName(BNType* type, BNPlatform* platform, BNTokenEscapingType escaping);
@@ -6848,6 +6857,11 @@ extern "C"
68486857
BINARYNINJACOREAPI bool BNTypeBuilderHasTemplateArguments(BNTypeBuilder* type);
68496858
BINARYNINJACOREAPI void BNSetTypeBuilderNameType(BNTypeBuilder* type, BNNameType nameType);
68506859
BINARYNINJACOREAPI void BNSetTypeBuilderHasTemplateArguments(BNTypeBuilder* type, bool hasTemplateArguments);
6860+
BINARYNINJACOREAPI void BNSetTypeBuilderAttribute(BNTypeBuilder* type, const char* name, const char* value);
6861+
BINARYNINJACOREAPI void BNSetTypeBuilderAttributeList(BNTypeBuilder* type, BNTypeAttribute* attrs, size_t count);
6862+
BINARYNINJACOREAPI void BNRemoveTypeBuilderAttribute(BNTypeBuilder* type, const char* name);
6863+
BINARYNINJACOREAPI BNTypeAttribute* BNGetTypeBuilderAttributes(BNTypeBuilder* type, size_t* count);
6864+
BINARYNINJACOREAPI char* BNGetTypeBuilderAttributeByName(BNTypeBuilder* type, const char* name);
68516865

68526866
BINARYNINJACOREAPI char* BNGetTypeBuilderString(BNTypeBuilder* type, BNPlatform* platform);
68536867
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)