process_read_write/
lib.rs1#![allow(dead_code)]
2
3use nix::{unistd::Pid,sys::{ptrace,uio::{process_vm_readv,process_vm_writev,RemoteIoVec}},Error};
4use std::io::{IoSliceMut,IoSlice};
5use sysinfo::System;
6use std::collections::HashMap;
7use nix::{self,sys::wait::waitpid};
8use serde_json;
9
10const SYSCALL_DATA: &str = include_str!("../data/syscall.json");
11
12pub fn get_proc_by_id(id: i32) -> Pid{
14 Pid::from_raw(id)
15}
16
17fn syscalls_list() -> HashMap<u64,String>{
18 let mut map = HashMap::new();
19 let parse: serde_json::Value = serde_json::from_str(&SYSCALL_DATA).unwrap();
20 for sysobj in parse["aaData"].as_array().unwrap() {
21 map.insert(sysobj[0].as_u64().unwrap(),sysobj[1].as_str().unwrap().to_string());
22 }
23 map
24}
25fn printsyscall(syscall_names:&HashMap<u64,String>,regs:nix::libc::user_regs_struct,i:usize) {
26 let syscall_name = syscall_names.get(®s.orig_rax).unwrap();
27 eprint!("{} => ",i/2);
29 eprintln!("{} ({},{:x},{:x},..) = {}",
30 syscall_name,
31 regs.rdi,
32 regs.rsi,
33 regs.rdx,
34 regs.rax
35 );
36}
37
38pub fn watch_proc(pid:i32){
40 let syscall_names = syscalls_list();
41 let childpid = Pid::from_raw(pid);
42 ptrace::attach(childpid).expect("cant attach to pid");
43 let _ = waitpid(childpid,None).expect("timeout waiting for pid");
44 let mut i = 0;
45 loop{
46 ptrace::syscall(childpid,None).unwrap();
47 let _ = waitpid(childpid,None).unwrap();
48 let regs = ptrace::getregs(childpid).expect(&format!("{}","Error: process most likely terminated!"));
49 if i%2 == 0{
50 printsyscall(&syscall_names,regs,i);
51 }
52 i+=1;
53 }
54}
55
56pub fn get_proc_by_name(process_name: &str) -> Pid{
75 let s = System::new_all();
76 let pid:usize;
77 let procs:Vec<_> = s.processes_by_exact_name(process_name).collect();
78 match procs.len() {
79 1 => pid = procs[0].pid().into(),
80 0 => panic!("No process found!"),
81 _ => {
82 println!("Multipe processes found!, please try get_proc_by_id(pid) instead");
83 for proc in procs{
84 println!("{} => {}",proc.name(),proc.pid());
85 }
86 println!("Trying to use pidof");
87 std::process::exit(1);
88 },
89 }
90 Pid::from_raw(pid.try_into().unwrap())
91}
92
93
94pub fn read_addr(pid:Pid,addr:usize,length:usize) -> Result<Vec<u8>,Error>
109{
110 let mut data: Vec<u8> = vec![0;length];
111 let local_iov = IoSliceMut::new(&mut data);
112
113 let remote_iov = RemoteIoVec {
114 base : addr,
115 len : length,
116 };
117
118 process_vm_readv(pid,&mut [local_iov],&[remote_iov])?;
119 Ok(data[..length].to_vec())
120}
121
122pub fn write_addr(pid:Pid,addr:usize,data:&[u8]){
129 let mut _data:&[u8] = data;
130 let local_iov = IoSlice::new(&mut _data);
131
132 let remote_iov = RemoteIoVec {
133 base : addr,
134 len : data.len(),
135 };
136
137 process_vm_writev(pid,&mut [local_iov],&[remote_iov]).unwrap();
138}