use anyhow::Result; use log::info; use std::fs; use std::path::Path; use std::str::FromStr; pub struct Process { pub pid: i32, #[allow(dead_code)] pub name: String, } #[derive(Debug, Clone)] pub struct MemoryRegion { pub start_addr: usize, pub end_addr: usize, #[allow(dead_code)] pub permissions: String, #[allow(dead_code)] pub offset: usize, #[allow(dead_code)] pub pathname: String, } impl Process { pub fn find_by_name(name: &str) -> Result { // Search for process using pgrep-like functionality let proc_dir = Path::new("/proc"); let mut found_pid = None; for entry in fs::read_dir(proc_dir)? { let entry = entry?; let path = entry.path(); if !path.is_dir() { continue; } let file_name = path.file_name().unwrap().to_string_lossy(); if !file_name.chars().all(|c| c.is_digit(10)) { continue; } let pid = i32::from_str(&file_name)?; let cmdline_path = path.join("cmdline"); if !cmdline_path.exists() { continue; } let cmdline = fs::read_to_string(cmdline_path)?; if cmdline.contains(name) { println!("Process found with PID: {}", pid); found_pid = Some(pid); break; } } match found_pid { Some(pid) => Ok(Process { pid, name: name.to_string(), }), None => anyhow::bail!("Process '{}' not found", name), } } pub fn get_memory_maps(&self) -> Result> { let maps_path = format!("/proc/{}/maps", self.pid); info!("maps file located at {} opened.", maps_path); let maps_content = fs::read_to_string(&maps_path)?; let mut regions = Vec::new(); for line in maps_content.lines() { let parts: Vec<&str> = line.split_whitespace().collect(); if parts.len() < 5 { continue; } let addr_range: Vec<&str> = parts[0].split('-').collect(); if addr_range.len() != 2 { continue; } let start_addr = usize::from_str_radix(addr_range[0], 16)?; let end_addr = usize::from_str_radix(addr_range[1], 16)?; let permissions = parts[1].to_string(); // Only add regions with read permission if permissions.contains('r') { regions.push(MemoryRegion { start_addr, end_addr, permissions, offset: usize::from_str_radix(parts[2], 16)?, pathname: if parts.len() > 5 { parts[5..].join(" ") } else { String::new() }, }); } } info!("{} suitable regions found.", regions.len()); Ok(regions) } }