pub use procfs::process::MMapPath;
pub use procfs::process::MemoryMap;
use reverie::Guest;
use reverie::Pid;
use reverie::Tool;
use reverie::syscalls::Addr;
use reverie::syscalls::MemoryAccess;
use crate::Digest;
fn display_pathname(p: &MMapPath) -> String {
match p {
MMapPath::Vdso => String::from("[vsdo]"),
MMapPath::Stack => String::from("[stack]"),
MMapPath::TStack(tid) => format!("[tstack:{}]", tid),
MMapPath::Vvar => String::from("[vvar]"),
MMapPath::Vsyscall => String::from("[syscalls]"),
MMapPath::Heap => String::from("[heap]"),
MMapPath::Other(s) => format!("[other: {}]", s),
MMapPath::Anonymous => String::from("[annonymous]"),
MMapPath::Path(s) => s.display().to_string(),
MMapPath::Rollup => String::from("[rollup]"),
MMapPath::Vsys(vsys) => vsys.to_string(),
}
}
pub fn display(map: &MemoryMap) -> String {
display_as(map, &display_pathname(&map.pathname))
}
pub fn display_as(map: &MemoryMap, pathname: &str) -> String {
display_range_as(map, map.address.0, map.address.1, pathname)
}
pub fn display_range_as(map: &MemoryMap, start: u64, end: u64, pathname: &str) -> String {
format!(
"{:#x}-{:#x} {:?} {:x} {:x}:{:x} {} {}",
start, end, map.perms, map.offset, map.dev.0, map.dev.1, map.inode, pathname
)
}
fn map_error(err: procfs::ProcError) -> reverie::Error {
match err {
procfs::ProcError::Io(err, _) => reverie::Error::Io(err),
err => reverie::Error::Tool(anyhow::anyhow!(err)),
}
}
pub fn from_pid<F>(pid: Pid, filter: F) -> Result<Vec<MemoryMap>, reverie::Error>
where
F: Fn(&MemoryMap) -> bool,
{
match procfs::process::Process::new(pid.as_raw()) {
Ok(process) => match process.maps() {
Ok(mut maps) => {
maps.0.retain(filter);
Ok(maps.0)
}
Err(err) => Err(map_error(err)),
},
Err(err) => Err(map_error(err)),
}
}
pub fn compute_hash<G, T: Tool>(guest: &mut G, map: &MemoryMap) -> Result<Digest, reverie::Error>
where
G: Guest<T>,
{
compute_hash_range(guest, map.address.0, map.address.1)
}
pub fn compute_hash_range<G, T: Tool>(
guest: &mut G,
start: u64,
end: u64,
) -> Result<Digest, reverie::Error>
where
G: Guest<T>,
{
let size = end.saturating_sub(start) as usize;
let memory = guest.memory();
let mut buf = vec![0; size];
let start = Addr::<u8>::from_raw(start as usize).unwrap();
memory.read_values(start, buf.as_mut_slice())?;
Ok(Digest::new(buf.as_slice()))
}