1use nix::unistd::Pid;
2use std::io;
3
4use crate::platform;
5
6pub fn read_string(pid: Pid, addr: u64, max_len: usize) -> io::Result<String> {
9 if addr == 0 {
10 return Ok("NULL".to_string());
11 }
12
13 let mut result = Vec::with_capacity(128);
14 let mut offset = 0u64;
15
16 while result.len() < max_len {
17 let word = match platform::read_word(pid, addr + offset) {
18 Ok(w) => w,
19 Err(_) => return Ok(format!("{:#x}", addr)),
20 };
21 let bytes = word.to_ne_bytes();
22
23 for &b in &bytes {
24 if b == 0 {
25 return Ok(String::from_utf8_lossy(&result).into_owned());
26 }
27 result.push(b);
28 if result.len() >= max_len {
29 return Ok(format!("{}...", String::from_utf8_lossy(&result)));
30 }
31 }
32 offset += size_of::<i64>() as u64;
33 }
34 Ok(String::from_utf8_lossy(&result).into_owned())
35}
36
37pub fn read_bytes(pid: Pid, addr: u64, len: usize) -> io::Result<Vec<u8>> {
39 if addr == 0 || len == 0 {
40 return Ok(Vec::new());
41 }
42
43 let mut result = Vec::with_capacity(len);
44 let mut offset = 0u64;
45
46 while result.len() < len {
47 let word = platform::read_word(pid, addr + offset)?;
48 let bytes = word.to_ne_bytes();
49 for &b in &bytes {
50 if result.len() >= len {
51 break;
52 }
53 result.push(b);
54 }
55 offset += size_of::<i64>() as u64;
56 }
57 result.truncate(len);
58 Ok(result)
59}