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
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
//! Parse and inspect Nim-compiled native binaries.
//!
//! This crate provides a pure-Rust parser and forensic-artifact extractor for
//! binaries produced by the Nim compiler via its C, C++, or Objective-C
//! backends. A Nim-compiled program is a normal ELF, PE, or Mach-O executable
//! — there is no Nim-specific container. The crate recovers Nim **runtime
//! artifacts** left inside an otherwise-ordinary native binary.
//!
//! # What it extracts
//!
//! | Artifact | Method | Notes |
//! |----------|--------|-------|
//! | Detection verdict | [`NimBinary::is_nim`] | 11 independent probes |
//! | Format / arch / GC mode | [`NimBinary::format`], [`NimBinary::gc_mode`] | ELF, PE, Mach-O; refc vs ARC/ORC |
//! | Entry shims | [`NimBinary::entry_shims`] | `NimMain`, `PreMain`, etc. |
//! | Init functions | [`NimBinary::init_functions`] | With decoded module paths |
//! | Module map | [`NimBinary::module_map`] | Per-module: symbols, sizes, init VAs, leaked paths |
//! | RTTI globals | [`NimBinary::rtti_symbols`] | V1 (`TNimType`) and V2 (`TNimTypeV2`) with parsed fields |
//! | String literals | [`NimBinary::string_literals_v2`] | V2 `NIM_STRLIT_FLAG` scan |
//! | Stack-trace metadata | [`NimBinary::stack_trace`] | Proc names + `.nim` file paths (build-host leaks) |
//! | Nimble path leaks | [`NimBinary::nimble_paths`] | Package name, version, hash, username, OS |
//! | Exception types | [`NimBinary::exception_types`] | `*Error`, `*Defect` cstrings in rodata |
//! | Raise sites | [`NimBinary::raise_sites`] | Full (type, proc, file, line) tuples via instruction analysis |
//! | Demangled symbols | [`demangle::symbol::parse`] | Identifier, module, item ID |
//!
//! # Quick start
//!
//! ```no_run
//! use nimrod::NimBinary;
//!
//! let data = std::fs::read("sample").unwrap();
//! let bin = NimBinary::from_bytes(&data).unwrap();
//!
//! if !bin.is_nim() {
//! eprintln!("not a Nim binary");
//! return;
//! }
//!
//! // Detection and classification
//! println!("format: {:?}, gc: {:?}", bin.format(), bin.gc_mode());
//!
//! // Module map: which Nim modules are compiled in, with every function
//! let mmap = bin.module_map();
//! for (name, info) in &mmap.modules {
//! println!("{name}: {} functions", info.symbol_count());
//! for sym in &info.symbols {
//! // sym.name = demangled Nim identifier
//! // sym.address = VA (start disassembling here)
//! // sym.size = byte count (ELF; 0 on Mach-O/PE)
//! let _ = (sym.name.as_str(), sym.address, sym.size);
//! }
//! }
//!
//! // Raise sites: exception type + enclosing function + source location
//! for rs in &bin.raise_sites() {
//! let _ = (
//! rs.exception_type.as_deref(), // "ValueError"
//! rs.enclosing_function.as_deref(), // "parseHexInt__strutils_u1234"
//! rs.file.as_deref(), // "strutils.nim"
//! rs.line, // Some(1242)
//! );
//! }
//! ```
//!
//! # Design
//!
//! - **Pure Rust**, `#![deny(unsafe_code)]`.
//! - **Cross-format**: ELF, PE, Mach-O via [`goblin`](https://docs.rs/goblin).
//! - **Zero-copy** where possible — borrows from the input byte slice.
//! - **Forensic-oriented**: prioritises attribution-grade artifacts (build-host
//! paths, package refs, exception locations) over pretty-printing.
//!
//! The format-level research backing every probe and struct layout is
//! documented in `RESEARCH.md` at the crate root.
pub use NimBinary;
pub use ;
pub use ;
pub use ;
pub use ;
pub use GcMode;
pub use ;
pub use ;
pub use ExceptionRef;
pub use ;
pub use ;
pub use RaiseSite;
pub use ;
pub use StringLiteralV1;
pub use StringLiteral;