summaryrefslogtreecommitdiff
path: root/demangler/msvc/demangle_msvc.h
diff options
context:
space:
mode:
authorGlenn Smith <glenn@vector35.com>2024-09-23 17:15:17 -0400
committerGlenn Smith <glenn@vector35.com>2024-10-17 17:33:52 -0400
commit8149774201203326096099394434871992996628 (patch)
treed968976df167dc74090f61051c41ca30e5cc7c8e /demangler/msvc/demangle_msvc.h
parent5353484086517832418955474757290903351986 (diff)
Demangler plugin API
Closes #467
Diffstat (limited to 'demangler/msvc/demangle_msvc.h')
-rw-r--r--demangler/msvc/demangle_msvc.h162
1 files changed, 162 insertions, 0 deletions
diff --git a/demangler/msvc/demangle_msvc.h b/demangler/msvc/demangle_msvc.h
new file mode 100644
index 00000000..d52b666a
--- /dev/null
+++ b/demangler/msvc/demangle_msvc.h
@@ -0,0 +1,162 @@
+// Copyright 2016-2024 Vector 35 Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#pragma once
+#include <stdexcept>
+#include <exception>
+#include <string>
+#include <vector>
+#include <set>
+#include "binaryninjaapi.h"
+
+
+class DemangleException: public std::exception
+{
+ std::string m_message;
+public:
+ DemangleException(std::string msg="Attempt to read beyond bounds or missing expected character"): m_message(msg){}
+ virtual const char* what() const noexcept { return m_message.c_str(); }
+};
+
+
+class Demangle
+{
+ enum NameType
+ {
+ NameEmpty,
+ NameString,
+ NameLookup,
+ NameBackref,
+ NameTemplate,
+ NameConstructor,
+ NameDestructor,
+ NameRtti,
+ NameReturn,
+ NameDynamicInitializer,
+ NameDynamicAtExitDestructor,
+ NameLocalStaticThreadGuard,
+ NameLocalVftable
+ };
+
+ enum FunctionClass
+ {
+ NoneFunctionClass = 0,
+ PrivateFunctionClass = 1 << 0,
+ ProtectedFunctionClass = 1 << 1,
+ PublicFunctionClass = 1 << 2,
+ GlobalFunctionClass = 1 << 3,
+ StaticFunctionClass = 1 << 4,
+ VirtualFunctionClass = 1 << 5,
+ FriendFunctionClass = 1 << 6,
+ StaticThunkFunctionClass = 1 << 7,
+ VirtualThunkFunctionClass = 1 << 8,
+ VirtualThunkExFunctionClass = 1 << 9,
+ };
+
+ class Reader
+ {
+ public:
+ Reader(std::string data);
+ std::string PeekString(size_t count=1);
+ char Peek();
+ const char* GetRaw();
+ char Read();
+ std::string ReadString(size_t count=1);
+ std::string ReadUntil(char sentinal);
+ void Consume(size_t count=1);
+ size_t Length();
+ private:
+ std::string m_data;
+ };
+
+ class BackrefList
+ {
+ public:
+ std::vector<BinaryNinja::TypeBuilder> typeList;
+ std::vector<std::string> nameList;
+ const BinaryNinja::TypeBuilder& GetTypeBackref(size_t reference);
+ std::string GetStringBackref(size_t reference);
+ void PushTypeBackref(BinaryNinja::TypeBuilder t);
+ void PushStringBackref(std::string& s);
+ void PushFrontStringBackref(std::string& s);
+ };
+
+ Reader reader;
+ BackrefList m_backrefList;
+ BinaryNinja::Architecture* m_arch;
+ BinaryNinja::Ref<BinaryNinja::Platform> m_platform;
+ BinaryNinja::Ref<BinaryNinja::BinaryView> m_view;
+ BinaryNinja::QualifiedName m_varName;
+ BinaryNinja::Ref<BinaryNinja::Logger> m_logger;
+
+ NameType GetNameType();
+ BinaryNinja::TypeBuilder DemangleVarType(BackrefList& varList, bool isReturn, BinaryNinja::QualifiedName& name);
+ void DemangleNumber(int64_t& num);
+ void DemangleChar(char& ch);
+ void DemangleWideChar(uint16_t& wch);
+ void DemangleModifiers(bool& _const, bool& _volatile, bool& isMember);
+ std::set<BNPointerSuffix> DemanglePointerSuffix();
+ void DemangleVariableList(std::vector<BinaryNinja::FunctionParameter>& paramList, BackrefList& varList);
+ void DemangleNameTypeRtti(BNNameType& classFunctionType,
+ BackrefList& nameBackrefList,
+ std::string& out,
+ std::string& rttiTypeName);
+ void DemangleTypeNameLookup(std::string& out, BNNameType& functionType);
+ void DemangleNameTypeString(std::string& out);
+ void DemangleNameTypeBackref(std::string& out, const std::vector<std::string>& backrefList);
+ void DemangleName(BinaryNinja::QualifiedName& nameList,
+ BNNameType& classFunctionType,
+ BackrefList& nameBackrefList);
+ BinaryNinja::Ref<BinaryNinja::CallingConvention> GetCallingConventionForType(BNCallingConventionName ccName);
+ BNCallingConventionName DemangleCallingConvention();
+ BinaryNinja::TypeBuilder DemangleFunction(BNNameType classFunctionType, bool pointerSuffix, BackrefList& varList, int funcClass = NoneFunctionClass);
+ BinaryNinja::TypeBuilder DemangleData();
+ void DemangleNameTypeRtti(BNNameType& classFunctionType,
+ BackrefList& nameBackrefList,
+ std::string& out);
+ BinaryNinja::TypeBuilder DemangleVTable();
+ BinaryNinja::TypeBuilder DemanagleRTTI(BNNameType classFunctionType);
+ std::string DemangleTemplateInstantiationName(BackrefList& nameBackrefList);
+ std::string DemangleTemplateParams(std::vector<BinaryNinja::FunctionParameter>& params, BackrefList& nameBackrefList, std::string& out);
+ std::string DemangleUnqualifiedSymbolName(BinaryNinja::QualifiedName& nameList, BackrefList& nameBackrefList, BNNameType& classFunctionType);
+ BinaryNinja::TypeBuilder DemangleString();
+ BinaryNinja::TypeBuilder DemangleTypeInfoName();
+
+public:
+ struct DemangleContext
+ {
+ BinaryNinja::TypeBuilder type;
+ BNMemberAccess access;
+ BNMemberScope scope;
+ };
+ Demangle(BinaryNinja::Architecture* arch, std::string mangledName);
+ Demangle(BinaryNinja::Ref<BinaryNinja::BinaryView> view, std::string mangledName);
+ Demangle(BinaryNinja::Ref<BinaryNinja::Platform> platform, std::string mangledName);
+ DemangleContext DemangleSymbol();
+ BinaryNinja::QualifiedName GetVarName() const { return m_varName; }
+
+ // Be careful not to accidentally implicitly cast a BinaryView* to a bool
+ static bool DemangleMS(BinaryNinja::Architecture* arch, const std::string& mangledName, BinaryNinja::Ref<BinaryNinja::Type>& outType,
+ BinaryNinja::QualifiedName& outVarName, const BinaryNinja::Ref<BinaryNinja::BinaryView>& view);
+ static bool DemangleMS(BinaryNinja::Architecture* arch, const std::string& mangledName, BinaryNinja::Ref<BinaryNinja::Type>& outType,
+ BinaryNinja::QualifiedName& outVarName, BinaryNinja::BinaryView* view);
+ static bool DemangleMS(BinaryNinja::Architecture* arch, const std::string& mangledName, BinaryNinja::Ref<BinaryNinja::Type>& outType,
+ BinaryNinja::QualifiedName& outVarName);
+
+ static bool DemangleMS(const std::string& mangledName, BinaryNinja::Ref<BinaryNinja::Type>& outType,
+ BinaryNinja::QualifiedName& outVarName, const BinaryNinja::Ref<BinaryNinja::BinaryView>& view);
+ static bool DemangleMS(const std::string& mangledName, BinaryNinja::Ref<BinaryNinja::Type>& outType,
+ BinaryNinja::QualifiedName& outVarName, BinaryNinja::BinaryView* view);
+};
+