probe_names/
probe_names.rs1use idakit::prelude::*;
7
8fn main() -> Result<(), Box<dyn std::error::Error>> {
9 let mut args = std::env::args().skip(1);
10 let bin = args
11 .next()
12 .expect("usage: probe_names <db.i64> [max-names]");
13 let max: usize = args.next().and_then(|s| s.parse().ok()).unwrap_or(50_000);
14
15 Ida::run(move |ida| -> Result<(), Error> {
16 ida.call(move |idb| -> Result<(), Error> {
17 idb.open(&bin).call()?;
18
19 let (mut total, mut weak, mut public, mut mangled) = (0usize, 0usize, 0usize, 0usize);
20 let mut demangles = 0usize;
21 let mut substitutes = 0usize;
22 let mut short_differs = 0usize;
23 let mut short_vs_long = 0usize;
24 let mut samples: Vec<String> = Vec::new();
25 let mut first_weak: Option<usize> = None;
26 let mut first_public: Option<usize> = None;
27
28 for Name { address, name } in idb.names().take(max) {
29 total += 1;
30 let is_weak = idb.is_weak_name(address);
31 weak += usize::from(is_weak);
32 if is_weak && first_weak.is_none() {
33 first_weak = Some(total - 1);
34 }
35 if idb.is_public_name(address) && first_public.is_none() {
36 first_public = Some(total - 1);
37 }
38 public += usize::from(idb.is_public_name(address));
39 if name.starts_with("_Z") {
40 mangled += 1;
41 }
42 if idb.demangle(&name).is_some() {
43 demangles += 1;
44 }
45
46 let raw = idb.name_with(address, NameFlags::empty());
47 let visible = idb.visible_name(address);
48 if raw != visible {
49 substitutes += 1;
50 if samples.len() < 4 {
51 samples.push(format!(
52 " subst {:#x}\n raw {raw:?}\n visible {visible:?}",
53 address.get()
54 ));
55 }
56 }
57
58 let short = idb.short_name(address);
61 if short != visible {
62 short_differs += 1;
63 }
64 if short != idb.long_name(address) {
65 short_vs_long += 1;
66 }
67
68 if is_weak && name.starts_with("_Z") && samples.len() < 8 {
69 samples.push(format!(
70 " weak+mangled {:#x}\n raw {name:?}\n short {short:?}",
71 address.get()
72 ));
73 }
74 }
75
76 println!("=== {total} names scanned");
77 println!("weak {weak} (first at index {first_weak:?})");
78 println!("public {public} (first at index {first_public:?})");
79 println!("raw '_Z' prefix {mangled}");
80 println!("demangle(name) {demangles}");
81 println!("raw != visible {substitutes}");
82 println!("short != visible {short_differs} <- kills the short_name mutant");
83 println!("short != long {short_vs_long}");
84 println!("=== samples");
85 for s in &samples {
86 println!("{s}");
87 }
88
89 idb.close(false);
90 Ok(())
91 })??;
92 Ok(())
93 })??;
94
95 println!("PROBE_NAMES OK");
96 Ok(())
97}