stack_replace/
lib.rs

1use std::convert::TryInto;
2use std::ffi::CString;
3use std::fs::File;
4use std::io;
5use std::io::BufRead;
6
7pub struct ReplaceStack {
8    stack: (usize, usize),
9}
10
11#[derive(Debug)]
12pub struct StrBlock(usize, usize);
13impl StrBlock{
14    fn new(start: usize, len: usize)-> Self{
15        Self{0: start, 1: len}
16    }
17}
18
19
20impl ReplaceStack {
21    pub fn new() -> Result<Self, ()> {
22        match Self::find_stack() {
23            Ok(stack) => Ok(Self { stack }),
24            Err(_) => Err(()),
25        }
26    }
27    fn find_stack() -> Result<(usize, usize), ()> {
28        let map_file = File::open("/proc/self/maps").unwrap();
29        let stack = io::BufReader::new(map_file)
30            .lines()
31            .map(|line| line.unwrap_or("".to_string()))
32            .filter(|line| line.contains("[stack]"))
33            .collect::<Vec<String>>();
34        if stack.is_empty() {
35            return Err(());
36        }
37        let stack_range: [&str; 2] = stack[0].split(" ").collect::<Vec<&str>>()[0]
38            .splitn(2, "-")
39            .collect::<Vec<&str>>()
40            .try_into()
41            .unwrap();
42        let start = usize::from_str_radix(stack_range[0], 16).unwrap_or(0);
43        let end = usize::from_str_radix(stack_range[1], 16).unwrap_or(0);
44        if start != 0 && end != 0 {
45            return Ok((start, end));
46        }
47        Err(())
48    }
49    pub fn find_string_addr(&self, name: &String) -> Result<Vec<StrBlock>, ()> {
50        let mut tmp = Vec::<u8>::new();
51        let mut argv_addr = Vec::<StrBlock>::new();
52        let (start, end) = self.stack;
53        for i in start..end {
54            tmp.clear();
55            for x in 0..name.len() {
56                if i + x >= end {
57                    break;
58                }
59                tmp.push(unsafe { std::ptr::read((i + x) as *const u8) })
60            }
61            let p_name = unsafe { CString::from_vec_unchecked(tmp.clone()) }
62                .to_str()
63                .unwrap_or("")
64                .to_string();
65            if p_name.contains(name) {
66                let mut len = 0usize;
67                loop {
68                    if (unsafe { std::ptr::read((i + len) as *const u8) }).eq(&0){
69                        break
70                    }
71                    len += 1;
72                }
73                argv_addr.push(StrBlock::new(i, len))
74            }
75        }
76        if argv_addr.is_empty() {
77            return Err(());
78        }
79        Ok(argv_addr)
80    }
81    pub fn replace_string(block: StrBlock, name: &str) {
82        let name_len = name.len();
83        let str_ptr: &mut [u8] =
84            unsafe { std::slice::from_raw_parts_mut(block.0 as *mut u8, block.1) };
85        str_ptr.fill(0);
86        for c in 0..name_len {
87            str_ptr[c] = name.as_bytes()[c];
88        }
89    }
90}