summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--binaryninjaapi.h20
-rw-r--r--binaryninjacore.h5
-rw-r--r--demangle.cpp23
-rw-r--r--python/demangle.py33
-rw-r--r--rust/src/demangle.rs43
-rw-r--r--suite/api_test.py2
6 files changed, 125 insertions, 1 deletions
diff --git a/binaryninjaapi.h b/binaryninjaapi.h
index 5ec190b2..9d4a3ae6 100644
--- a/binaryninjaapi.h
+++ b/binaryninjaapi.h
@@ -1531,6 +1531,26 @@ namespace BinaryNinja {
std::function<bool(size_t, size_t)> progress = {}, Ref<Metadata> options = new Metadata(MetadataType::KeyValueDataType),
bool isDatabase = false);
+ /*! Demangles using LLVM's demangler
+
+ \param[in] mangledName a mangled (msvc/itanium/rust/dlang) name
+ \param[out] outVarName QualifiedName reference to write the output name to.
+ \param[in] simplify Whether to simplify demangled names.
+
+ \ingroup demangle
+ */
+ bool DemangleLLVM(const std::string& mangledName, QualifiedName& outVarName, const bool simplify = false);
+
+ /*! Demangles using LLVM's demangler
+
+ \param[in] mangledName a mangled (msvc/itanium/rust/dlang) name
+ \param[out] outVarName QualifiedName reference to write the output name to.
+ \param[in] view View to check the analysis.types.templateSimplifier for
+
+ \ingroup demangle
+ */
+ bool DemangleLLVM(const std::string& mangledName, QualifiedName& outVarName, BinaryView* view);
+
/*! Demangles a Microsoft Visual Studio C++ name
\param[in] arch Architecture for the symbol. Required for pointer and integer sizes.
diff --git a/binaryninjacore.h b/binaryninjacore.h
index 826ebf48..23d63acc 100644
--- a/binaryninjacore.h
+++ b/binaryninjacore.h
@@ -6530,6 +6530,11 @@ extern "C"
char*** outVarName, size_t* outVarNameElements, const BNBinaryView* const view);
BINARYNINJACOREAPI void BNFreeDemangledName(char*** name, size_t nameElements);
+ BINARYNINJACOREAPI bool BNDemangleLLVM(const char* mangledName,
+ char*** outVarName, size_t* outVarNameElements, const bool simplify);
+ BINARYNINJACOREAPI bool BNDemangleLLVMWithOptions(const char* mangledName,
+ char*** outVarName, size_t* outVarNameElements, const BNBinaryView* const view);
+
// Plugin repository APIs
BINARYNINJACOREAPI char** BNPluginGetApis(BNRepoPlugin* p, size_t* count);
BINARYNINJACOREAPI const char* BNPluginGetAuthor(BNRepoPlugin* p);
diff --git a/demangle.cpp b/demangle.cpp
index 56f4ba90..fbe39672 100644
--- a/demangle.cpp
+++ b/demangle.cpp
@@ -3,6 +3,29 @@
using namespace std;
namespace BinaryNinja {
+ bool DemangleLLVM(const std::string& mangledName, QualifiedName& outVarName,
+ BinaryView* view)
+ {
+ const bool simplify = Settings::Instance()->Get<bool>("analysis.types.templateSimplifier", view);
+ return DemangleLLVM(mangledName, outVarName, simplify);
+ }
+
+ bool DemangleLLVM(const std::string& mangledName, QualifiedName& outVarName,
+ const bool simplify)
+ {
+ BNType* localType = nullptr;
+ char** localVarName = nullptr;
+ size_t localSize = 0;
+ if (!BNDemangleLLVM(mangledName.c_str(), &localVarName, &localSize, simplify))
+ return false;
+ for (size_t i = 0; i < localSize; i++)
+ {
+ outVarName.push_back(localVarName[i]);
+ }
+ BNFreeDemangledName(&localVarName, localSize);
+ return true;
+ }
+
bool DemangleMS(Architecture* arch, const std::string& mangledName, Ref<Type>& outType, QualifiedName& outVarName,
BinaryView* view)
{
diff --git a/python/demangle.py b/python/demangle.py
index 874b13cf..158880f0 100644
--- a/python/demangle.py
+++ b/python/demangle.py
@@ -46,6 +46,39 @@ def get_qualified_name(names):
return "::".join(names)
+def demangle_llvm(mangled_name: str, options=None):
+ """
+ ``demangle_llvm`` demangles a mangled name to a Type object.
+
+ :param str mangled_name: a mangled (msvc/itanium/rust/dlang) name
+ :param options: (optional) Whether to simplify demangled names : None falls back to user settings, a BinaryView uses that BinaryView's settings, or a boolean to set it directly
+ :type options: Tuple[bool, BinaryView, None]
+ :return: returns demangled name or None on error
+ :rtype: str
+ """
+ outName = ctypes.POINTER(ctypes.c_char_p)()
+ outSize = ctypes.c_ulonglong()
+ names = []
+ if (
+ isinstance(options, binaryview.BinaryView) and core.BNDemangleLLVMWithOptions(
+ mangled_name, ctypes.byref(outName), ctypes.byref(outSize), options
+ )
+ ) or (
+ isinstance(options, bool) and core.BNDemangleLLVM(
+ mangled_name, ctypes.byref(outName), ctypes.byref(outSize), options
+ )
+ ) or (
+ options is None and core.BNDemangleLLVMWithOptions(
+ mangled_name, ctypes.byref(outName), ctypes.byref(outSize), None
+ )
+ ):
+ for i in range(outSize.value):
+ names.append(outName[i].decode('utf8')) # type: ignore
+ core.BNFreeDemangledName(ctypes.byref(outName), outSize.value)
+ return names
+ return None
+
+
def demangle_ms(archOrPlatform:Union[Architecture, Platform], mangled_name:str, options=False):
"""
``demangle_ms`` demangles a mangled Microsoft Visual Studio C++ name to a Type object.
diff --git a/rust/src/demangle.rs b/rust/src/demangle.rs
index 3756ea06..1b940ff9 100644
--- a/rust/src/demangle.rs
+++ b/rust/src/demangle.rs
@@ -26,6 +26,49 @@ use crate::rc::*;
pub type Result<R> = result::Result<R, ()>;
+pub fn demangle_llvm<S: BnStrCompatible>(
+ mangled_name: S,
+ simplify: bool,
+) -> Result<Vec<String>> {
+ let mangled_name_bwn = mangled_name.into_bytes_with_nul();
+ let mangled_name_ptr = mangled_name_bwn.as_ref();
+ let mut out_name: *mut *mut std::os::raw::c_char = unsafe { std::mem::zeroed() };
+ let mut out_size: usize = 0;
+ let res = unsafe {
+ BNDemangleLLVM(
+ mangled_name_ptr.as_ptr() as *const c_char,
+ &mut out_name,
+ &mut out_size,
+ simplify,
+ )
+ };
+
+ if !res || out_size == 0 {
+ let cstr = match CStr::from_bytes_with_nul(mangled_name_ptr) {
+ Ok(cstr) => cstr,
+ Err(_) => {
+ log::error!("demangle_llvm: failed to parse mangled name");
+ return Err(());
+ }
+ };
+ return Ok(vec![cstr.to_string_lossy().into_owned()]);
+ }
+
+ if out_name.is_null() {
+ log::error!("demangle_llvm: out_name is NULL");
+ return Err(());
+ }
+
+ let names = unsafe { ArrayGuard::<BnString>::new(out_name, out_size, ()) }
+ .iter()
+ .map(str::to_string)
+ .collect();
+
+ unsafe { BNFreeDemangledName(&mut out_name, out_size) };
+
+ Ok(names)
+}
+
pub fn demangle_gnu3<S: BnStrCompatible>(
arch: &CoreArchitecture,
mangled_name: S,
diff --git a/suite/api_test.py b/suite/api_test.py
index 7054008a..fb3103cb 100644
--- a/suite/api_test.py
+++ b/suite/api_test.py
@@ -5,7 +5,7 @@ import binaryninja as bn
from binaryninja.binaryview import BinaryView, BinaryViewType
from binaryninja.settings import Settings, SettingsScope
from binaryninja.metadata import Metadata
-from binaryninja.demangle import demangle_gnu3, demangle_ms, get_qualified_name
+from binaryninja.demangle import demangle_gnu3, demangle_ms, demangle_llvm, get_qualified_name
from binaryninja.architecture import Architecture
from binaryninja.pluginmanager import RepositoryManager
from binaryninja.platform import Platform