diff options
| author | Rusty Wagner <rusty@vector35.com> | 2015-07-28 01:09:04 -0400 |
|---|---|---|
| committer | Rusty Wagner <rusty@vector35.com> | 2015-07-28 01:09:04 -0400 |
| commit | 3fc101f475a763a09d779f119dcbec3185a472a0 (patch) | |
| tree | 8705deb4f6745a7a29571a51df4c19691204c24b | |
| parent | 37bc7f679b870b169726e746b75e573db1f3e268 (diff) | |
Initial implementation of type info
| -rw-r--r-- | api.pro | 1 | ||||
| -rw-r--r-- | architecture.cpp | 22 | ||||
| -rw-r--r-- | binaryninjaapi.h | 111 | ||||
| -rw-r--r-- | function.cpp | 6 | ||||
| -rw-r--r-- | type.cpp | 357 |
5 files changed, 497 insertions, 0 deletions
@@ -28,6 +28,7 @@ SOURCES += \ log.cpp \ tempfile.cpp \ lowlevelil.cpp \ + type.cpp \ ../core/json/jsoncpp.cpp HEADERS += binaryninjaapi.h diff --git a/architecture.cpp b/architecture.cpp index 6c7e0e4c..a3ec56b7 100644 --- a/architecture.cpp +++ b/architecture.cpp @@ -60,6 +60,13 @@ size_t Architecture::GetAddressSizeCallback(void* ctxt) } +size_t Architecture::GetDefaultIntegerSizeCallback(void* ctxt) +{ + Architecture* arch = (Architecture*)ctxt; + return arch->GetDefaultIntegerSize(); +} + + bool Architecture::GetInstructionInfoCallback(void* ctxt, const uint8_t* data, uint64_t addr, size_t maxLen, BNInstructionInfo* result) { @@ -267,6 +274,7 @@ void Architecture::Register(Architecture* arch) callbacks.context = arch; callbacks.getEndianness = GetEndiannessCallback; callbacks.getAddressSize = GetAddressSizeCallback; + callbacks.getDefaultIntegerSize = GetDefaultIntegerSizeCallback; callbacks.getInstructionInfo = GetInstructionInfoCallback; callbacks.getInstructionText = GetInstructionTextCallback; callbacks.freeInstructionText = FreeInstructionTextCallback; @@ -326,6 +334,14 @@ string Architecture::GetName() const } +size_t Architecture::GetDefaultIntegerSize() const +{ + if (GetAddressSize() < 4) + return GetAddressSize(); + return 4; +} + + bool Architecture::GetInstructionLowLevelIL(const uint8_t*, uint64_t, size_t&, LowLevelILFunction& il) { il.AddInstruction(il.Unimplemented()); @@ -478,6 +494,12 @@ size_t CoreArchitecture::GetAddressSize() const } +size_t CoreArchitecture::GetDefaultIntegerSize() const +{ + return BNGetArchitectureDefaultIntegerSize(m_arch); +} + + bool CoreArchitecture::GetInstructionInfo(const uint8_t* data, uint64_t addr, size_t maxLen, InstructionInfo& result) { return BNGetInstructionInfo(m_arch, data, addr, maxLen, &result); diff --git a/binaryninjaapi.h b/binaryninjaapi.h index a5a3419e..0fcf1204 100644 --- a/binaryninjaapi.h +++ b/binaryninjaapi.h @@ -801,6 +801,7 @@ namespace BinaryNinja static BNEndianness GetEndiannessCallback(void* ctxt); static size_t GetAddressSizeCallback(void* ctxt); + static size_t GetDefaultIntegerSizeCallback(void* ctxt); static bool GetInstructionInfoCallback(void* ctxt, const uint8_t* data, uint64_t addr, size_t maxLen, BNInstructionInfo* result); static bool GetInstructionTextCallback(void* ctxt, const uint8_t* data, uint64_t addr, @@ -843,6 +844,7 @@ namespace BinaryNinja virtual BNEndianness GetEndianness() const = 0; virtual size_t GetAddressSize() const = 0; + virtual size_t GetDefaultIntegerSize() const; virtual bool GetInstructionInfo(const uint8_t* data, uint64_t addr, size_t maxLen, InstructionInfo& result) = 0; virtual bool GetInstructionText(const uint8_t* data, uint64_t addr, size_t& len, @@ -878,6 +880,7 @@ namespace BinaryNinja CoreArchitecture(BNArchitecture* arch); virtual BNEndianness GetEndianness() const override; virtual size_t GetAddressSize() const override; + virtual size_t GetDefaultIntegerSize() const override; virtual bool GetInstructionInfo(const uint8_t* data, uint64_t addr, size_t maxLen, InstructionInfo& result) override; virtual bool GetInstructionText(const uint8_t* data, uint64_t addr, size_t& len, std::vector<InstructionTextToken>& result) override; @@ -904,6 +907,112 @@ namespace BinaryNinja virtual bool SkipAndReturnValue(uint8_t* data, uint64_t addr, size_t len, uint64_t value) override; }; + class Type; + class Structure; + class Enumeration; + + struct NameAndType + { + std::string name; + Ref<Type> type; + }; + + class Type: public RefCountObject + { + BNType* m_type; + + public: + Type(BNType* type); + ~Type(); + + BNType* GetTypeObject() const { return m_type; } + + BNTypeClass GetClass() const; + uint64_t GetWidth() const; + size_t GetAlignment() const; + bool IsSigned() const; + bool IsConst() const; + bool IsFloat() const; + Ref<Type> GetChildType() const; + std::vector<NameAndType> GetParameters() const; + bool HasVariableArguments() const; + Ref<Structure> GetStructure() const; + Ref<Enumeration> GetEnumeration() const; + uint64_t GetElementCount() const; + + std::string GetString() const; + std::string GetStringBeforeName() const; + std::string GetStringAfterName() const; + + static Ref<Type> VoidType(); + static Ref<Type> BoolType(); + static Ref<Type> IntegerType(size_t width, bool sign); + static Ref<Type> FloatType(size_t width); + static Ref<Type> StructureType(Structure* strct); + static Ref<Type> EnumerationType(Architecture* arch, Enumeration* enm, size_t width = 0); + static Ref<Type> PointerType(Architecture* arch, Type* type, bool cnst = false); + static Ref<Type> ArrayType(Type* type, uint64_t elem); + static Ref<Type> FunctionType(Type* returnValue, const std::vector<NameAndType>& params, bool varArg = false); + }; + + struct StructureMember + { + Ref<Type> type; + std::string name; + uint64_t offset; + }; + + class Structure: public RefCountObject + { + BNStructure* m_struct; + + public: + Structure(BNStructure* s); + ~Structure(); + + BNStructure* GetStructureObject() const { return m_struct; } + + std::string GetName() const; + void SetName(const std::string& name); + std::vector<StructureMember> GetMembers() const; + uint64_t GetWidth() const; + size_t GetAlignment() const; + bool IsPacked() const; + void SetPacked(bool packed); + bool IsUnion() const; + void SetUnion(bool u); + + void AddMember(Type* type, const std::string& name); + void AddMemberAtOffset(Type* type, const std::string& name, uint64_t offset); + void RemoveMember(size_t idx); + }; + + struct EnumerationMember + { + std::string name; + uint64_t value; + bool isDefault; + }; + + class Enumeration: public RefCountObject + { + BNEnumeration* m_enum; + + public: + Enumeration(BNEnumeration* e); + ~Enumeration(); + + BNEnumeration* GetEnumerationObject() const { return m_enum; } + + std::string GetName() const; + void SetName(const std::string& name); + + std::vector<EnumerationMember> GetMembers() const; + + void AddMember(const std::string& name); + void AddMemberWithValue(const std::string& name, uint64_t value); + }; + class Function; struct BasicBlockEdge @@ -959,6 +1068,8 @@ namespace BinaryNinja Ref<LowLevelILFunction> GetLowLevelIL() const; std::vector<Ref<BasicBlock>> GetLowLevelILBasicBlocks() const; + Ref<Type> GetType() const; + Ref<FunctionGraph> CreateFunctionGraph(); }; diff --git a/function.cpp b/function.cpp index 45b29752..89b2dfbb 100644 --- a/function.cpp +++ b/function.cpp @@ -99,6 +99,12 @@ vector<Ref<BasicBlock>> Function::GetLowLevelILBasicBlocks() const } +Ref<Type> Function::GetType() const +{ + return new Type(BNGetFunctionType(m_func)); +} + + Ref<FunctionGraph> Function::CreateFunctionGraph() { BNFunctionGraph* graph = BNCreateFunctionGraph(m_func); diff --git a/type.cpp b/type.cpp new file mode 100644 index 00000000..62176deb --- /dev/null +++ b/type.cpp @@ -0,0 +1,357 @@ +#include "binaryninjaapi.h" + +using namespace BinaryNinja; +using namespace std; + + +Type::Type(BNType* type): m_type(type) +{ +} + + +Type::~Type() +{ + BNFreeType(m_type); +} + + +BNTypeClass Type::GetClass() const +{ + return BNGetTypeClass(m_type); +} + + +uint64_t Type::GetWidth() const +{ + return BNGetTypeWidth(m_type); +} + + +size_t Type::GetAlignment() const +{ + return BNGetTypeAlignment(m_type); +} + + +bool Type::IsSigned() const +{ + return BNIsTypeSigned(m_type); +} + + +bool Type::IsConst() const +{ + return BNIsTypeConst(m_type); +} + + +bool Type::IsFloat() const +{ + return BNIsTypeFloatingPoint(m_type); +} + + +Ref<Type> Type::GetChildType() const +{ + BNType* type = BNGetChildType(m_type); + if (type) + return new Type(type); + return nullptr; +} + + +vector<NameAndType> Type::GetParameters() const +{ + size_t count; + BNNameAndType* types = BNGetTypeParameters(m_type, &count); + + vector<NameAndType> result; + for (size_t i = 0; i < count; i++) + { + NameAndType param; + param.name = types[i].name; + param.type = new Type(BNNewTypeReference(types[i].type)); + result.push_back(param); + } + + BNFreeTypeParameterList(types, count); + return result; +} + + +bool Type::HasVariableArguments() const +{ + return BNTypeHasVariableArguments(m_type); +} + + +Ref<Structure> Type::GetStructure() const +{ + BNStructure* s = BNGetTypeStructure(m_type); + if (s) + return new Structure(s); + return nullptr; +} + + +Ref<Enumeration> Type::GetEnumeration() const +{ + BNEnumeration* e = BNGetTypeEnumeration(m_type); + if (e) + return new Enumeration(e); + return nullptr; +} + + +uint64_t Type::GetElementCount() const +{ + return BNGetTypeElementCount(m_type); +} + + +string Type::GetString() const +{ + char* str = BNGetTypeString(m_type); + string result = str; + BNFreeString(str); + return result; +} + + +string Type::GetStringBeforeName() const +{ + char* str = BNGetTypeStringBeforeName(m_type); + string result = str; + BNFreeString(str); + return result; +} + + +string Type::GetStringAfterName() const +{ + char* str = BNGetTypeStringAfterName(m_type); + string result = str; + BNFreeString(str); + return result; +} + + +Ref<Type> Type::VoidType() +{ + return new Type(BNCreateVoidType()); +} + + +Ref<Type> Type::BoolType() +{ + return new Type(BNCreateBoolType()); +} + + +Ref<Type> Type::IntegerType(size_t width, bool sign) +{ + return new Type(BNCreateIntegerType(width, sign)); +} + + +Ref<Type> Type::FloatType(size_t width) +{ + return new Type(BNCreateFloatType(width)); +} + + +Ref<Type> Type::StructureType(Structure* strct) +{ + return new Type(BNCreateStructureType(strct->GetStructureObject())); +} + + +Ref<Type> Type::EnumerationType(Architecture* arch, Enumeration* enm, size_t width) +{ + return new Type(BNCreateEnumerationType(arch->GetArchitectureObject(), enm->GetEnumerationObject(), width)); +} + + +Ref<Type> Type::PointerType(Architecture* arch, Type* type, bool cnst) +{ + return new Type(BNCreatePointerType(arch->GetArchitectureObject(), type->GetTypeObject(), cnst)); +} + + +Ref<Type> Type::ArrayType(Type* type, uint64_t elem) +{ + return new Type(BNCreateArrayType(type->GetTypeObject(), elem)); +} + + +Ref<Type> Type::FunctionType(Type* returnValue, const std::vector<NameAndType>& params, bool varArg) +{ + BNNameAndType* paramArray = new BNNameAndType[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->GetTypeObject(); + } + + Type* type = new Type(BNCreateFunctionType(returnValue->GetTypeObject(), paramArray, params.size(), varArg)); + delete[] paramArray; + return type; +} + + +Structure::Structure(BNStructure* s): m_struct(s) +{ +} + + +Structure::~Structure() +{ + BNFreeStructure(m_struct); +} + + +string Structure::GetName() const +{ + char* name = BNGetStructureName(m_struct); + string result = name; + BNFreeString(name); + return result; +} + + +void Structure::SetName(const string& name) +{ + BNSetStructureName(m_struct, name.c_str()); +} + + +vector<StructureMember> Structure::GetMembers() const +{ + size_t count; + BNStructureMember* members = BNGetStructureMembers(m_struct, &count); + + vector<StructureMember> result; + 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; +} + + +uint64_t Structure::GetWidth() const +{ + return BNGetStructureWidth(m_struct); +} + + +size_t Structure::GetAlignment() const +{ + return BNGetStructureAlignment(m_struct); +} + + +bool Structure::IsPacked() const +{ + return BNIsStructurePacked(m_struct); +} + + +void Structure::SetPacked(bool packed) +{ + BNSetStructurePacked(m_struct, packed); +} + + +bool Structure::IsUnion() const +{ + return BNIsStructureUnion(m_struct); +} + + +void Structure::SetUnion(bool u) +{ + BNSetStructureUnion(m_struct, u); +} + + +void Structure::AddMember(Type* type, const string& name) +{ + BNAddStructureMember(m_struct, type->GetTypeObject(), name.c_str()); +} + + +void Structure::AddMemberAtOffset(Type* type, const string& name, uint64_t offset) +{ + BNAddStructureMemberAtOffset(m_struct, type->GetTypeObject(), name.c_str(), offset); +} + + +void Structure::RemoveMember(size_t idx) +{ + BNRemoveStructureMember(m_struct, idx); +} + + +Enumeration::Enumeration(BNEnumeration* e): m_enum(e) +{ +} + + +Enumeration::~Enumeration() +{ + BNFreeEnumeration(m_enum); +} + + +string Enumeration::GetName() const +{ + char* name = BNGetEnumerationName(m_enum); + string result = name; + BNFreeString(name); + return result; +} + + +void Enumeration::SetName(const string& name) +{ + BNSetEnumerationName(m_enum, name.c_str()); +} + + +vector<EnumerationMember> Enumeration::GetMembers() const +{ + size_t count; + BNEnumerationMember* members = BNGetEnumerationMembers(m_enum, &count); + + vector<EnumerationMember> result; + 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; +} + + +void Enumeration::AddMember(const string& name) +{ + BNAddEnumerationMember(m_enum, name.c_str()); +} + + +void Enumeration::AddMemberWithValue(const string& name, uint64_t value) +{ + BNAddEnumerationMemberWithValue(m_enum, name.c_str(), value); +} |
