// Copyright (c) 2015-2016 Vector 35 LLC // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to // deal in the Software without restriction, including without limitation the // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or // sell copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS // IN THE SOFTWARE. #include "binaryninjaapi.h" using namespace BinaryNinja; using namespace std; Type::Type(BNType* type) { m_object = type; } BNTypeClass Type::GetClass() const { return BNGetTypeClass(m_object); } uint64_t Type::GetWidth() const { return BNGetTypeWidth(m_object); } size_t Type::GetAlignment() const { return BNGetTypeAlignment(m_object); } bool Type::IsSigned() const { return BNIsTypeSigned(m_object); } bool Type::IsConst() const { return BNIsTypeConst(m_object); } bool Type::IsFloat() const { return BNIsTypeFloatingPoint(m_object); } Ref Type::GetChildType() const { BNType* type = BNGetChildType(m_object); if (type) return new Type(type); return nullptr; } Ref Type::GetCallingConvention() const { BNCallingConvention* cc = BNGetTypeCallingConvention(m_object); if (cc) return new CoreCallingConvention(cc); return nullptr; } vector Type::GetParameters() const { size_t count; BNNameAndType* types = BNGetTypeParameters(m_object, &count); vector 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_object); } bool Type::CanReturn() const { return BNFunctionTypeCanReturn(m_object); } Ref Type::GetStructure() const { BNStructure* s = BNGetTypeStructure(m_object); if (s) return new Structure(s); return nullptr; } Ref Type::GetEnumeration() const { BNEnumeration* e = BNGetTypeEnumeration(m_object); if (e) return new Enumeration(e); return nullptr; } uint64_t Type::GetElementCount() const { return BNGetTypeElementCount(m_object); } string Type::GetString() const { char* str = BNGetTypeString(m_object); string result = str; BNFreeString(str); return result; } string Type::GetStringBeforeName() const { char* str = BNGetTypeStringBeforeName(m_object); string result = str; BNFreeString(str); return result; } string Type::GetStringAfterName() const { char* str = BNGetTypeStringAfterName(m_object); string result = str; BNFreeString(str); return result; } Ref Type::Duplicate() const { return new Type(BNDuplicateType(m_object)); } Ref Type::VoidType() { return new Type(BNCreateVoidType()); } Ref Type::BoolType() { return new Type(BNCreateBoolType()); } Ref Type::IntegerType(size_t width, bool sign) { return new Type(BNCreateIntegerType(width, sign)); } Ref Type::FloatType(size_t width) { return new Type(BNCreateFloatType(width)); } Ref Type::StructureType(Structure* strct) { return new Type(BNCreateStructureType(strct->GetObject())); } Ref Type::EnumerationType(Architecture* arch, Enumeration* enm, size_t width) { return new Type(BNCreateEnumerationType(arch->GetObject(), enm->GetObject(), width)); } Ref Type::PointerType(Architecture* arch, Type* type, bool cnst) { return new Type(BNCreatePointerType(arch->GetObject(), type->GetObject(), cnst)); } Ref Type::ArrayType(Type* type, uint64_t elem) { return new Type(BNCreateArrayType(type->GetObject(), elem)); } Ref Type::FunctionType(Type* returnValue, CallingConvention* callingConvention, const std::vector& 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->GetObject(); } Type* type = new Type(BNCreateFunctionType(returnValue->GetObject(), callingConvention ? callingConvention->GetObject() : nullptr, paramArray, params.size(), varArg)); delete[] paramArray; return type; } Structure::Structure(BNStructure* s) { m_object = s; } string Structure::GetName() const { char* name = BNGetStructureName(m_object); string result = name; BNFreeString(name); return result; } void Structure::SetName(const string& name) { BNSetStructureName(m_object, name.c_str()); } vector Structure::GetMembers() const { size_t count; BNStructureMember* members = BNGetStructureMembers(m_object, &count); vector 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_object); } size_t Structure::GetAlignment() const { return BNGetStructureAlignment(m_object); } bool Structure::IsPacked() const { return BNIsStructurePacked(m_object); } void Structure::SetPacked(bool packed) { BNSetStructurePacked(m_object, packed); } bool Structure::IsUnion() const { return BNIsStructureUnion(m_object); } void Structure::SetUnion(bool u) { BNSetStructureUnion(m_object, u); } void Structure::AddMember(Type* type, const string& name) { BNAddStructureMember(m_object, type->GetObject(), name.c_str()); } void Structure::AddMemberAtOffset(Type* type, const string& name, uint64_t offset) { BNAddStructureMemberAtOffset(m_object, type->GetObject(), name.c_str(), offset); } void Structure::RemoveMember(size_t idx) { BNRemoveStructureMember(m_object, idx); } Enumeration::Enumeration(BNEnumeration* e) { m_object = e; } string Enumeration::GetName() const { char* name = BNGetEnumerationName(m_object); string result = name; BNFreeString(name); return result; } void Enumeration::SetName(const string& name) { BNSetEnumerationName(m_object, name.c_str()); } vector Enumeration::GetMembers() const { size_t count; BNEnumerationMember* members = BNGetEnumerationMembers(m_object, &count); vector 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_object, name.c_str()); } void Enumeration::AddMemberWithValue(const string& name, uint64_t value) { BNAddEnumerationMemberWithValue(m_object, name.c_str(), value); } bool BinaryNinja::PreprocessSource(const string& source, const string& fileName, string& output, string& errors, const vector& includeDirs) { char* outStr; char* errorStr; const char** includeDirList = new const char*[includeDirs.size()]; for (size_t i = 0; i < includeDirs.size(); i++) includeDirList[i] = includeDirs[i].c_str(); bool result = BNPreprocessSource(source.c_str(), fileName.c_str(), &outStr, &errorStr, includeDirList, includeDirs.size()); output = outStr; errors = errorStr; BNFreeString(outStr); BNFreeString(errorStr); delete[] includeDirList; return result; }