// Copyright (c) 2015-2026 Vector 35 Inc // // 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" #include using namespace BinaryNinja; using namespace std; NameList::NameList(const string& join, size_t size) : m_join(join) { m_name.reserve(size); } NameList::NameList(const BNQualifiedName* name) { if (name->join) m_join = name->join; m_name.reserve(name->nameCount); for (size_t i = 0; i < name->nameCount; i++) m_name.push_back(name->name[i]); } NameList::NameList(const string& name, const string& join) : m_join(join) { if (!name.empty()) m_name.push_back(name); } NameList::NameList(const vector& name, const string& join) : m_join(join), m_name(name) {} NameList::NameList(const NameList& name, const string& join) : m_join(join), m_name(name.m_name) {} NameList::NameList(const NameList& name) : m_join(name.m_join), m_name(name.m_name) {} NameList::~NameList() {} NameList& NameList::operator=(const string& name) { m_name = vector {name}; return *this; } NameList& NameList::operator=(const vector& name) { m_name = name; return *this; } NameList& NameList::operator=(const NameList& name) { m_name = name.m_name; m_join = name.m_join; return *this; } bool NameList::operator==(const NameList& other) const { return m_name == other.m_name && m_join == other.m_join; } bool NameList::operator!=(const NameList& other) const { return m_name != other.m_name || m_join != other.m_join; } bool NameList::operator<(const NameList& other) const { if (m_name < other.m_name) return true; if (m_name > other.m_name) return false; return m_join < other.m_join; } bool NameList::operator>(const NameList& other) const { if (m_name > other.m_name) return true; if (m_name < other.m_name) return false; return m_join > other.m_join; } NameList NameList::operator+(const NameList& other) const { NameList result(*this); result.m_name.insert(result.m_name.end(), other.m_name.begin(), other.m_name.end()); return result; } string& NameList::operator[](size_t i) { return m_name[i]; } const string& NameList::operator[](size_t i) const { return m_name[i]; } vector::iterator NameList::begin() { return m_name.begin(); } vector::iterator NameList::end() { return m_name.end(); } vector::const_iterator NameList::begin() const { return m_name.begin(); } vector::const_iterator NameList::end() const { return m_name.end(); } string& NameList::front() { return m_name.front(); } const string& NameList::front() const { return m_name.front(); } string& NameList::back() { return m_name.back(); } const string& NameList::back() const { return m_name.back(); } void NameList::insert(vector::iterator loc, const string& name) { m_name.insert(loc, name); } void NameList::insert(vector::iterator loc, vector::iterator b, vector::iterator e) { m_name.insert(loc, b, e); } void NameList::erase(vector::iterator i) { m_name.erase(i); } void NameList::clear() { m_name.clear(); } void NameList::push_back(const string& name) { m_name.push_back(name); } size_t NameList::size() const { return m_name.size(); } size_t NameList::StringSize() const { if (m_name.size() == 0) return 0; size_t size = 0; for (auto& name : m_name) size += name.size() + m_join.size(); return size - m_join.size(); } string NameList::GetString(BNTokenEscapingType escaping) const { bool first = true; string out; for (auto& name : m_name) { if (!first) { out += m_join + name; } else { out += name; } if (name.length() != 0) first = false; } return EscapeTypeName(out, escaping); } std::string NameList::EscapeTypeName(const std::string& name, BNTokenEscapingType escaping) { char* str = BNEscapeTypeName(name.c_str(), escaping); std::string result(str); BNFreeString(str); return result; } std::string NameList::UnescapeTypeName(const std::string& name, BNTokenEscapingType escaping) { char* str = BNUnescapeTypeName(name.c_str(), escaping); std::string result(str); BNFreeString(str); return result; } BNNameList NameList::GetAPIObject() const { BNNameList result; result.nameCount = m_name.size(); result.join = BNAllocString(m_join.c_str()); result.name = new char*[m_name.size()]; for (size_t i = 0; i < m_name.size(); i++) result.name[i] = BNAllocString(m_name[i].c_str()); return result; } void NameList::FreeAPIObject(BNNameList* name) { for (size_t i = 0; i < name->nameCount; i++) BNFreeString(name->name[i]); BNFreeString(name->join); delete[] name->name; } NameList NameList::FromAPIObject(BNNameList* name) { NameList result(name->join); for (size_t i = 0; i < name->nameCount; i++) result.push_back(name->name[i]); return result; } QualifiedName::QualifiedName() : NameList("::") {} QualifiedName::QualifiedName(const BNQualifiedName* name) : NameList(name) {} QualifiedName::QualifiedName(const string& name) : NameList(name, "::") {} QualifiedName::QualifiedName(const vector& name) : NameList(name, "::") {} QualifiedName::QualifiedName(const QualifiedName& name) : NameList(name.m_name, "::") {} QualifiedName::~QualifiedName() {} QualifiedName& QualifiedName::operator=(const string& name) { m_name = vector {name}; m_join = "::"; return *this; } QualifiedName& QualifiedName::operator=(const vector& name) { m_name = name; m_join = "::"; return *this; } QualifiedName& QualifiedName::operator=(const QualifiedName& name) { m_name = name.m_name; m_join = "::"; return *this; } QualifiedName QualifiedName::operator+(const QualifiedName& other) const { QualifiedName result(*this); result.m_join = "::"; result.m_name.insert(result.m_name.end(), other.m_name.begin(), other.m_name.end()); return result; } BNQualifiedName QualifiedName::GetAPIObject() const { BNQualifiedName result; result.nameCount = m_name.size(); result.join = BNAllocString(m_join.c_str()); result.name = new char*[m_name.size()]; for (size_t i = 0; i < m_name.size(); i++) result.name[i] = BNAllocString(m_name[i].c_str()); return result; } void QualifiedName::FreeAPIObject(BNQualifiedName* name) { for (size_t i = 0; i < name->nameCount; i++) BNFreeString(name->name[i]); BNFreeString(name->join); delete[] name->name; } QualifiedName QualifiedName::FromAPIObject(const BNQualifiedName* name) { return QualifiedName(name); } NameSpace::NameSpace() : NameList("::") {} NameSpace::NameSpace(const string& name) : NameList(name, "::") {} NameSpace::NameSpace(const vector& name) : NameList(name, "::") {} NameSpace::NameSpace(const NameSpace& name) : NameList(name.m_name, "::") {} NameSpace::~NameSpace() {} NameSpace& NameSpace::operator=(const string& name) { m_name = vector {name}; m_join = "::"; return *this; } NameSpace& NameSpace::operator=(const vector& name) { m_name = name; m_join = "::"; return *this; } NameSpace& NameSpace::operator=(const NameSpace& name) { m_name = name.m_name; m_join = "::"; return *this; } NameSpace NameSpace::operator+(const NameSpace& other) const { NameSpace result(*this); result.m_join = "::"; result.m_name.insert(result.m_name.end(), other.m_name.begin(), other.m_name.end()); return result; } bool NameSpace::IsDefaultNameSpace() const { return ((GetString() == DEFAULT_INTERNAL_NAMESPACE) || (GetString() == DEFAULT_EXTERNAL_NAMESPACE)); } BNNameSpace NameSpace::GetAPIObject() const { BNNameSpace result; result.nameCount = m_name.size(); result.join = BNAllocString(m_join.c_str()); result.name = new char*[m_name.size()]; for (size_t i = 0; i < m_name.size(); i++) result.name[i] = BNAllocString(m_name[i].c_str()); return result; } void NameSpace::FreeAPIObject(BNNameSpace* name) { if (!name) return; for (size_t i = 0; i < name->nameCount; i++) BNFreeString(name->name[i]); BNFreeString(name->join); delete[] name->name; } NameSpace NameSpace::FromAPIObject(const BNNameSpace* name) { NameSpace result; if (!name) return result; for (size_t i = 0; i < name->nameCount; i++) result.push_back(name->name[i]); return result; } TypeDefinitionLine TypeDefinitionLine::FromAPIObject(BNTypeDefinitionLine* line) { TypeDefinitionLine result; result.lineType = line->lineType; result.tokens = InstructionTextToken::ConvertInstructionTextTokenList(line->tokens, line->count); result.type = new Type(BNNewTypeReference(line->type)); result.parentType = new Type(BNNewTypeReference(line->parentType)); result.rootType = new Type(BNNewTypeReference(line->rootType)); result.rootTypeName = line->rootTypeName; result.baseType = line->baseType ? new NamedTypeReference(BNNewNamedTypeReference(line->baseType)) : nullptr; result.baseOffset = line->baseOffset; result.offset = line->offset; result.fieldIndex = line->fieldIndex; return result; } BNTypeDefinitionLine* TypeDefinitionLine::CreateTypeDefinitionLineList( const std::vector& lines) { BNTypeDefinitionLine* result = new BNTypeDefinitionLine[lines.size()]; for (size_t i = 0; i < lines.size(); ++i) { result[i].lineType = lines[i].lineType; result[i].tokens = InstructionTextToken::CreateInstructionTextTokenList(lines[i].tokens); result[i].count = lines[i].tokens.size(); result[i].type = BNNewTypeReference(lines[i].type->GetObject()); result[i].parentType = BNNewTypeReference(lines[i].parentType->GetObject()); result[i].rootType = BNNewTypeReference(lines[i].rootType->GetObject()); result[i].rootTypeName = BNAllocString(lines[i].rootTypeName.c_str()); result[i].baseType = lines[i].baseType ? BNNewNamedTypeReference(lines[i].baseType->GetObject()) : nullptr; result[i].baseOffset = lines[i].baseOffset; result[i].offset = lines[i].offset; result[i].fieldIndex = lines[i].fieldIndex; } return result; } void TypeDefinitionLine::FreeTypeDefinitionLineList(BNTypeDefinitionLine* lines, size_t count) { for (size_t i = 0; i < count; ++i) { InstructionTextToken::FreeInstructionTextTokenList(lines[i].tokens, lines[i].count); BNFreeType(lines[i].type); BNFreeType(lines[i].parentType); BNFreeType(lines[i].rootType); BNFreeNamedTypeReference(lines[i].baseType); BNFreeString(lines[i].rootTypeName); } delete[] lines; } FieldResolutionInfo::FieldResolutionInfo(BNFieldResolutionInfo* info) { m_object = info; } BaseStructure::BaseStructure(NamedTypeReference* _type, uint64_t _offset, uint64_t _width) : type(_type), offset(_offset), width(_width) {} BaseStructure::BaseStructure(Type* _type, uint64_t _offset) { type = _type->IsNamedTypeRefer() ? _type->GetNamedTypeReference() : _type->GetRegisteredName(); offset = _offset; width = _type->GetWidth(); } Type::Type(BNType* type) { m_object = type; } bool Type::operator==(const Type& other) { return BNTypesEqual(m_object, other.m_object); } bool Type::operator!=(const Type& other) { return BNTypesNotEqual(m_object, other.m_object); } 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); } Confidence Type::IsSigned() const { BNBoolWithConfidence result = BNIsTypeSigned(m_object); return Confidence(result.value, result.confidence); } Confidence Type::IsConst() const { BNBoolWithConfidence result = BNIsTypeConst(m_object); return Confidence(result.value, result.confidence); } Confidence Type::IsVolatile() const { BNBoolWithConfidence result = BNIsTypeVolatile(m_object); return Confidence(result.value, result.confidence); } Confidence> Type::GetChildType() const { BNTypeWithConfidence type = BNGetChildType(m_object); if (type.type) return Confidence>(new Type(type.type), type.confidence); return nullptr; } Confidence> Type::GetCallingConvention() const { BNCallingConventionWithConfidence cc = BNGetTypeCallingConvention(m_object); if (cc.convention) return Confidence>(new CoreCallingConvention(cc.convention), cc.confidence); return nullptr; } BNCallingConventionName Type::GetCallingConventionName() const { return BNGetTypeCallingConventionName(m_object); } vector Type::GetParameters() const { size_t count; BNFunctionParameter* types = BNGetTypeParameters(m_object, &count); vector result; result.reserve(count); for (size_t i = 0; i < count; i++) { FunctionParameter param; param.name = types[i].name; param.type = Confidence>(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 Type::HasVariableArguments() const { BNBoolWithConfidence result = BNTypeHasVariableArguments(m_object); return Confidence(result.value, result.confidence); } bool Type::HasTemplateArguments() const { return BNTypeHasTemplateArguments(m_object); } Confidence Type::CanReturn() const { BNBoolWithConfidence result = BNFunctionTypeCanReturn(m_object); return Confidence(result.value, result.confidence); } Confidence Type::IsPure() const { BNBoolWithConfidence result = BNIsTypePure(m_object); return Confidence(result.value, result.confidence); } 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; } Ref Type::GetNamedTypeReference() const { BNNamedTypeReference* ref = BNGetTypeNamedTypeReference(m_object); if (ref) return new NamedTypeReference(ref); return nullptr; } uint64_t Type::GetElementCount() const { return BNGetTypeElementCount(m_object); } uint64_t Type::GetOffset() const { return BNGetTypeOffset(m_object); } BNPointerBaseType Type::GetPointerBaseType() const { return BNTypeGetPointerBaseType(m_object); } int64_t Type::GetPointerBaseOffset() const { return BNTypeGetPointerBaseOffset(m_object); } Confidence Type::GetStackAdjustment() const { BNOffsetWithConfidence result = BNGetTypeStackAdjustment(m_object); return Confidence(result.value, result.confidence); } std::set Type::GetPointerSuffix() const { size_t count = 0; BNPointerSuffix* suffix = BNGetTypePointerSuffix(m_object, &count); std::set result(suffix, suffix + count); BNFreePointerSuffixList(suffix, count); return result; } std::string Type::GetPointerSuffixString() const { char* string = BNGetTypePointerSuffixString(m_object); std::string result(string); BNFreeString(string); return result; } std::vector Type::GetPointerSuffixTokens(uint8_t baseConfidence) const { size_t count = 0; BNInstructionTextToken* tokens = BNGetTypePointerSuffixTokens(m_object, baseConfidence, &count); std::vector result = InstructionTextToken::ConvertInstructionTextTokenList(tokens, count); BNFreeInstructionText(tokens, count); return result; } std::vector Type::GetAttributes() const { size_t count = 0; BNTypeAttribute* attributes = BNGetTypeAttributes(m_object, &count); std::vector result; result.reserve(count); for (size_t i = 0; i < count; i++) result.emplace_back(attributes[i].name, attributes[i].value); BNFreeTypeAttributeList(attributes, count); return result; } std::optional Type::GetAttribute(const std::string& name) const { char* result = BNGetTypeAttributeByName(m_object, name.c_str()); if (!result) return std::nullopt; std::string resultStr(result); BNFreeString(result); return resultStr; } string Type::GetString(Platform* platform, BNTokenEscapingType escaping) const { char* str = BNGetTypeString(m_object, platform ? platform->GetObject() : nullptr, escaping); string result = str; BNFreeString(str); return result; } string Type::GetTypeAndName(const QualifiedName& nameList, BNTokenEscapingType escaping) const { BNQualifiedName name = nameList.GetAPIObject(); char* outName = BNGetTypeAndName(m_object, &name, escaping); QualifiedName::FreeAPIObject(&name); return outName; } string Type::GetStringBeforeName(Platform* platform, BNTokenEscapingType escaping) const { char* str = BNGetTypeStringBeforeName(m_object, platform ? platform->GetObject() : nullptr, escaping); string result = str; BNFreeString(str); return result; } string Type::GetStringAfterName(Platform* platform, BNTokenEscapingType escaping) const { char* str = BNGetTypeStringAfterName(m_object, platform ? platform->GetObject() : nullptr, escaping); string result = str; BNFreeString(str); return result; } vector Type::GetTokens(Platform* platform, uint8_t baseConfidence, BNTokenEscapingType escaping) const { size_t count; BNInstructionTextToken* tokens = BNGetTypeTokens(m_object, platform ? platform->GetObject() : nullptr, baseConfidence, escaping, &count); return InstructionTextToken::ConvertAndFreeInstructionTextTokenList(tokens, count); } vector Type::GetTokensBeforeName(Platform* platform, uint8_t baseConfidence, BNTokenEscapingType escaping) const { size_t count; BNInstructionTextToken* tokens = BNGetTypeTokensBeforeName(m_object, platform ? platform->GetObject() : nullptr, baseConfidence, escaping, &count); return InstructionTextToken::ConvertAndFreeInstructionTextTokenList(tokens, count); } vector Type::GetTokensAfterName(Platform* platform, uint8_t baseConfidence, BNTokenEscapingType escaping) const { size_t count; BNInstructionTextToken* tokens = BNGetTypeTokensAfterName(m_object, platform ? platform->GetObject() : nullptr, baseConfidence, escaping, &count); return InstructionTextToken::ConvertAndFreeInstructionTextTokenList(tokens, count); } Ref Type::Duplicate() const { return new Type(BNDuplicateType(m_object)); } Type* Type::SetIgnored(bool setIgnored) { BNTypeSetIgnored(m_object, setIgnored); return this; } Ref Type::VoidType() { return new Type(BNCreateVoidType()); } Ref Type::BoolType() { return new Type(BNCreateBoolType()); } Ref Type::IntegerType(size_t width, const Confidence& sign, const string& altName) { BNBoolWithConfidence bc; bc.value = sign.GetValue(); bc.confidence = sign.GetConfidence(); return new Type(BNCreateIntegerType(width, &bc, altName.c_str())); } Ref Type::FloatType(size_t width, const string& altName) { return new Type(BNCreateFloatType(width, altName.c_str())); } Ref Type::WideCharType(size_t width, const string& altName) { return new Type(BNCreateWideCharType(width, altName.c_str())); } Ref Type::StructureType(Structure* strct) { return new Type(BNCreateStructureType(strct->GetObject())); } Ref Type::NamedType( NamedTypeReference* ref, size_t width, size_t align, const Confidence& cnst, const Confidence& vltl) { BNBoolWithConfidence cnstConf; cnstConf.value = cnst.GetValue(); cnstConf.confidence = cnst.GetConfidence(); BNBoolWithConfidence vltlConf; vltlConf.value = vltl.GetValue(); vltlConf.confidence = vltl.GetConfidence(); return new Type(BNCreateNamedTypeReference(ref->GetObject(), width, align, &cnstConf, &vltlConf)); } Ref Type::NamedType(const QualifiedName& name, Type* type) { return NamedType("", name, type); } Ref Type::NamedType(const string& id, const QualifiedName& name, Type* type) { BNQualifiedName nameObj = name.GetAPIObject(); BNType* coreObj = BNCreateNamedTypeReferenceFromTypeAndId(id.c_str(), &nameObj, type ? type->GetObject() : nullptr); QualifiedName::FreeAPIObject(&nameObj); return coreObj ? new Type(coreObj) : nullptr; } Ref Type::NamedType(BinaryView* view, const QualifiedName& name) { BNQualifiedName nameObj = name.GetAPIObject(); BNType* coreObj = BNCreateNamedTypeReferenceFromType(view->GetObject(), &nameObj); QualifiedName::FreeAPIObject(&nameObj); return coreObj ? new Type(coreObj) : nullptr; } Ref Type::EnumerationType(Architecture* arch, Enumeration* enm, size_t width, const Confidence& isSigned) { BNBoolWithConfidence isSignedConf; isSignedConf.value = isSigned.GetValue(); isSignedConf.confidence = isSigned.GetConfidence(); return new Type( BNCreateEnumerationType(arch ? arch->GetObject() : nullptr, enm->GetObject(), width, &isSignedConf)); } Ref Type::EnumerationType(Enumeration* enm, size_t width, const Confidence& isSigned) { BNBoolWithConfidence isSignedConf; isSignedConf.value = isSigned.GetValue(); isSignedConf.confidence = isSigned.GetConfidence(); return new Type(BNCreateEnumerationTypeOfWidth(enm->GetObject(), width, &isSignedConf)); } Ref Type::PointerType(Architecture* arch, const Confidence>& type, const Confidence& cnst, const Confidence& 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 new Type(BNCreatePointerType(arch->GetObject(), &typeConf, &cnstConf, &vltlConf, refType)); } Ref Type::PointerType(size_t width, const Confidence>& type, const Confidence& cnst, const Confidence& 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 new Type(BNCreatePointerTypeOfWidth(width, &typeConf, &cnstConf, &vltlConf, refType)); } Ref Type::ArrayType(const Confidence>& type, uint64_t elem) { BNTypeWithConfidence typeConf; typeConf.type = type->GetObject(); typeConf.confidence = type.GetConfidence(); return new Type(BNCreateArrayType(&typeConf, elem)); } Ref Type::FunctionType(const Confidence>& returnValue, const Confidence>& callingConvention, const std::vector& params, const Confidence& varArg, const Confidence& stackAdjust) { BNTypeWithConfidence returnValueConf; returnValueConf.type = returnValue->GetObject(); returnValueConf.confidence = returnValue.GetConfidence(); BNCallingConventionWithConfidence callingConventionConf; callingConventionConf.convention = callingConvention.GetValue() ? 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(); BNBoolWithConfidence canReturnConf; canReturnConf.value = true; canReturnConf.confidence = 0; BNOffsetWithConfidence stackAdjustConf; stackAdjustConf.value = stackAdjust.GetValue(); stackAdjustConf.confidence = stackAdjust.GetConfidence(); BNRegisterSetWithConfidence returnRegsConf; returnRegsConf.regs = nullptr; returnRegsConf.count = 0; returnRegsConf.confidence = 0; BNBoolWithConfidence pureConf; pureConf.value = false; pureConf.confidence = 0; Type* type = new Type(BNCreateFunctionType( &returnValueConf, &callingConventionConf, paramArray, params.size(), &varArgConf, &canReturnConf, &stackAdjustConf, nullptr, nullptr, 0, &returnRegsConf, NoNameType, &pureConf)); delete[] paramArray; return type; } Ref Type::FunctionType(const Confidence>& returnValue, const Confidence>& callingConvention, const std::vector& params, const Confidence& hasVariableArguments, const Confidence& canReturn, const Confidence& stackAdjust, const std::map>& regStackAdjust, const Confidence>& returnRegs, BNNameType ft, const Confidence& pure) { BNTypeWithConfidence returnValueConf; returnValueConf.type = returnValue->GetObject(); returnValueConf.confidence = returnValue.GetConfidence(); BNCallingConventionWithConfidence callingConventionConf; callingConventionConf.convention = callingConvention.GetValue() ? 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 = hasVariableArguments.GetValue(); varArgConf.confidence = hasVariableArguments.GetConfidence(); BNBoolWithConfidence canReturnConf; canReturnConf.value = canReturn.GetValue(); canReturnConf.confidence = canReturn.GetConfidence(); BNOffsetWithConfidence stackAdjustConf; stackAdjustConf.value = stackAdjust.GetValue(); stackAdjustConf.confidence = stackAdjust.GetConfidence(); std::vector regStackAdjustRegs; std::vector regStackAdjustValues; size_t i = 0; for (const auto& adjust: regStackAdjust) { regStackAdjustRegs[i] = adjust.first; regStackAdjustValues[i].value = adjust.second.GetValue(); regStackAdjustValues[i].confidence = adjust.second.GetConfidence(); i ++; } std::vector returnRegsRegs = returnRegs.GetValue(); BNRegisterSetWithConfidence returnRegsConf; returnRegsConf.regs = returnRegsRegs.data(); returnRegsConf.count = returnRegs->size(); returnRegsConf.confidence = returnRegs.GetConfidence(); BNBoolWithConfidence pureConf; pureConf.value = pure.GetValue(); pureConf.confidence = pure.GetConfidence(); Type* type = new Type(BNCreateFunctionType( &returnValueConf, &callingConventionConf, paramArray, params.size(), &varArgConf, &canReturnConf, &stackAdjustConf, regStackAdjustRegs.data(), regStackAdjustValues.data(), regStackAdjust.size(), &returnRegsConf, NoNameType, &pureConf)); delete[] paramArray; return type; } Ref Type::VarArgsType() { Type* type = new Type(BNCreateVarArgsType()); return type; } Ref Type::ValueType(const std::string& value) { Type* type = new Type(BNCreateValueType(value.c_str())); return type; } std::string Type::GetNameTypeString(BNNameType classFunctionType) { char* value = BNGetNameTypeString(classFunctionType); std::string result(value); BNFreeString(value); return result; } BNIntegerDisplayType Type::GetIntegerTypeDisplayType() const { return BNGetIntegerTypeDisplayType(m_object); } BNNameType Type::GetNameType() const { return BNTypeGetNameType(m_object); } bool Type::ShouldDisplayReturnType() const { return BNTypeShouldDisplayReturnType(m_object); } string Type::GenerateAutoTypeId(const string& source, const QualifiedName& name) { BNQualifiedName nameObj = name.GetAPIObject(); char* str = BNGenerateAutoTypeId(source.c_str(), &nameObj); string result = str; QualifiedName::FreeAPIObject(&nameObj); BNFreeString(str); return result; } string Type::GenerateAutoDemangledTypeId(const QualifiedName& name) { BNQualifiedName nameObj = name.GetAPIObject(); char* str = BNGenerateAutoDemangledTypeId(&nameObj); string result = str; QualifiedName::FreeAPIObject(&nameObj); BNFreeString(str); return result; } string Type::GetAutoDemangledTypeIdSource() { char* str = BNGetAutoDemangledTypeIdSource(); string result = str; BNFreeString(str); return result; } string Type::GenerateAutoDebugTypeId(const QualifiedName& name) { BNQualifiedName nameObj = name.GetAPIObject(); char* str = BNGenerateAutoDebugTypeId(&nameObj); string result = str; QualifiedName::FreeAPIObject(&nameObj); BNFreeString(str); return result; } string Type::GetAutoDebugTypeIdSource() { char* str = BNGetAutoDebugTypeIdSource(); string result = str; BNFreeString(str); return result; } QualifiedName Type::GetTypeName() const { BNQualifiedName name = BNTypeGetTypeName(m_object); QualifiedName result = QualifiedName::FromAPIObject(&name); BNFreeQualifiedName(&name); return result; } Confidence> Type::WithConfidence(uint8_t conf) { return Confidence>(this, conf); } bool Type::IsReferenceOfType(BNNamedTypeReferenceClass refType) { return (GetClass() == NamedTypeReferenceClass) && (GetNamedTypeReference()->GetTypeReferenceClass() == refType); } QualifiedName Type::GetStructureName() const { BNQualifiedName name = BNTypeGetStructureName(m_object); QualifiedName result = QualifiedName::FromAPIObject(&name); BNFreeQualifiedName(&name); return result; } bool Type::IsSystemCall() const { return BNTypeIsSystemCall(m_object); } uint32_t Type::GetSystemCallNumber() const { return BNTypeGetSystemCallNumber(m_object); } Ref Type::GetRegisteredName() const { BNNamedTypeReference* name = BNGetRegisteredTypeName(m_object); if (!name) return nullptr; return new NamedTypeReference(name); } string Type::GetAlternateName() const { char* name = BNGetTypeAlternateName(m_object); string result = name; BNFreeString(name); return result; } Ref Type::WithReplacedStructure(Structure* from, Structure* to) { BNType* result = BNTypeWithReplacedStructure(m_object, from->GetObject(), to->GetObject()); if (result == m_object) { BNFreeType(result); return this; } return new Type(result); } Ref Type::WithReplacedEnumeration(Enumeration* from, Enumeration* to) { BNType* result = BNTypeWithReplacedEnumeration(m_object, from->GetObject(), to->GetObject()); if (result == m_object) { BNFreeType(result); return this; } return new Type(result); } Ref Type::WithReplacedNamedTypeReference(NamedTypeReference* from, NamedTypeReference* to) { BNType* result = BNTypeWithReplacedNamedTypeReference(m_object, from->GetObject(), to->GetObject()); if (result == m_object) { BNFreeType(result); return this; } return new Type(result); } bool Type::AddTypeMemberTokens(BinaryView* data, vector& tokens, int64_t offset, vector& nameList, size_t size, bool indirect, FieldResolutionInfo* info) { size_t tokenCount; BNInstructionTextToken* list; size_t nameCount; char** names = nullptr; if (!BNAddTypeMemberTokens(m_object, data->GetObject(), &list, &tokenCount, offset, &names, &nameCount, size, indirect, info ? info->m_object : nullptr)) return false; vector newTokens = InstructionTextToken::ConvertAndFreeInstructionTextTokenList(list, tokenCount); tokens.insert(tokens.end(), newTokens.begin(), newTokens.end()); nameList.clear(); nameList.reserve(nameCount); for (size_t i = 0; i < nameCount; i++) nameList.emplace_back(names[i]); BNFreeStringList(names, nameCount); return true; } struct EnumerateTypesForAccessCallbackInfo { const std::function>& type, FieldResolutionInfo* path)>* callback; }; static void EnumerateTypesForAccessCallback(void* ctxt, BNTypeWithConfidence* tc, BNFieldResolutionInfo* info) { EnumerateTypesForAccessCallbackInfo* enumerateFunc = (EnumerateTypesForAccessCallbackInfo *) ctxt; Confidence> typeRef(tc->type ? new Type(BNNewTypeReference(tc->type)) : nullptr, tc->confidence); Ref path = new FieldResolutionInfo(BNNewFieldResolutionInfoReference(info)); (*enumerateFunc->callback)(typeRef, path); } bool Type::EnumerateTypesForAccess(BinaryView* data, uint64_t offset, size_t size, uint8_t baseConfidence, const std::function>& type, FieldResolutionInfo* path)>& terminal) { EnumerateTypesForAccessCallbackInfo callbackInfo = { &terminal }; return BNEnumerateTypesForAccess(m_object, data->GetObject(), offset, size, baseConfidence, EnumerateTypesForAccessCallback, &callbackInfo); } std::vector Type::GetLines(const TypeContainer& types, const std::string& name, int paddingCols, bool collapsed, BNTokenEscapingType escaping) const { size_t count; BNTypeDefinitionLine* list = BNGetTypeLines(m_object, types.GetObject(), name.c_str(), paddingCols, collapsed, escaping, &count); std::vector results; for (size_t i = 0; i < count; i++) { TypeDefinitionLine line; line.lineType = list[i].lineType; line.tokens = InstructionTextToken::ConvertInstructionTextTokenList(list[i].tokens, list[i].count); line.type = new Type(BNNewTypeReference(list[i].type)); line.parentType = list[i].parentType ? new Type(BNNewTypeReference(list[i].parentType)) : nullptr; line.rootType = list[i].rootType ? new Type(BNNewTypeReference(list[i].rootType)) : nullptr; line.rootTypeName = list[i].rootTypeName; line.baseType = list[i].baseType ? new NamedTypeReference(BNNewNamedTypeReference(list[i].baseType)) : nullptr; line.baseOffset = list[i].baseOffset; line.offset = list[i].offset; line.fieldIndex = list[i].fieldIndex; results.push_back(line); } BNFreeTypeDefinitionLineList(list, count); return results; } string Type::GetSizeSuffix(size_t size) { switch (size) { case 0: return ""; case 1: return ".b"; case 2: return ".w"; case 4: return ".d"; case 8: return ".q"; case 10: return ".t"; case 16: return ".o"; default: return fmt::format(".{}", size); } } Ref Type::DerefNamedTypeReference(BinaryView* view) const { return new Type(BNDerefNamedTypeReference(view->GetObject(), m_object)); } TypeBuilder::TypeBuilder() { m_object = BNCreateVoidTypeBuilder(); } TypeBuilder::~TypeBuilder() { BNFreeTypeBuilder(m_object); } TypeBuilder::TypeBuilder(BNTypeBuilder* type) { m_object = type; } TypeBuilder::TypeBuilder(const TypeBuilder& type) { 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 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 TypeBuilder::IsSigned() const { BNBoolWithConfidence result = BNIsTypeBuilderSigned(m_object); return Confidence(result.value, result.confidence); } Confidence TypeBuilder::IsConst() const { BNBoolWithConfidence result = BNIsTypeBuilderConst(m_object); return Confidence(result.value, result.confidence); } Confidence TypeBuilder::IsVolatile() const { BNBoolWithConfidence result = BNIsTypeBuilderVolatile(m_object); return Confidence(result.value, result.confidence); } void TypeBuilder::SetIntegerTypeDisplayType(BNIntegerDisplayType displayType) { BNSetIntegerTypeDisplayType(m_object, displayType); } TypeBuilder& TypeBuilder::SetWidth(size_t width) { BNTypeBuilderSetWidth(m_object, width); return *this; } TypeBuilder& TypeBuilder::SetAlignment(size_t alignment) { BNTypeBuilderSetAlignment(m_object, alignment); return *this; } TypeBuilder& TypeBuilder::SetConst(const Confidence& cnst) { BNBoolWithConfidence bc; bc.value = cnst.GetValue(); bc.confidence = cnst.GetConfidence(); BNTypeBuilderSetConst(m_object, &bc); return *this; } TypeBuilder& TypeBuilder::SetVolatile(const Confidence& vltl) { BNBoolWithConfidence bc; bc.value = vltl.GetValue(); bc.confidence = vltl.GetConfidence(); BNTypeBuilderSetVolatile(m_object, &bc); return *this; } TypeBuilder& TypeBuilder::SetSigned(const Confidence& s) { BNBoolWithConfidence bc; bc.value = s.GetValue(); bc.confidence = s.GetConfidence(); BNTypeBuilderSetSigned(m_object, &bc); return *this; } Confidence> TypeBuilder::GetChildType() const { BNTypeWithConfidence type = BNGetTypeBuilderChildType(m_object); if (type.type) return Confidence>(new Type(type.type), type.confidence); return nullptr; } TypeBuilder& TypeBuilder::SetChildType(const Confidence>& child) { BNTypeWithConfidence childType; childType.type = child->GetObject(); childType.confidence = child.GetConfidence(); BNTypeBuilderSetChildType(m_object, &childType); return *this; } TypeBuilder& TypeBuilder::SetCallingConvention(const Confidence>& cc) { BNCallingConventionWithConfidence ccwc; ccwc.convention = cc->GetObject(); ccwc.confidence = cc.GetConfidence(); BNTypeBuilderSetCallingConvention(m_object, &ccwc); return *this; } TypeBuilder& TypeBuilder::SetCallingConventionName(BNCallingConventionName cc) { BNTypeBuilderSetCallingConventionName(m_object, cc); return *this; } Confidence> TypeBuilder::GetCallingConvention() const { BNCallingConventionWithConfidence cc = BNGetTypeBuilderCallingConvention(m_object); if (cc.convention) return Confidence>(new CoreCallingConvention(cc.convention), cc.confidence); return nullptr; } BNCallingConventionName TypeBuilder::GetCallingConventionName() const { return BNGetTypeBuilderCallingConventionName(m_object); } vector TypeBuilder::GetParameters() const { size_t count; BNFunctionParameter* types = BNGetTypeBuilderParameters(m_object, &count); vector result; result.reserve(count); for (size_t i = 0; i < count; i++) { FunctionParameter param; param.name = types[i].name; param.type = Confidence>(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 TypeBuilder::HasVariableArguments() const { BNBoolWithConfidence result = BNTypeBuilderHasVariableArguments(m_object); return Confidence(result.value, result.confidence); } Confidence TypeBuilder::CanReturn() const { BNBoolWithConfidence result = BNFunctionTypeBuilderCanReturn(m_object); return Confidence(result.value, result.confidence); } Confidence TypeBuilder::IsPure() const { BNBoolWithConfidence result = BNIsTypeBuilderPure(m_object); return Confidence(result.value, result.confidence); } Ref TypeBuilder::GetStructure() const { BNStructure* s = BNGetTypeBuilderStructure(m_object); if (s) return new Structure(s); return nullptr; } Ref TypeBuilder::GetEnumeration() const { BNEnumeration* e = BNGetTypeBuilderEnumeration(m_object); if (e) return new Enumeration(e); return nullptr; } Ref TypeBuilder::GetNamedTypeReference() const { BNNamedTypeReference* ref = BNGetTypeBuilderNamedTypeReference(m_object); if (ref) return new NamedTypeReference(ref); return nullptr; } TypeBuilder& TypeBuilder::SetNamedTypeReference(NamedTypeReference* ntr) { BNSetTypeBuilderNamedTypeReference(m_object, ntr ? ntr->GetObject() : nullptr); return *this; } BNNameType TypeBuilder::GetNameType() const { return BNGetTypeBuilderNameType(m_object); } bool TypeBuilder::HasTemplateArguments() const { return BNTypeBuilderHasTemplateArguments(m_object); } TypeBuilder& TypeBuilder::SetNameType(BNNameType type) { BNSetTypeBuilderNameType(m_object, type); return *this; } TypeBuilder& TypeBuilder::SetHasTemplateArguments(bool hasTemplateArguments) { BNSetTypeBuilderHasTemplateArguments(m_object, hasTemplateArguments); return *this; } uint64_t TypeBuilder::GetElementCount() const { return BNGetTypeBuilderElementCount(m_object); } uint64_t TypeBuilder::GetOffset() const { return BNGetTypeBuilderOffset(m_object); } TypeBuilder& TypeBuilder::SetOffset(uint64_t offset) { BNSetTypeBuilderOffset(m_object, offset); return *this; } Confidence TypeBuilder::GetStackAdjustment() const { BNOffsetWithConfidence result = BNGetTypeBuilderStackAdjustment(m_object); return Confidence(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; } string TypeBuilder::GetStringAfterName(Platform* platform) const { char* str = BNGetTypeBuilderStringAfterName(m_object, platform ? platform->GetObject() : nullptr); string result = str; BNFreeString(str); return result; } vector 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 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 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() { return TypeBuilder(BNCreateVoidTypeBuilder()); } TypeBuilder TypeBuilder::BoolType() { return TypeBuilder(BNCreateBoolTypeBuilder()); } TypeBuilder TypeBuilder::IntegerType(size_t width, const Confidence& 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::WideCharType(size_t width, const string& altName) { return TypeBuilder(BNCreateWideCharTypeBuilder(width, altName.c_str())); } TypeBuilder TypeBuilder::StructureType(Structure* strct) { return TypeBuilder(BNCreateStructureTypeBuilder(strct->GetObject())); } TypeBuilder TypeBuilder::StructureType(StructureBuilder* strct) { return TypeBuilder(BNCreateStructureTypeBuilderWithBuilder(strct->GetObject())); } TypeBuilder TypeBuilder::NamedType( NamedTypeReference* ref, size_t width, size_t align, const Confidence& cnst, const Confidence& vltl) { BNBoolWithConfidence cnstConf; cnstConf.value = cnst.GetValue(); cnstConf.confidence = cnst.GetConfidence(); BNBoolWithConfidence vltlConf; vltlConf.value = vltl.GetValue(); vltlConf.confidence = vltl.GetConfidence(); return TypeBuilder(BNCreateNamedTypeReferenceBuilder(ref->GetObject(), width, align, &cnstConf, &vltlConf)); } TypeBuilder TypeBuilder::NamedType(NamedTypeReferenceBuilder* ref, size_t width, size_t align, const Confidence& cnst, const Confidence& vltl) { BNBoolWithConfidence cnstConf; cnstConf.value = cnst.GetValue(); cnstConf.confidence = cnst.GetConfidence(); BNBoolWithConfidence vltlConf; vltlConf.value = vltl.GetValue(); vltlConf.confidence = vltl.GetConfidence(); return TypeBuilder( BNCreateNamedTypeReferenceBuilderWithBuilder(ref->GetObject(), width, align, &cnstConf, &vltlConf)); } 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, const Confidence& isSigned) { BNBoolWithConfidence isSignedConf; isSignedConf.value = isSigned.GetValue(); isSignedConf.confidence = isSigned.GetConfidence(); return TypeBuilder( BNCreateEnumerationTypeBuilder(arch ? arch->GetObject() : nullptr, enm->GetObject(), width, &isSignedConf)); } TypeBuilder TypeBuilder::EnumerationType( Architecture* arch, EnumerationBuilder* enm, size_t width, const Confidence& isSigned) { BNBoolWithConfidence isSignedConf; isSignedConf.value = isSigned.GetValue(); isSignedConf.confidence = isSigned.GetConfidence(); return TypeBuilder(BNCreateEnumerationTypeBuilderWithBuilder( arch ? arch->GetObject() : nullptr, enm->GetObject(), width, &isSignedConf)); } TypeBuilder TypeBuilder::PointerType(Architecture* arch, const Confidence>& type, const Confidence& cnst, const Confidence& 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>& type, const Confidence& cnst, const Confidence& 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>& type, uint64_t elem) { BNTypeWithConfidence typeConf; typeConf.type = type->GetObject(); typeConf.confidence = type.GetConfidence(); return TypeBuilder(BNCreateArrayTypeBuilder(&typeConf, elem)); } static BNFunctionParameter* GetParamArray(const std::vector& params, size_t& count) { 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; } count = params.size(); return paramArray; } TypeBuilder TypeBuilder::FunctionType(const Confidence>& returnValue, const Confidence>& callingConvention, const std::vector& params, const Confidence& varArg, const Confidence& stackAdjust) { BNTypeWithConfidence returnValueConf; returnValueConf.type = returnValue->GetObject(); returnValueConf.confidence = returnValue.GetConfidence(); BNCallingConventionWithConfidence callingConventionConf; callingConventionConf.convention = callingConvention.GetValue() ? callingConvention->GetObject() : nullptr; callingConventionConf.confidence = callingConvention.GetConfidence(); size_t paramCount = 0; BNFunctionParameter* paramArray = GetParamArray(params, paramCount); BNBoolWithConfidence varArgConf; varArgConf.value = varArg.GetValue(); varArgConf.confidence = varArg.GetConfidence(); BNOffsetWithConfidence stackAdjustConf; stackAdjustConf.value = stackAdjust.GetValue(); stackAdjustConf.confidence = stackAdjust.GetConfidence(); BNBoolWithConfidence canReturnConf; canReturnConf.value = true; canReturnConf.confidence = 0; BNRegisterSetWithConfidence returnRegsConf; returnRegsConf.regs = nullptr; returnRegsConf.count = 0; returnRegsConf.confidence = 0; BNBoolWithConfidence pureConf; pureConf.value = false; pureConf.confidence = 0; TypeBuilder type(BNCreateFunctionTypeBuilder( &returnValueConf, &callingConventionConf, paramArray, paramCount, &varArgConf, &canReturnConf, &stackAdjustConf, nullptr, nullptr, 0, &returnRegsConf, NoNameType, &pureConf)); delete[] paramArray; return type; } TypeBuilder TypeBuilder::FunctionType(const Confidence>& returnValue, const Confidence>& callingConvention, const std::vector& params, const Confidence& hasVariableArguments, const Confidence& canReturn, const Confidence& stackAdjust, const std::map>& regStackAdjust, const Confidence>& returnRegs, BNNameType ft, const Confidence& pure) { BNTypeWithConfidence returnValueConf; returnValueConf.type = returnValue->GetObject(); returnValueConf.confidence = returnValue.GetConfidence(); BNCallingConventionWithConfidence callingConventionConf; callingConventionConf.convention = callingConvention.GetValue() ? 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 = hasVariableArguments.GetValue(); varArgConf.confidence = hasVariableArguments.GetConfidence(); BNBoolWithConfidence canReturnConf; canReturnConf.value = canReturn.GetValue(); canReturnConf.confidence = canReturn.GetConfidence(); BNOffsetWithConfidence stackAdjustConf; stackAdjustConf.value = stackAdjust.GetValue(); stackAdjustConf.confidence = stackAdjust.GetConfidence(); std::vector regStackAdjustRegs; std::vector regStackAdjustValues; size_t i = 0; for (const auto& adjust: regStackAdjust) { regStackAdjustRegs[i] = adjust.first; regStackAdjustValues[i].value = adjust.second.GetValue(); regStackAdjustValues[i].confidence = adjust.second.GetConfidence(); i ++; } std::vector returnRegsRegs = returnRegs.GetValue(); BNRegisterSetWithConfidence returnRegsConf; returnRegsConf.regs = returnRegsRegs.data(); returnRegsConf.count = returnRegs->size(); returnRegsConf.confidence = returnRegs.GetConfidence(); BNBoolWithConfidence pureConf; pureConf.value = pure.GetValue(); pureConf.confidence = pure.GetConfidence(); TypeBuilder type(BNCreateFunctionTypeBuilder( &returnValueConf, &callingConventionConf, paramArray, params.size(), &varArgConf, &canReturnConf, &stackAdjustConf, regStackAdjustRegs.data(), regStackAdjustValues.data(), regStackAdjust.size(), &returnRegsConf, NoNameType, &pureConf)); delete[] paramArray; return type; } TypeBuilder TypeBuilder::VarArgsType() { TypeBuilder type(BNCreateVarArgsTypeBuilder()); return type; } TypeBuilder TypeBuilder::ValueType(const std::string& value) { TypeBuilder type(BNCreateValueTypeBuilder(value.c_str())); return type; } TypeBuilder& TypeBuilder::SetFunctionCanReturn(const Confidence& canReturn) { BNBoolWithConfidence bc; bc.value = canReturn.GetValue(); bc.confidence = canReturn.GetConfidence(); BNSetFunctionTypeBuilderCanReturn(m_object, &bc); return *this; } TypeBuilder& TypeBuilder::SetPure(const Confidence& pure) { BNBoolWithConfidence bc; bc.value = pure.GetValue(); bc.confidence = pure.GetConfidence(); BNSetTypeBuilderPure(m_object, &bc); return *this; } TypeBuilder& TypeBuilder::SetParameters(const std::vector& params) { size_t paramCount = 0; BNFunctionParameter* paramArray = GetParamArray(params, paramCount); BNSetFunctionTypeBuilderParameters(m_object, paramArray, paramCount); delete[] paramArray; return *this; } TypeBuilder& TypeBuilder::SetPointerBase(BNPointerBaseType baseType, int64_t baseOffset) { BNSetTypeBuilderPointerBase(m_object, baseType, baseOffset); return *this; } std::set TypeBuilder::GetPointerSuffix() const { size_t count = 0; BNPointerSuffix* suffix = BNGetTypeBuilderPointerSuffix(m_object, &count); std::set result(suffix, suffix + count); BNFreePointerSuffixList(suffix, count); return result; } std::string TypeBuilder::GetPointerSuffixString() const { char* string = BNGetTypeBuilderPointerSuffixString(m_object); std::string result(string); BNFreeString(string); return result; } std::vector TypeBuilder::GetPointerSuffixTokens(uint8_t baseConfidence) const { size_t count = 0; BNInstructionTextToken* tokens = BNGetTypeBuilderPointerSuffixTokens(m_object, baseConfidence, &count); std::vector result = InstructionTextToken::ConvertInstructionTextTokenList(tokens, count); BNFreeInstructionText(tokens, count); return result; } TypeBuilder& TypeBuilder::AddPointerSuffix(BNPointerSuffix ps) { BNAddTypeBuilderPointerSuffix(m_object, ps); return *this; } TypeBuilder& TypeBuilder::SetPointerSuffix(const std::set& suffix) { std::vector apiSuffix; apiSuffix.reserve(suffix.size()); for (auto& s: suffix) { apiSuffix.push_back(s); } BNSetTypeBuilderPointerSuffix(m_object, apiSuffix.data(), apiSuffix.size()); return *this; } void TypeBuilder::SetAttribute(const std::string& name, const std::string& value) { BNSetTypeBuilderAttribute(m_object, name.c_str(), value.c_str()); } void TypeBuilder::SetAttributes(const std::map& values) { BNTypeAttribute* attrs = new BNTypeAttribute[values.size()]; size_t i = 0; for (auto& [name, value] : values) { attrs[i].name = (char*)name.c_str(); attrs[i].value = (char*)value.c_str(); i++; } BNSetTypeBuilderAttributeList(m_object, attrs, values.size()); } void TypeBuilder::RemoveAttribute(const std::string& name) { BNRemoveTypeBuilderAttribute(m_object, name.c_str()); } std::vector TypeBuilder::GetAttributes() const { size_t count; BNTypeAttribute* attributes = BNGetTypeBuilderAttributes(m_object, &count); std::vector result; result.reserve(count); for (size_t i = 0; i < count; i++) result.emplace_back(attributes[i].name, attributes[i].value); BNFreeTypeAttributeList(attributes, count); return result; } std::optional TypeBuilder::GetAttribute(const std::string& name) const { char* result = BNGetTypeBuilderAttributeByName(m_object, name.c_str()); if (!result) return std::nullopt; std::string resultStr(result); BNFreeString(result); return resultStr; } QualifiedName TypeBuilder::GetTypeName() const { BNQualifiedName name = BNTypeBuilderGetTypeName(m_object); QualifiedName result = QualifiedName::FromAPIObject(&name); BNFreeQualifiedName(&name); return result; } TypeBuilder& TypeBuilder::SetTypeName(const QualifiedName& names) { BNQualifiedName nameObj = names.GetAPIObject(); BNTypeBuilderSetTypeName(m_object, &nameObj); QualifiedName::FreeAPIObject(&nameObj); return *this; } TypeBuilder& TypeBuilder::SetAlternateName(const string& name) { BNTypeBuilderSetAlternateName(m_object, name.c_str()); return *this; } TypeBuilder& TypeBuilder::SetSystemCall(bool sc, uint32_t n) { BNTypeBuilderSetSystemCallNumber(m_object, sc, n); return *this; } bool TypeBuilder::IsSystemCall() const { return BNTypeBuilderIsSystemCall(m_object); } uint32_t TypeBuilder::GetSystemCallNumber() const { return BNTypeBuilderGetSystemCallNumber(m_object); } BNPointerBaseType TypeBuilder::GetPointerBaseType() const { return BNTypeBuilderGetPointerBaseType(m_object); } int64_t TypeBuilder::GetPointerBaseOffset() const { return BNTypeBuilderGetPointerBaseOffset(m_object); } 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(); m_object = BNCreateNamedType(cls, id.c_str(), &nameObj); QualifiedName::FreeAPIObject(&nameObj); } BNNamedTypeReferenceClass NamedTypeReference::GetTypeReferenceClass() 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); QualifiedName result = QualifiedName::FromAPIObject(&name); BNFreeQualifiedName(&name); return result; } Ref NamedTypeReference::GenerateAutoTypeReference( BNNamedTypeReferenceClass cls, const string& source, const QualifiedName& name) { string id = Type::GenerateAutoTypeId(source, name); return new NamedTypeReference(cls, id, name); } Ref NamedTypeReference::GenerateAutoDemangledTypeReference( BNNamedTypeReferenceClass cls, const QualifiedName& name) { string id = Type::GenerateAutoDemangledTypeId(name); return new NamedTypeReference(cls, id, name); } Ref NamedTypeReference::GenerateAutoDebugTypeReference( BNNamedTypeReferenceClass cls, const QualifiedName& name) { string id = Type::GenerateAutoDebugTypeId(name); return new NamedTypeReference(cls, id, name); } NamedTypeReferenceBuilder::NamedTypeReferenceBuilder(BNNamedTypeReferenceBuilder* nt) { m_object = nt; } NamedTypeReferenceBuilder::NamedTypeReferenceBuilder( BNNamedTypeReferenceClass cls, const std::string& id, const QualifiedName& name) { BNQualifiedName n = name.GetAPIObject(); m_object = BNCreateNamedTypeBuilder(cls, id.c_str(), &n); QualifiedName::FreeAPIObject(&n); } NamedTypeReferenceBuilder::~NamedTypeReferenceBuilder() { BNFreeNamedTypeReferenceBuilder(m_object); } BNNamedTypeReferenceClass NamedTypeReferenceBuilder::GetTypeReferenceClass() const { return BNGetTypeReferenceBuilderClass(m_object); } std::string NamedTypeReferenceBuilder::GetTypeId() const { char* str = BNGetTypeReferenceBuilderId(m_object); string result = str; BNFreeString(str); return result; } QualifiedName NamedTypeReferenceBuilder::GetName() const { BNQualifiedName name = BNGetTypeReferenceBuilderName(m_object); QualifiedName result = QualifiedName::FromAPIObject(&name); BNFreeQualifiedName(&name); return result; } void NamedTypeReferenceBuilder::SetTypeReferenceClass(BNNamedTypeReferenceClass type) { BNSetNamedTypeReferenceBuilderTypeClass(m_object, type); } void NamedTypeReferenceBuilder::SetTypeId(const string& id) { BNSetNamedTypeReferenceBuilderTypeId(m_object, id.c_str()); } void NamedTypeReferenceBuilder::SetName(const QualifiedName& name) { BNQualifiedName n = name.GetAPIObject(); BNSetNamedTypeReferenceBuilderName(m_object, &n); QualifiedName::FreeAPIObject(&n); } Ref NamedTypeReferenceBuilder::Finalize() { BNNamedTypeReference* ref = BNFinalizeNamedTypeReferenceBuilder(m_object); if (ref) return new NamedTypeReference(ref); return nullptr; } Structure::Structure(BNStructure* s) { m_object = s; } vector Structure::GetBaseStructures() const { size_t count; BNBaseStructure* bases = BNGetBaseStructuresForStructure(m_object, &count); vector result; for (size_t i = 0; i < count; i++) { BaseStructure base( new NamedTypeReference(BNNewNamedTypeReference(bases[i].type)), bases[i].offset, bases[i].width); result.push_back(base); } BNFreeBaseStructureList(bases, count); return result; } vector Structure::GetMembers() const { size_t count; BNStructureMember* members = BNGetStructureMembers(m_object, &count); vector result; result.reserve(count); for (size_t i = 0; i < count; i++) { StructureMember member; member.type = Confidence>(new Type(BNNewTypeReference(members[i].type)), members[i].typeConfidence); member.name = members[i].name; member.offset = members[i].offset; member.access = members[i].access; member.scope = members[i].scope; member.bitPosition = members[i].bitPosition; member.bitWidth = members[i].bitWidth; result.push_back(member); } BNFreeStructureMemberList(members, count); return result; } vector Structure::GetMembersIncludingInherited(const TypeContainer& types) const { size_t count; BNInheritedStructureMember* members = BNGetStructureMembersIncludingInherited(m_object, types.GetObject(), &count); vector result; result.reserve(count); for (size_t i = 0; i < count; i++) { InheritedStructureMember member; member.base = members[i].base ? new NamedTypeReference(BNNewNamedTypeReference(members[i].base)) : nullptr; member.baseOffset = members[i].baseOffset; member.member.type = Confidence>(new Type(BNNewTypeReference(members[i].member.type)), members[i].member.typeConfidence); member.member.name = members[i].member.name; member.member.offset = members[i].member.offset; member.member.access = members[i].member.access; member.member.scope = members[i].member.scope; member.member.bitPosition = members[i].member.bitPosition; member.member.bitWidth = members[i].member.bitWidth; member.memberIndex = members[i].memberIndex; result.push_back(member); } BNFreeInheritedStructureMemberList(members, count); return result; } bool Structure::GetMemberIncludingInheritedAtOffset(BinaryView* view, int64_t offset, InheritedStructureMember& result) const { BNInheritedStructureMember* member = BNGetMemberIncludingInheritedAtOffset(m_object, view->GetObject(), offset); if (!member) return false; result.base = member->base ? new NamedTypeReference(BNNewNamedTypeReference(member->base)) : nullptr; result.baseOffset = member->baseOffset; result.member.type = Confidence>(new Type(BNNewTypeReference(member->member.type)), member->member.typeConfidence); result.member.name = member->member.name; result.member.offset = member->member.offset; result.member.access = member->member.access; result.member.scope = member->member.scope; result.member.bitPosition = member->member.bitPosition; result.member.bitWidth = member->member.bitWidth; result.memberIndex = member->memberIndex; BNFreeInheritedStructureMember(member); return true; } bool Structure::GetMemberByName(const string& name, StructureMember& result) const { BNStructureMember* member = BNGetStructureMemberByName(m_object, name.c_str()); if (member) { result.type = Confidence>(new Type(BNNewTypeReference(member->type)), member->typeConfidence); result.name = member->name; result.offset = member->offset; result.access = member->access; result.scope = member->scope; result.bitPosition = member->bitPosition; result.bitWidth = member->bitWidth; BNFreeStructureMember(member); return true; } return false; } bool Structure::GetMemberAtOffset(int64_t offset, StructureMember& result) const { 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 = Confidence>(new Type(BNNewTypeReference(member->type)), member->typeConfidence); result.name = member->name; result.offset = member->offset; result.access = member->access; result.scope = member->scope; result.bitPosition = member->bitPosition; result.bitWidth = member->bitWidth; BNFreeStructureMember(member); return true; } return false; } uint64_t Structure::GetWidth() const { return BNGetStructureWidth(m_object); } int64_t Structure::GetPointerOffset() const { return BNGetStructurePointerOffset(m_object); } size_t Structure::GetAlignment() const { return BNGetStructureAlignment(m_object); } bool Structure::IsPacked() const { return BNIsStructurePacked(m_object); } bool Structure::IsUnion() const { return BNIsStructureUnion(m_object); } bool Structure::PropagateDataVariableReferences() const { return BNStructurePropagatesDataVariableReferences(m_object); } BNStructureVariant Structure::GetStructureType() const { return BNGetStructureType(m_object); } Ref Structure::WithReplacedStructure(Structure* from, Structure* to) { BNStructure* result = BNStructureWithReplacedStructure(m_object, from->GetObject(), to->GetObject()); if (result == m_object) { BNFreeStructure(result); return this; } return new Structure(result); } Ref Structure::WithReplacedEnumeration(Enumeration* from, Enumeration* to) { BNStructure* result = BNStructureWithReplacedEnumeration(m_object, from->GetObject(), to->GetObject()); if (result == m_object) { BNFreeStructure(result); return this; } return new Structure(result); } Ref Structure::WithReplacedNamedTypeReference(NamedTypeReference* from, NamedTypeReference* to) { BNStructure* result = BNStructureWithReplacedNamedTypeReference(m_object, from->GetObject(), to->GetObject()); if (result == m_object) { BNFreeStructure(result); return this; } return new Structure(result); } struct ResolveMemberCallbackInfo { const std::function* callback; }; static void ResolveMemberCallback(void* ctxt, BNNamedTypeReference* baseName, BNStructure* resolvedStruct, size_t memberIndex, uint64_t structOffset, uint64_t adjustedOffset, BNStructureMember member) { ResolveMemberCallbackInfo* resolveFunc = (ResolveMemberCallbackInfo*)ctxt; Ref baseNameRef = baseName ? new NamedTypeReference(BNNewNamedTypeReference(baseName)) : nullptr; Ref resolvedStructRef = resolvedStruct ? new Structure(BNNewStructureReference(resolvedStruct)) : nullptr; StructureMember apiMember; apiMember.type = Confidence>(new Type(BNNewTypeReference(member.type)), member.typeConfidence); apiMember.name = member.name; apiMember.offset = member.offset; apiMember.access = member.access; apiMember.scope = member.scope; apiMember.bitPosition = member.bitPosition; apiMember.bitWidth = member.bitWidth; (*resolveFunc->callback)(baseNameRef, resolvedStructRef, memberIndex, structOffset, adjustedOffset, apiMember); } bool Structure::ResolveMemberOrBaseMember(BinaryView* data, uint64_t offset, size_t size, const std::function& resolveFunc, std::optional memberIndexHint) { ResolveMemberCallbackInfo callbackInfo = { &resolveFunc }; return BNResolveStructureMemberOrBaseMember(m_object, data ? data->GetObject() : nullptr, offset, size, &callbackInfo, ResolveMemberCallback, memberIndexHint.has_value(), memberIndexHint.value_or(0)); } StructureBuilder::StructureBuilder() { m_object = BNCreateStructureBuilder(); } StructureBuilder::StructureBuilder(BNStructureBuilder* s) { m_object = s; } StructureBuilder::StructureBuilder(BNStructureVariant 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(); } 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 StructureBuilder::Finalize() const { return new Structure(BNFinalizeStructureBuilder(m_object)); } vector StructureBuilder::GetBaseStructures() const { size_t count; BNBaseStructure* bases = BNGetBaseStructuresForStructureBuilder(m_object, &count); vector result; for (size_t i = 0; i < count; i++) { BaseStructure base( new NamedTypeReference(BNNewNamedTypeReference(bases[i].type)), bases[i].offset, bases[i].width); result.push_back(base); } BNFreeBaseStructureList(bases, count); return result; } StructureBuilder& StructureBuilder::SetBaseStructures(const vector& bases) { BNBaseStructure* baseObjs = new BNBaseStructure[bases.size()]; for (size_t i = 0; i < bases.size(); i++) { baseObjs[i].type = bases[i].type->GetObject(); baseObjs[i].offset = bases[i].offset; baseObjs[i].width = bases[i].width; } BNSetBaseStructuresForStructureBuilder(m_object, baseObjs, bases.size()); delete[] baseObjs; return *this; } vector StructureBuilder::GetMembers() const { size_t count; BNStructureMember* members = BNGetStructureBuilderMembers(m_object, &count); vector result; result.reserve(count); for (size_t i = 0; i < count; i++) { StructureMember member; member.type = Confidence>(new Type(BNNewTypeReference(members[i].type)), members[i].typeConfidence); member.name = members[i].name; member.offset = members[i].offset; member.access = members[i].access; member.scope = members[i].scope; member.bitPosition = members[i].bitPosition; member.bitWidth = members[i].bitWidth; 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 = Confidence>(new Type(BNNewTypeReference(member->type)), member->typeConfidence); result.name = member->name; result.offset = member->offset; result.access = member->access; result.scope = member->scope; result.bitPosition = member->bitPosition; result.bitWidth = member->bitWidth; 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 = Confidence>(new Type(BNNewTypeReference(member->type)), member->typeConfidence); result.name = member->name; result.offset = member->offset; result.access = member->access; result.scope = member->scope; result.bitPosition = member->bitPosition; result.bitWidth = member->bitWidth; BNFreeStructureMember(member); return true; } return false; } uint64_t StructureBuilder::GetWidth() const { return BNGetStructureBuilderWidth(m_object); } StructureBuilder& StructureBuilder::SetWidth(size_t width) { BNSetStructureBuilderWidth(m_object, width); return *this; } int64_t StructureBuilder::GetPointerOffset() const { return BNGetStructureBuilderPointerOffset(m_object); } StructureBuilder& StructureBuilder::SetPointerOffset(int64_t offset) { BNSetStructureBuilderPointerOffset(m_object, offset); return *this; } size_t StructureBuilder::GetAlignment() const { return BNGetStructureBuilderAlignment(m_object); } StructureBuilder& StructureBuilder::SetAlignment(size_t align) { BNSetStructureBuilderAlignment(m_object, align); return *this; } bool StructureBuilder::IsPacked() const { return BNIsStructureBuilderPacked(m_object); } StructureBuilder& StructureBuilder::SetPacked(bool packed) { BNSetStructureBuilderPacked(m_object, packed); return *this; } bool StructureBuilder::IsUnion() const { return BNIsStructureBuilderUnion(m_object); } bool StructureBuilder::PropagateDataVariableReferences() const { return BNStructureBuilderPropagatesDataVariableReferences(m_object); } StructureBuilder& StructureBuilder::SetPropagateDataVariableReferences(bool value) { BNSetStructureBuilderPropagatesDataVariableReferences(m_object, value); return *this; } StructureBuilder& StructureBuilder::SetStructureType(BNStructureVariant t) { BNSetStructureBuilderType(m_object, t); return *this; } BNStructureVariant StructureBuilder::GetStructureType() const { return BNGetStructureBuilderType(m_object); } StructureBuilder& StructureBuilder::AddMember( const Confidence>& type, const string& name, BNMemberAccess access, BNMemberScope scope) { BNTypeWithConfidence tc; tc.type = type->GetObject(); tc.confidence = type.GetConfidence(); BNAddStructureBuilderMember(m_object, &tc, name.c_str(), access, scope); return *this; } StructureBuilder& StructureBuilder::AddMemberAtOffset(const Confidence>& type, const string& name, uint64_t offset, bool overwriteExisting, BNMemberAccess access, BNMemberScope scope, uint8_t bitPosition, uint8_t bitWidth) { BNTypeWithConfidence tc; tc.type = type->GetObject(); tc.confidence = type.GetConfidence(); BNAddStructureBuilderMemberAtOffset(m_object, &tc, name.c_str(), offset, overwriteExisting, access, scope, bitPosition, bitWidth); return *this; } StructureBuilder& StructureBuilder::AddMemberAtBitOffset(const Confidence>& type, const string& name, uint64_t bitOffset, uint8_t bitWidth, bool overwriteExisting, BNMemberAccess access, BNMemberScope scope) { const uint64_t byteOffset = bitOffset / 8; const uint8_t bitPosition = bitOffset % 8; return AddMemberAtOffset(type, name, byteOffset, overwriteExisting, access, scope, bitPosition, bitWidth); } StructureBuilder& StructureBuilder::RemoveMember(size_t idx) { BNRemoveStructureBuilderMember(m_object, idx); return *this; } StructureBuilder& StructureBuilder::ReplaceMember( size_t idx, const Confidence>& type, const std::string& name, bool overwriteExisting) { BNTypeWithConfidence tc; tc.type = type->GetObject(); tc.confidence = type.GetConfidence(); BNReplaceStructureBuilderMember(m_object, idx, &tc, name.c_str(), overwriteExisting); return *this; } Enumeration::Enumeration(BNEnumeration* e) { m_object = e; } vector Enumeration::GetMembers() const { size_t count; BNEnumerationMember* members = BNGetEnumerationMembers(m_object, &count); vector 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; } vector Enumeration::GetTokensForValue(uint64_t value, size_t width, Ref type) { size_t count; BNInstructionTextToken* tokens = BNGetEnumerationTokensForValue(m_object, value, width, &count, type->GetObject()); return InstructionTextToken::ConvertAndFreeInstructionTextTokenList(tokens, count); } EnumerationBuilder::EnumerationBuilder() { m_object = BNCreateEnumerationBuilder(); } 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 EnumerationBuilder::Finalize() const { return new Enumeration(BNFinalizeEnumerationBuilder(m_object)); } vector EnumerationBuilder::GetMembers() const { size_t count; BNEnumerationMember* members = BNGetEnumerationBuilderMembers(m_object, &count); vector 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::AddMember(const string& name) { BNAddEnumerationBuilderMember(m_object, name.c_str()); return *this; } EnumerationBuilder& EnumerationBuilder::AddMemberWithValue(const string& name, uint64_t value) { BNAddEnumerationBuilderMemberWithValue(m_object, name.c_str(), value); return *this; } EnumerationBuilder& EnumerationBuilder::RemoveMember(size_t idx) { BNRemoveEnumerationBuilderMember(m_object, idx); return *this; } EnumerationBuilder& EnumerationBuilder::ReplaceMember(size_t idx, const string& name, uint64_t value) { BNReplaceEnumerationBuilderMember(m_object, idx, name.c_str(), value); return *this; } 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; } fmt::format_context::iterator fmt::formatter::format( const Type& obj, fmt::format_context& ctx ) const { if (presentation == '?') { auto tc = TypeContainer::GetEmptyTypeContainer(); auto lines = obj.GetLines(tc, ""); string result = ""; for (auto& line: lines) { string lineStr = ""; for (auto& token: line.tokens) { lineStr += token.text; } result += lineStr + "\n"; } // Remove trailing newline if (!result.empty()) result.erase(result.size() - 1); return fmt::format_to(ctx.out(), "{}", result); } else { return fmt::format_to(ctx.out(), "{}{}", obj.GetStringBeforeName(), obj.GetStringAfterName()); } }