#pragma once #include "binaryninjaapi.h" constexpr const char *VIEW_METADATA_RTTI = "rtti"; constexpr int RTTI_CONFIDENCE = 100; namespace BinaryNinja::RTTI { Ref GetRealSymbol(BinaryView *view, uint64_t relocAddr, uint64_t symAddr); std::optional DemangleNameMS(BinaryView* view, bool allowMangled, const std::string &mangledName); std::optional DemangleNameGNU3(BinaryView* view, bool allowMangled, const std::string &mangledName); std::optional DemangleNameItanium(BinaryView* view, bool allowMangled, const std::string &mangledName); std::optional DemangleNameLLVM(bool allowMangled, const std::string &mangledName); struct VirtualFunctionInfo { uint64_t funcAddr; Ref SerializedMetadata() const; static VirtualFunctionInfo DeserializedMetadata(const Ref &metadata); }; struct VirtualFunctionTableInfo { uint64_t address; std::vector virtualFunctions; Ref SerializedMetadata(bool serializeFunctions = true) const; static VirtualFunctionTableInfo DeserializedMetadata(const Ref &metadata); }; enum class RTTIProcessorType { Microsoft = 0, Itanium = 1, }; struct BaseClassInfo { std::string className; // TODO: This has to be optional, as we might need to resolve this at a later stage. // TODO: The offset also might literally not exist. uint64_t offset; std::optional vft; Ref SerializedMetadata() const; static BaseClassInfo DeserializedMetadata(const Ref &metadata); }; // TODO: This needs to have some flags. Virtual, pure iirc. struct ClassInfo { RTTIProcessorType processor; std::string className; std::optional vft; std::vector baseClasses; Ref SerializedMetadata() const; static ClassInfo DeserializedMetadata(const Ref &metadata); }; class RTTIProcessor { protected: enum class FunctionDiscoverState { Failed = 0, AlreadyExists = 1, Discovered = 2, Extern = 3 }; Ref m_view; Ref m_logger; std::map m_classInfo; std::map m_unhandledClassInfo; virtual std::optional ProcessRTTI(uint64_t objectAddr) = 0; virtual std::optional ProcessVFT(uint64_t vftAddr, ClassInfo &classInfo, std::optional baseClassInfo) = 0; [[nodiscard]] bool IsLikelyFunction(uint64_t addr) const; [[nodiscard]] FunctionDiscoverState DiscoverVirtualFunction(uint64_t vftEntryAddr, uint64_t& vFuncAddr); public: virtual ~RTTIProcessor() = default; void DeserializedMetadata(RTTIProcessorType type, const Ref &metadata); Ref SerializedMetadata(); virtual void ProcessRTTI() = 0; virtual void ProcessVFT() = 0; }; }