mirror of
https://github.com/encounter/ghidra-cli.git
synced 2026-07-10 03:18:56 -07:00
This commit implements the daemon-only architecture where all query operations (functions, strings, decompile, memory, summary, xrefs) must go through the persistent daemon instead of spawning new Ghidra processes per command. Key changes: - Wire IPC client in main.rs to route queries through daemon - Add requires_daemon() to determine which commands need daemon - Add execute_via_daemon() to translate CLI commands to IPC calls - Deprecate HeadlessExecutor with migration notice - Fix filter.pest hex number parsing order (hex before number) - Add #[allow(dead_code)] to infrastructure modules for future use - Mark E2E tests requiring daemon as #[ignore] Architecture benefits: - Faster queries: Ghidra stays loaded, no 5-30s startup per command - Simpler code: One execution path instead of two - Better UX: Clear daemon requirement with helpful error messages When daemon is not running, users see: Error: This command requires the daemon to be running. Start the daemon with: ghidra daemon start --project <name> Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
175 lines
4.0 KiB
Rust
175 lines
4.0 KiB
Rust
//! Data structures for Ghidra query results.
|
|
//!
|
|
//! These are used to parse JSON responses from Ghidra scripts.
|
|
|
|
#![allow(dead_code)]
|
|
|
|
use serde::{Deserialize, Serialize};
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
pub struct Function {
|
|
pub name: String,
|
|
pub address: String,
|
|
pub size: u64,
|
|
pub signature: Option<String>,
|
|
pub entry_point: String,
|
|
pub calling_convention: Option<String>,
|
|
#[serde(default)]
|
|
pub parameters: Vec<Parameter>,
|
|
#[serde(default)]
|
|
pub local_variables: Vec<LocalVariable>,
|
|
#[serde(default)]
|
|
pub calls: Vec<String>,
|
|
#[serde(default)]
|
|
pub called_by: Vec<String>,
|
|
pub decompiled: Option<String>,
|
|
pub comment: Option<String>,
|
|
}
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
pub struct Parameter {
|
|
pub name: String,
|
|
pub data_type: String,
|
|
pub ordinal: u32,
|
|
}
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
pub struct LocalVariable {
|
|
pub name: String,
|
|
pub data_type: String,
|
|
pub stack_offset: Option<i32>,
|
|
}
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
pub struct StringData {
|
|
pub address: String,
|
|
pub value: String,
|
|
pub length: usize,
|
|
pub encoding: String,
|
|
#[serde(default)]
|
|
pub references: Vec<String>,
|
|
}
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
pub struct Symbol {
|
|
pub name: String,
|
|
pub address: String,
|
|
pub symbol_type: String,
|
|
pub namespace: Option<String>,
|
|
pub source: String,
|
|
}
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
pub struct Import {
|
|
pub name: String,
|
|
pub address: String,
|
|
pub library: String,
|
|
pub ordinal: Option<u32>,
|
|
pub is_external: bool,
|
|
}
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
pub struct Export {
|
|
pub name: String,
|
|
pub address: String,
|
|
pub ordinal: Option<u32>,
|
|
}
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
pub struct XRef {
|
|
pub from: String,
|
|
pub to: String,
|
|
pub ref_type: String,
|
|
pub from_function: Option<String>,
|
|
pub to_function: Option<String>,
|
|
}
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
pub struct MemoryBlock {
|
|
pub name: String,
|
|
pub start: String,
|
|
pub end: String,
|
|
pub size: u64,
|
|
pub permissions: String,
|
|
pub is_initialized: bool,
|
|
pub is_loaded: bool,
|
|
}
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
pub struct Section {
|
|
pub name: String,
|
|
pub address: String,
|
|
pub size: u64,
|
|
pub virtual_address: String,
|
|
pub file_offset: u64,
|
|
}
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
pub struct Comment {
|
|
pub address: String,
|
|
pub comment_type: String,
|
|
pub text: String,
|
|
}
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
pub struct DataType {
|
|
pub name: String,
|
|
pub category: String,
|
|
pub size: Option<u64>,
|
|
pub description: Option<String>,
|
|
}
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
pub struct Instruction {
|
|
pub address: String,
|
|
pub mnemonic: String,
|
|
pub operands: String,
|
|
pub bytes: String,
|
|
pub length: u32,
|
|
pub flow_type: String,
|
|
}
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
pub struct BasicBlock {
|
|
pub start: String,
|
|
pub end: String,
|
|
pub size: u64,
|
|
pub instruction_count: u32,
|
|
#[serde(default)]
|
|
pub successors: Vec<String>,
|
|
#[serde(default)]
|
|
pub predecessors: Vec<String>,
|
|
}
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
pub struct ProgramInfo {
|
|
pub name: String,
|
|
pub executable_path: String,
|
|
pub executable_format: String,
|
|
pub compiler: Option<String>,
|
|
pub language: String,
|
|
pub creation_date: Option<String>,
|
|
pub image_base: String,
|
|
pub min_address: String,
|
|
pub max_address: String,
|
|
pub function_count: usize,
|
|
pub instruction_count: usize,
|
|
}
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
#[serde(tag = "type")]
|
|
pub enum GhidraData {
|
|
Function(Function),
|
|
String(StringData),
|
|
Symbol(Symbol),
|
|
Import(Import),
|
|
Export(Export),
|
|
XRef(XRef),
|
|
MemoryBlock(MemoryBlock),
|
|
Section(Section),
|
|
Comment(Comment),
|
|
DataType(DataType),
|
|
Instruction(Instruction),
|
|
BasicBlock(BasicBlock),
|
|
}
|