1pub 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
20pub struct Decompiler {
22 binary_analysis: BinaryAnalysis,
23}
24
25impl Decompiler {
26 pub fn new(binary_analysis: BinaryAnalysis) -> Self {
28 Self { binary_analysis }
29 }
30
31 pub fn analyze(&self) -> Result<DecompilerAnalysis> {
33 let disasm = disasm::disassemble_binary(&self.binary_analysis)?;
34
35 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 pub fn analyze_function(&self, address: u64) -> Result<FunctionAnalysis> {
57 let disasm = disasm::disassemble_from_address(&self.binary_analysis, address)?;
58
59 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#[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
84pub struct DecompilerEngine {
86 }
88
89impl DecompilerEngine {
90 pub async fn new() -> Result<Self> {
92 Ok(Self {})
93 }
94
95 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#[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}