1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
|
use binaryninja::architecture::CoreArchitecture;
use binaryninja::binary_view::BinaryView;
use binaryninja::demangle::{
demangle_generic, demangle_gnu3, demangle_llvm, demangle_ms, CustomDemangler, Demangler,
};
use binaryninja::headless::Session;
use binaryninja::rc::Ref;
use binaryninja::types::{QualifiedName, Type};
#[test]
fn test_demangler_simple() {
let _session = Session::new().expect("Failed to initialize session");
let placeholder_arch = CoreArchitecture::by_name("x86").expect("x86 exists");
// Example LLVM-style mangled name
let llvm_mangled = "_Z3fooi"; // "foo(int)" in LLVM mangling
let llvm_demangled = demangle_llvm(llvm_mangled, true).unwrap();
assert_eq!(llvm_demangled, "foo(int)".into());
// Example GNU-style mangled name
let gnu_mangled = "_Z3bari"; // "bar(int)" in GNU mangling
let (gnu_demangled_name, gnu_demangled_type) =
demangle_gnu3(&placeholder_arch, gnu_mangled, true).unwrap();
assert_eq!(gnu_demangled_name, "bar".into());
// TODO: We check the type display because other means include things such as confidence which is hard to get 1:1
assert_eq!(
gnu_demangled_type.unwrap().to_string(),
"int32_t(int32_t)".to_string()
);
// Example MSVC-style mangled name
let msvc_mangled = "?baz@@YAHH@Z"; // "int __cdecl baz(int)" in MSVC mangling
let (msvc_demangled_name, msvc_demangled_type) =
demangle_ms(&placeholder_arch, msvc_mangled, true).unwrap();
assert_eq!(msvc_demangled_name, "baz".into());
// TODO: We check the type display because other means include things such as confidence which is hard to get 1:1
assert_eq!(
msvc_demangled_type.unwrap().to_string(),
"int32_t __cdecl(int32_t)".to_string()
);
}
#[test]
fn test_custom_demangler() {
let _session = Session::new().expect("Failed to initialize session");
struct TestDemangler;
impl CustomDemangler for TestDemangler {
fn is_mangled_string(&self, name: &str) -> bool {
name == "test_name" || name == "test_name2"
}
fn demangle(
&self,
_arch: &CoreArchitecture,
name: &str,
_view: Option<Ref<BinaryView>>,
) -> Option<(QualifiedName, Option<Ref<Type>>)> {
match name {
"test_name" => Some((QualifiedName::from(vec!["test_name"]), Some(Type::bool()))),
"test_name2" => Some((QualifiedName::from(vec!["test_name2", "aaa"]), None)),
_ => None,
}
}
}
Demangler::register("Test", TestDemangler);
let placeholder_arch = CoreArchitecture::by_name("x86_64").expect("x86_64 exists");
let demangled = demangle_generic(&placeholder_arch, "test_name", None, true).unwrap();
assert_eq!(
demangled,
(QualifiedName::from(vec!["test_name"]), Some(Type::bool()))
);
let demangled2 = demangle_generic(&placeholder_arch, "test_name2", None, true).unwrap();
assert_eq!(
demangled2,
(QualifiedName::from(vec!["test_name2", "aaa"]), None)
);
}
|