diff options
| author | Glenn Smith <glenn@vector35.com> | 2024-09-23 17:15:17 -0400 |
|---|---|---|
| committer | Glenn Smith <glenn@vector35.com> | 2024-10-17 17:33:52 -0400 |
| commit | 8149774201203326096099394434871992996628 (patch) | |
| tree | d968976df167dc74090f61051c41ca30e5cc7c8e /demangle.cpp | |
| parent | 5353484086517832418955474757290903351986 (diff) | |
Demangler plugin API
Closes #467
Diffstat (limited to 'demangle.cpp')
| -rw-r--r-- | demangle.cpp | 135 |
1 files changed, 135 insertions, 0 deletions
diff --git a/demangle.cpp b/demangle.cpp index 3217905c..ad392d47 100644 --- a/demangle.cpp +++ b/demangle.cpp @@ -1,8 +1,27 @@ #include "binaryninjaapi.h" #include <string> using namespace std; +using namespace BinaryNinja; namespace BinaryNinja { + bool DemangleGeneric(Ref<Architecture> arch, const std::string& name, Ref<Type>& outType, + QualifiedName& outVarName, Ref<BinaryView> view, bool simplify) + { + BNType* apiType; + BNQualifiedName apiVarName; + bool success = BNDemangleGeneric( + arch->m_object, name.c_str(), &apiType, &apiVarName, view ? view->m_object : nullptr, simplify); + + if (!success) + return false; + + if (apiType) + outType = new Type(apiType); + outVarName = QualifiedName::FromAPIObject(&apiVarName); + BNFreeQualifiedName(&apiVarName); + return true; + } + bool DemangleLLVM(const std::string& mangledName, QualifiedName& outVarName, BinaryView* view) { @@ -109,4 +128,120 @@ namespace BinaryNinja { BNFreeQualifiedName(&name); return result; } + + Demangler::Demangler(const std::string& name): m_nameForRegister(name) + { + } + + Demangler::Demangler(BNDemangler* demangler) + { + m_object = demangler; + } + + bool Demangler::IsMangledStringCallback(void* ctxt, const char* name) + { + Demangler* demangler = (Demangler*)ctxt; + return demangler->IsMangledString(name); + } + + bool Demangler::DemangleCallback(void* ctxt, BNArchitecture* arch, const char* name, BNType** outType, + BNQualifiedName* outVarName, BNBinaryView* view) + { + Demangler* demangler = (Demangler*)ctxt; + + Ref<Architecture> apiArch = new CoreArchitecture(arch); + Ref<BinaryView> apiView = view ? new BinaryView(BNNewViewReference(view)) : nullptr; + + Ref<Type> apiType; + QualifiedName apiVarName; + bool success = demangler->Demangle(apiArch, name, apiType, apiVarName, apiView); + if (!success) + return false; + + if (apiType) + { + *outType = BNNewTypeReference(apiType->m_object); + } + else + { + *outType = nullptr; + } + *outVarName = apiVarName.GetAPIObject(); + + return true; + } + + void Demangler::FreeVarNameCallback(void* ctxt, BNQualifiedName* name) + { + QualifiedName::FreeAPIObject(name); + } + + void Demangler::Register(Demangler* demangler) + { + BNDemanglerCallbacks cb; + cb.context = (void*)demangler; + cb.isMangledString = IsMangledStringCallback; + cb.demangle = DemangleCallback; + cb.freeVarName = FreeVarNameCallback; + demangler->m_object = BNRegisterDemangler(demangler->m_nameForRegister.c_str(), &cb); + } + + std::vector<Ref<Demangler>> Demangler::GetList() + { + size_t count; + BNDemangler** list = BNGetDemanglerList(&count); + vector<Ref<Demangler>> result; + for (size_t i = 0; i < count; i++) + result.push_back(new CoreDemangler(list[i])); + BNFreeDemanglerList(list); + return result; + } + + Ref<Demangler> Demangler::GetByName(const std::string& name) + { + BNDemangler* result = BNGetDemanglerByName(name.c_str()); + if (!result) + return nullptr; + return new CoreDemangler(result); + } + + void Demangler::Promote(Ref<Demangler> demangler) + { + BNPromoteDemangler(demangler->m_object); + } + + std::string Demangler::GetName() const + { + char* name = BNGetDemanglerName(m_object); + std::string value = name; + BNFreeString(name); + return value; + } + + CoreDemangler::CoreDemangler(BNDemangler* demangler): Demangler(demangler) + { + } + + bool CoreDemangler::IsMangledString(const std::string& name) + { + return BNIsDemanglerMangledName(m_object, name.c_str()); + } + + bool CoreDemangler::Demangle(Ref<Architecture> arch, const std::string& name, Ref<Type>& outType, + QualifiedName& outVarName, Ref<BinaryView> view) + { + BNType* apiType; + BNQualifiedName apiVarName; + bool success = BNDemanglerDemangle( + m_object, arch->m_object, name.c_str(), &apiType, &apiVarName, view ? view->m_object : nullptr); + + if (!success) + return false; + + if (apiType) + outType = new Type(apiType); + outVarName = QualifiedName::FromAPIObject(&apiVarName); + BNFreeQualifiedName(&apiVarName); + return true; + } } // namespace BinaryNinja |
