process_memory_reader/
linux.rs1use crate::{MemoryReadError, Process};
2use libc::{iovec, process_vm_readv};
3use std::fs::{read_dir, File};
4use std::io::{Error as IoError, BufReader, BufRead};
5
6pub fn open_process(pid: u32) -> Option<LinuxProcess> {
10 Some(LinuxProcess { pid })
11}
12
13pub fn find_by_name(name: &str) -> Result<Vec<LinuxProcess>, IoError> {
15 let paths = read_dir("/proc")?;
16 let mut processes = vec![];
17
18 for path_entry in paths {
19 if let Ok(path) = path_entry {
20 let maps_path = path.path().join("maps");
21
22 if let Ok(file) = File::open(maps_path) {
23 let mut reader = BufReader::new(file);
24 let mut buffer = String::new();
25 reader.read_line(&mut buffer)?;
26
27 if buffer.trim().ends_with(name) {
28 if let Some(pid_name) = path.file_name().to_str() {
29 let pid = pid_name.parse::<u32>().unwrap();
30
31 open_process(pid).map(|process| processes.push(process));
32 }
33 }
34 }
35 }
36 }
37
38 Ok(processes)
39}
40
41#[derive(Debug)]
42pub struct LinuxProcess {
43 pub pid: u32,
44}
45
46impl Process for LinuxProcess {
47 fn base_address(&self, module_name: &str) -> Option<usize> {
48 let file_name = format!("/proc/{}/maps", self.pid);
49 let file = File::open(file_name).ok()?;
50 let reader = BufReader::new(file);
51
52 for result in reader.lines() {
53 if let Ok(line) = result {
54 if line.trim().ends_with(module_name) {
55 let split_line: Vec<&str> = line.split("-").collect();
56 let address_str = split_line[0];
57
58 return usize::from_str_radix(address_str, 16).ok();
59 }
60 }
61 }
62
63 None
64 }
65
66 fn read_bytes(&self, address: usize, buffer: &mut [u8]) -> Result<(), MemoryReadError> {
67 let local_iov = iovec {
68 iov_base: buffer.as_mut_ptr() as *mut _,
69 iov_len: buffer.len(),
70 };
71
72 let remote_iov = iovec {
73 iov_base: address as *mut _,
74 iov_len: buffer.len(),
75 };
76
77 let result = unsafe { process_vm_readv(self.pid as i32, &local_iov, 1, &remote_iov, 1, 0) };
78
79 if result == -1 {
80 return Err(MemoryReadError::IOError {
81 io_error: IoError::last_os_error(),
82 });
83 }
84
85 Ok(())
86 }
87}