Skip to main content

threatflux_binary_analysis/
types.rs

1//! Core types and data structures for binary analysis
2
3use std::collections::HashMap;
4
5#[cfg(feature = "serde-support")]
6use serde::{Deserialize, Serialize};
7
8// Type aliases to reduce complexity
9pub 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/// Supported binary formats
20#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
21#[cfg_attr(feature = "serde-support", derive(Serialize, Deserialize))]
22pub enum BinaryFormat {
23    /// Executable and Linkable Format (Linux/Unix)
24    Elf,
25    /// Portable Executable (Windows)
26    Pe,
27    /// Mach Object (macOS/iOS)
28    MachO,
29    /// Java Class file
30    Java,
31    /// WebAssembly
32    Wasm,
33    /// Raw binary data
34    Raw,
35    /// Unknown format
36    #[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/// Supported architectures
55#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
56#[cfg_attr(feature = "serde-support", derive(Serialize, Deserialize))]
57pub enum Architecture {
58    /// x86 32-bit
59    X86,
60    /// x86 64-bit
61    X86_64,
62    /// ARM 32-bit
63    Arm,
64    /// ARM 64-bit
65    Arm64,
66    /// MIPS
67    Mips,
68    /// MIPS 64-bit
69    Mips64,
70    /// PowerPC
71    PowerPC,
72    /// PowerPC 64-bit
73    PowerPC64,
74    /// RISC-V
75    RiscV,
76    /// RISC-V 64-bit
77    RiscV64,
78    /// WebAssembly
79    Wasm,
80    /// Java Virtual Machine
81    Jvm,
82    /// Unknown architecture
83    #[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/// Binary metadata
108#[derive(Debug, Clone)]
109#[cfg_attr(feature = "serde-support", derive(Serialize, Deserialize))]
110pub struct BinaryMetadata {
111    /// File size in bytes
112    pub size: usize,
113    /// Detected format
114    pub format: BinaryFormat,
115    /// Target architecture
116    pub architecture: Architecture,
117    /// Entry point address
118    pub entry_point: Option<u64>,
119    /// Base address for loading
120    pub base_address: Option<u64>,
121    /// Compilation timestamp
122    pub timestamp: Option<u64>,
123    /// Compiler information
124    pub compiler_info: Option<String>,
125    /// Endianness
126    pub endian: Endianness,
127    /// Security features
128    pub security_features: SecurityFeatures,
129}
130
131/// Endianness
132#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
133#[cfg_attr(feature = "serde-support", derive(Serialize, Deserialize))]
134pub enum Endianness {
135    Little,
136    Big,
137    /// The byte order is not known or does not apply to this input.
138    #[default]
139    Unknown,
140}
141
142/// Security features detected in the binary
143#[derive(Debug, Clone, Default)]
144#[cfg_attr(feature = "serde-support", derive(Serialize, Deserialize))]
145pub struct SecurityFeatures {
146    /// Data Execution Prevention / No-Execute bit
147    pub nx_bit: bool,
148    /// Address Space Layout Randomization
149    pub aslr: bool,
150    /// Stack canaries / stack protection
151    pub stack_canary: bool,
152    /// Control Flow Integrity
153    pub cfi: bool,
154    /// Fortify source
155    pub fortify: bool,
156    /// Position Independent Executable
157    pub pie: bool,
158    /// Relocation Read-Only
159    pub relro: bool,
160    /// Format-specific code-signature or certificate data is present.
161    ///
162    /// This does not establish that the signature is cryptographically valid or
163    /// chains to a trusted identity.
164    pub signed: bool,
165}
166
167/// Binary section information
168#[derive(Debug, Clone)]
169#[cfg_attr(feature = "serde-support", derive(Serialize, Deserialize))]
170pub struct Section {
171    /// Section name
172    pub name: String,
173    /// Virtual address
174    pub address: u64,
175    /// Size of the section's virtual/memory span in bytes
176    pub size: u64,
177    /// File offset
178    pub offset: u64,
179    /// Number of bytes backed by the file from [`Self::offset`]
180    pub file_size: u64,
181    /// Section permissions
182    pub permissions: SectionPermissions,
183    /// Section type
184    pub section_type: SectionType,
185    /// Inline raw-data preview (optional, for small file-backed sections)
186    pub data: Option<Vec<u8>>,
187}
188
189/// Section permissions
190#[derive(Debug, Clone, Default)]
191#[cfg_attr(feature = "serde-support", derive(Serialize, Deserialize))]
192pub struct SectionPermissions {
193    pub read: bool,
194    pub write: bool,
195    pub execute: bool,
196}
197
198/// Section types
199#[derive(Debug, Clone, PartialEq, Eq)]
200#[cfg_attr(feature = "serde-support", derive(Serialize, Deserialize))]
201pub enum SectionType {
202    Code,
203    Data,
204    ReadOnlyData,
205    Bss,
206    Debug,
207    Symbol,
208    String,
209    Relocation,
210    Dynamic,
211    Note,
212    Other(String),
213}
214
215/// Symbol information
216#[derive(Debug, Clone)]
217#[cfg_attr(feature = "serde-support", derive(Serialize, Deserialize))]
218pub struct Symbol {
219    /// Symbol name
220    pub name: String,
221    /// Demangled name (if applicable)
222    pub demangled_name: Option<String>,
223    /// Address
224    pub address: u64,
225    /// Size
226    pub size: u64,
227    /// Symbol type
228    pub symbol_type: SymbolType,
229    /// Binding
230    pub binding: SymbolBinding,
231    /// Visibility
232    pub visibility: SymbolVisibility,
233    /// Section index
234    pub section_index: Option<usize>,
235}
236
237/// Symbol types
238#[derive(Debug, Clone, PartialEq, Eq)]
239#[cfg_attr(feature = "serde-support", derive(Serialize, Deserialize))]
240pub enum SymbolType {
241    Function,
242    Object,
243    Section,
244    File,
245    Common,
246    Thread,
247    Other(String),
248}
249
250/// Symbol binding
251#[derive(Debug, Clone, PartialEq, Eq)]
252#[cfg_attr(feature = "serde-support", derive(Serialize, Deserialize))]
253pub enum SymbolBinding {
254    Local,
255    Global,
256    Weak,
257    Other(String),
258}
259
260/// Symbol visibility
261#[derive(Debug, Clone, PartialEq, Eq)]
262#[cfg_attr(feature = "serde-support", derive(Serialize, Deserialize))]
263pub enum SymbolVisibility {
264    Default,
265    Internal,
266    Hidden,
267    Protected,
268}
269
270/// Import information
271#[derive(Debug, Clone)]
272#[cfg_attr(feature = "serde-support", derive(Serialize, Deserialize))]
273pub struct Import {
274    /// Function or symbol name
275    pub name: String,
276    /// Library name
277    pub library: Option<String>,
278    /// Address (if resolved)
279    pub address: Option<u64>,
280    /// Ordinal (for PE files)
281    pub ordinal: Option<u16>,
282}
283
284/// Export information
285#[derive(Debug, Clone)]
286#[cfg_attr(feature = "serde-support", derive(Serialize, Deserialize))]
287pub struct Export {
288    /// Function or symbol name
289    pub name: String,
290    /// Address
291    pub address: u64,
292    /// Ordinal (for PE files)
293    pub ordinal: Option<u16>,
294    /// Forwarded name (if applicable)
295    pub forwarded_name: Option<String>,
296}
297
298/// Disassembled instruction
299#[derive(Debug, Clone)]
300#[cfg_attr(feature = "serde-support", derive(Serialize, Deserialize))]
301pub struct Instruction {
302    /// Instruction address
303    pub address: u64,
304    /// Raw instruction bytes
305    pub bytes: Vec<u8>,
306    /// Assembly mnemonic
307    pub mnemonic: String,
308    /// Operand string
309    pub operands: String,
310    /// Instruction category
311    pub category: InstructionCategory,
312    /// Control flow information
313    pub flow: ControlFlow,
314    /// Size in bytes
315    pub size: usize,
316}
317
318/// Instruction categories
319#[derive(Debug, Clone, PartialEq, Eq, Hash)]
320#[cfg_attr(feature = "serde-support", derive(Serialize, Deserialize))]
321pub enum InstructionCategory {
322    Arithmetic,
323    Logic,
324    Memory,
325    Control,
326    System,
327    Crypto,
328    Vector,
329    Float,
330    Unknown,
331}
332
333/// Control flow information
334#[derive(Debug, Clone, PartialEq, Eq)]
335#[cfg_attr(feature = "serde-support", derive(Serialize, Deserialize))]
336pub enum ControlFlow {
337    /// Normal sequential flow
338    Sequential,
339    /// Unconditional jump
340    Jump(u64),
341    /// Conditional jump
342    ConditionalJump(u64),
343    /// Function call
344    Call(u64),
345    /// Function return
346    Return,
347    /// Interrupt/system call
348    Interrupt,
349    /// Unknown/indirect
350    Unknown,
351}
352
353/// Basic block in control flow graph
354#[derive(Debug, Clone)]
355#[cfg_attr(feature = "serde-support", derive(Serialize, Deserialize))]
356pub struct BasicBlock {
357    /// Block ID
358    pub id: usize,
359    /// Start address
360    pub start_address: u64,
361    /// End address
362    pub end_address: u64,
363    /// Instructions in this block
364    pub instructions: Vec<Instruction>,
365    /// Successor blocks
366    pub successors: Vec<usize>,
367    /// Predecessor blocks
368    pub predecessors: Vec<usize>,
369    /// Block type classification
370    pub block_type: BlockType,
371    /// Dominator block ID (if computed)
372    pub dominator: Option<usize>,
373    /// Dominance frontier block IDs
374    pub dominance_frontier: Vec<usize>,
375}
376
377/// Control flow graph
378#[derive(Debug, Clone)]
379#[cfg_attr(feature = "serde-support", derive(Serialize, Deserialize))]
380pub struct ControlFlowGraph {
381    /// Function information
382    pub function: Function,
383    /// Basic blocks
384    pub basic_blocks: Vec<BasicBlock>,
385    /// Complexity metrics
386    pub complexity: ComplexityMetrics,
387    /// Detected loops (enhanced analysis)
388    pub loops: Vec<Loop>,
389}
390
391/// Function information
392#[derive(Debug, Clone)]
393#[cfg_attr(feature = "serde-support", derive(Serialize, Deserialize))]
394pub struct Function {
395    /// Function name
396    pub name: String,
397    /// Start address
398    pub start_address: u64,
399    /// End address
400    pub end_address: u64,
401    /// Size in bytes
402    pub size: u64,
403    /// Function type
404    pub function_type: FunctionType,
405    /// Calling convention
406    pub calling_convention: Option<String>,
407    /// Parameters (if available)
408    pub parameters: Vec<Parameter>,
409    /// Return type (if available)
410    pub return_type: Option<String>,
411}
412
413/// Function types
414#[derive(Debug, Clone, PartialEq, Eq)]
415#[cfg_attr(feature = "serde-support", derive(Serialize, Deserialize))]
416pub enum FunctionType {
417    Normal,
418    Constructor,
419    Destructor,
420    Operator,
421    Main,
422    Entrypoint,
423    Import,
424    Export,
425    Thunk,
426    Unknown,
427}
428
429/// Function parameter
430#[derive(Debug, Clone)]
431#[cfg_attr(feature = "serde-support", derive(Serialize, Deserialize))]
432pub struct Parameter {
433    /// Parameter name
434    pub name: Option<String>,
435    /// Parameter type
436    pub param_type: String,
437    /// Register or stack location
438    pub location: ParameterLocation,
439}
440
441/// Parameter location
442#[derive(Debug, Clone, PartialEq)]
443#[cfg_attr(feature = "serde-support", derive(Serialize, Deserialize))]
444pub enum ParameterLocation {
445    Register(String),
446    Stack(i64),
447    Unknown,
448}
449
450/// Complexity metrics for control flow
451#[derive(Debug, Clone, Default)]
452#[cfg_attr(feature = "serde-support", derive(Serialize, Deserialize))]
453pub struct ComplexityMetrics {
454    /// Cyclomatic complexity
455    pub cyclomatic_complexity: u32,
456    /// Number of basic blocks
457    pub basic_block_count: u32,
458    /// Number of edges
459    pub edge_count: u32,
460    /// Depth of nesting
461    pub nesting_depth: u32,
462    /// Number of loops
463    pub loop_count: u32,
464    /// Cognitive complexity (different from cyclomatic)
465    pub cognitive_complexity: u32,
466    /// Halstead metrics (if calculated)
467    pub halstead_metrics: Option<HalsteadMetrics>,
468    /// Maintainability index (if calculated)
469    pub maintainability_index: Option<f64>,
470}
471
472/// Halstead metrics for software complexity
473#[derive(Debug, Clone)]
474#[cfg_attr(feature = "serde-support", derive(Serialize, Deserialize))]
475pub struct HalsteadMetrics {
476    /// Number of distinct operators
477    pub n1: u32,
478    /// Number of distinct operands
479    pub n2: u32,
480    /// Total number of operators
481    pub capital_n1: u32,
482    /// Total number of operands
483    pub capital_n2: u32,
484    /// Program vocabulary
485    pub vocabulary: u32,
486    /// Program length
487    pub length: u32,
488    /// Calculated length
489    pub calculated_length: f64,
490    /// Volume
491    pub volume: f64,
492    /// Difficulty
493    pub difficulty: f64,
494    /// Effort
495    pub effort: f64,
496    /// Time required to program
497    pub time: f64,
498    /// Number of delivered bugs
499    pub bugs: f64,
500}
501
502/// Loop types for enhanced control flow analysis
503#[derive(Debug, Clone, PartialEq, Eq, Hash)]
504#[cfg_attr(feature = "serde-support", derive(Serialize, Deserialize))]
505pub enum LoopType {
506    /// Single entry point (reducible)
507    Natural,
508    /// Multiple entry points
509    Irreducible,
510    /// Test at end
511    DoWhile,
512    /// Test at beginning
513    While,
514    /// Counted loop with induction variable
515    For,
516    /// No clear exit condition
517    Infinite,
518    /// Unknown loop type
519    Unknown,
520}
521
522/// Loop information for control flow analysis
523#[derive(Debug, Clone)]
524#[cfg_attr(feature = "serde-support", derive(Serialize, Deserialize))]
525pub struct Loop {
526    /// Loop header block ID
527    pub header_block: usize,
528    /// Loop body block IDs
529    pub body_blocks: Vec<usize>,
530    /// Loop exit block IDs
531    pub exit_blocks: Vec<usize>,
532    /// Loop type classification
533    pub loop_type: LoopType,
534    /// Induction variables (if detected)
535    pub induction_variables: Vec<String>,
536    /// Whether this is a natural loop
537    pub is_natural: bool,
538    /// Nesting level
539    pub nesting_level: u32,
540}
541
542/// Basic block types for enhanced classification
543#[derive(Debug, Clone, PartialEq, Eq)]
544#[cfg_attr(feature = "serde-support", derive(Serialize, Deserialize))]
545pub enum BlockType {
546    Entry,
547    Exit,
548    Normal,
549    LoopHeader,
550    LoopBody,
551    LoopExit,
552    Conditional,
553    Call,
554    Return,
555    Exception,
556}
557
558/// Entropy analysis results
559#[derive(Debug, Clone)]
560#[cfg_attr(feature = "serde-support", derive(Serialize, Deserialize))]
561pub struct EntropyAnalysis {
562    /// Overall entropy score (0.0 - 8.0)
563    pub overall_entropy: f64,
564    /// Section-wise entropy
565    pub section_entropy: HashMap<String, f64>,
566    /// High entropy regions
567    pub high_entropy_regions: Vec<EntropyRegion>,
568    /// Packing indicators
569    pub packing_indicators: PackingIndicators,
570}
571
572/// High entropy region
573#[derive(Debug, Clone)]
574#[cfg_attr(feature = "serde-support", derive(Serialize, Deserialize))]
575pub struct EntropyRegion {
576    /// Start offset
577    pub start: u64,
578    /// End offset
579    pub end: u64,
580    /// Entropy value
581    pub entropy: f64,
582    /// Possible explanation
583    pub description: String,
584}
585
586/// Packing indicators
587#[derive(Debug, Clone, Default)]
588#[cfg_attr(feature = "serde-support", derive(Serialize, Deserialize))]
589pub struct PackingIndicators {
590    /// Likely packed
591    pub is_packed: bool,
592    /// Detected packer (if any)
593    pub packer_name: Option<String>,
594    /// Compression ratio estimate
595    pub compression_ratio: Option<f64>,
596    /// Obfuscation indicators
597    pub obfuscation_level: ObfuscationLevel,
598}
599
600/// Obfuscation level
601#[derive(Debug, Clone, PartialEq, Eq, Default)]
602#[cfg_attr(feature = "serde-support", derive(Serialize, Deserialize))]
603pub enum ObfuscationLevel {
604    #[default]
605    None,
606    Low,
607    Medium,
608    High,
609    Extreme,
610}
611
612/// Security indicators
613#[derive(Debug, Clone, Default)]
614#[cfg_attr(feature = "serde-support", derive(Serialize, Deserialize))]
615pub struct SecurityIndicators {
616    /// Suspicious API calls
617    pub suspicious_apis: Vec<String>,
618    /// Anti-debugging techniques
619    pub anti_debug: Vec<String>,
620    /// Anti-VM techniques
621    pub anti_vm: Vec<String>,
622    /// Cryptographic indicators
623    pub crypto_indicators: Vec<String>,
624    /// Network indicators
625    pub network_indicators: Vec<String>,
626    /// File system indicators
627    pub filesystem_indicators: Vec<String>,
628    /// Registry indicators (Windows)
629    pub registry_indicators: Vec<String>,
630}
631
632/// Call graph analysis results
633#[derive(Debug, Clone)]
634#[cfg_attr(feature = "serde-support", derive(Serialize, Deserialize))]
635pub struct CallGraph {
636    /// Call graph nodes (functions)
637    pub nodes: Vec<CallGraphNode>,
638    /// Call graph edges (calls)
639    pub edges: Vec<CallGraphEdge>,
640    /// Entry point function addresses
641    pub entry_points: Vec<u64>,
642    /// Unreachable function addresses
643    pub unreachable_functions: Vec<u64>,
644    /// Call graph statistics
645    pub statistics: CallGraphStatistics,
646}
647
648/// Call graph node representing a function
649#[derive(Debug, Clone)]
650#[cfg_attr(feature = "serde-support", derive(Serialize, Deserialize))]
651pub struct CallGraphNode {
652    /// Function address
653    pub function_address: u64,
654    /// Function name
655    pub function_name: String,
656    /// Node type classification
657    pub node_type: NodeType,
658    /// Function complexity
659    pub complexity: u32,
660    /// Number of callers
661    pub in_degree: u32,
662    /// Number of callees
663    pub out_degree: u32,
664    /// Whether function is recursive
665    pub is_recursive: bool,
666    /// Distance from entry point
667    pub call_depth: Option<u32>,
668}
669
670/// Call graph node types
671#[derive(Debug, Clone, PartialEq, Eq)]
672#[cfg_attr(feature = "serde-support", derive(Serialize, Deserialize))]
673pub enum NodeType {
674    /// Program entry point (main, _start, DllMain)
675    EntryPoint,
676    /// Standard library function
677    Library,
678    /// User-defined function
679    Internal,
680    /// Imported function
681    External,
682    /// Function pointer or indirect call
683    Indirect,
684    /// C++ virtual method
685    Virtual,
686    /// Unknown function type
687    Unknown,
688}
689
690/// Call graph edge representing a function call
691#[derive(Debug, Clone)]
692#[cfg_attr(feature = "serde-support", derive(Serialize, Deserialize))]
693pub struct CallGraphEdge {
694    /// Calling function address
695    pub caller: u64,
696    /// Called function address, or `None` when an indirect target is unresolved.
697    pub callee: Option<u64>,
698    /// Type of call
699    pub call_type: CallType,
700    /// All call sites for this edge
701    pub call_sites: Vec<CallSite>,
702}
703
704/// Types of function calls
705#[derive(Debug, Clone, PartialEq, Eq)]
706#[cfg_attr(feature = "serde-support", derive(Serialize, Deserialize))]
707pub enum CallType {
708    /// Direct call (call 0x401000)
709    Direct,
710    /// Indirect call (call \[eax\], call rax)
711    Indirect,
712    /// Tail call optimization (jmp)
713    TailCall,
714    /// C++ virtual method call
715    Virtual,
716    /// Recursive call (self-calling)
717    Recursive,
718    /// Call inside conditional block
719    Conditional,
720}
721
722/// Individual call site information
723#[derive(Debug, Clone)]
724#[cfg_attr(feature = "serde-support", derive(Serialize, Deserialize))]
725pub struct CallSite {
726    /// Address of the call instruction
727    pub address: u64,
728    /// Raw instruction bytes
729    pub instruction_bytes: Vec<u8>,
730    /// Call context
731    pub context: CallContext,
732}
733
734/// Context in which a call occurs
735#[derive(Debug, Clone, PartialEq, Eq)]
736#[cfg_attr(feature = "serde-support", derive(Serialize, Deserialize))]
737pub enum CallContext {
738    Normal,
739    Exception,
740    Loop,
741    Conditional,
742}
743
744/// Call graph statistics
745#[derive(Debug, Clone, Default)]
746#[cfg_attr(feature = "serde-support", derive(Serialize, Deserialize))]
747pub struct CallGraphStatistics {
748    /// Total number of functions
749    pub total_functions: usize,
750    /// Total number of calls
751    pub total_calls: usize,
752    /// Direct function calls
753    pub direct_calls: usize,
754    /// Indirect function calls
755    pub indirect_calls: usize,
756    /// Recursive functions
757    pub recursive_functions: usize,
758    /// Leaf functions (make no calls)
759    pub leaf_functions: usize,
760    /// Number of entry points
761    pub entry_points: usize,
762    /// Number of unreachable functions
763    pub unreachable_functions: usize,
764    /// Maximum call depth
765    pub max_call_depth: u32,
766    /// Average call depth
767    pub average_call_depth: f64,
768    /// Number of cyclic dependencies
769    pub cyclic_dependencies: usize,
770}
771
772/// Configuration for call graph analysis
773#[derive(Debug, Clone)]
774#[cfg_attr(feature = "serde-support", derive(Serialize, Deserialize))]
775pub struct CallGraphConfig {
776    /// Record unresolved indirect call-family instructions with an unknown target.
777    pub analyze_indirect_calls: bool,
778    /// Detect direct jumps at function ends as potential tail calls.
779    pub detect_tail_calls: bool,
780    /// Maximum number of discovered functions accepted for one analysis.
781    pub max_functions: usize,
782    /// Maximum number of instructions decoded across all discovered functions.
783    pub max_total_instructions: usize,
784    /// Maximum breadth-first depth for assigning [`CallGraphNode::call_depth`].
785    ///
786    /// This does not limit call-edge extraction or reachability analysis.
787    pub max_labeled_call_depth: Option<u32>,
788    /// Include calls to functions classified as libraries.
789    pub include_library_calls: bool,
790}
791
792impl Default for CallGraphConfig {
793    fn default() -> Self {
794        Self {
795            analyze_indirect_calls: true,
796            detect_tail_calls: true,
797            max_functions: 10_000,
798            max_total_instructions: 1_000_000,
799            max_labeled_call_depth: Some(50),
800            include_library_calls: false,
801        }
802    }
803}
804
805/// Complete analysis result
806#[derive(Debug, Clone, Default)]
807#[cfg_attr(feature = "serde-support", derive(Serialize, Deserialize))]
808pub struct AnalysisResult {
809    /// Binary format
810    pub format: BinaryFormat,
811    /// Target architecture
812    pub architecture: Architecture,
813    /// Entry point
814    pub entry_point: Option<u64>,
815    /// Binary metadata
816    pub metadata: BinaryMetadata,
817    /// Sections
818    pub sections: Vec<Section>,
819    /// Symbols
820    pub symbols: Vec<Symbol>,
821    /// Imports
822    pub imports: Vec<Import>,
823    /// Exports
824    pub exports: Vec<Export>,
825    /// Disassembly (optional)
826    pub disassembly: Option<Vec<Instruction>>,
827    /// Control flow graphs (optional)
828    pub control_flow: Option<Vec<ControlFlowGraph>>,
829    /// Entropy analysis (optional)
830    pub entropy: Option<EntropyAnalysis>,
831    /// Security indicators (optional)
832    pub security: Option<SecurityIndicators>,
833    /// Call graph analysis (optional)
834    pub call_graph: Option<CallGraph>,
835    /// Enhanced control flow analysis (optional)
836    pub enhanced_control_flow: Option<EnhancedControlFlowAnalysis>,
837}
838
839/// Enhanced control flow analysis results
840#[derive(Debug, Clone)]
841#[cfg_attr(feature = "serde-support", derive(Serialize, Deserialize))]
842pub struct EnhancedControlFlowAnalysis {
843    /// Control flow graphs with enhanced features
844    pub control_flow_graphs: Vec<ControlFlowGraph>,
845    /// Cognitive complexity summary
846    pub cognitive_complexity_summary: CognitiveComplexityStats,
847    /// Loop analysis summary
848    pub loop_analysis_summary: LoopAnalysisStats,
849}
850
851/// Cognitive complexity statistics
852#[derive(Debug, Clone, Default)]
853#[cfg_attr(feature = "serde-support", derive(Serialize, Deserialize))]
854pub struct CognitiveComplexityStats {
855    /// Total cognitive complexity across all functions
856    pub total_cognitive_complexity: u32,
857    /// Average cognitive complexity per function
858    pub average_cognitive_complexity: f64,
859    /// Maximum cognitive complexity in a single function
860    pub max_cognitive_complexity: u32,
861    /// Function with highest cognitive complexity
862    pub most_complex_function: Option<String>,
863    /// Number of functions analyzed
864    pub functions_analyzed: usize,
865}
866
867/// Loop analysis statistics
868#[derive(Debug, Clone, Default)]
869#[cfg_attr(feature = "serde-support", derive(Serialize, Deserialize))]
870pub struct LoopAnalysisStats {
871    /// Total number of loops detected
872    pub total_loops: usize,
873    /// Natural loops count
874    pub natural_loops: usize,
875    /// Irreducible loops count
876    pub irreducible_loops: usize,
877    /// Nested loops count
878    pub nested_loops: usize,
879    /// Maximum nesting depth
880    pub max_nesting_depth: u32,
881    /// Loops by type
882    pub loops_by_type: HashMap<LoopType, usize>,
883}
884
885impl Default for BinaryMetadata {
886    fn default() -> Self {
887        Self {
888            size: 0,
889            format: BinaryFormat::Unknown,
890            architecture: Architecture::Unknown,
891            entry_point: None,
892            base_address: None,
893            timestamp: None,
894            compiler_info: None,
895            endian: Endianness::Unknown,
896            security_features: SecurityFeatures::default(),
897        }
898    }
899}
900
901/// Trait for binary format parsers
902pub trait BinaryFormatParser {
903    /// Parse binary data
904    fn parse(data: &[u8]) -> ParseResult;
905
906    /// Check if this parser can handle the data
907    fn can_parse(data: &[u8]) -> bool;
908}
909
910/// Trait implemented by all binary formats
911pub trait BinaryFormatTrait: Send + Sync {
912    /// Get format type
913    fn format_type(&self) -> BinaryFormat;
914
915    /// Get target architecture
916    fn architecture(&self) -> Architecture;
917
918    /// Get entry point
919    fn entry_point(&self) -> Option<u64>;
920
921    /// Get sections
922    fn sections(&self) -> &[Section];
923
924    /// Get symbols
925    fn symbols(&self) -> &[Symbol];
926
927    /// Get imports
928    fn imports(&self) -> &[Import];
929
930    /// Get exports
931    fn exports(&self) -> &[Export];
932
933    /// Get metadata
934    fn metadata(&self) -> &BinaryMetadata;
935}