1use std::thread;
6
7use idakit::prelude::*;
8
9fn main() -> Result<(), Box<dyn std::error::Error>> {
10 let db = std::env::args().nth(1).expect("usage: actor <db.i64>");
11
12 Ida::run(move |ida| -> Result<(), Error> {
14 {
15 let db = db;
16 ida.call(move |idb| idb.open(&db).call())??;
17 }
18
19 let n = ida.call(|idb| idb.functions().count())?;
20 let segs = ida.call(|idb| idb.segments().count())?;
21 println!("[app] func_count={n} segments={segs}");
22
23 let hits = ida.call(|idb| {
27 let Some(address) = idb.functions().next().map(|f| f.address()) else {
28 return 0;
29 };
30 let sig = idb
31 .bytes(address, 8)
32 .iter()
33 .map(|b| format!("{b:02X}"))
34 .collect::<Vec<_>>()
35 .join(" ");
36 match Pattern::hex(idb, &sig) {
37 Ok(pat) => idb.search(&pat).count(),
38 Err(_) => 0,
39 }
40 })?;
41 println!("[app] first function's opening 8 bytes recur {hits} time(s) in the image");
42
43 let mut hs = vec![];
45 for t in 0..4usize {
46 let ida = ida.clone();
47 hs.push(thread::spawn(move || {
48 let idx = t * 1000;
49 let found = ida
50 .call(move |idb| idb.functions().nth(idx).map(|f| (f.address(), f.name())))
51 .expect("kernel call");
52 let (address, name) = match found {
53 Some((address, name)) => (format!("{address:#012x}"), String::from(name)),
54 None => ("<none>".into(), "<unnamed>".into()),
55 };
56 println!("[worker {t}] function[{idx}] @ {address} {name}");
57 }));
58 }
59 for h in hs {
60 h.join().unwrap();
61 }
62
63 ida.call(|idb| idb.close(false))?;
64 Ok(())
65 })??;
66
67 println!("\nACTOR OK (kernel on its own thread; calls marshaled from app + 4 workers)");
68 Ok(())
69}