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}