Skip to main content

nabla_decompiler/
lib.rs

1//! Nabla Binary Decompiler Engine
2//! 
3//! Provides binary analysis, control flow graph generation, and pseudocode lifting
4//! for reverse engineering and security analysis of embedded systems firmware.
5
6pub mod analysis;
7pub mod cfg;
8pub mod cfg_analyzer;
9pub mod disasm;
10pub mod lifting;
11pub mod patcher;
12pub mod types;
13
14pub use types::*;
15
16use anyhow::Result;
17use nabla_scanner::binary::analysis::BinaryAnalysis;
18use serde::{Deserialize, Serialize};
19
20/// Main decompiler interface
21pub struct Decompiler {
22    binary_analysis: BinaryAnalysis,
23}
24
25impl Decompiler {
26    /// Create a new decompiler instance from binary analysis
27    pub fn new(binary_analysis: BinaryAnalysis) -> Self {
28        Self { binary_analysis }
29    }
30
31    /// Perform full decompilation analysis
32    pub fn analyze(&self) -> Result<DecompilerAnalysis> {
33        let disasm = disasm::disassemble_binary(&self.binary_analysis)?;
34        
35        // Extract architecture and format from binary analysis
36        let arch = self.binary_analysis.architecture.as_str();
37        let format = self.binary_analysis.format.as_str();
38        
39        let functions = analysis::identify_functions_with_yara(&disasm, arch, format)?;
40        let call_graph = cfg::build_call_graph(&functions)?;
41        let function_cfgs = cfg::build_function_cfgs(&functions, &disasm, arch, format)?;
42        let pseudocode = lifting::generate_pseudocode(&functions, &disasm)?;
43
44        Ok(DecompilerAnalysis {
45            binary: self.binary_analysis.clone(),
46            disassembly: disasm,
47            functions,
48            call_graph,
49            function_cfgs,
50            pseudocode,
51            analysis_timestamp: chrono::Utc::now(),
52        })
53    }
54
55    /// Analyze a specific function by address
56    pub fn analyze_function(&self, address: u64) -> Result<FunctionAnalysis> {
57        let disasm = disasm::disassemble_from_address(&self.binary_analysis, address)?;
58        
59        // Extract architecture and format from binary analysis
60        let arch = self.binary_analysis.architecture.as_str();
61        let format = self.binary_analysis.format.as_str();
62        
63        let function = analysis::analyze_single_function_with_arch(&disasm, address, arch, format)?;
64        let cfg = cfg::build_function_cfg_with_arch(&function, &disasm, arch, format)?;
65        let pseudocode = lifting::lift_function_to_pseudocode(&function, &disasm)?;
66
67        Ok(FunctionAnalysis {
68            function,
69            cfg,
70            pseudocode,
71            disassembly: disasm,
72        })
73    }
74}
75
76/// Request structure for decompilation operations
77#[derive(Debug, Clone, Serialize, Deserialize)]
78pub struct DecompileRequest {
79    pub binary_path: String,
80    pub function_address: Option<u64>,
81    pub output_format: String,
82}
83
84/// Engine for handling decompilation operations
85pub struct DecompilerEngine {
86    // Future: could cache decompilers or configurations here
87}
88
89impl DecompilerEngine {
90    /// Create a new decompiler engine
91    pub async fn new() -> Result<Self> {
92        Ok(Self {})
93    }
94
95    /// Perform decompilation based on request
96    pub async fn decompile(&mut self, request: DecompileRequest, binary_analysis: &BinaryAnalysis) -> Result<DecompilerResult> {
97        let decompiler = Decompiler::new(binary_analysis.clone());
98        
99        match request.function_address {
100            Some(address) => {
101                let func_analysis = decompiler.analyze_function(address)?;
102                Ok(DecompilerResult::FunctionAnalysis(func_analysis))
103            }
104            None => {
105                let full_analysis = decompiler.analyze()?;
106                Ok(DecompilerResult::FullAnalysis(full_analysis))
107            }
108        }
109    }
110}
111
112/// Result type for decompilation operations
113#[derive(Debug, Clone)]
114pub enum DecompilerResult {
115    FullAnalysis(DecompilerAnalysis),
116    FunctionAnalysis(FunctionAnalysis),
117}
118
119#[cfg(test)]
120mod tests {
121    include!("lifting_tests.rs");
122}