diff options
| author | KyleMiles <krm504@nyu.edu> | 2022-02-14 19:18:37 -0500 |
|---|---|---|
| committer | KyleMiles <krm504@nyu.edu> | 2022-02-14 19:23:30 -0500 |
| commit | 80f3ca9e22b40a92f3f671d1a840ec1c11674e4a (patch) | |
| tree | 642fc482b413275802f4d2d986f01de685194263 /rust/src | |
| parent | 2845ba6208ce3c29998a48df5073ed15a11ead77 (diff) | |
rust: add demangle helpers for gnu3 and ms
Co-authored-by: EliseZeroTwo <mail@elise.moe>
Diffstat (limited to 'rust/src')
| -rw-r--r-- | rust/src/demangle.rs | 121 | ||||
| -rw-r--r-- | rust/src/lib.rs | 1 |
2 files changed, 122 insertions, 0 deletions
diff --git a/rust/src/demangle.rs b/rust/src/demangle.rs new file mode 100644 index 00000000..ccc3d2de --- /dev/null +++ b/rust/src/demangle.rs @@ -0,0 +1,121 @@ +use binaryninjacore_sys::*; +use std::{ffi::CStr, result}; + +use crate::architecture::CoreArchitecture; +use crate::string::{BnStrCompatible, BnString}; +use crate::types::Type; + +use crate::rc::*; + +pub type Result<R> = result::Result<R, ()>; + +pub fn demangle_gnu3<S: BnStrCompatible>( + arch: &CoreArchitecture, + mangled_name: S, + simplify: bool, +) -> Result<(Option<Ref<Type>>, Vec<String>)> { + let mangled_name_bwn = mangled_name.as_bytes_with_nul(); + let mangled_name_ptr = mangled_name_bwn.as_ref(); + let mut out_type: *mut BNType = unsafe { std::mem::zeroed() }; + let mut out_name: *mut *mut std::os::raw::c_char = unsafe { std::mem::zeroed() }; + let mut out_size: usize = 0; + let res = unsafe { + BNDemangleGNU3( + arch.0, + mangled_name_ptr.as_ptr() as *const i8, + &mut out_type, + &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_gnu3: failed to parse mangled name"); + return Err(()); + } + }; + return Ok((None, vec![cstr.to_string_lossy().into_owned()])); + } + + let out_type = match out_type.is_null() { + true => { + log::debug!("demangle_gnu3: out_type is NULL"); + None + } + false => Some(unsafe { Type::ref_from_raw(out_type) }), + }; + + if out_name.is_null() { + log::error!("demangle_gnu3: out_name is NULL"); + return Err(()); + } + + let names = unsafe { ArrayGuard::<BnString>::new(out_name, out_size, ()) } + .iter() + .map(|name| name.to_string()) + .collect(); + + unsafe { BNFreeDemangledName(&mut out_name, out_size) }; + + Ok((out_type, names)) +} + +pub fn demangle_ms<S: BnStrCompatible>( + arch: &CoreArchitecture, + mangled_name: S, + simplify: bool, +) -> Result<(Option<Ref<Type>>, Vec<String>)> { + let mangled_name_bwn = mangled_name.as_bytes_with_nul(); + let mangled_name_ptr = mangled_name_bwn.as_ref(); + + let mut out_type: *mut BNType = unsafe { std::mem::zeroed() }; + let mut out_name: *mut *mut std::os::raw::c_char = unsafe { std::mem::zeroed() }; + let mut out_size: usize = 0; + let res = unsafe { + BNDemangleMS( + arch.0, + mangled_name_ptr.as_ptr() as *const i8, + &mut out_type, + &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_ms: failed to parse mangled name"); + return Err(()); + } + }; + return Ok((None, vec![cstr.to_string_lossy().into_owned()])); + } + + let out_type = match out_type.is_null() { + true => { + log::debug!("demangle_ms: out_type is NULL"); + None + } + false => Some(unsafe { Type::ref_from_raw(out_type) }), + }; + + if out_name.is_null() { + log::error!("demangle_ms: out_name is NULL"); + return Err(()); + } + + let names = unsafe { ArrayGuard::<BnString>::new(out_name, out_size, ()) } + .iter() + .map(|name| name.to_string()) + .collect(); + + unsafe { BNFreeDemangledName(&mut out_name, out_size) }; + + Ok((out_type, names)) +} diff --git a/rust/src/lib.rs b/rust/src/lib.rs index 9c18d91d..966f3ff2 100644 --- a/rust/src/lib.rs +++ b/rust/src/lib.rs @@ -48,6 +48,7 @@ pub mod custombinaryview; pub mod databuffer; pub mod datavariable; pub mod debuginfo; +pub mod demangle; pub mod disassembly; pub mod fileaccessor; pub mod filemetadata; |
