paavohtl Claude Opus 4.6 commited on
Commit
9d55850
·
1 Parent(s): 586482f

feat: add openwa-debug-proto crate with wire protocol types

Browse files

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

crates/openwa-debug-proto/Cargo.toml ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ [package]
2
+ name = "openwa-debug-proto"
3
+ version = "0.1.0"
4
+ edition = "2021"
5
+ description = "Wire protocol types for OpenWA debug server"
6
+
7
+ [dependencies]
8
+ serde = { version = "1", features = ["derive"] }
9
+ rmp-serde = "1"
crates/openwa-debug-proto/src/lib.rs ADDED
@@ -0,0 +1,84 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ use serde::{Deserialize, Serialize};
2
+ use std::io::{self, Read, Write};
3
+
4
+ // --- Pointer classification ---
5
+
6
+ #[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
7
+ pub enum PointerKind {
8
+ Vtable,
9
+ Code,
10
+ Data,
11
+ Object,
12
+ Heap,
13
+ }
14
+
15
+ #[derive(Debug, Clone, Serialize, Deserialize)]
16
+ pub struct PointerInfo {
17
+ pub offset: u32,
18
+ pub raw_value: u32,
19
+ pub ghidra_value: u32,
20
+ pub kind: PointerKind,
21
+ pub detail: Option<String>,
22
+ }
23
+
24
+ // --- Protocol messages ---
25
+
26
+ #[derive(Debug, Clone, Serialize, Deserialize)]
27
+ pub enum Request {
28
+ Ping,
29
+ Help,
30
+ Read { addr: u32, len: u32 },
31
+ }
32
+
33
+ #[derive(Debug, Clone, Serialize, Deserialize)]
34
+ pub struct CommandHelp {
35
+ pub name: String,
36
+ pub usage: String,
37
+ pub description: String,
38
+ }
39
+
40
+ #[derive(Debug, Clone, Serialize, Deserialize)]
41
+ pub enum Response {
42
+ Pong,
43
+ Help { commands: Vec<CommandHelp> },
44
+ ReadResult {
45
+ ghidra_addr: u32,
46
+ runtime_addr: u32,
47
+ data: Vec<u8>,
48
+ pointers: Vec<PointerInfo>,
49
+ },
50
+ Error { message: String },
51
+ }
52
+
53
+ // --- Length-prefixed framing ---
54
+
55
+ pub const DEFAULT_PORT: u16 = 19840;
56
+ pub const MAX_READ_SIZE: u32 = 1024 * 1024; // 1 MB
57
+ pub const MAX_FRAME_SIZE: usize = 8 * 1024 * 1024; // 8 MB (read data + pointer metadata overhead)
58
+
59
+ /// Write a length-prefixed MessagePack frame.
60
+ pub fn write_frame<W: Write, T: Serialize>(writer: &mut W, msg: &T) -> io::Result<()> {
61
+ let payload =
62
+ rmp_serde::to_vec(msg).map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))?;
63
+ let len = payload.len() as u32;
64
+ writer.write_all(&len.to_le_bytes())?;
65
+ writer.write_all(&payload)?;
66
+ writer.flush()
67
+ }
68
+
69
+ /// Read a length-prefixed MessagePack frame.
70
+ pub fn read_frame<R: Read, T: for<'de> Deserialize<'de>>(reader: &mut R) -> io::Result<T> {
71
+ let mut len_buf = [0u8; 4];
72
+ reader.read_exact(&mut len_buf)?;
73
+ let len = u32::from_le_bytes(len_buf) as usize;
74
+ if len > MAX_FRAME_SIZE {
75
+ return Err(io::Error::new(
76
+ io::ErrorKind::InvalidData,
77
+ "frame too large",
78
+ ));
79
+ }
80
+ let mut payload = vec![0u8; len];
81
+ reader.read_exact(&mut payload)?;
82
+ rmp_serde::from_slice(&payload)
83
+ .map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))
84
+ }