extern crate nix;
extern crate libc;
#[macro_use] extern crate log;
extern crate env_logger;
#[cfg(unix)]
use libc::{open, c_uint, ptrace, waitpid, pid_t, c_int, pwrite};
use nix::errno;
#[cfg(target_pointer_width="64")]
pub struct Transaction{
pub adress : u64,
pub data : Vec<u8>,
}
#[cfg(target_pointer_width="32")]
pub struct Transaction{
pub adress : u32,
pub data : Vec<u8>,
}
#[cfg(unix)]
#[allow(dead_code)]
pub struct Transactions{
pub transactions : Vec<Transaction>,
targetpid : u32,
}
#[cfg(unix)]
#[allow(unused_assignments)]
#[allow(unused_variables)]
impl Transactions{
pub fn make_transactions(&self) -> bool{
let mut mem = "/proc/".to_string();
mem.push_str(&self.targetpid.to_string());
mem.push_str(&"/mem".to_string());
let mut handle : Option<i32>;
handle = None;
unsafe{
let ptrace_attach : c_uint = 0x10;
let mut status : c_int = 0;
let option : c_int = 0;
ptrace(ptrace_attach, self.targetpid as pid_t);
debug!("Val of ptrace {}", errno::errno());
waitpid(self.targetpid as pid_t, &mut status, option);
debug!("Val of waitpid {}", errno::errno());
handle = Some(open(mem.as_ptr() as *const i8, 0x2));
debug!("Val of open {}", errno::errno());
}
for transaction in &self.transactions{
match handle{
Some(val) =>
unsafe{
pwrite(val, transaction.data.as_ptr() as *const libc::c_void,
transaction.data.len(), transaction.adress as i64);
debug!("Val of pwrite {}", errno::errno());
if errno::errno() != 0 {
debug!("Failed to write data");
return false;
}
},
None => {debug!("failed to write data"); return false;},
}
}
debug!("Successfully written all data");
return true;
}
}
#[test]
fn mem_test() {
env_logger::init().unwrap();
debug!("Testing now");
let test = Transaction{
adress : 0x0,
data : vec![0,0,0],
};
let test2 = Transactions{
targetpid : 11211,
transactions : vec![test]
};
assert!(test2.make_transactions());
}