#![allow(dead_code)]
use nix::{unistd::Pid,sys::{ptrace,uio::{process_vm_readv,process_vm_writev,RemoteIoVec}},Error};
use std::io::{IoSliceMut,IoSlice};
use sysinfo::System;
use std::collections::HashMap;
use nix::{self,sys::wait::waitpid};
use serde_json;
const SYSCALL_DATA: &str = include_str!("../data/syscall.json");
pub fn get_proc_by_id(id: i32) -> Pid{
Pid::from_raw(id)
}
fn syscalls_list() -> HashMap<u64,String>{
let mut map = HashMap::new();
let parse: serde_json::Value = serde_json::from_str(&SYSCALL_DATA).unwrap();
for sysobj in parse["aaData"].as_array().unwrap() {
map.insert(sysobj[0].as_u64().unwrap(),sysobj[1].as_str().unwrap().to_string());
}
map
}
fn printsyscall(syscall_names:&HashMap<u64,String>,regs:nix::libc::user_regs_struct,i:usize) {
let syscall_name = syscall_names.get(®s.orig_rax).unwrap();
eprint!("{} => ",i/2);
eprintln!("{} ({},{:x},{:x},..) = {}",
syscall_name,
regs.rdi,
regs.rsi,
regs.rdx,
regs.rax
);
}
pub fn watch_proc(pid:i32){
let syscall_names = syscalls_list();
let childpid = Pid::from_raw(pid);
ptrace::attach(childpid).expect("cant attach to pid");
let _ = waitpid(childpid,None).expect("timeout waiting for pid");
let mut i = 0;
loop{
ptrace::syscall(childpid,None).unwrap();
let _ = waitpid(childpid,None).unwrap();
let regs = ptrace::getregs(childpid).expect(&format!("{}","Error: process most likely terminated!"));
if i%2 == 0{
printsyscall(&syscall_names,regs,i);
}
i+=1;
}
}
pub fn get_proc_by_name(process_name: &str) -> Pid{
let s = System::new_all();
let pid:usize;
let procs:Vec<_> = s.processes_by_exact_name(process_name).collect();
match procs.len() {
1 => pid = procs[0].pid().into(),
0 => panic!("No process found!"),
_ => {
println!("Multipe processes found!, please try get_proc_by_id(pid) instead");
for proc in procs{
println!("{} => {}",proc.name(),proc.pid());
}
println!("Trying to use pidof");
std::process::exit(1);
},
}
Pid::from_raw(pid.try_into().unwrap())
}
pub fn read_addr(pid:Pid,addr:usize,length:usize) -> Result<Vec<u8>,Error>
{
let mut data: Vec<u8> = vec![0;length];
let local_iov = IoSliceMut::new(&mut data);
let remote_iov = RemoteIoVec {
base : addr,
len : length,
};
process_vm_readv(pid,&mut [local_iov],&[remote_iov])?;
Ok(data[..length].to_vec())
}
pub fn write_addr(pid:Pid,addr:usize,data:&[u8]){
let mut _data:&[u8] = data;
let local_iov = IoSlice::new(&mut _data);
let remote_iov = RemoteIoVec {
base : addr,
len : data.len(),
};
process_vm_writev(pid,&mut [local_iov],&[remote_iov]).unwrap();
}