1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
//! # Purpose
//!
//! This example is a CLI application that can find and replace arbitrary
//! data in an arbitrary process, using the raminspect library as a backend.
//!
//! # Usage
//!
//! `sudo cargo run --example replacemem --release -- <pid> <search term> <replacement>`
//!
//! Or if you want to install this as a command line application, you may build it using this command:
//!
//! `cargo build --release --example replacemem`
//!
//! And then copy the output to /usr/bin like so:
//!
//! `sudo cp target/release/examples/replacemem /usr/bin/replacemem`
//!
//! And then use the resulting executable like this after you refresh your shell:
//!
//! `replacemem <pid> <string search term> <string replacement>`
fn exit_err(msg: &str) -> ! {
eprintln!("Error: {}", msg);
eprintln!("Program usage: replacemem pidnumber \"searchterm\" \"replacement\"");
std::process::exit(1);
}
fn main() {
use raminspect::RamInspector;
let mut args = std::env::args();
let pid_parse_err = "Expected a number as the first argument";
// Skip the first argument which is the program name on Unix systems
args.next();
let pid = args.next().unwrap_or_else(|| exit_err(pid_parse_err)).parse::<i32>().unwrap_or_else(|_| {
exit_err(pid_parse_err)
});
let search_term = args.next().unwrap_or_else(|| exit_err("Expected three arguments."));
let replacement_term = args.next().unwrap_or_else(|| exit_err("Expected three arguments."));
if args.next().is_some() {
exit_err("Expected no more than three arguments.");
}
use raminspect::RamInspectError;
fn inspect_process(pid: i32, search_term: &str, replacement_term: &str) -> Result<(), RamInspectError> {
unsafe {
let mut inspector = RamInspector::new(pid)?;
for (result_addr, memory_region) in inspector.search_for_term(search_term.as_bytes())? {
if !memory_region.writable() {
continue;
}
inspector.queue_write(result_addr, replacement_term.as_bytes());
}
inspector.flush().unwrap();
}
Ok(())
}
if let Err(error) = inspect_process(pid, &search_term, &replacement_term) {
exit_err(&format!("{:?}", error));
}
}