summaryrefslogtreecommitdiff
path: root/rust/examples/create_type_library.rs
blob: 14c387a4a36d05fa8ab3144b2b4b3e5150f2143e (plain)
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
// Usage: cargo run --example create_type_library <header_file_path> <platform> <type_library_path>

use binaryninja::platform::Platform;
use binaryninja::tracing::TracingLogListener;
use binaryninja::types::{CoreTypeParser, TypeLibrary, TypeParser};

fn main() {
    tracing_subscriber::fmt::init();
    let _listener = TracingLogListener::new().register();

    let header_path_str = std::env::args().nth(1).expect("No header provided");
    let header_path = std::path::Path::new(&header_path_str);
    let header_name = header_path.file_stem().unwrap().to_str().unwrap();
    let type_lib_plat_str = std::env::args().nth(2).expect("No type library provided");
    let type_lib_path_str = std::env::args().nth(3).expect("No type library provided");
    let type_lib_path = std::path::Path::new(&type_lib_path_str);
    let type_lib_name = type_lib_path.file_stem().unwrap().to_str().unwrap();

    let header_contents = std::fs::read_to_string(header_path).expect("Failed to read header file");

    // This loads all the core architecture, platform, etc plugins
    let _headless_session =
        binaryninja::headless::Session::new().expect("Failed to initialize session");

    let type_lib_plat = Platform::by_name(&type_lib_plat_str).expect("Invalid platform");

    let type_lib = TypeLibrary::new(type_lib_plat.arch(), type_lib_name);

    let plat_type_container = type_lib_plat.type_container();
    let parser = CoreTypeParser::default();
    let parsed_types = parser
        .parse_types_from_source(
            &header_contents,
            header_name,
            &type_lib_plat,
            &plat_type_container,
            &[],
            &[],
            "",
        )
        .expect("Parsed types");

    for ty in parsed_types.types {
        tracing::debug!("Adding type: {}", ty.name);
        type_lib.add_named_type(ty.name, &ty.ty);
    }

    for func in parsed_types.functions {
        tracing::debug!("Adding function: {}", func.name);
        type_lib.add_named_object(func.name, &func.ty);
    }

    tracing::info!(
        "Created type library with {} types and {} functions",
        type_lib.named_types().len(),
        type_lib.named_objects().len()
    );
    type_lib.write_to_file(&type_lib_path);
}