@@ -1564,11 +1564,29 @@ namespace BinaryNinja {
15641564 */
15651565 Ref<BinaryView> Load(Ref<BinaryView> rawData, bool updateAnalysis, std::function<bool(size_t, size_t)> progress, Ref<Metadata> options = new Metadata(MetadataType::KeyValueDataType), bool isDatabase = false);
15661566
1567+ /*! Attempt to demangle a mangled name, trying all relevant demanglers and using whichever one accepts it
1568+
1569+ \see Demangler::Demangle for a discussion on which demangler will be used.
1570+
1571+ \param[in] arch Architecture for the symbol. Required for pointer and integer sizes.
1572+ \param[in] mangledName a mangled Microsoft Visual Studio C++ name
1573+ \param[out] outType Pointer to Type to output
1574+ \param[out] outVarName QualifiedName reference to write the output name to.
1575+ \param[in] view (Optional) view of the binary containing the mangled name
1576+ \param[in] simplify (Optional) Whether to simplify demangled names.
1577+ \return True if the name was demangled and written to the out* parameters
1578+
1579+ \ingroup demangle
1580+ */
1581+ bool DemangleGeneric(Ref<Architecture> arch, const std::string& mangledName, Ref<Type>& outType, QualifiedName& outVarName,
1582+ Ref<BinaryView> view = nullptr, const bool simplify = false);
1583+
15671584 /*! Demangles using LLVM's demangler
15681585
15691586 \param[in] mangledName a mangled (msvc/itanium/rust/dlang) name
15701587 \param[out] outVarName QualifiedName reference to write the output name to.
15711588 \param[in] simplify Whether to simplify demangled names.
1589+ \return True if the name was demangled and written to the out* parameters
15721590
15731591 \ingroup demangle
15741592 */
@@ -1579,6 +1597,7 @@ namespace BinaryNinja {
15791597 \param[in] mangledName a mangled (msvc/itanium/rust/dlang) name
15801598 \param[out] outVarName QualifiedName reference to write the output name to.
15811599 \param[in] view View to check the analysis.types.templateSimplifier for
1600+ \return True if the name was demangled and written to the out* parameters
15821601
15831602 \ingroup demangle
15841603 */
@@ -1591,6 +1610,7 @@ namespace BinaryNinja {
15911610 \param[out] outType Reference to Type to output
15921611 \param[out] outVarName QualifiedName reference to write the output name to.
15931612 \param[in] simplify Whether to simplify demangled names.
1613+ \return True if the name was demangled and written to the out* parameters
15941614
15951615 \ingroup demangle
15961616 */
@@ -1607,6 +1627,7 @@ namespace BinaryNinja {
16071627 \param[out] outType Reference to Type to output
16081628 \param[out] outVarName QualifiedName reference to write the output name to.
16091629 \param[in] view View to check the analysis.types.templateSimplifier for
1630+ \return True if the name was demangled and written to the out* parameters
16101631
16111632 \ingroup demangle
16121633 */
@@ -1620,6 +1641,7 @@ namespace BinaryNinja {
16201641 \param[out] outType Reference to Type to output
16211642 \param[out] outVarName QualifiedName reference to write the output name to.
16221643 \param[in] simplify Whether to simplify demangled names.
1644+ \return True if the name was demangled and written to the out* parameters
16231645
16241646 \ingroup demangle
16251647 */
@@ -1636,6 +1658,7 @@ namespace BinaryNinja {
16361658 \param[out] outType Reference to Type to output
16371659 \param[out] outVarName QualifiedName reference to write the output name to.
16381660 \param[in] view View to check the analysis.types.templateSimplifier for
1661+ \return True if the name was demangled and written to the out* parameters
16391662
16401663 \ingroup demangle
16411664 */
@@ -17968,6 +17991,98 @@ namespace BinaryNinja {
1796817991 bool IsAborted();
1796917992 };
1797017993
17994+ /*!
17995+ \ingroup demangler
17996+ */
17997+ class Demangler: public StaticCoreRefCountObject<BNDemangler>
17998+ {
17999+ std::string m_nameForRegister;
18000+
18001+ protected:
18002+ explicit Demangler(const std::string& name);
18003+ Demangler(BNDemangler* demangler);
18004+ virtual ~Demangler() = default;
18005+
18006+ static bool IsMangledStringCallback(void* ctxt, const char* name);
18007+ static bool DemangleCallback(void* ctxt, BNArchitecture* arch, const char* name, BNType** outType,
18008+ BNQualifiedName* outVarName, BNBinaryView* view);
18009+ static void FreeVarNameCallback(void* ctxt, BNQualifiedName* name);
18010+
18011+ public:
18012+ /*! Register a custom Demangler. Newly registered demanglers will get priority over
18013+ previously registered demanglers and built-in demanglers.
18014+ */
18015+ static void Register(Demangler* demangler);
18016+
18017+ /*! Get the list of currently registered demanglers, sorted by lowest to highest priority.
18018+
18019+ \return List of demanglers
18020+ */
18021+ static std::vector<Ref<Demangler>> GetList();
18022+ static Ref<Demangler> GetByName(const std::string& name);
18023+
18024+ /*! Promote a demangler to the highest-priority position.
18025+
18026+ \param demangler Demangler to promote
18027+ */
18028+ static void Promote(Ref<Demangler> demangler);
18029+
18030+ std::string GetName() const;
18031+
18032+ /*! Determine if a given name is mangled and this demangler can process it
18033+
18034+ The most recently registered demangler that claims a name is a mangled string
18035+ (returns true from this function), and then returns a value from Demangle will
18036+ determine the result of a call to DemangleGeneric. Returning True from this
18037+ does not require the demangler to succeed the call to Demangle, but simply
18038+ implies that it may succeed.
18039+
18040+ \param name Raw mangled name string
18041+ \return True if the demangler thinks it can handle the name
18042+ */
18043+ virtual bool IsMangledString(const std::string& name) = 0;
18044+
18045+ /*! Demangle a raw name into a Type and QualifiedName.
18046+
18047+ Any unresolved named types referenced by the resulting Type will be created as
18048+ empty structures or void typedefs in the view, if the result is used on
18049+ a data structure in the view. Given this, the call to Demangle should NOT
18050+ cause any side-effects creating types in the view trying to resolve this
18051+ and instead just return a type with unresolved named type references.
18052+
18053+ The most recently registered demangler that claims a name is a mangled string
18054+ (returns true from IsMangledString), and then returns a value from
18055+ this function will determine the result of a call to DemangleGeneric.
18056+ If this call returns None, the next most recently used demangler(s) will be tried instead.
18057+
18058+ If the mangled name has no type information, but a name is still possible to extract,
18059+ this function may return a successful result with outType=nullptr, which will be accepted.
18060+
18061+ \param arch Architecture for context in which the name exists, eg for pointer sizes
18062+ \param name Raw mangled name
18063+ \param outType Resulting type, if one can be deduced, will be written here. Otherwise nullptr will be written
18064+ \param outVarName Resulting variable name
18065+ \param view (Optional) BinaryView context in which the name exists, eg for type lookup
18066+ \return True if demangling was successful and results were stored into out-parameters
18067+ */
18068+ virtual bool Demangle(Ref<Architecture> arch, const std::string& name, Ref<Type>& outType,
18069+ QualifiedName& outVarName, Ref<BinaryView> view = nullptr) = 0;
18070+ };
18071+
18072+ /*!
18073+ \ingroup demangler
18074+ */
18075+ class CoreDemangler: public Demangler
18076+ {
18077+ public:
18078+ CoreDemangler(BNDemangler* demangler);
18079+ virtual ~CoreDemangler() = default;
18080+
18081+ virtual bool IsMangledString(const std::string& name);
18082+ virtual bool Demangle(Ref<Architecture> arch, const std::string& name, Ref<Type>& outType,
18083+ QualifiedName& outVarName, Ref<BinaryView> view);
18084+ };
18085+
1797118086 namespace Unicode
1797218087 {
1797318088 std::string UTF16ToUTF8(const uint8_t* utf16, const size_t len);
0 commit comments