1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
use { PutAddress, CopyAddress, ProcessHandle };

use std::{ io, mem, marker, fmt, str };
use std::marker::PhantomData;
use std::cell::RefCell;

pub trait Memory {
    fn set_offset(&mut self, Vec<usize>);
    fn read(&self, handle: ProcessHandle) -> Result<String, io::Error>;
    fn write(&self, handle: ProcessHandle, value: &str) -> Result<(), io::Error>;
}

pub struct DataMember<T> 
    where <T as str::FromStr>::Err: fmt::Debug,
    T: marker::Sized + fmt::Display + ToString + str::FromStr 
{
    offsets:    Vec<usize>,
    buffer:     RefCell<Vec<u8>>,
    _phantom:   PhantomData<*const T>
} 

impl<T> DataMember<T> 
    where <T as str::FromStr>::Err: fmt::Debug,
    T: marker::Sized + fmt::Display + ToString + str::FromStr
{
    pub fn new() -> DataMember<T> {
        DataMember {
            offsets:    Vec::new(),
            buffer:     RefCell::new(vec![0u8; mem::size_of::<T>()]),
            _phantom:   PhantomData
        }
    }
} 

impl Memory for DataMember<String> {
    fn set_offset(&mut self, new_offsets: Vec<usize>) {
        self.offsets = new_offsets;
    }
    fn read(&self, handle: ProcessHandle) -> Result<String, io::Error> {
        let offset = handle.get_offset(&self.offsets);
        let mut parts = Vec::<u8>::new(); 
        let mut addition_offset = 0usize;
        loop {
            let mut byte = [0u8; 1];
            match handle.copy_address(offset + addition_offset, &mut byte) {
                Ok(_) => {},
                Err(x) => return Err(x)
            };
            if byte[0] == 0 {
                break;
            }
            addition_offset += 1;
            parts.push(byte[0]);
        }
        Ok(String::from_utf8(parts).unwrap())
    }
    fn write(&self, handle: ProcessHandle, value: &str) -> Result<(), io::Error> {
        let offset = handle.get_offset(&self.offsets);
        let bytes = value.as_bytes();
        match handle.put_address(offset, bytes) {
            Ok(_) => {
                handle.put_address(offset + bytes.len(), &[0u8])
            }
            Err(x) => Err(x)
        }
    }
}

impl <T> Memory for DataMember<T> 
    where <T as str::FromStr>::Err: fmt::Debug,
    T: marker::Sized + fmt::Display + ToString + str::FromStr
{
    default fn set_offset(&mut self, new_offsets: Vec<usize>) {
        self.offsets = new_offsets;
    }
    default fn read(&self, handle: ProcessHandle) -> Result<String, io::Error> {
        let offset = handle.get_offset(&self.offsets);
        let mut buffer = self.buffer.borrow_mut();
        match handle.copy_address(offset, &mut buffer) {
            Ok(_) => { 
                let x : &T = unsafe { mem::transmute_copy(mem::transmute::<*mut Vec<u8>, &Vec<u8>>(self.buffer.as_ptr())) };
                Ok(x.to_string())
            },
            Err(x) => {
               return Err(x) 
            }
        }
    }
    default fn write(&self, handle: ProcessHandle, value: &str) -> Result<(), io::Error> {
        use std::slice;
        let offset = handle.get_offset(&self.offsets);
        let value : T = value.parse().unwrap();
        let p1 : *const T = &value;
        let p2 : *const u8 = p1 as *const _;
        let buffer = unsafe { 
            slice::from_raw_parts(p2, mem::size_of::<T>())
        };
        handle.put_address(offset, &buffer)
    }
}