1use chrono::{DateTime, Utc};
4use nabla_scanner::binary::analysis::BinaryAnalysis;
5use petgraph::Graph;
6use serde::{Deserialize, Serialize};
7use std::collections::HashMap;
8use uuid::Uuid;
9
10pub type Address = u64;
12
13#[derive(Debug, Clone, serde::Serialize)]
15pub struct DecompilerAnalysis {
16 pub binary: BinaryAnalysis,
17 pub disassembly: Disassembly,
18 pub functions: Vec<Function>,
19 #[serde(skip)] pub call_graph: CallGraph,
21 #[serde(skip)] pub function_cfgs: HashMap<Address, ControlFlowGraph>,
23 pub pseudocode: HashMap<Address, PseudoCode>,
24 pub analysis_timestamp: DateTime<Utc>,
25}
26
27#[derive(Debug, Clone, serde::Serialize)]
29pub struct FunctionAnalysis {
30 pub function: Function,
31 #[serde(skip)] pub cfg: ControlFlowGraph,
33 pub pseudocode: PseudoCode,
34 pub disassembly: Disassembly,
35}
36
37#[derive(Debug, Clone, serde::Serialize)]
39pub struct Disassembly {
40 pub instructions: Vec<Instruction>,
41 pub sections: Vec<Section>,
42 pub symbols: HashMap<Address, String>,
43}
44
45#[derive(Debug, Clone, serde::Serialize)]
47pub struct Instruction {
48 pub address: Address,
49 pub bytes: Vec<u8>,
50 pub mnemonic: String,
51 pub operands: String,
52 pub size: usize,
53 pub group: InstructionGroup,
54}
55
56#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
58pub enum InstructionGroup {
59 Jump,
60 Call,
61 Return,
62 Move,
63 Arithmetic,
64 Logical,
65 Compare,
66 Load,
67 Store,
68 Nop,
69 Other,
70}
71
72#[derive(Debug, Clone, serde::Serialize)]
74pub struct Section {
75 pub name: String,
76 pub address: Address,
77 pub size: u64,
78 pub permissions: String,
79}
80
81#[derive(Debug, Clone, serde::Serialize)]
83pub struct Function {
84 pub address: Address,
85 pub name: Option<String>,
86 pub size: u64,
87 pub instructions: Vec<Address>,
88 pub basic_blocks: Vec<BasicBlock>,
89 pub entry_point: Address,
90 pub exit_points: Vec<Address>,
91 pub calls: Vec<Address>, pub called_by: Vec<Address>, }
94
95#[derive(Debug, Clone, serde::Serialize)]
97pub struct BasicBlock {
98 pub id: Uuid,
99 pub start_address: Address,
100 pub end_address: Address,
101 pub instructions: Vec<Address>,
102 pub predecessors: Vec<Uuid>,
103 pub successors: Vec<Uuid>,
104 pub block_type: BlockType,
105}
106
107#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
109pub enum BlockType {
110 Entry,
111 Normal,
112 Conditional,
113 Loop,
114 Exit,
115}
116
117pub type CallGraph = Graph<FunctionNode, CallEdge>;
119
120#[derive(Debug, Clone, serde::Serialize)]
121pub struct FunctionNode {
122 pub address: Address,
123 pub name: Option<String>,
124 pub size: u64,
125}
126
127#[derive(Debug, Clone, serde::Serialize)]
128pub struct CallEdge {
129 pub call_type: CallType,
130 pub call_site: Address,
131}
132
133#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
134pub enum CallType {
135 Direct,
136 Indirect,
137 Tail,
138}
139
140pub type ControlFlowGraph = Graph<BasicBlockNode, ControlFlowEdge>;
142
143#[derive(Debug, Clone, serde::Serialize)]
144pub struct BasicBlockNode {
145 pub id: Uuid,
146 pub start_address: Address,
147 pub end_address: Address,
148 pub instruction_count: usize,
149 pub block_type: BlockType,
150}
151
152#[derive(Debug, Clone, serde::Serialize)]
153pub struct ControlFlowEdge {
154 pub edge_type: ControlFlowType,
155 pub condition: Option<String>,
156}
157
158#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
159pub enum ControlFlowType {
160 Unconditional,
161 ConditionalTrue,
162 ConditionalFalse,
163 FallThrough,
164}
165
166#[derive(Debug, Clone, serde::Serialize)]
168pub struct PseudoCode {
169 pub function_address: Address,
170 pub function_name: Option<String>,
171 pub code: String,
172 pub variables: Vec<Variable>,
173 pub comments: HashMap<Address, String>,
174 pub confidence: f32, }
176
177#[derive(Debug, Clone, serde::Serialize)]
179pub struct Variable {
180 pub name: String,
181 pub var_type: VariableType,
182 pub first_use: Address,
183 pub scope: VariableScope,
184}
185
186#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
187pub enum VariableType {
188 Integer(u8), Float(u8), Pointer,
191 Array(Box<VariableType>, usize),
192 Struct(String),
193 Unknown,
194}
195
196#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
197pub enum VariableScope {
198 Local,
199 Parameter,
200 Global,
201 Register,
202}
203
204#[derive(thiserror::Error, Debug)]
206pub enum DecompilerError {
207 #[error("Disassembly failed: {0}")]
208 DisassemblyError(String),
209
210 #[error("Function analysis failed: {0}")]
211 FunctionAnalysisError(String),
212
213 #[error("CFG generation failed: {0}")]
214 CfgError(String),
215
216 #[error("Pseudocode generation failed: {0}")]
217 LiftingError(String),
218
219 #[error("Binary format not supported: {0}")]
220 UnsupportedFormat(String),
221
222 #[error("Invalid address: 0x{0:x}")]
223 InvalidAddress(u64),
224}