diff options
| -rw-r--r-- | binaryninjaapi.h | 175 | ||||
| -rw-r--r-- | binaryninjacore.h | 136 | ||||
| -rw-r--r-- | python/settings.py | 2 | ||||
| -rw-r--r-- | python/types.py | 395 | ||||
| -rw-r--r-- | type.cpp | 989 | ||||
| -rw-r--r-- | ui/uitypes.h | 1 |
6 files changed, 1425 insertions, 273 deletions
diff --git a/binaryninjaapi.h b/binaryninjaapi.h index 4d9ca8e5..5c11d0b8 100644 --- a/binaryninjaapi.h +++ b/binaryninjaapi.h @@ -2478,20 +2478,13 @@ __attribute__ ((format (printf, 1, 2))) Ref<Enumeration> GetEnumeration() const; Ref<NamedTypeReference> GetNamedTypeReference() const; Confidence<BNMemberScope> GetScope() const; - void SetScope(const Confidence<BNMemberScope>& scope); Confidence<BNMemberAccess> GetAccess() const; - void SetAccess(const Confidence<BNMemberAccess>& access); - void SetConst(const Confidence<bool>& cnst); - void SetVolatile(const Confidence<bool>& vltl); - void SetTypeName(const QualifiedName& name); Confidence<int64_t> GetStackAdjustment() const; QualifiedName GetStructureName() const; uint64_t GetElementCount() const; uint64_t GetOffset() const; - void SetFunctionCanReturn(const Confidence<bool>& canReturn); - std::string GetString(Platform* platform = nullptr) const; std::string GetTypeAndName(const QualifiedName& name) const; std::string GetStringBeforeName(Platform* platform = nullptr) const; @@ -2557,6 +2550,114 @@ __attribute__ ((format (printf, 1, 2))) bool IsValue() const { return GetClass() == ValueTypeClass; } bool IsNamedTypeRefer() const { return GetClass() == NamedTypeReferenceClass; } bool IsWideChar() const { return GetClass() == WideCharTypeClass; } + + Ref<Type> WithReplacedStructure(Structure* from, Structure* to); + Ref<Type> WithReplacedEnumeration(Enumeration* from, Enumeration* to); + Ref<Type> WithReplacedNamedTypeReference(NamedTypeReference* from, NamedTypeReference* to); + }; + + class TypeBuilder + { + BNTypeBuilder* m_object; + + public: + TypeBuilder(); + TypeBuilder(BNTypeBuilder* type); + TypeBuilder(const TypeBuilder& type); + TypeBuilder(TypeBuilder&& type); + TypeBuilder(Type* type); + TypeBuilder& operator=(const TypeBuilder& type); + TypeBuilder& operator=(TypeBuilder&& type); + TypeBuilder& operator=(Type* type); + + Ref<Type> Finalize(); + + BNTypeClass GetClass() const; + uint64_t GetWidth() const; + size_t GetAlignment() const; + QualifiedName GetTypeName() const; + Confidence<bool> IsSigned() const; + Confidence<bool> IsConst() const; + Confidence<bool> IsVolatile() const; + + Confidence<Ref<Type>> GetChildType() const; + Confidence<Ref<CallingConvention>> GetCallingConvention() const; + std::vector<FunctionParameter> GetParameters() const; + Confidence<bool> HasVariableArguments() const; + Confidence<bool> CanReturn() const; + Ref<Structure> GetStructure() const; + Ref<Enumeration> GetEnumeration() const; + Ref<NamedTypeReference> GetNamedTypeReference() const; + Confidence<BNMemberScope> GetScope() const; + void SetScope(const Confidence<BNMemberScope>& scope); + Confidence<BNMemberAccess> GetAccess() const; + void SetAccess(const Confidence<BNMemberAccess>& access); + void SetConst(const Confidence<bool>& cnst); + void SetVolatile(const Confidence<bool>& vltl); + void SetTypeName(const QualifiedName& name); + Confidence<int64_t> GetStackAdjustment() const; + QualifiedName GetStructureName() const; + + uint64_t GetElementCount() const; + uint64_t GetOffset() const; + + void SetFunctionCanReturn(const Confidence<bool>& canReturn); + + std::string GetString(Platform* platform = nullptr) const; + std::string GetTypeAndName(const QualifiedName& name) const; + std::string GetStringBeforeName(Platform* platform = nullptr) const; + std::string GetStringAfterName(Platform* platform = nullptr) const; + + std::vector<InstructionTextToken> GetTokens(Platform* platform = nullptr, + uint8_t baseConfidence = BN_FULL_CONFIDENCE) const; + std::vector<InstructionTextToken> GetTokensBeforeName(Platform* platform = nullptr, + uint8_t baseConfidence = BN_FULL_CONFIDENCE) const; + std::vector<InstructionTextToken> GetTokensAfterName(Platform* platform = nullptr, + uint8_t baseConfidence = BN_FULL_CONFIDENCE) const; + + static TypeBuilder VoidType(); + static TypeBuilder BoolType(); + static TypeBuilder IntegerType(size_t width, const Confidence<bool>& sign, const std::string& altName = ""); + static TypeBuilder FloatType(size_t width, const std::string& typeName = ""); + static TypeBuilder StructureType(Structure* strct); + static TypeBuilder NamedType(NamedTypeReference* ref, size_t width = 0, size_t align = 1); + static TypeBuilder NamedType(const QualifiedName& name, Type* type); + static TypeBuilder NamedType(const std::string& id, const QualifiedName& name, Type* type); + static TypeBuilder NamedType(BinaryView* view, const QualifiedName& name); + static TypeBuilder EnumerationType(Architecture* arch, Enumeration* enm, size_t width = 0, bool issigned = false); + static TypeBuilder PointerType(Architecture* arch, const Confidence<Ref<Type>>& type, + const Confidence<bool>& cnst = Confidence<bool>(false, 0), + const Confidence<bool>& vltl = Confidence<bool>(false, 0), BNReferenceType refType = PointerReferenceType); + static TypeBuilder PointerType(size_t width, const Confidence<Ref<Type>>& type, + const Confidence<bool>& cnst = Confidence<bool>(false, 0), + const Confidence<bool>& vltl = Confidence<bool>(false, 0), BNReferenceType refType = PointerReferenceType); + static TypeBuilder ArrayType(const Confidence<Ref<Type>>& type, uint64_t elem); + static TypeBuilder FunctionType(const Confidence<Ref<Type>>& returnValue, + const Confidence<Ref<CallingConvention>>& callingConvention, + const std::vector<FunctionParameter>& params, const Confidence<bool>& varArg = Confidence<bool>(false, 0), + const Confidence<int64_t>& stackAdjust = Confidence<int64_t>(0, 0)); + + bool IsReferenceOfType(BNNamedTypeReferenceClass refType); + bool IsStructReference() { return IsReferenceOfType(StructNamedTypeClass); } + bool IsEnumReference() { return IsReferenceOfType(EnumNamedTypeClass); } + bool IsUnionReference() { return IsReferenceOfType(UnionNamedTypeClass); } + bool IsClassReference() { return IsReferenceOfType(ClassNamedTypeClass); } + bool IsTypedefReference() { return IsReferenceOfType(TypedefNamedTypeClass); } + bool IsStructOrClassReference() { return IsReferenceOfType(StructNamedTypeClass) || IsReferenceOfType(ClassNamedTypeClass); } + + bool IsVoid() const { return GetClass() == VoidTypeClass; } + bool IsBool() const { return GetClass() == BoolTypeClass; } + bool IsInteger() const { return GetClass() == IntegerTypeClass; } + bool IsFloat() const { return GetClass() == FloatTypeClass; } + bool IsStructure() const { return GetClass() == StructureTypeClass; } + bool IsEnumeration() const { return GetClass() == EnumerationTypeClass; } + bool IsPointer() const { return GetClass() == PointerTypeClass; } + bool IsArray() const { return GetClass() == ArrayTypeClass; } + bool IsFunction() const { return GetClass() == FunctionTypeClass; } + bool IsVarArgs() const { return GetClass() == VarArgsTypeClass; } + bool IsValue() const { return GetClass() == ValueTypeClass; } + bool IsNamedTypeRefer() const { return GetClass() == NamedTypeReferenceClass; } + bool IsWideChar() const { return GetClass() == WideCharTypeClass; } }; class NamedTypeReference: public CoreRefCountObject<BNNamedTypeReference, BNNewNamedTypeReference, @@ -2567,11 +2668,8 @@ __attribute__ ((format (printf, 1, 2))) NamedTypeReference(BNNamedTypeReferenceClass cls = UnknownNamedTypeClass, const std::string& id = "", const QualifiedName& name = QualifiedName()); BNNamedTypeReferenceClass GetTypeClass() const; - void SetTypeClass(BNNamedTypeReferenceClass cls); std::string GetTypeId() const; - void SetTypeId(const std::string& id); QualifiedName GetName() const; - void SetName(const QualifiedName& name); static Ref<NamedTypeReference> GenerateAutoTypeReference(BNNamedTypeReferenceClass cls, const std::string& source, const QualifiedName& name); @@ -2591,13 +2689,45 @@ __attribute__ ((format (printf, 1, 2))) class Structure: public CoreRefCountObject<BNStructure, BNNewStructureReference, BNFreeStructure> { public: - Structure(); Structure(BNStructure* s); - Structure(BNStructureType type, bool packed = false); std::vector<StructureMember> GetMembers() const; bool GetMemberByName(const std::string& name, StructureMember& result) const; bool GetMemberAtOffset(int64_t offset, StructureMember& result) const; + bool GetMemberAtOffset(int64_t offset, StructureMember& result, size_t& idx) const; + uint64_t GetWidth() const; + size_t GetAlignment() const; + bool IsPacked() const; + bool IsUnion() const; + BNStructureType GetStructureType() const; + + Ref<Structure> WithReplacedStructure(Structure* from, Structure* to); + Ref<Structure> WithReplacedEnumeration(Enumeration* from, Enumeration* to); + Ref<Structure> WithReplacedNamedTypeReference(NamedTypeReference* from, NamedTypeReference* to); + }; + + class StructureBuilder + { + BNStructureBuilder* m_object; + + public: + StructureBuilder(); + StructureBuilder(BNStructureBuilder* s); + StructureBuilder(BNStructureType type, bool packed = false); + StructureBuilder(const StructureBuilder& s); + StructureBuilder(StructureBuilder&& s); + StructureBuilder(Structure* s); + ~StructureBuilder(); + StructureBuilder& operator=(const StructureBuilder& s); + StructureBuilder& operator=(StructureBuilder&& s); + StructureBuilder& operator=(Structure* s); + + Ref<Structure> Finalize() const; + + std::vector<StructureMember> GetMembers() const; + bool GetMemberByName(const std::string& name, StructureMember& result) const; + bool GetMemberAtOffset(int64_t offset, StructureMember& result) const; + bool GetMemberAtOffset(int64_t offset, StructureMember& result, size_t& idx) const; uint64_t GetWidth() const; void SetWidth(size_t width); size_t GetAlignment() const; @@ -2623,10 +2753,29 @@ __attribute__ ((format (printf, 1, 2))) class Enumeration: public CoreRefCountObject<BNEnumeration, BNNewEnumerationReference, BNFreeEnumeration> { public: - Enumeration(); Enumeration(BNEnumeration* e); std::vector<EnumerationMember> GetMembers() const; + }; + + class EnumerationBuilder + { + BNEnumerationBuilder* m_object; + + public: + EnumerationBuilder(); + EnumerationBuilder(BNEnumerationBuilder* e); + EnumerationBuilder(const EnumerationBuilder& e); + EnumerationBuilder(EnumerationBuilder&& e); + EnumerationBuilder(Enumeration* e); + ~EnumerationBuilder(); + EnumerationBuilder& operator=(const EnumerationBuilder& e); + EnumerationBuilder& operator=(EnumerationBuilder&& e); + EnumerationBuilder& operator=(Enumeration* e); + + Ref<Enumeration> Finalize() const; + + std::vector<EnumerationMember> GetMembers() const; void AddMember(const std::string& name); void AddMemberWithValue(const std::string& name, uint64_t value); diff --git a/binaryninjacore.h b/binaryninjacore.h index b584f0da..55f9bfa0 100644 --- a/binaryninjacore.h +++ b/binaryninjacore.h @@ -134,14 +134,17 @@ extern "C" struct BNLowLevelILFunction; struct BNMediumLevelILFunction; struct BNType; + struct BNTypeBuilder; struct BNTypeLibrary; struct BNTypeLibraryMapping; struct BNStructure; + struct BNStructureBuilder; struct BNTagType; struct BNTag; struct BNTagReference; struct BNNamedTypeReference; struct BNEnumeration; + struct BNEnumerationBuilder; struct BNCallingConvention; struct BNPlatform; struct BNAnalysisCompletionEvent; @@ -3526,8 +3529,27 @@ __attribute__ ((format (printf, 1, 2))) BINARYNINJACOREAPI char* BNGetTypeAndName(BNType* type, BNQualifiedName* name); BINARYNINJACOREAPI void BNFreeType(BNType* type); + BINARYNINJACOREAPI BNTypeBuilder* BNCreateTypeBuilderFromType(BNType* type); + BINARYNINJACOREAPI BNTypeBuilder* BNCreateVoidTypeBuilder(void); + BINARYNINJACOREAPI BNTypeBuilder* BNCreateBoolTypeBuilder(void); + BINARYNINJACOREAPI BNTypeBuilder* BNCreateIntegerTypeBuilder(size_t width, BNBoolWithConfidence* sign, const char* altName); + BINARYNINJACOREAPI BNTypeBuilder* BNCreateFloatTypeBuilder(size_t width, const char* altName); + BINARYNINJACOREAPI BNTypeBuilder* BNCreateStructureTypeBuilder(BNStructure* s); + BINARYNINJACOREAPI BNTypeBuilder* BNCreateEnumerationTypeBuilder(BNArchitecture* arch, BNEnumeration* e, size_t width, bool isSigned); + BINARYNINJACOREAPI BNTypeBuilder* BNCreatePointerTypeBuilder(BNArchitecture* arch, BNTypeWithConfidence* type, + BNBoolWithConfidence* cnst, BNBoolWithConfidence* vltl, BNReferenceType refType); + BINARYNINJACOREAPI BNTypeBuilder* BNCreatePointerTypeBuilderOfWidth(size_t width, BNTypeWithConfidence* type, + BNBoolWithConfidence* cnst, BNBoolWithConfidence* vltl, BNReferenceType refType); + BINARYNINJACOREAPI BNTypeBuilder* BNCreateArrayTypeBuilder(BNTypeWithConfidence* type, uint64_t elem); + BINARYNINJACOREAPI BNTypeBuilder* BNCreateFunctionTypeBuilder(BNTypeWithConfidence* returnValue, + BNCallingConventionWithConfidence* callingConvention, BNFunctionParameter* params, + size_t paramCount, BNBoolWithConfidence* varArg, BNOffsetWithConfidence* stackAdjust); + BINARYNINJACOREAPI BNType* BNFinalizeTypeBuilder(BNTypeBuilder* type); + BINARYNINJACOREAPI BNTypeBuilder* BNDuplicateTypeBuilder(BNTypeBuilder* type); + BINARYNINJACOREAPI char* BNGetTypeBuilderTypeAndName(BNTypeBuilder* type, BNQualifiedName* name); + BINARYNINJACOREAPI void BNFreeTypeBuilder(BNTypeBuilder* type); + BINARYNINJACOREAPI BNQualifiedName BNTypeGetTypeName(BNType* nt); - BINARYNINJACOREAPI void BNTypeSetTypeName(BNType* type, BNQualifiedName* name); BINARYNINJACOREAPI BNTypeClass BNGetTypeClass(BNType* type); BINARYNINJACOREAPI uint64_t BNGetTypeWidth(BNType* type); BINARYNINJACOREAPI size_t BNGetTypeAlignment(BNType* type); @@ -3546,13 +3568,8 @@ __attribute__ ((format (printf, 1, 2))) BINARYNINJACOREAPI BNNamedTypeReference* BNGetTypeNamedTypeReference(BNType* type); BINARYNINJACOREAPI uint64_t BNGetTypeElementCount(BNType* type); BINARYNINJACOREAPI uint64_t BNGetTypeOffset(BNType* type); - BINARYNINJACOREAPI void BNSetFunctionTypeCanReturn(BNType* type, BNBoolWithConfidence* canReturn); BINARYNINJACOREAPI BNMemberScopeWithConfidence BNTypeGetMemberScope(BNType* type); - BINARYNINJACOREAPI void BNTypeSetMemberScope(BNType* type, BNMemberScopeWithConfidence* scope); BINARYNINJACOREAPI BNMemberAccessWithConfidence BNTypeGetMemberAccess(BNType* type); - BINARYNINJACOREAPI void BNTypeSetMemberAccess(BNType* type, BNMemberAccessWithConfidence* access); - BINARYNINJACOREAPI void BNTypeSetConst(BNType* type, BNBoolWithConfidence* cnst); - BINARYNINJACOREAPI void BNTypeSetVolatile(BNType* type, BNBoolWithConfidence* vltl); BINARYNINJACOREAPI BNOffsetWithConfidence BNGetTypeStackAdjustment(BNType* type); BINARYNINJACOREAPI BNQualifiedName BNTypeGetStructureName(BNType* type); @@ -3566,58 +3583,125 @@ __attribute__ ((format (printf, 1, 2))) BINARYNINJACOREAPI BNInstructionTextToken* BNGetTypeTokensAfterName(BNType* type, BNPlatform* platform, uint8_t baseConfidence, size_t* count); + BINARYNINJACOREAPI BNType* BNTypeWithReplacedStructure(BNType* type, BNStructure* from, BNStructure* to); + BINARYNINJACOREAPI BNType* BNTypeWithReplacedEnumeration(BNType* type, BNEnumeration* from, BNEnumeration* to); + BINARYNINJACOREAPI BNType* BNTypeWithReplacedNamedTypeReference(BNType* type, BNNamedTypeReference* from, BNNamedTypeReference* to); + + BINARYNINJACOREAPI BNQualifiedName BNTypeBuilderGetTypeName(BNTypeBuilder* nt); + BINARYNINJACOREAPI void BNTypeBuilderSetTypeName(BNTypeBuilder* type, BNQualifiedName* name); + BINARYNINJACOREAPI BNTypeClass BNGetTypeBuilderClass(BNTypeBuilder* type); + BINARYNINJACOREAPI uint64_t BNGetTypeBuilderWidth(BNTypeBuilder* type); + BINARYNINJACOREAPI size_t BNGetTypeBuilderAlignment(BNTypeBuilder* type); + BINARYNINJACOREAPI BNBoolWithConfidence BNIsTypeBuilderSigned(BNTypeBuilder* type); + BINARYNINJACOREAPI BNBoolWithConfidence BNIsTypeBuilderConst(BNTypeBuilder* type); + BINARYNINJACOREAPI BNBoolWithConfidence BNIsTypeBuilderVolatile(BNTypeBuilder* type); + BINARYNINJACOREAPI bool BNIsTypeBuilderFloatingPoint(BNTypeBuilder* type); + BINARYNINJACOREAPI BNTypeWithConfidence BNGetTypeBuilderChildType(BNTypeBuilder* type); + BINARYNINJACOREAPI BNCallingConventionWithConfidence BNGetTypeBuilderCallingConvention(BNTypeBuilder* type); + BINARYNINJACOREAPI BNFunctionParameter* BNGetTypeBuilderParameters(BNTypeBuilder* type, size_t* count); + BINARYNINJACOREAPI BNBoolWithConfidence BNTypeBuilderHasVariableArguments(BNTypeBuilder* type); + BINARYNINJACOREAPI BNBoolWithConfidence BNFunctionTypeBuilderCanReturn(BNTypeBuilder* type); + BINARYNINJACOREAPI BNStructure* BNGetTypeBuilderStructure(BNTypeBuilder* type); + BINARYNINJACOREAPI BNEnumeration* BNGetTypeBuilderEnumeration(BNTypeBuilder* type); + BINARYNINJACOREAPI BNNamedTypeReference* BNGetTypeBuilderNamedTypeReference(BNTypeBuilder* type); + BINARYNINJACOREAPI uint64_t BNGetTypeBuilderElementCount(BNTypeBuilder* type); + BINARYNINJACOREAPI uint64_t BNGetTypeBuilderOffset(BNTypeBuilder* type); + BINARYNINJACOREAPI void BNSetFunctionTypeBuilderCanReturn(BNTypeBuilder* type, BNBoolWithConfidence* canReturn); + BINARYNINJACOREAPI BNMemberScopeWithConfidence BNTypeBuilderGetMemberScope(BNTypeBuilder* type); + BINARYNINJACOREAPI void BNTypeBuilderSetMemberScope(BNTypeBuilder* type, BNMemberScopeWithConfidence* scope); + BINARYNINJACOREAPI BNMemberAccessWithConfidence BNTypeBuilderGetMemberAccess(BNTypeBuilder* type); + BINARYNINJACOREAPI void BNTypeBuilderSetMemberAccess(BNTypeBuilder* type, BNMemberAccessWithConfidence* access); + BINARYNINJACOREAPI void BNTypeBuilderSetConst(BNTypeBuilder* type, BNBoolWithConfidence* cnst); + BINARYNINJACOREAPI void BNTypeBuilderSetVolatile(BNTypeBuilder* type, BNBoolWithConfidence* vltl); + BINARYNINJACOREAPI BNOffsetWithConfidence BNGetTypeBuilderStackAdjustment(BNTypeBuilder* type); + BINARYNINJACOREAPI BNQualifiedName BNTypeBuilderGetStructureName(BNTypeBuilder* type); + + BINARYNINJACOREAPI char* BNGetTypeBuilderString(BNTypeBuilder* type, BNPlatform* platform); + BINARYNINJACOREAPI char* BNGetTypeBuilderStringBeforeName(BNTypeBuilder* type, BNPlatform* platform); + BINARYNINJACOREAPI char* BNGetTypeBuilderStringAfterName(BNTypeBuilder* type, BNPlatform* platform); + BINARYNINJACOREAPI BNInstructionTextToken* BNGetTypeBuilderTokens(BNTypeBuilder* type, BNPlatform* platform, + uint8_t baseConfidence, size_t* count); + BINARYNINJACOREAPI BNInstructionTextToken* BNGetTypeBuilderTokensBeforeName(BNTypeBuilder* type, BNPlatform* platform, + uint8_t baseConfidence, size_t* count); + BINARYNINJACOREAPI BNInstructionTextToken* BNGetTypeBuilderTokensAfterName(BNTypeBuilder* type, BNPlatform* platform, + uint8_t baseConfidence, size_t* count); + BINARYNINJACOREAPI BNType* BNCreateNamedTypeReference(BNNamedTypeReference* nt, size_t width, size_t align); BINARYNINJACOREAPI BNType* BNCreateNamedTypeReferenceFromTypeAndId(const char* id, BNQualifiedName* name, BNType* type); BINARYNINJACOREAPI BNType* BNCreateNamedTypeReferenceFromType(BNBinaryView* view, BNQualifiedName* name); - BINARYNINJACOREAPI BNNamedTypeReference* BNCreateNamedType(void); - BINARYNINJACOREAPI void BNSetTypeReferenceClass(BNNamedTypeReference* nt, BNNamedTypeReferenceClass cls); + BINARYNINJACOREAPI BNTypeBuilder* BNCreateNamedTypeReferenceBuilder(BNNamedTypeReference* nt, size_t width, size_t align); + BINARYNINJACOREAPI BNTypeBuilder* BNCreateNamedTypeReferenceBuilderFromTypeAndId(const char* id, BNQualifiedName* name, BNType* type); + BINARYNINJACOREAPI BNTypeBuilder* BNCreateNamedTypeReferenceBuilderFromType(BNBinaryView* view, BNQualifiedName* name); + BINARYNINJACOREAPI BNNamedTypeReference* BNCreateNamedType(BNNamedTypeReferenceClass cls, const char* id, BNQualifiedName* name); BINARYNINJACOREAPI BNNamedTypeReferenceClass BNGetTypeReferenceClass(BNNamedTypeReference* nt); - BINARYNINJACOREAPI void BNSetTypeReferenceId(BNNamedTypeReference* nt, const char* id); BINARYNINJACOREAPI char* BNGetTypeReferenceId(BNNamedTypeReference* nt); - BINARYNINJACOREAPI void BNSetTypeReferenceName(BNNamedTypeReference* nt, BNQualifiedName* name); BINARYNINJACOREAPI BNQualifiedName BNGetTypeReferenceName(BNNamedTypeReference* nt); BINARYNINJACOREAPI void BNFreeQualifiedName(BNQualifiedName* name); BINARYNINJACOREAPI void BNFreeNamedTypeReference(BNNamedTypeReference* nt); BINARYNINJACOREAPI BNNamedTypeReference* BNNewNamedTypeReference(BNNamedTypeReference* nt); - BINARYNINJACOREAPI BNStructure* BNCreateStructure(void); - BINARYNINJACOREAPI BNStructure* BNCreateStructureWithOptions(BNStructureType type, bool packed); + BINARYNINJACOREAPI BNStructureBuilder* BNCreateStructureBuilder(void); + BINARYNINJACOREAPI BNStructureBuilder* BNCreateStructureBuilderWithOptions(BNStructureType type, bool packed); + BINARYNINJACOREAPI BNStructureBuilder* BNCreateStructureBuilderFromStructure(BNStructure* s); + BINARYNINJACOREAPI BNStructureBuilder* BNDuplicateStructureBuilder(BNStructureBuilder* s); + BINARYNINJACOREAPI BNStructure* BNFinalizeStructureBuilder(BNStructureBuilder* s); BINARYNINJACOREAPI BNStructure* BNNewStructureReference(BNStructure* s); BINARYNINJACOREAPI void BNFreeStructure(BNStructure* s); + BINARYNINJACOREAPI void BNFreeStructureBuilder(BNStructureBuilder* s); BINARYNINJACOREAPI BNStructureMember* BNGetStructureMemberByName(BNStructure* s, const char* name); - BINARYNINJACOREAPI BNStructureMember* BNGetStructureMemberAtOffset(BNStructure* s, int64_t offset); + BINARYNINJACOREAPI BNStructureMember* BNGetStructureMemberAtOffset(BNStructure* s, int64_t offset, size_t* idx); BINARYNINJACOREAPI void BNFreeStructureMember(BNStructureMember* s); BINARYNINJACOREAPI BNStructureMember* BNGetStructureMembers(BNStructure* s, size_t* count); BINARYNINJACOREAPI void BNFreeStructureMemberList(BNStructureMember* members, size_t count); BINARYNINJACOREAPI uint64_t BNGetStructureWidth(BNStructure* s); - BINARYNINJACOREAPI void BNSetStructureWidth(BNStructure* s, uint64_t width); BINARYNINJACOREAPI size_t BNGetStructureAlignment(BNStructure* s); - BINARYNINJACOREAPI void BNSetStructureAlignment(BNStructure* s, size_t align); BINARYNINJACOREAPI bool BNIsStructurePacked(BNStructure* s); - BINARYNINJACOREAPI void BNSetStructurePacked(BNStructure* s, bool packed); BINARYNINJACOREAPI bool BNIsStructureUnion(BNStructure* s); - BINARYNINJACOREAPI void BNSetStructureType(BNStructure* s, BNStructureType type); BINARYNINJACOREAPI BNStructureType BNGetStructureType(BNStructure* s); - BINARYNINJACOREAPI void BNAddStructureMember(BNStructure* s, BNTypeWithConfidence* type, const char* name); - BINARYNINJACOREAPI void BNAddStructureMemberAtOffset(BNStructure* s, BNTypeWithConfidence* type, + BINARYNINJACOREAPI BNStructure* BNStructureWithReplacedStructure(BNStructure* s, BNStructure* from, BNStructure* to); + BINARYNINJACOREAPI BNStructure* BNStructureWithReplacedEnumeration(BNStructure* s, BNEnumeration* from, BNEnumeration* to); + BINARYNINJACOREAPI BNStructure* BNStructureWithReplacedNamedTypeReference(BNStructure* s, + BNNamedTypeReference* from, BNNamedTypeReference* to); + + BINARYNINJACOREAPI BNStructureMember* BNGetStructureBuilderMemberByName(BNStructureBuilder* s, const char* name); + BINARYNINJACOREAPI BNStructureMember* BNGetStructureBuilderMemberAtOffset(BNStructureBuilder* s, int64_t offset, size_t* idx); + BINARYNINJACOREAPI BNStructureMember* BNGetStructureBuilderMembers(BNStructureBuilder* s, size_t* count); + BINARYNINJACOREAPI uint64_t BNGetStructureBuilderWidth(BNStructureBuilder* s); + BINARYNINJACOREAPI void BNSetStructureBuilderWidth(BNStructureBuilder* s, uint64_t width); + BINARYNINJACOREAPI size_t BNGetStructureBuilderAlignment(BNStructureBuilder* s); + BINARYNINJACOREAPI void BNSetStructureBuilderAlignment(BNStructureBuilder* s, size_t align); + BINARYNINJACOREAPI bool BNIsStructureBuilderPacked(BNStructureBuilder* s); + BINARYNINJACOREAPI void BNSetStructureBuilderPacked(BNStructureBuilder* s, bool packed); + BINARYNINJACOREAPI bool BNIsStructureBuilderUnion(BNStructureBuilder* s); + BINARYNINJACOREAPI void BNSetStructureBuilderType(BNStructureBuilder* s, BNStructureType type); + BINARYNINJACOREAPI BNStructureType BNGetStructureBuilderType(BNStructureBuilder* s); + + BINARYNINJACOREAPI void BNAddStructureBuilderMember(BNStructureBuilder* s, BNTypeWithConfidence* type, const char* name); + BINARYNINJACOREAPI void BNAddStructureBuilderMemberAtOffset(BNStructureBuilder* s, BNTypeWithConfidence* type, const char* name, uint64_t offset); - BINARYNINJACOREAPI void BNRemoveStructureMember(BNStructure* s, size_t idx); - BINARYNINJACOREAPI void BNReplaceStructureMember(BNStructure* s, size_t idx, BNTypeWithConfidence* type, + BINARYNINJACOREAPI void BNRemoveStructureBuilderMember(BNStructureBuilder* s, size_t idx); + BINARYNINJACOREAPI void BNReplaceStructureBuilderMember(BNStructureBuilder* s, size_t idx, BNTypeWithConfidence* type, const char* name); - BINARYNINJACOREAPI BNEnumeration* BNCreateEnumeration(void); + BINARYNINJACOREAPI BNEnumerationBuilder* BNCreateEnumerationBuilder(void); + BINARYNINJACOREAPI BNEnumerationBuilder* BNCreateEnumerationBuilderFromEnumeration(BNEnumeration* e); + BINARYNINJACOREAPI BNEnumerationBuilder* BNDuplicateEnumerationBuilder(BNEnumerationBuilder* e); + BINARYNINJACOREAPI BNEnumeration* BNFinalizeEnumerationBuilder(BNEnumerationBuilder* e); BINARYNINJACOREAPI BNEnumeration* BNNewEnumerationReference(BNEnumeration* e); BINARYNINJACOREAPI void BNFreeEnumeration(BNEnumeration* e); + BINARYNINJACOREAPI void BNFreeEnumerationBuilder(BNEnumerationBuilder* e); BINARYNINJACOREAPI BNEnumerationMember* BNGetEnumerationMembers(BNEnumeration* e, size_t* count); BINARYNINJACOREAPI void BNFreeEnumerationMemberList(BNEnumerationMember* members, size_t count); - BINARYNINJACOREAPI void BNAddEnumerationMember(BNEnumeration* e, const char* name); - BINARYNINJACOREAPI void BNAddEnumerationMemberWithValue(BNEnumeration* e, const char* name, uint64_t value); - BINARYNINJACOREAPI void BNRemoveEnumerationMember(BNEnumeration* e, size_t idx); - BINARYNINJACOREAPI void BNReplaceEnumerationMember(BNEnumeration* e, size_t idx, const char* name, uint64_t value); + BINARYNINJACOREAPI BNEnumerationMember* BNGetEnumerationBuilderMembers(BNEnumerationBuilder* e, size_t* count); + + BINARYNINJACOREAPI void BNAddEnumerationBuilderMember(BNEnumerationBuilder* e, const char* name); + BINARYNINJACOREAPI void BNAddEnumerationBuilderMemberWithValue(BNEnumerationBuilder* e, const char* name, uint64_t value); + BINARYNINJACOREAPI void BNRemoveEnumerationBuilderMember(BNEnumerationBuilder* e, size_t idx); + BINARYNINJACOREAPI void BNReplaceEnumerationBuilderMember(BNEnumerationBuilder* e, size_t idx, const char* name, uint64_t value); // Source code processing BINARYNINJACOREAPI bool BNPreprocessSource(const char* source, const char* fileName, char** output, char** errors, diff --git a/python/settings.py b/python/settings.py index fec4023d..f81c8eef 100644 --- a/python/settings.py +++ b/python/settings.py @@ -65,7 +65,7 @@ class Settings(object): def __init__(self, instance_id = "default", handle = None): if handle is None: - if instance_id is None or instance_id is "": + if instance_id is None or instance_id == "": instance_id = "default" self._instance_id = instance_id if instance_id == "default": diff --git a/python/types.py b/python/types.py index ed4360d6..720f8568 100644 --- a/python/types.py +++ b/python/types.py @@ -320,12 +320,16 @@ class FunctionParameter(object): class Type(object): def __init__(self, handle, platform = None, confidence = max_confidence): - self.handle = handle + self._handle = handle + self._mutable = isinstance(handle.contents, core.BNTypeBuilder) self._confidence = confidence self._platform = platform def __del__(self): - core.BNFreeType(self.handle) + if self._mutable: + core.BNFreeTypeBuilder(self._handle) + else: + core.BNFreeType(self._handle) def __eq__(self, value): if not isinstance(value, Type): @@ -338,51 +342,101 @@ class Type(object): return core.BNTypesNotEqual(self.handle, value.handle) @property + def handle(self): + if self._mutable: + # First use of a mutable Type makes it immutable + finalized = core.BNFinalizeTypeBuilder(self._handle) + core.BNFreeTypeBuilder(self._handle) + self._handle = finalized + self._mutable = False + return self._handle + + @property def type_class(self): """Type class (read-only)""" - return TypeClass(core.BNGetTypeClass(self.handle)) + if self._mutable: + return TypeClass(core.BNGetTypeBuilderClass(self._handle)) + return TypeClass(core.BNGetTypeClass(self._handle)) @property def width(self): """Type width (read-only)""" - return core.BNGetTypeWidth(self.handle) + if self._mutable: + return core.BNGetTypeBuilderWidth(self._handle) + return core.BNGetTypeWidth(self._handle) @property def alignment(self): """Type alignment (read-only)""" - return core.BNGetTypeAlignment(self.handle) + if self._mutable: + return core.BNGetTypeBuilderAlignment(self._handle) + return core.BNGetTypeAlignment(self._handle) @property def signed(self): """Wether type is signed (read-only)""" - result = core.BNIsTypeSigned(self.handle) + if self._mutable: + result = core.BNIsTypeBuilderSigned(self._handle) + else: + result = core.BNIsTypeSigned(self._handle) return BoolWithConfidence(result.value, confidence = result.confidence) @property def const(self): """Whether type is const (read/write)""" - result = core.BNIsTypeConst(self.handle) + if self._mutable: + result = core.BNIsTypeBuilderConst(self._handle) + else: + result = core.BNIsTypeConst(self._handle) return BoolWithConfidence(result.value, confidence = result.confidence) @const.setter def const(self, value): + if not self._mutable: + raise AttributeError("Finalized Type object is immutable, use mutable_copy()") + bc = core.BNBoolWithConfidence() + bc.value = bool(value) + if hasattr(value, 'confidence'): + bc.confidence = value.confidence + else: + bc.confidence = max_confidence + core.BNTypeBuilderSetConst(self._handle, bc) + + @property + def volatile(self): + """Whether type is volatile (read/write)""" + if self._mutable: + result = core.BNIsTypeBuilderVolatile(self._handle) + else: + result = core.BNIsTypeVolatile(self._handle) + return BoolWithConfidence(result.value, confidence = result.confidence) + + @volatile.setter + def volatile(self, value): + if not self._mutable: + raise AttributeError("Finalized Type object is immutable, use mutable_copy()") bc = core.BNBoolWithConfidence() bc.value = bool(value) if hasattr(value, 'confidence'): bc.confidence = value.confidence else: bc.confidence = max_confidence - core.BNTypeSetConst(self.handle, bc) + core.BNTypeBuilderSetVolatile(self._handle, bc) @property - def modified(self): - """Whether type is modified (read-only)""" - return core.BNIsTypeFloatingPoint(self.handle) + def floating_point(self): + """Whether type is floating point (read-only)""" + if self._mutable: + return core.BNIsTypeBuilderFloatingPoint(self._handle) + return core.BNIsTypeFloatingPoint(self._handle) @property def target(self): """Target (read-only)""" - result = core.BNGetChildType(self.handle) + if self._mutable: + result = core.BNGetTypeBuilderChildType(self._handle) + else: + result = core.BNGetChildType(self._handle) if not result.type: return None return Type(result.type, platform = self._platform, confidence = result.confidence) @@ -390,7 +444,10 @@ class Type(object): @property def element_type(self): """Target (read-only)""" - result = core.BNGetChildType(self.handle) + if self._mutable: + result = core.BNGetTypeBuilderChildType(self._handle) + else: + result = core.BNGetChildType(self._handle) if not result.type: return None return Type(result.type, platform = self._platform, confidence = result.confidence) @@ -398,7 +455,10 @@ class Type(object): @property def return_value(self): """Return value (read-only)""" - result = core.BNGetChildType(self.handle) + if self._mutable: + result = core.BNGetTypeBuilderChildType(self._handle) + else: + result = core.BNGetChildType(self._handle) if not result.type: return None return Type(result.type, platform = self._platform, confidence = result.confidence) @@ -406,7 +466,10 @@ class Type(object): @property def calling_convention(self): """Calling convention (read-only)""" - result = core.BNGetTypeCallingConvention(self.handle) + if self._mutable: + result = core.BNGetTypeBuilderCallingConvention(self._handle) + else: + result = core.BNGetTypeCallingConvention(self._handle) if not result.convention: return None return binaryninja.callingconvention.CallingConvention(None, handle = result.convention, confidence = result.confidence) @@ -415,7 +478,10 @@ class Type(object): def parameters(self): """Type parameters list (read-only)""" count = ctypes.c_ulonglong() - params = core.BNGetTypeParameters(self.handle, count) + if self._mutable: + params = core.BNGetTypeBuilderParameters(self._handle, count) + else: + params = core.BNGetTypeParameters(self._handle, count) result = [] for i in range(0, count.value): param_type = Type(core.BNNewTypeReference(params[i].type), platform = self._platform, confidence = params[i].typeConfidence) @@ -436,19 +502,28 @@ class Type(object): @property def has_variable_arguments(self): """Whether type has variable arguments (read-only)""" - result = core.BNTypeHasVariableArguments(self.handle) + if self._mutable: + result = core.BNTypeBuilderHasVariableArguments(self._handle) + else: + result = core.BNTypeHasVariableArguments(self._handle) return BoolWithConfidence(result.value, confidence = result.confidence) @property def can_return(self): """Whether type can return (read-only)""" - result = core.BNFunctionTypeCanReturn(self.handle) + if self._mutable: + result = core.BNFunctionTypeBuilderCanReturn(self._handle) + else: + result = core.BNFunctionTypeCanReturn(self._handle) return BoolWithConfidence(result.value, confidence = result.confidence) @property def structure(self): """Structure of the type (read-only)""" - result = core.BNGetTypeStructure(self.handle) + if self._mutable: + result = core.BNGetTypeBuilderStructure(self._handle) + else: + result = core.BNGetTypeStructure(self._handle) if result is None: return None return Structure(result) @@ -456,7 +531,10 @@ class Type(object): @property def enumeration(self): """Type enumeration (read-only)""" - result = core.BNGetTypeEnumeration(self.handle) + if self._mutable: + result = core.BNGetTypeBuilderEnumeration(self._handle) + else: + result = core.BNGetTypeEnumeration(self._handle) if result is None: return None return Enumeration(result) @@ -464,7 +542,10 @@ class Type(object): @property def named_type_reference(self): """Reference to a named type (read-only)""" - result = core.BNGetTypeNamedTypeReference(self.handle) + if self._mutable: + result = core.BNGetTypeBuilderNamedTypeReference(self._handle) + else: + result = core.BNGetTypeNamedTypeReference(self._handle) if result is None: return None return NamedTypeReference(handle = result) @@ -472,17 +553,24 @@ class Type(object): @property def count(self): """Type count (read-only)""" - return core.BNGetTypeElementCount(self.handle) + if self._mutable: + return core.BNGetTypeBuilderElementCount(self._handle) + return core.BNGetTypeElementCount(self._handle) @property def offset(self): """Offset into structure (read-only)""" - return core.BNGetTypeOffset(self.handle) + if self._mutable: + return core.BNGetTypeBuilderOffset(self._handle) + return core.BNGetTypeOffset(self._handle) @property def stack_adjustment(self): """Stack adjustment for function (read-only)""" - result = core.BNGetTypeStackAdjustment(self.handle) + if self._mutable: + result = core.BNGetTypeBuilderStackAdjustment(self._handle) + else: + result = core.BNGetTypeStackAdjustment(self._handle) return SizeWithConfidence(result.value, confidence = result.confidence) def __len__(self): @@ -492,7 +580,9 @@ class Type(object): platform = None if self._platform is not None: platform = self._platform.handle - return core.BNGetTypeString(self.handle, platform) + if self._mutable: + return core.BNGetTypeBuilderString(self._handle, platform) + return core.BNGetTypeString(self._handle, platform) def __repr__(self): if self._confidence < max_confidence: @@ -503,13 +593,17 @@ class Type(object): platform = None if self._platform is not None: platform = self._platform.handle - return core.BNGetTypeStringBeforeName(self.handle, platform) + if self._mutable: + return core.BNGetTypeBuilderStringBeforeName(self._handle, platform) + return core.BNGetTypeStringBeforeName(self._handle, platform) def get_string_after_name(self): platform = None if self._platform is not None: platform = self._platform.handle - return core.BNGetTypeStringAfterName(self.handle, platform) + if self._mutable: + return core.BNGetTypeBuilderStringAfterName(self._handle, platform) + return core.BNGetTypeStringAfterName(self._handle, platform) @property def tokens(self): @@ -521,7 +615,10 @@ class Type(object): platform = None if self._platform is not None: platform = self._platform.handle - tokens = core.BNGetTypeTokens(self.handle, platform, base_confidence, count) + if self._mutable: + tokens = core.BNGetTypeBuilderTokens(self._handle, platform, base_confidence, count) + else: + tokens = core.BNGetTypeTokens(self._handle, platform, base_confidence, count) result = binaryninja.function.InstructionTextToken.get_instruction_lines(tokens, count.value) core.BNFreeInstructionText(tokens, count.value) return result @@ -531,7 +628,10 @@ class Type(object): platform = None if self._platform is not None: platform = self._platform.handle - tokens = core.BNGetTypeTokensBeforeName(self.handle, platform, base_confidence, count) + if self._mutable: + tokens = core.BNGetTypeBuilderTokensBeforeName(self._handle, platform, base_confidence, count) + else: + tokens = core.BNGetTypeTokensBeforeName(self._handle, platform, base_confidence, count) result = binaryninja.function.InstructionTextToken.get_instruction_lines(tokens, count.value) core.BNFreeInstructionText(tokens, count.value) return result @@ -541,18 +641,21 @@ class Type(object): platform = None if self._platform is not None: platform = self._platform.handle - tokens = core.BNGetTypeTokensAfterName(self.handle, platform, base_confidence, count) + if self._mutable: + tokens = core.BNGetTypeBuilderTokensAfterName(self._handle, platform, base_confidence, count) + else: + tokens = core.BNGetTypeTokensAfterName(self._handle, platform, base_confidence, count) result = binaryninja.function.InstructionTextToken.get_instruction_lines(tokens, count.value) core.BNFreeInstructionText(tokens, count.value) return result @classmethod def void(cls): - return Type(core.BNCreateVoidType()) + return Type(core.BNCreateVoidTypeBuilder()) @classmethod def bool(self): - return Type(core.BNCreateBoolType()) + return Type(core.BNCreateBoolTypeBuilder()) @classmethod def char(self): @@ -576,7 +679,7 @@ class Type(object): sign_conf.value = sign.value sign_conf.confidence = sign.confidence - return Type(core.BNCreateIntegerType(width, sign_conf, altname)) + return Type(core.BNCreateIntegerTypeBuilder(width, sign_conf, altname)) @classmethod def float(self, width, altname=""): @@ -586,40 +689,40 @@ class Type(object): :param int width: width of the floating point number in bytes :param str altname: alternate name for type """ - return Type(core.BNCreateFloatType(width, altname)) + return Type(core.BNCreateFloatTypeBuilder(width, altname)) @classmethod def structure_type(self, structure_type): - return Type(core.BNCreateStructureType(structure_type.handle)) + return Type(core.BNCreateStructureTypeBuilder(structure_type.handle)) @classmethod def named_type(self, named_type, width = 0, align = 1): - return Type(core.BNCreateNamedTypeReference(named_type.handle, width, align)) + return Type(core.BNCreateNamedTypeReferenceBuilder(named_type.handle, width, align)) @classmethod def named_type_from_type_and_id(self, type_id, name, t): name = QualifiedName(name)._get_core_struct() if t is not None: t = t.handle - return Type(core.BNCreateNamedTypeReferenceFromTypeAndId(type_id, name, t)) + return Type(core.BNCreateNamedTypeReferenceBuilderFromTypeAndId(type_id, name, t)) @classmethod def named_type_from_type(self, name, t): name = QualifiedName(name)._get_core_struct() if t is not None: t = t.handle - return Type(core.BNCreateNamedTypeReferenceFromTypeAndId("", name, t)) + return Type(core.BNCreateNamedTypeReferenceBuilderFromTypeAndId("", name, t)) @classmethod def named_type_from_registered_type(self, view, name): name = QualifiedName(name)._get_core_struct() - return Type(core.BNCreateNamedTypeReferenceFromType(view.handle, name)) + return Type(core.BNCreateNamedTypeReferenceBuilderFromType(view.handle, name)) @classmethod def enumeration_type(self, arch, e, width=None, sign=False): if width is None: width = arch.default_int_size - return Type(core.BNCreateEnumerationType(arch.handle, e.handle, width, sign)) + return Type(core.BNCreateEnumerationTypeBuilder(arch.handle, e.handle, width, sign)) @classmethod def pointer(self, arch, t, const=None, volatile=None, ref_type=None): @@ -648,14 +751,14 @@ class Type(object): volatile_conf.value = volatile.value volatile_conf.confidence = volatile.confidence - return Type(core.BNCreatePointerType(arch.handle, type_conf, const_conf, volatile_conf, ref_type)) + return Type(core.BNCreatePointerTypeBuilder(arch.handle, type_conf, const_conf, volatile_conf, ref_type)) @classmethod def array(self, t, count): type_conf = core.BNTypeWithConfidence() type_conf.type = t.handle type_conf.confidence = t.confidence - return Type(core.BNCreateArrayType(type_conf, count)) + return Type(core.BNCreateArrayTypeBuilder(type_conf, count)) @classmethod def function(self, ret, params, calling_convention=None, variable_arguments=None, stack_adjust=None): @@ -722,7 +825,7 @@ class Type(object): stack_adjust_conf.value = stack_adjust.value stack_adjust_conf.confidence = stack_adjust.confidence - return Type(core.BNCreateFunctionType(ret_conf, conv_conf, param_buf, len(params), + return Type(core.BNCreateFunctionTypeBuilder(ret_conf, conv_conf, param_buf, len(params), vararg_conf, stack_adjust_conf)) @classmethod @@ -742,12 +845,6 @@ class Type(object): def with_confidence(self, confidence): return Type(handle = core.BNNewTypeReference(self.handle), platform = self._platform, confidence = confidence) - def __setattr__(self, name, value): - try: - object.__setattr__(self, name, value) - except AttributeError: - raise AttributeError("attribute '%s' is read only" % name) - @property def confidence(self): """ """ @@ -766,6 +863,20 @@ class Type(object): def platform(self, value): self._platform = value + def mutable_copy(self): + if self._mutable: + return Type(core.BNDuplicateTypeBuilder(self._handle), confidence = self._confidence) + return Type(core.BNCreateTypeBuilderFromType(self._handle), confidence = self._confidence) + + def with_replaced_structure(self, from_struct, to_struct): + return Type(handle = core.BNTypeWithReplacedStructure(self.handle, from_struct.handle, to_struct.handle)) + + def with_replaced_enumeration(self, from_enum, to_enum): + return Type(handle = core.BNTypeWithReplacedEnumeration(self.handle, from_enum.handle, to_enum.handle)) + + def with_replaced_named_type_reference(self, from_ref, to_ref): + return Type(handle = core.BNTypeWithReplacedNamedTypeReference(self.handle, from_ref.handle, to_ref.handle)) + class BoolWithConfidence(object): def __init__(self, value, confidence = max_confidence): @@ -942,13 +1053,9 @@ class ReferenceTypeWithConfidence(object): class NamedTypeReference(object): def __init__(self, type_class = NamedTypeReferenceClass.UnknownNamedTypeClass, type_id = None, name = None, handle = None): if handle is None: - self.handle = core.BNCreateNamedType() - core.BNSetTypeReferenceClass(self.handle, type_class) - if type_id is not None: - core.BNSetTypeReferenceId(self.handle, type_id) if name is not None: name = QualifiedName(name)._get_core_struct() - core.BNSetTypeReferenceName(self.handle, name) + self.handle = core.BNCreateNamedType(type_class, type_id, name) else: self.handle = handle @@ -969,18 +1076,10 @@ class NamedTypeReference(object): def type_class(self): return NamedTypeReferenceClass(core.BNGetTypeReferenceClass(self.handle)) - @type_class.setter - def type_class(self, value): - core.BNSetTypeReferenceClass(self.handle, value) - @property def type_id(self): return core.BNGetTypeReferenceId(self.handle) - @type_id.setter - def type_id(self, value): - core.BNSetTypeReferenceId(self.handle, value) - @property def name(self): name = core.BNGetTypeReferenceName(self.handle) @@ -988,11 +1087,6 @@ class NamedTypeReference(object): core.BNFreeQualifiedName(name) return result - @name.setter - def name(self, value): - value = QualifiedName(value)._get_core_struct() - core.BNSetTypeReferenceName(self.handle, value) - def __repr__(self): if self.type_class == NamedTypeReferenceClass.TypedefNamedTypeClass: return "<named type: typedef %s>" % str(self.name) @@ -1058,26 +1152,34 @@ class StructureMember(object): class Structure(object): def __init__(self, handle=None): if handle is None: - self.handle = core.BNCreateStructure() + self._handle = core.BNCreateStructureBuilder() + self._mutable = True else: - self.handle = handle + self._handle = handle + self._mutable = isinstance(handle.contents, core.BNStructureBuilder) def __del__(self): - core.BNFreeStructure(self.handle) + if self._mutable: + core.BNFreeStructureBuilder(self._handle) + else: + core.BNFreeStructure(self._handle) def __eq__(self, value): if not isinstance(value, Structure): return False - return ctypes.addressof(self.handle.contents) == ctypes.addressof(value.handle.contents) + return ctypes.addressof(self._handle.contents) == ctypes.addressof(value._handle.contents) def __ne__(self, value): if not isinstance(value, Structure): return True - return ctypes.addressof(self.handle.contents) != ctypes.addressof(value.handle.contents) + return ctypes.addressof(self._handle.contents) != ctypes.addressof(value._handle.contents) def __getitem__(self, name): try: - member = core.BNGetStructureMemberByName(self.handle, name) + if self._mutable: + member = core.BNGetStructureBuilderMemberByName(self._handle, name) + else: + member = core.BNGetStructureMemberByName(self._handle, name) return StructureMember(Type(core.BNNewTypeReference(member.contents.type), confidence=member.contents.typeConfidence), member.contents.name, member.contents.offset) finally: @@ -1085,17 +1187,33 @@ class Structure(object): def member_at_offset(self, offset): try: - member = core.BNGetStructureMemberAtOffset(self.handle, offset) + if self._mutable: + member = core.BNGetStructureBuilderMemberAtOffset(self._handle, offset, None) + else: + member = core.BNGetStructureMemberAtOffset(self._handle, offset, None) return StructureMember(Type(core.BNNewTypeReference(member.contents.type), confidence=member.contents.typeConfidence), member.contents.name, member.contents.offset) finally: core.BNFreeStructureMember(member) @property + def handle(self): + if self._mutable: + # First use of a mutable Structure makes it immutable + finalized = core.BNFinalizeStructureBuilder(self._handle) + core.BNFreeStructureBuilder(self._handle) + self._handle = finalized + self._mutable = False + return self._handle + + @property def members(self): """Structure member list (read-only)""" count = ctypes.c_ulonglong() - members = core.BNGetStructureMembers(self.handle, count) + if self._mutable: + members = core.BNGetStructureBuilderMembers(self._handle, count) + else: + members = core.BNGetStructureMembers(self._handle, count) try: result = [] for i in range(0, count.value): @@ -1108,70 +1226,104 @@ class Structure(object): @property def width(self): """Structure width""" - return core.BNGetStructureWidth(self.handle) + if self._mutable: + return core.BNGetStructureBuilderWidth(self._handle) + return core.BNGetStructureWidth(self._handle) @width.setter def width(self, new_width): - core.BNSetStructureWidth(self.handle, new_width) + if not self._mutable: + raise AttributeError("Finalized Structure object is immutable, use mutable_copy()") + core.BNSetStructureBuilderWidth(self._handle, new_width) @property def alignment(self): """Structure alignment""" - return core.BNGetStructureAlignment(self.handle) + if self._mutable: + return core.BNGetStructureBuilderAlignment(self._handle) + return core.BNGetStructureAlignment(self._handle) @alignment.setter def alignment(self, align): - core.BNSetStructureAlignment(self.handle, align) + if not self._mutable: + raise AttributeError("Finalized Structure object is immutable, use mutable_copy()") + core.BNSetStructureBuilderAlignment(self._handle, align) @property def packed(self): - return core.BNIsStructurePacked(self.handle) + if self._mutable: + return core.BNIsStructureBuilderPacked(self._handle) + return core.BNIsStructurePacked(self._handle) @packed.setter def packed(self, value): - core.BNSetStructurePacked(self.handle, value) + if not self._mutable: + raise AttributeError("Finalized Structure object is immutable, use mutable_copy()") + core.BNSetStructureBuilderPacked(self._handle, value) @property def union(self): - return core.BNIsStructureUnion(self.handle) + if self._mutable: + return core.BNIsStructureBuilderUnion(self._handle) + return core.BNIsStructureUnion(self._handle) @property def type(self): - return StructureType(core.BNGetStructureType(self.handle)) + if self._mutable: + return StructureType(core.BNGetStructureBuilderType(self._handle)) + return StructureType(core.BNGetStructureType(self._handle)) @type.setter def type(self, value): - core.BNSetStructureType(self.handle, value) - - def __setattr__(self, name, value): - try: - object.__setattr__(self, name, value) - except AttributeError: - raise AttributeError("attribute '%s' is read only" % name) + if not self._mutable: + raise AttributeError("Finalized Structure object is immutable, use mutable_copy()") + core.BNSetStructureBuilderType(self._handle, value) def __repr__(self): return "<struct: size %#x>" % self.width def append(self, t, name = ""): + if not self._mutable: + raise AttributeError("Finalized Structure object is immutable, use mutable_copy()") tc = core.BNTypeWithConfidence() tc.type = t.handle tc.confidence = t.confidence - core.BNAddStructureMember(self.handle, tc, name) + core.BNAddStructureBuilderMember(self._handle, tc, name) def insert(self, offset, t, name = ""): + if not self._mutable: + raise AttributeError("Finalized Structure object is immutable, use mutable_copy()") tc = core.BNTypeWithConfidence() tc.type = t.handle tc.confidence = t.confidence - core.BNAddStructureMemberAtOffset(self.handle, tc, name, offset) + core.BNAddStructureBuilderMemberAtOffset(self._handle, tc, name, offset) def remove(self, i): - core.BNRemoveStructureMember(self.handle, i) + if not self._mutable: + raise AttributeError("Finalized Structure object is immutable, use mutable_copy()") + core.BNRemoveStructureBuilderMember(self._handle, i) def replace(self, i, t, name = ""): + if not self._mutable: + raise AttributeError("Finalized Structure object is immutable, use mutable_copy()") tc = core.BNTypeWithConfidence() tc.type = t.handle tc.confidence = t.confidence - core.BNReplaceStructureMember(self.handle, i, tc, name) + core.BNReplaceStructureBuilderMember(self._handle, i, tc, name) + + def mutable_copy(self): + if self._mutable: + return Structure(core.BNDuplicateStructureBuilder(self._handle)) + return Structure(core.BNCreateStructureBuilderFromStructure(self._handle)) + + def with_replaced_structure(self, from_struct, to_struct): + return Structure(core.BNStructureWithReplacedStructure(self.handle, from_struct.handle, to_struct.handle)) + + def with_replaced_enumeration(self, from_enum, to_enum): + return Structure(core.BNStructureWithReplacedEnumeration(self.handle, from_enum.handle, to_enum.handle)) + + def with_replaced_named_type_reference(self, from_ref, to_ref): + return Structure(core.BNStructureWithReplacedNamedTypeReference(self.handle, from_ref.handle, to_ref.handle)) class EnumerationMember(object): @@ -1214,54 +1366,77 @@ class EnumerationMember(object): class Enumeration(object): def __init__(self, handle=None): if handle is None: - self.handle = core.BNCreateEnumeration() + self._handle = core.BNCreateEnumerationBuilder() + self._mutable = True else: - self.handle = handle + self._handle = handle + self._mutable = isinstance(handle.contents, core.BNEnumerationBuilder) def __del__(self): - core.BNFreeEnumeration(self.handle) + if self._mutable: + core.BNFreeEnumerationBuilder(self._handle) + else: + core.BNFreeEnumeration(self._handle) def __eq__(self, value): if not isinstance(value, Enumeration): return False - return ctypes.addressof(self.handle.contents) == ctypes.addressof(value.handle.contents) + return ctypes.addressof(self._handle.contents) == ctypes.addressof(value._handle.contents) def __ne__(self, value): if not isinstance(value, Enumeration): return True - return ctypes.addressof(self.handle.contents) != ctypes.addressof(value.handle.contents) + return ctypes.addressof(self._handle.contents) != ctypes.addressof(value._handle.contents) + + @property + def handle(self): + if self._mutable: + # First use of a mutable Enumeration makes it immutable + finalized = core.BNFinalizeEnumerationBuilder(self._handle) + core.BNFreeEnumerationBuilder(self._handle) + self._handle = finalized + self._mutable = False + return self._handle @property def members(self): """Enumeration member list (read-only)""" count = ctypes.c_ulonglong() - members = core.BNGetEnumerationMembers(self.handle, count) + if self._mutable: + members = core.BNGetEnumerationBuilderMembers(self._handle, count) + else: + members = core.BNGetEnumerationMembers(self._handle, count) result = [] for i in range(0, count.value): result.append(EnumerationMember(members[i].name, members[i].value, members[i].isDefault)) core.BNFreeEnumerationMemberList(members, count.value) return result - def __setattr__(self, name, value): - try: - object.__setattr__(self, name, value) - except AttributeError: - raise AttributeError("attribute '%s' is read only" % name) - def __repr__(self): return "<enum: %s>" % repr(self.members) def append(self, name, value = None): + if not self._mutable: + raise AttributeError("Finalized Enumeration object is immutable, use mutable_copy()") if value is None: - core.BNAddEnumerationMember(self.handle, name) + core.BNAddEnumerationBuilderMember(self._handle, name) else: - core.BNAddEnumerationMemberWithValue(self.handle, name, value) + core.BNAddEnumerationBuilderMemberWithValue(self._handle, name, value) def remove(self, i): - core.BNRemoveEnumerationMember(self.handle, i) + if not self._mutable: + raise AttributeError("Finalized Enumeration object is immutable, use mutable_copy()") + core.BNRemoveEnumerationBuilderMember(self._handle, i) def replace(self, i, name, value): - core.BNReplaceEnumerationMember(self.handle, i, name, value) + if not self._mutable: + raise AttributeError("Finalized Enumeration object is immutable, use mutable_copy()") + core.BNReplaceEnumerationBuilderMember(self._handle, i, name, value) + + def mutable_copy(self): + if self._mutable: + return Enumeration(core.BNDuplicateEnumerationBuilder(self._handle)) + return Enumeration(core.BNCreateEnumerationBuilderFromEnumeration(self._handle)) class TypeParserResult(object): @@ -496,15 +496,6 @@ Confidence<BNMemberScope> Type::GetScope() const } -void Type::SetScope(const Confidence<BNMemberScope>& scope) -{ - BNMemberScopeWithConfidence mc; - mc.value = scope.GetValue(); - mc.confidence = scope.GetConfidence(); - return BNTypeSetMemberScope(m_object, &mc); -} - - Confidence<BNMemberAccess> Type::GetAccess() const { BNMemberAccessWithConfidence result = BNTypeGetMemberAccess(m_object); @@ -512,33 +503,6 @@ Confidence<BNMemberAccess> Type::GetAccess() const } -void Type::SetAccess(const Confidence<BNMemberAccess>& access) -{ - BNMemberAccessWithConfidence mc; - mc.value = access.GetValue(); - mc.confidence = access.GetConfidence(); - return BNTypeSetMemberAccess(m_object, &mc); -} - - -void Type::SetConst(const Confidence<bool>& cnst) -{ - BNBoolWithConfidence bc; - bc.value = cnst.GetValue(); - bc.confidence = cnst.GetConfidence(); - BNTypeSetConst(m_object, &bc); -} - - -void Type::SetVolatile(const Confidence<bool>& vltl) -{ - BNBoolWithConfidence bc; - bc.value = vltl.GetValue(); - bc.confidence = vltl.GetConfidence(); - BNTypeSetVolatile(m_object, &bc); -} - - Confidence<Ref<Type>> Type::GetChildType() const { BNTypeWithConfidence type = BNGetChildType(m_object); @@ -868,15 +832,6 @@ Ref<Type> Type::FunctionType(const Confidence<Ref<Type>>& returnValue, } -void Type::SetFunctionCanReturn(const Confidence<bool>& canReturn) -{ - BNBoolWithConfidence bc; - bc.value = canReturn.GetValue(); - bc.confidence = canReturn.GetConfidence(); - BNSetFunctionTypeCanReturn(m_object, &bc); -} - - string Type::GenerateAutoTypeId(const string& source, const QualifiedName& name) { BNQualifiedName nameObj = name.GetAPIObject(); @@ -943,14 +898,6 @@ QualifiedName Type::GetTypeName() const } -void Type::SetTypeName(const QualifiedName& names) -{ - BNQualifiedName nameObj = names.GetAPIObject(); - BNTypeSetTypeName(m_object, &nameObj); - QualifiedName::FreeAPIObject(&nameObj); -} - - Confidence<Ref<Type>> Type::WithConfidence(uint8_t conf) { return Confidence<Ref<Type>>(this, conf); @@ -966,64 +913,580 @@ QualifiedName Type::GetStructureName() const } -NamedTypeReference::NamedTypeReference(BNNamedTypeReference* nt) +Ref<Type> Type::WithReplacedStructure(Structure* from, Structure* to) { - m_object = nt; + BNType* result = BNTypeWithReplacedStructure(m_object, from->GetObject(), to->GetObject()); + if (result == m_object) + { + BNFreeType(result); + return this; + } + return new Type(result); } -NamedTypeReference::NamedTypeReference(BNNamedTypeReferenceClass cls, const string& id, const QualifiedName& names) +Ref<Type> Type::WithReplacedEnumeration(Enumeration* from, Enumeration* to) { - m_object = BNCreateNamedType(); - BNSetTypeReferenceClass(m_object, cls); - if (id.size() != 0) + BNType* result = BNTypeWithReplacedEnumeration(m_object, from->GetObject(), to->GetObject()); + if (result == m_object) { - BNSetTypeReferenceId(m_object, id.c_str()); + BNFreeType(result); + return this; } - if (names.size() != 0) + return new Type(result); +} + + +Ref<Type> Type::WithReplacedNamedTypeReference(NamedTypeReference* from, NamedTypeReference* to) +{ + BNType* result = BNTypeWithReplacedNamedTypeReference(m_object, from->GetObject(), to->GetObject()); + if (result == m_object) { - BNQualifiedName nameObj = names.GetAPIObject(); - BNSetTypeReferenceName(m_object, &nameObj); - QualifiedName::FreeAPIObject(&nameObj); + BNFreeType(result); + return this; } + return new Type(result); } -void NamedTypeReference::SetTypeClass(BNNamedTypeReferenceClass cls) +TypeBuilder::TypeBuilder() { - BNSetTypeReferenceClass(m_object, cls); + m_object = BNCreateVoidTypeBuilder(); } -BNNamedTypeReferenceClass NamedTypeReference::GetTypeClass() const +TypeBuilder::TypeBuilder(BNTypeBuilder* type) { - return BNGetTypeReferenceClass(m_object); + m_object = type; } -string NamedTypeReference::GetTypeId() const +TypeBuilder::TypeBuilder(const TypeBuilder& type) { - char* str = BNGetTypeReferenceId(m_object); + m_object = BNDuplicateTypeBuilder(type.m_object); +} + + +TypeBuilder::TypeBuilder(TypeBuilder&& type) +{ + m_object = type.m_object; + type.m_object = BNCreateVoidTypeBuilder(); +} + + +TypeBuilder::TypeBuilder(Type* type) +{ + m_object = BNCreateTypeBuilderFromType(type->GetObject()); +} + + +TypeBuilder& TypeBuilder::operator=(const TypeBuilder& type) +{ + if (this != &type) + { + BNFreeTypeBuilder(m_object); + m_object = BNDuplicateTypeBuilder(type.m_object); + } + return *this; +} + + +TypeBuilder& TypeBuilder::operator=(TypeBuilder&& type) +{ + std::swap(m_object, type.m_object); + return *this; +} + + +TypeBuilder& TypeBuilder::operator=(Type* type) +{ + BNFreeTypeBuilder(m_object); + m_object = BNCreateTypeBuilderFromType(type->GetObject()); + return *this; +} + + +Ref<Type> TypeBuilder::Finalize() +{ + return new Type(BNFinalizeTypeBuilder(m_object)); +} + + +BNTypeClass TypeBuilder::GetClass() const +{ + return BNGetTypeBuilderClass(m_object); +} + + +uint64_t TypeBuilder::GetWidth() const +{ + return BNGetTypeBuilderWidth(m_object); +} + + +size_t TypeBuilder::GetAlignment() const +{ + return BNGetTypeBuilderAlignment(m_object); +} + + +Confidence<bool> TypeBuilder::IsSigned() const +{ + BNBoolWithConfidence result = BNIsTypeBuilderSigned(m_object); + return Confidence<bool>(result.value, result.confidence); +} + + +Confidence<bool> TypeBuilder::IsConst() const +{ + BNBoolWithConfidence result = BNIsTypeBuilderConst(m_object); + return Confidence<bool>(result.value, result.confidence); +} + + +Confidence<BNMemberScope> TypeBuilder::GetScope() const +{ + BNMemberScopeWithConfidence result = BNTypeBuilderGetMemberScope(m_object); + return Confidence<BNMemberScope>(result.value, result.confidence); +} + + +void TypeBuilder::SetScope(const Confidence<BNMemberScope>& scope) +{ + BNMemberScopeWithConfidence mc; + mc.value = scope.GetValue(); + mc.confidence = scope.GetConfidence(); + return BNTypeBuilderSetMemberScope(m_object, &mc); +} + + +Confidence<BNMemberAccess> TypeBuilder::GetAccess() const +{ + BNMemberAccessWithConfidence result = BNTypeBuilderGetMemberAccess(m_object); + return Confidence<BNMemberAccess>(result.value, result.confidence); +} + + +void TypeBuilder::SetAccess(const Confidence<BNMemberAccess>& access) +{ + BNMemberAccessWithConfidence mc; + mc.value = access.GetValue(); + mc.confidence = access.GetConfidence(); + return BNTypeBuilderSetMemberAccess(m_object, &mc); +} + + +void TypeBuilder::SetConst(const Confidence<bool>& cnst) +{ + BNBoolWithConfidence bc; + bc.value = cnst.GetValue(); + bc.confidence = cnst.GetConfidence(); + BNTypeBuilderSetConst(m_object, &bc); +} + + +void TypeBuilder::SetVolatile(const Confidence<bool>& vltl) +{ + BNBoolWithConfidence bc; + bc.value = vltl.GetValue(); + bc.confidence = vltl.GetConfidence(); + BNTypeBuilderSetVolatile(m_object, &bc); +} + + +Confidence<Ref<Type>> TypeBuilder::GetChildType() const +{ + BNTypeWithConfidence type = BNGetTypeBuilderChildType(m_object); + if (type.type) + return Confidence<Ref<Type>>(new Type(type.type), type.confidence); + return nullptr; +} + + +Confidence<Ref<CallingConvention>> TypeBuilder::GetCallingConvention() const +{ + BNCallingConventionWithConfidence cc = BNGetTypeBuilderCallingConvention(m_object); + if (cc.convention) + return Confidence<Ref<CallingConvention>>(new CoreCallingConvention(cc.convention), cc.confidence); + return nullptr; +} + + +vector<FunctionParameter> TypeBuilder::GetParameters() const +{ + size_t count; + BNFunctionParameter* types = BNGetTypeBuilderParameters(m_object, &count); + + vector<FunctionParameter> result; + result.reserve(count); + for (size_t i = 0; i < count; i++) + { + FunctionParameter param; + param.name = types[i].name; + param.type = Confidence<Ref<Type>>(new Type(BNNewTypeReference(types[i].type)), types[i].typeConfidence); + param.defaultLocation = types[i].defaultLocation; + param.location.type = types[i].location.type; + param.location.index = types[i].location.index; + param.location.storage = types[i].location.storage; + result.push_back(param); + } + + BNFreeTypeParameterList(types, count); + return result; +} + + +Confidence<bool> TypeBuilder::HasVariableArguments() const +{ + BNBoolWithConfidence result = BNTypeBuilderHasVariableArguments(m_object); + return Confidence<bool>(result.value, result.confidence); +} + + +Confidence<bool> TypeBuilder::CanReturn() const +{ + BNBoolWithConfidence result = BNFunctionTypeBuilderCanReturn(m_object); + return Confidence<bool>(result.value, result.confidence); +} + + +Ref<Structure> TypeBuilder::GetStructure() const +{ + BNStructure* s = BNGetTypeBuilderStructure(m_object); + if (s) + return new Structure(s); + return nullptr; +} + + +Ref<Enumeration> TypeBuilder::GetEnumeration() const +{ + BNEnumeration* e = BNGetTypeBuilderEnumeration(m_object); + if (e) + return new Enumeration(e); + return nullptr; +} + + +Ref<NamedTypeReference> TypeBuilder::GetNamedTypeReference() const +{ + BNNamedTypeReference* ref = BNGetTypeBuilderNamedTypeReference(m_object); + if (ref) + return new NamedTypeReference(ref); + return nullptr; +} + + +uint64_t TypeBuilder::GetElementCount() const +{ + return BNGetTypeBuilderElementCount(m_object); +} + + +uint64_t TypeBuilder::GetOffset() const +{ + return BNGetTypeBuilderOffset(m_object); +} + + +Confidence<int64_t> TypeBuilder::GetStackAdjustment() const +{ + BNOffsetWithConfidence result = BNGetTypeBuilderStackAdjustment(m_object); + return Confidence<int64_t>(result.value, result.confidence); +} + + +string TypeBuilder::GetString(Platform* platform) const +{ + char* str = BNGetTypeBuilderString(m_object, platform ? platform->GetObject() : nullptr); + string result = str; + BNFreeString(str); + return result; +} + + +string TypeBuilder::GetTypeAndName(const QualifiedName& nameList) const +{ + BNQualifiedName name = nameList.GetAPIObject(); + char* outName = BNGetTypeBuilderTypeAndName(m_object, &name); + QualifiedName::FreeAPIObject(&name); + return outName; +} + +string TypeBuilder::GetStringBeforeName(Platform* platform) const +{ + char* str = BNGetTypeBuilderStringBeforeName(m_object, platform ? platform->GetObject() : nullptr); string result = str; BNFreeString(str); return result; } -void NamedTypeReference::SetTypeId(const string& id) +string TypeBuilder::GetStringAfterName(Platform* platform) const +{ + char* str = BNGetTypeBuilderStringAfterName(m_object, platform ? platform->GetObject() : nullptr); + string result = str; + BNFreeString(str); + return result; +} + + +vector<InstructionTextToken> TypeBuilder::GetTokens(Platform* platform, uint8_t baseConfidence) const +{ + size_t count; + BNInstructionTextToken* tokens = BNGetTypeBuilderTokens(m_object, + platform ? platform->GetObject() : nullptr, baseConfidence, &count); + + return InstructionTextToken::ConvertAndFreeInstructionTextTokenList(tokens, count); +} + + +vector<InstructionTextToken> TypeBuilder::GetTokensBeforeName(Platform* platform, uint8_t baseConfidence) const +{ + size_t count; + BNInstructionTextToken* tokens = BNGetTypeBuilderTokensBeforeName(m_object, + platform ? platform->GetObject() : nullptr, baseConfidence, &count); + return InstructionTextToken::ConvertAndFreeInstructionTextTokenList(tokens, count); +} + + +vector<InstructionTextToken> TypeBuilder::GetTokensAfterName(Platform* platform, uint8_t baseConfidence) const +{ + size_t count; + BNInstructionTextToken* tokens = BNGetTypeBuilderTokensAfterName(m_object, + platform ? platform->GetObject() : nullptr, baseConfidence, &count); + + return InstructionTextToken::ConvertAndFreeInstructionTextTokenList(tokens, count); +} + + +TypeBuilder TypeBuilder::VoidType() { - BNSetTypeReferenceId(m_object, id.c_str()); + return TypeBuilder(BNCreateVoidTypeBuilder()); } -void NamedTypeReference::SetName(const QualifiedName& names) +TypeBuilder TypeBuilder::BoolType() +{ + return TypeBuilder(BNCreateBoolTypeBuilder()); +} + + +TypeBuilder TypeBuilder::IntegerType(size_t width, const Confidence<bool>& sign, const string& altName) +{ + BNBoolWithConfidence bc; + bc.value = sign.GetValue(); + bc.confidence = sign.GetConfidence(); + return TypeBuilder(BNCreateIntegerTypeBuilder(width, &bc, altName.c_str())); +} + + +TypeBuilder TypeBuilder::FloatType(size_t width, const string& altName) +{ + return TypeBuilder(BNCreateFloatTypeBuilder(width, altName.c_str())); +} + + +TypeBuilder TypeBuilder::StructureType(Structure* strct) +{ + return TypeBuilder(BNCreateStructureTypeBuilder(strct->GetObject())); +} + + +TypeBuilder TypeBuilder::NamedType(NamedTypeReference* ref, size_t width, size_t align) +{ + return TypeBuilder(BNCreateNamedTypeReferenceBuilder(ref->GetObject(), width, align)); +} + + +TypeBuilder TypeBuilder::NamedType(const QualifiedName& name, Type* type) +{ + return NamedType("", name, type); +} + + +TypeBuilder TypeBuilder::NamedType(const string& id, const QualifiedName& name, Type* type) +{ + BNQualifiedName nameObj = name.GetAPIObject(); + BNTypeBuilder* coreObj = BNCreateNamedTypeReferenceBuilderFromTypeAndId(id.c_str(), &nameObj, + type ? type->GetObject() : nullptr); + QualifiedName::FreeAPIObject(&nameObj); + return coreObj ? TypeBuilder(coreObj) : VoidType(); +} + + +TypeBuilder TypeBuilder::NamedType(BinaryView* view, const QualifiedName& name) +{ + BNQualifiedName nameObj = name.GetAPIObject(); + BNTypeBuilder* coreObj = BNCreateNamedTypeReferenceBuilderFromType(view->GetObject(), &nameObj); + QualifiedName::FreeAPIObject(&nameObj); + return coreObj ? TypeBuilder(coreObj) : VoidType(); +} + + +TypeBuilder TypeBuilder::EnumerationType(Architecture* arch, Enumeration* enm, size_t width, bool isSigned) +{ + return TypeBuilder(BNCreateEnumerationTypeBuilder(arch->GetObject(), enm->GetObject(), width, isSigned)); +} + + +TypeBuilder TypeBuilder::PointerType(Architecture* arch, const Confidence<Ref<Type>>& type, + const Confidence<bool>& cnst, const Confidence<bool>& vltl, BNReferenceType refType) +{ + BNTypeWithConfidence typeConf; + typeConf.type = type->GetObject(); + typeConf.confidence = type.GetConfidence(); + + BNBoolWithConfidence cnstConf; + cnstConf.value = cnst.GetValue(); + cnstConf.confidence = cnst.GetConfidence(); + + BNBoolWithConfidence vltlConf; + vltlConf.value = vltl.GetValue(); + vltlConf.confidence = vltl.GetConfidence(); + + return TypeBuilder(BNCreatePointerTypeBuilder(arch->GetObject(), &typeConf, &cnstConf, &vltlConf, refType)); +} + + +TypeBuilder TypeBuilder::PointerType(size_t width, const Confidence<Ref<Type>>& type, + const Confidence<bool>& cnst, const Confidence<bool>& vltl, BNReferenceType refType) +{ + BNTypeWithConfidence typeConf; + typeConf.type = type->GetObject(); + typeConf.confidence = type.GetConfidence(); + + BNBoolWithConfidence cnstConf; + cnstConf.value = cnst.GetValue(); + cnstConf.confidence = cnst.GetConfidence(); + + BNBoolWithConfidence vltlConf; + vltlConf.value = vltl.GetValue(); + vltlConf.confidence = vltl.GetConfidence(); + + return TypeBuilder(BNCreatePointerTypeBuilderOfWidth(width, &typeConf, &cnstConf, &vltlConf, refType)); +} + + +TypeBuilder TypeBuilder::ArrayType(const Confidence<Ref<Type>>& type, uint64_t elem) +{ + BNTypeWithConfidence typeConf; + typeConf.type = type->GetObject(); + typeConf.confidence = type.GetConfidence(); + return TypeBuilder(BNCreateArrayTypeBuilder(&typeConf, elem)); +} + + +TypeBuilder TypeBuilder::FunctionType(const Confidence<Ref<Type>>& returnValue, + const Confidence<Ref<CallingConvention>>& callingConvention, + const std::vector<FunctionParameter>& params, const Confidence<bool>& varArg, + const Confidence<int64_t>& stackAdjust) +{ + BNTypeWithConfidence returnValueConf; + returnValueConf.type = returnValue->GetObject(); + returnValueConf.confidence = returnValue.GetConfidence(); + + BNCallingConventionWithConfidence callingConventionConf; + callingConventionConf.convention = callingConvention ? callingConvention->GetObject() : nullptr; + callingConventionConf.confidence = callingConvention.GetConfidence(); + + BNFunctionParameter* paramArray = new BNFunctionParameter[params.size()]; + for (size_t i = 0; i < params.size(); i++) + { + paramArray[i].name = (char*)params[i].name.c_str(); + paramArray[i].type = params[i].type->GetObject(); + paramArray[i].typeConfidence = params[i].type.GetConfidence(); + paramArray[i].defaultLocation = params[i].defaultLocation; + paramArray[i].location.type = params[i].location.type; + paramArray[i].location.index = params[i].location.index; + paramArray[i].location.storage = params[i].location.storage; + } + + BNBoolWithConfidence varArgConf; + varArgConf.value = varArg.GetValue(); + varArgConf.confidence = varArg.GetConfidence(); + + BNOffsetWithConfidence stackAdjustConf; + stackAdjustConf.value = stackAdjust.GetValue(); + stackAdjustConf.confidence = stackAdjust.GetConfidence(); + + TypeBuilder type(BNCreateFunctionTypeBuilder(&returnValueConf, &callingConventionConf, + paramArray, params.size(), &varArgConf, &stackAdjustConf)); + delete[] paramArray; + return type; +} + + +void TypeBuilder::SetFunctionCanReturn(const Confidence<bool>& canReturn) +{ + BNBoolWithConfidence bc; + bc.value = canReturn.GetValue(); + bc.confidence = canReturn.GetConfidence(); + BNSetFunctionTypeBuilderCanReturn(m_object, &bc); +} + + +bool TypeBuilder::IsReferenceOfType(BNNamedTypeReferenceClass refType) +{ + return (GetClass() == NamedTypeReferenceClass) && (GetNamedTypeReference()->GetTypeClass() == refType); +} + + +QualifiedName TypeBuilder::GetTypeName() const +{ + BNQualifiedName name = BNTypeBuilderGetTypeName(m_object); + QualifiedName result = QualifiedName::FromAPIObject(&name); + BNFreeQualifiedName(&name); + return result; +} + + +void TypeBuilder::SetTypeName(const QualifiedName& names) +{ + BNQualifiedName nameObj = names.GetAPIObject(); + BNTypeBuilderSetTypeName(m_object, &nameObj); + QualifiedName::FreeAPIObject(&nameObj); +} + + +QualifiedName TypeBuilder::GetStructureName() const +{ + BNQualifiedName name = BNTypeBuilderGetStructureName(m_object); + QualifiedName result = QualifiedName::FromAPIObject(&name); + BNFreeQualifiedName(&name); + return result; +} + + +NamedTypeReference::NamedTypeReference(BNNamedTypeReference* nt) +{ + m_object = nt; +} + + +NamedTypeReference::NamedTypeReference(BNNamedTypeReferenceClass cls, const string& id, const QualifiedName& names) { BNQualifiedName nameObj = names.GetAPIObject(); - BNSetTypeReferenceName(m_object, &nameObj); + m_object = BNCreateNamedType(cls, id.c_str(), &nameObj); QualifiedName::FreeAPIObject(&nameObj); } +BNNamedTypeReferenceClass NamedTypeReference::GetTypeClass() const +{ + return BNGetTypeReferenceClass(m_object); +} + + +string NamedTypeReference::GetTypeId() const +{ + char* str = BNGetTypeReferenceId(m_object); + string result = str; + BNFreeString(str); + return result; +} + + QualifiedName NamedTypeReference::GetName() const { BNQualifiedName name = BNGetTypeReferenceName(m_object); @@ -1057,18 +1520,6 @@ Ref<NamedTypeReference> NamedTypeReference::GenerateAutoDebugTypeReference(BNNam } -Structure::Structure() -{ - m_object = BNCreateStructure(); -} - - -Structure::Structure(BNStructureType type, bool packed) -{ - m_object = BNCreateStructureWithOptions(type, packed); -} - - Structure::Structure(BNStructure* s) { m_object = s; @@ -1113,7 +1564,14 @@ bool Structure::GetMemberByName(const string& name, StructureMember& result) con bool Structure::GetMemberAtOffset(int64_t offset, StructureMember& result) const { - BNStructureMember* member = BNGetStructureMemberAtOffset(m_object, offset); + size_t i; + return GetMemberAtOffset(offset, result, i); +} + + +bool Structure::GetMemberAtOffset(int64_t offset, StructureMember& result, size_t& idx) const +{ + BNStructureMember* member = BNGetStructureMemberAtOffset(m_object, offset, &idx); if (member) { result.type = new Type(BNNewTypeReference(member->type)); @@ -1132,84 +1590,284 @@ uint64_t Structure::GetWidth() const } -void Structure::SetWidth(size_t width) +size_t Structure::GetAlignment() const { - BNSetStructureWidth(m_object, width); + return BNGetStructureAlignment(m_object); } -size_t Structure::GetAlignment() const +bool Structure::IsPacked() const { - return BNGetStructureAlignment(m_object); + return BNIsStructurePacked(m_object); } -void Structure::SetAlignment(size_t align) +bool Structure::IsUnion() const { - BNSetStructureAlignment(m_object, align); + return BNIsStructureUnion(m_object); } -bool Structure::IsPacked() const +BNStructureType Structure::GetStructureType() const { - return BNIsStructurePacked(m_object); + return BNGetStructureType(m_object); } -void Structure::SetPacked(bool packed) +Ref<Structure> Structure::WithReplacedStructure(Structure* from, Structure* to) { - BNSetStructurePacked(m_object, packed); + BNStructure* result = BNStructureWithReplacedStructure(m_object, from->GetObject(), to->GetObject()); + if (result == m_object) + { + BNFreeStructure(result); + return this; + } + return new Structure(result); } -bool Structure::IsUnion() const +Ref<Structure> Structure::WithReplacedEnumeration(Enumeration* from, Enumeration* to) { - return BNIsStructureUnion(m_object); + BNStructure* result = BNStructureWithReplacedEnumeration(m_object, from->GetObject(), to->GetObject()); + if (result == m_object) + { + BNFreeStructure(result); + return this; + } + return new Structure(result); } -void Structure::SetStructureType(BNStructureType t) +Ref<Structure> Structure::WithReplacedNamedTypeReference(NamedTypeReference* from, NamedTypeReference* to) { - BNSetStructureType(m_object, t); + BNStructure* result = BNStructureWithReplacedNamedTypeReference(m_object, from->GetObject(), to->GetObject()); + if (result == m_object) + { + BNFreeStructure(result); + return this; + } + return new Structure(result); } -BNStructureType Structure::GetStructureType() const +StructureBuilder::StructureBuilder() { - return BNGetStructureType(m_object); + m_object = BNCreateStructureBuilder(); +} + + +StructureBuilder::StructureBuilder(BNStructureBuilder* s) +{ + m_object = s; +} + + +StructureBuilder::StructureBuilder(BNStructureType type, bool packed) +{ + m_object = BNCreateStructureBuilderWithOptions(type, packed); +} + + +StructureBuilder::StructureBuilder(const StructureBuilder& s) +{ + m_object = BNDuplicateStructureBuilder(s.m_object); +} + + +StructureBuilder::StructureBuilder(StructureBuilder&& s) +{ + m_object = s.m_object; + s.m_object = BNCreateStructureBuilder(); } -void Structure::AddMember(const Confidence<Ref<Type>>& type, const string& name) +StructureBuilder::StructureBuilder(Structure* s) +{ + m_object = BNCreateStructureBuilderFromStructure(s->GetObject()); +} + + +StructureBuilder::~StructureBuilder() +{ + BNFreeStructureBuilder(m_object); +} + + +StructureBuilder& StructureBuilder::operator=(const StructureBuilder& s) +{ + if (this != &s) + { + BNFreeStructureBuilder(m_object); + m_object = BNDuplicateStructureBuilder(s.m_object); + } + return *this; +} + + +StructureBuilder& StructureBuilder::operator=(StructureBuilder&& s) +{ + if (this != &s) + std::swap(m_object, s.m_object); + return *this; +} + + +StructureBuilder& StructureBuilder::operator=(Structure* s) +{ + BNFreeStructureBuilder(m_object); + m_object = BNCreateStructureBuilderFromStructure(s->GetObject()); + return *this; +} + + +Ref<Structure> StructureBuilder::Finalize() const +{ + return new Structure(BNFinalizeStructureBuilder(m_object)); +} + + +vector<StructureMember> StructureBuilder::GetMembers() const +{ + size_t count; + BNStructureMember* members = BNGetStructureBuilderMembers(m_object, &count); + + vector<StructureMember> result; + result.reserve(count); + for (size_t i = 0; i < count; i++) + { + StructureMember member; + member.type = new Type(BNNewTypeReference(members[i].type)); + member.name = members[i].name; + member.offset = members[i].offset; + result.push_back(member); + } + + BNFreeStructureMemberList(members, count); + return result; +} + + +bool StructureBuilder::GetMemberByName(const string& name, StructureMember& result) const +{ + BNStructureMember* member = BNGetStructureBuilderMemberByName(m_object, name.c_str()); + if (member) + { + result.type = new Type(BNNewTypeReference(member->type)); + result.name = member->name; + result.offset = member->offset; + BNFreeStructureMember(member); + return true; + } + return false; +} + + +bool StructureBuilder::GetMemberAtOffset(int64_t offset, StructureMember& result) const +{ + size_t i; + return GetMemberAtOffset(offset, result, i); +} + + +bool StructureBuilder::GetMemberAtOffset(int64_t offset, StructureMember& result, size_t& idx) const +{ + BNStructureMember* member = BNGetStructureBuilderMemberAtOffset(m_object, offset, &idx); + if (member) + { + result.type = new Type(BNNewTypeReference(member->type)); + result.name = member->name; + result.offset = member->offset; + BNFreeStructureMember(member); + return true; + } + return false; +} + + +uint64_t StructureBuilder::GetWidth() const +{ + return BNGetStructureBuilderWidth(m_object); +} + + +void StructureBuilder::SetWidth(size_t width) +{ + BNSetStructureBuilderWidth(m_object, width); +} + + +size_t StructureBuilder::GetAlignment() const +{ + return BNGetStructureBuilderAlignment(m_object); +} + + +void StructureBuilder::SetAlignment(size_t align) +{ + BNSetStructureBuilderAlignment(m_object, align); +} + + +bool StructureBuilder::IsPacked() const +{ + return BNIsStructureBuilderPacked(m_object); +} + + +void StructureBuilder::SetPacked(bool packed) +{ + BNSetStructureBuilderPacked(m_object, packed); +} + + +bool StructureBuilder::IsUnion() const +{ + return BNIsStructureBuilderUnion(m_object); +} + + +void StructureBuilder::SetStructureType(BNStructureType t) +{ + BNSetStructureBuilderType(m_object, t); +} + + +BNStructureType StructureBuilder::GetStructureType() const +{ + return BNGetStructureBuilderType(m_object); +} + + +void StructureBuilder::AddMember(const Confidence<Ref<Type>>& type, const string& name) { BNTypeWithConfidence tc; tc.type = type->GetObject(); tc.confidence = type.GetConfidence(); - BNAddStructureMember(m_object, &tc, name.c_str()); + BNAddStructureBuilderMember(m_object, &tc, name.c_str()); } -void Structure::AddMemberAtOffset(const Confidence<Ref<Type>>& type, const string& name, uint64_t offset) +void StructureBuilder::AddMemberAtOffset(const Confidence<Ref<Type>>& type, const string& name, uint64_t offset) { BNTypeWithConfidence tc; tc.type = type->GetObject(); tc.confidence = type.GetConfidence(); - BNAddStructureMemberAtOffset(m_object, &tc, name.c_str(), offset); + BNAddStructureBuilderMemberAtOffset(m_object, &tc, name.c_str(), offset); } -void Structure::RemoveMember(size_t idx) +void StructureBuilder::RemoveMember(size_t idx) { - BNRemoveStructureMember(m_object, idx); + BNRemoveStructureBuilderMember(m_object, idx); } -void Structure::ReplaceMember(size_t idx, const Confidence<Ref<Type>>& type, const std::string& name) +void StructureBuilder::ReplaceMember(size_t idx, const Confidence<Ref<Type>>& type, const std::string& name) { BNTypeWithConfidence tc; tc.type = type->GetObject(); tc.confidence = type.GetConfidence(); - BNReplaceStructureMember(m_object, idx, &tc, name.c_str()); + BNReplaceStructureBuilderMember(m_object, idx, &tc, name.c_str()); } @@ -1219,16 +1877,101 @@ Enumeration::Enumeration(BNEnumeration* e) } -Enumeration::Enumeration() +vector<EnumerationMember> Enumeration::GetMembers() const +{ + size_t count; + BNEnumerationMember* members = BNGetEnumerationMembers(m_object, &count); + + vector<EnumerationMember> result; + result.reserve(count); + for (size_t i = 0; i < count; i++) + { + EnumerationMember member; + member.name = members[i].name; + member.value = members[i].value; + member.isDefault = members[i].isDefault; + result.push_back(member); + } + + BNFreeEnumerationMemberList(members, count); + return result; +} + + +EnumerationBuilder::EnumerationBuilder() { - m_object = BNCreateEnumeration(); + m_object = BNCreateEnumerationBuilder(); } -vector<EnumerationMember> Enumeration::GetMembers() const +EnumerationBuilder::EnumerationBuilder(BNEnumerationBuilder* e) +{ + m_object = e; +} + + +EnumerationBuilder::EnumerationBuilder(const EnumerationBuilder& e) +{ + m_object = BNDuplicateEnumerationBuilder(e.m_object); +} + + +EnumerationBuilder::EnumerationBuilder(EnumerationBuilder&& e) +{ + m_object = e.m_object; + e.m_object = BNCreateEnumerationBuilder(); +} + + +EnumerationBuilder::EnumerationBuilder(Enumeration* e) +{ + m_object = BNCreateEnumerationBuilderFromEnumeration(e->GetObject()); +} + + +EnumerationBuilder::~EnumerationBuilder() +{ + BNFreeEnumerationBuilder(m_object); +} + + +EnumerationBuilder& EnumerationBuilder::operator=(const EnumerationBuilder& e) +{ + if (this != &e) + { + BNFreeEnumerationBuilder(m_object); + m_object = BNDuplicateEnumerationBuilder(e.m_object); + } + return *this; +} + + +EnumerationBuilder& EnumerationBuilder::operator=(EnumerationBuilder&& e) +{ + if (this != &e) + std::swap(m_object, e.m_object); + return *this; +} + + +EnumerationBuilder& EnumerationBuilder::operator=(Enumeration* e) +{ + BNFreeEnumerationBuilder(m_object); + m_object = BNCreateEnumerationBuilderFromEnumeration(e->GetObject()); + return *this; +} + + +Ref<Enumeration> EnumerationBuilder::Finalize() const +{ + return new Enumeration(BNFinalizeEnumerationBuilder(m_object)); +} + + +vector<EnumerationMember> EnumerationBuilder::GetMembers() const { size_t count; - BNEnumerationMember* members = BNGetEnumerationMembers(m_object, &count); + BNEnumerationMember* members = BNGetEnumerationBuilderMembers(m_object, &count); vector<EnumerationMember> result; result.reserve(count); @@ -1246,27 +1989,27 @@ vector<EnumerationMember> Enumeration::GetMembers() const } -void Enumeration::AddMember(const string& name) +void EnumerationBuilder::AddMember(const string& name) { - BNAddEnumerationMember(m_object, name.c_str()); + BNAddEnumerationBuilderMember(m_object, name.c_str()); } -void Enumeration::AddMemberWithValue(const string& name, uint64_t value) +void EnumerationBuilder::AddMemberWithValue(const string& name, uint64_t value) { - BNAddEnumerationMemberWithValue(m_object, name.c_str(), value); + BNAddEnumerationBuilderMemberWithValue(m_object, name.c_str(), value); } -void Enumeration::RemoveMember(size_t idx) +void EnumerationBuilder::RemoveMember(size_t idx) { - BNRemoveEnumerationMember(m_object, idx); + BNRemoveEnumerationBuilderMember(m_object, idx); } -void Enumeration::ReplaceMember(size_t idx, const string& name, uint64_t value) +void EnumerationBuilder::ReplaceMember(size_t idx, const string& name, uint64_t value) { - BNReplaceEnumerationMember(m_object, idx, name.c_str(), value); + BNReplaceEnumerationBuilderMember(m_object, idx, name.c_str(), value); } diff --git a/ui/uitypes.h b/ui/uitypes.h index b9917321..5ea7e300 100644 --- a/ui/uitypes.h +++ b/ui/uitypes.h @@ -39,6 +39,7 @@ typedef BinaryNinja::Ref<BinaryNinja::BinaryView> BinaryViewRef; typedef BinaryNinja::Ref<BinaryNinja::BinaryViewType> BinaryViewTypeRef; typedef BinaryNinja::Ref<BinaryNinja::DisassemblySettings> DisassemblySettingsRef; typedef BinaryNinja::Ref<BinaryNinja::DownloadProvider> DownloadProviderRef; +typedef BinaryNinja::Ref<BinaryNinja::Enumeration> EnumerationRef; typedef BinaryNinja::Ref<BinaryNinja::FileMetadata> FileMetadataRef; typedef BinaryNinja::Ref<BinaryNinja::FlowGraph> FlowGraphRef; typedef BinaryNinja::Ref<BinaryNinja::FlowGraphLayoutRequest> FlowGraphLayoutRequestRef; |
