mnemosyne 0.3.1

a process hooking library
Documentation
use crate::module;

pub struct VTable {
    method_index: u64,
    original_pointer: u64,
    original_method: u64,

    pub is_hooked: bool,
}

impl VTable {
    pub fn new(original: u64, index: u64) -> Self {
        Self {
            method_index: index,
            original_pointer: original,
            original_method: 0,

            is_hooked: false,
        }
    }

    pub fn set_hook(&mut self, hook: u64) -> Result<(), String> {
        let vmt = module::read::<*mut u64>(self.original_pointer).unwrap();

        self.original_method = unsafe {
            let result = module::read::<u64>(vmt.add(self.method_index as usize) as u64);
            if result.is_none() {
                return Err("invalid method index".into());
            }

            result.unwrap()
        };

        let result = unsafe { module::write(vmt.add(self.method_index as usize) as u64, &hook) };
        if result.is_ok() {
            self.is_hooked = true;
        }

        result
    }

    pub fn unhook(&mut self) -> Result<(), String> {
        let vmt = module::read::<*mut u64>(self.original_pointer).unwrap();
        let result = unsafe {
            module::write(
                vmt.add(self.method_index as usize) as u64,
                &(self.original_method),
            )
        };

        if result.is_ok() {
            self.is_hooked = false;
        }

        result
    }

    pub fn call_original<R, Args>(&mut self, args: Args) -> R {
        unsafe { std::mem::transmute::<_, extern "C" fn(Args) -> R>(self.original_method)(args) }
    }
}