1use std::collections::HashMap;
4
5#[cfg(feature = "serde-support")]
6use serde::{Deserialize, Serialize};
7
8pub type BinaryResult<T> = crate::Result<T>;
10pub type ParsedBinary = Box<dyn BinaryFormatTrait>;
11pub type ParseResult = BinaryResult<ParsedBinary>;
12pub type ImportExportResult = BinaryResult<(Vec<Import>, Vec<Export>)>;
13pub type ByteSliceResult<'a> = BinaryResult<&'a [u8]>;
14pub type PatternMatchMap =
15 HashMap<crate::utils::patterns::PatternCategory, Vec<crate::utils::patterns::PatternMatch>>;
16pub type HexPatternResult = BinaryResult<Vec<Option<u8>>>;
17pub type HexPattern = Vec<Option<u8>>;
18
19#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
21#[cfg_attr(feature = "serde-support", derive(Serialize, Deserialize))]
22pub enum BinaryFormat {
23 Elf,
25 Pe,
27 MachO,
29 Java,
31 Wasm,
33 Raw,
35 #[default]
37 Unknown,
38}
39
40impl std::fmt::Display for BinaryFormat {
41 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
42 match self {
43 BinaryFormat::Elf => write!(f, "ELF"),
44 BinaryFormat::Pe => write!(f, "PE"),
45 BinaryFormat::MachO => write!(f, "Mach-O"),
46 BinaryFormat::Java => write!(f, "Java"),
47 BinaryFormat::Wasm => write!(f, "WebAssembly"),
48 BinaryFormat::Raw => write!(f, "Raw"),
49 BinaryFormat::Unknown => write!(f, "Unknown"),
50 }
51 }
52}
53
54#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
56#[cfg_attr(feature = "serde-support", derive(Serialize, Deserialize))]
57pub enum Architecture {
58 X86,
60 X86_64,
62 Arm,
64 Arm64,
66 Mips,
68 Mips64,
70 PowerPC,
72 PowerPC64,
74 RiscV,
76 RiscV64,
78 Wasm,
80 Jvm,
82 #[default]
84 Unknown,
85}
86
87impl std::fmt::Display for Architecture {
88 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
89 match self {
90 Architecture::X86 => write!(f, "x86"),
91 Architecture::X86_64 => write!(f, "x86-64"),
92 Architecture::Arm => write!(f, "ARM"),
93 Architecture::Arm64 => write!(f, "ARM64"),
94 Architecture::Mips => write!(f, "MIPS"),
95 Architecture::Mips64 => write!(f, "MIPS64"),
96 Architecture::PowerPC => write!(f, "PowerPC"),
97 Architecture::PowerPC64 => write!(f, "PowerPC64"),
98 Architecture::RiscV => write!(f, "RISC-V"),
99 Architecture::RiscV64 => write!(f, "RISC-V64"),
100 Architecture::Wasm => write!(f, "WebAssembly"),
101 Architecture::Jvm => write!(f, "JVM"),
102 Architecture::Unknown => write!(f, "Unknown"),
103 }
104 }
105}
106
107#[derive(Debug, Clone)]
109#[cfg_attr(feature = "serde-support", derive(Serialize, Deserialize))]
110pub struct BinaryMetadata {
111 pub size: usize,
113 pub format: BinaryFormat,
115 pub architecture: Architecture,
117 pub entry_point: Option<u64>,
119 pub base_address: Option<u64>,
121 pub timestamp: Option<u64>,
123 pub compiler_info: Option<String>,
125 pub endian: Endianness,
127 pub security_features: SecurityFeatures,
129}
130
131#[derive(Debug, Clone, Copy, PartialEq, Eq)]
133#[cfg_attr(feature = "serde-support", derive(Serialize, Deserialize))]
134pub enum Endianness {
135 Little,
136 Big,
137}
138
139#[derive(Debug, Clone, Default)]
141#[cfg_attr(feature = "serde-support", derive(Serialize, Deserialize))]
142pub struct SecurityFeatures {
143 pub nx_bit: bool,
145 pub aslr: bool,
147 pub stack_canary: bool,
149 pub cfi: bool,
151 pub fortify: bool,
153 pub pie: bool,
155 pub relro: bool,
157 pub signed: bool,
159}
160
161#[derive(Debug, Clone)]
163#[cfg_attr(feature = "serde-support", derive(Serialize, Deserialize))]
164pub struct Section {
165 pub name: String,
167 pub address: u64,
169 pub size: u64,
171 pub offset: u64,
173 pub permissions: SectionPermissions,
175 pub section_type: SectionType,
177 pub data: Option<Vec<u8>>,
179}
180
181#[derive(Debug, Clone, Default)]
183#[cfg_attr(feature = "serde-support", derive(Serialize, Deserialize))]
184pub struct SectionPermissions {
185 pub read: bool,
186 pub write: bool,
187 pub execute: bool,
188}
189
190#[derive(Debug, Clone, PartialEq, Eq)]
192#[cfg_attr(feature = "serde-support", derive(Serialize, Deserialize))]
193pub enum SectionType {
194 Code,
195 Data,
196 ReadOnlyData,
197 Bss,
198 Debug,
199 Symbol,
200 String,
201 Relocation,
202 Dynamic,
203 Note,
204 Other(String),
205}
206
207#[derive(Debug, Clone)]
209#[cfg_attr(feature = "serde-support", derive(Serialize, Deserialize))]
210pub struct Symbol {
211 pub name: String,
213 pub demangled_name: Option<String>,
215 pub address: u64,
217 pub size: u64,
219 pub symbol_type: SymbolType,
221 pub binding: SymbolBinding,
223 pub visibility: SymbolVisibility,
225 pub section_index: Option<usize>,
227}
228
229#[derive(Debug, Clone, PartialEq, Eq)]
231#[cfg_attr(feature = "serde-support", derive(Serialize, Deserialize))]
232pub enum SymbolType {
233 Function,
234 Object,
235 Section,
236 File,
237 Common,
238 Thread,
239 Other(String),
240}
241
242#[derive(Debug, Clone, PartialEq, Eq)]
244#[cfg_attr(feature = "serde-support", derive(Serialize, Deserialize))]
245pub enum SymbolBinding {
246 Local,
247 Global,
248 Weak,
249 Other(String),
250}
251
252#[derive(Debug, Clone, PartialEq, Eq)]
254#[cfg_attr(feature = "serde-support", derive(Serialize, Deserialize))]
255pub enum SymbolVisibility {
256 Default,
257 Internal,
258 Hidden,
259 Protected,
260}
261
262#[derive(Debug, Clone)]
264#[cfg_attr(feature = "serde-support", derive(Serialize, Deserialize))]
265pub struct Import {
266 pub name: String,
268 pub library: Option<String>,
270 pub address: Option<u64>,
272 pub ordinal: Option<u16>,
274}
275
276#[derive(Debug, Clone)]
278#[cfg_attr(feature = "serde-support", derive(Serialize, Deserialize))]
279pub struct Export {
280 pub name: String,
282 pub address: u64,
284 pub ordinal: Option<u16>,
286 pub forwarded_name: Option<String>,
288}
289
290#[derive(Debug, Clone)]
292#[cfg_attr(feature = "serde-support", derive(Serialize, Deserialize))]
293pub struct Instruction {
294 pub address: u64,
296 pub bytes: Vec<u8>,
298 pub mnemonic: String,
300 pub operands: String,
302 pub category: InstructionCategory,
304 pub flow: ControlFlow,
306 pub size: usize,
308}
309
310#[derive(Debug, Clone, PartialEq, Eq, Hash)]
312#[cfg_attr(feature = "serde-support", derive(Serialize, Deserialize))]
313pub enum InstructionCategory {
314 Arithmetic,
315 Logic,
316 Memory,
317 Control,
318 System,
319 Crypto,
320 Vector,
321 Float,
322 Unknown,
323}
324
325#[derive(Debug, Clone, PartialEq, Eq)]
327#[cfg_attr(feature = "serde-support", derive(Serialize, Deserialize))]
328pub enum ControlFlow {
329 Sequential,
331 Jump(u64),
333 ConditionalJump(u64),
335 Call(u64),
337 Return,
339 Interrupt,
341 Unknown,
343}
344
345#[derive(Debug, Clone)]
347#[cfg_attr(feature = "serde-support", derive(Serialize, Deserialize))]
348pub struct BasicBlock {
349 pub id: usize,
351 pub start_address: u64,
353 pub end_address: u64,
355 pub instructions: Vec<Instruction>,
357 pub successors: Vec<usize>,
359 pub predecessors: Vec<usize>,
361}
362
363#[derive(Debug, Clone)]
365#[cfg_attr(feature = "serde-support", derive(Serialize, Deserialize))]
366pub struct ControlFlowGraph {
367 pub function: Function,
369 pub basic_blocks: Vec<BasicBlock>,
371 pub complexity: ComplexityMetrics,
373}
374
375#[derive(Debug, Clone)]
377#[cfg_attr(feature = "serde-support", derive(Serialize, Deserialize))]
378pub struct Function {
379 pub name: String,
381 pub start_address: u64,
383 pub end_address: u64,
385 pub size: u64,
387 pub function_type: FunctionType,
389 pub calling_convention: Option<String>,
391 pub parameters: Vec<Parameter>,
393 pub return_type: Option<String>,
395}
396
397#[derive(Debug, Clone, PartialEq, Eq)]
399#[cfg_attr(feature = "serde-support", derive(Serialize, Deserialize))]
400pub enum FunctionType {
401 Normal,
402 Constructor,
403 Destructor,
404 Operator,
405 Main,
406 Entrypoint,
407 Import,
408 Export,
409 Thunk,
410 Unknown,
411}
412
413#[derive(Debug, Clone)]
415#[cfg_attr(feature = "serde-support", derive(Serialize, Deserialize))]
416pub struct Parameter {
417 pub name: Option<String>,
419 pub param_type: String,
421 pub location: ParameterLocation,
423}
424
425#[derive(Debug, Clone, PartialEq)]
427#[cfg_attr(feature = "serde-support", derive(Serialize, Deserialize))]
428pub enum ParameterLocation {
429 Register(String),
430 Stack(i64),
431 Unknown,
432}
433
434#[derive(Debug, Clone, Default)]
436#[cfg_attr(feature = "serde-support", derive(Serialize, Deserialize))]
437pub struct ComplexityMetrics {
438 pub cyclomatic_complexity: u32,
440 pub basic_block_count: u32,
442 pub edge_count: u32,
444 pub nesting_depth: u32,
446 pub loop_count: u32,
448}
449
450#[derive(Debug, Clone)]
452#[cfg_attr(feature = "serde-support", derive(Serialize, Deserialize))]
453pub struct EntropyAnalysis {
454 pub overall_entropy: f64,
456 pub section_entropy: HashMap<String, f64>,
458 pub high_entropy_regions: Vec<EntropyRegion>,
460 pub packing_indicators: PackingIndicators,
462}
463
464#[derive(Debug, Clone)]
466#[cfg_attr(feature = "serde-support", derive(Serialize, Deserialize))]
467pub struct EntropyRegion {
468 pub start: u64,
470 pub end: u64,
472 pub entropy: f64,
474 pub description: String,
476}
477
478#[derive(Debug, Clone, Default)]
480#[cfg_attr(feature = "serde-support", derive(Serialize, Deserialize))]
481pub struct PackingIndicators {
482 pub is_packed: bool,
484 pub packer_name: Option<String>,
486 pub compression_ratio: Option<f64>,
488 pub obfuscation_level: ObfuscationLevel,
490}
491
492#[derive(Debug, Clone, PartialEq, Eq, Default)]
494#[cfg_attr(feature = "serde-support", derive(Serialize, Deserialize))]
495pub enum ObfuscationLevel {
496 #[default]
497 None,
498 Low,
499 Medium,
500 High,
501 Extreme,
502}
503
504#[derive(Debug, Clone, Default)]
506#[cfg_attr(feature = "serde-support", derive(Serialize, Deserialize))]
507pub struct SecurityIndicators {
508 pub suspicious_apis: Vec<String>,
510 pub anti_debug: Vec<String>,
512 pub anti_vm: Vec<String>,
514 pub crypto_indicators: Vec<String>,
516 pub network_indicators: Vec<String>,
518 pub filesystem_indicators: Vec<String>,
520 pub registry_indicators: Vec<String>,
522}
523
524#[derive(Debug, Clone, Default)]
526#[cfg_attr(feature = "serde-support", derive(Serialize, Deserialize))]
527pub struct AnalysisResult {
528 pub format: BinaryFormat,
530 pub architecture: Architecture,
532 pub entry_point: Option<u64>,
534 pub metadata: BinaryMetadata,
536 pub sections: Vec<Section>,
538 pub symbols: Vec<Symbol>,
540 pub imports: Vec<Import>,
542 pub exports: Vec<Export>,
544 pub disassembly: Option<Vec<Instruction>>,
546 pub control_flow: Option<Vec<ControlFlowGraph>>,
548 pub entropy: Option<EntropyAnalysis>,
550 pub security: Option<SecurityIndicators>,
552}
553
554impl Default for BinaryMetadata {
555 fn default() -> Self {
556 Self {
557 size: 0,
558 format: BinaryFormat::Unknown,
559 architecture: Architecture::Unknown,
560 entry_point: None,
561 base_address: None,
562 timestamp: None,
563 compiler_info: None,
564 endian: Endianness::Little,
565 security_features: SecurityFeatures::default(),
566 }
567 }
568}
569
570pub trait BinaryFormatParser {
572 fn parse(data: &[u8]) -> ParseResult;
574
575 fn can_parse(data: &[u8]) -> bool;
577}
578
579pub trait BinaryFormatTrait: Send + Sync {
581 fn format_type(&self) -> BinaryFormat;
583
584 fn architecture(&self) -> Architecture;
586
587 fn entry_point(&self) -> Option<u64>;
589
590 fn sections(&self) -> &[Section];
592
593 fn symbols(&self) -> &[Symbol];
595
596 fn imports(&self) -> &[Import];
598
599 fn exports(&self) -> &[Export];
601
602 fn metadata(&self) -> &BinaryMetadata;
604}