use nix::sys::ptrace;
use nix::unistd::Pid;
use std::io::{self, Write, Read, Seek};
use std::fs::OpenOptions;
pub struct Memory {
pid: Pid,
}
impl Memory {
pub fn attach(pid: i32) -> io::Result<Self> {
ptrace::attach(Pid::from_raw(pid)).map_err(|e| io::Error::new(io::ErrorKind::Other, e))?;
Ok(Memory { pid: Pid::from_raw(pid) })
}
pub fn detach(&self) -> io::Result<()> {
ptrace::detach(self.pid, None).map_err(|e| io::Error::new(io::ErrorKind::Other, e))
}
pub fn read(&self, address: u64, buffer: &mut [u8]) -> io::Result<()> {
let mem_file = format!("/proc/{}/mem", self.pid);
let mut file = OpenOptions::new().read(true).open(&mem_file)?;
file.seek(io::SeekFrom::Start(address))?;
file.read_exact(buffer)?;
Ok(())
}
pub fn write(&self, address: u64, data: &[u8]) -> io::Result<()> {
let mem_file = format!("/proc/{}/mem", self.pid);
let mut file = OpenOptions::new().write(true).open(&mem_file)?;
file.seek(io::SeekFrom::Start(address))?;
file.write_all(data)?;
Ok(())
}
}