Skip to main content

nabla_decompiler/
types.rs

1//! Core data types for the decompiler
2
3use chrono::{DateTime, Utc};
4use nabla_scanner::binary::analysis::BinaryAnalysis;
5use petgraph::Graph;
6use serde::{Deserialize, Serialize};
7use std::collections::HashMap;
8use uuid::Uuid;
9
10/// Memory address type
11pub type Address = u64;
12
13/// Complete decompilation analysis of a binary
14#[derive(Debug, Clone, serde::Serialize)]
15pub struct DecompilerAnalysis {
16    pub binary: BinaryAnalysis,
17    pub disassembly: Disassembly,
18    pub functions: Vec<Function>,
19    #[serde(skip)] // Skip graphs for JSON serialization
20    pub call_graph: CallGraph,
21    #[serde(skip)] // Skip graphs for JSON serialization
22    pub function_cfgs: HashMap<Address, ControlFlowGraph>,
23    pub pseudocode: HashMap<Address, PseudoCode>,
24    pub analysis_timestamp: DateTime<Utc>,
25}
26
27/// Analysis of a single function
28#[derive(Debug, Clone, serde::Serialize)]
29pub struct FunctionAnalysis {
30    pub function: Function,
31    #[serde(skip)] // Skip CFG for JSON serialization
32    pub cfg: ControlFlowGraph,
33    pub pseudocode: PseudoCode,
34    pub disassembly: Disassembly,
35}
36
37/// Disassembled binary representation
38#[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/// Single assembly instruction
46#[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/// Instruction classification
57#[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/// Binary section information
73#[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/// Function representation
82#[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>, // Functions this calls
92    pub called_by: Vec<Address>, // Functions that call this
93}
94
95/// Basic block in a function
96#[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/// Basic block classification
108#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
109pub enum BlockType {
110    Entry,
111    Normal,
112    Conditional,
113    Loop,
114    Exit,
115}
116
117/// Function call graph
118pub 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
140/// Control flow graph for a single function
141pub 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/// Generated pseudocode
167#[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, // 0.0 - 1.0 confidence in pseudocode accuracy
175}
176
177/// Variable in pseudocode
178#[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), // bit width
189    Float(u8),   // bit width
190    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/// Error types for decompiler
205#[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}