Struct VTableHook

Source
pub struct VTableHook<T> { /* private fields */ }
Expand description

Represents a structure responsible for hooking and managing the virtual function table (VTable) of a given type.

§Example

use vmt_hook::VTableHook;

use windows::{
    core::HRESULT,
    Win32::{
        Foundation::{HWND, RECT},
        Graphics::{
            Direct3D9::IDirect3DDevice9,
            Gdi::RGNDATA,
        },
    },
};

type FnPresent = extern "stdcall" fn(
    IDirect3DDevice9,
    *const RECT,
    *const RECT,
    HWND,
    *const RGNDATA,
) -> HRESULT;

static mut ORIGINAL_PRESENT: Option<FnPresent> = None;

extern "stdcall" fn hk_present(
    device: IDirect3DDevice9,
    source_rect: *const RECT,
    dest_rect: *const RECT,
    dest_window_override: HWND,
    dirty_region: *const RGNDATA,
) -> HRESULT {
    // Your code.

    unsafe {
        let original_present = ORIGINAL_PRESENT.unwrap();
        original_present(device, source_rect, dest_rect, dest_window_override, dirty_region)
    }
}

unsafe fn instal_d3d9_hook() {
    let device: IDirect3DDevice9 = /* Your ptr. */;

    // Creating a hook with automatic detection of the number of methods in its VMT.
    // let hook = VTableHook::new(device);

    // If you know the number of methods in the table, you can specify it manually.
    let hook = VTableHook::with_count(device, 119);

    // Getting the original method.
    ORIGINAL_PRESENT = Some(std::mem::transmute(hook.get_original_method(17)));

    // Replacing the method at index 17 in the VMT with our function.
    hook.replace_method(17, hk_present as usize);
}

Implementations§

Source§

impl<T> VTableHook<T>

Source

pub unsafe fn new(object: T) -> Self

Creates a new VTableHook instance for the provided object and replaces its VTable with the hooked VTable. The count of methods is automatically determined.

Source

pub unsafe fn with_count(object: T, count: usize) -> Self

Creates a new VTableHook instance for the provided object with a specified method count and replaces its VTable with the hooked VTable.

Source

pub fn get_original_method(&self, id: usize) -> usize

Returns the original method address at the specified index in the VTable.

Source

pub fn get_replaced_method(&self, id: usize) -> usize

Returns the replaced method address at the specified index in the VTable.

Source

pub unsafe fn replace_method(&self, id: usize, func: usize)

Hooks the method at the specified index in the VTable with a new function address.

Source

pub unsafe fn restore_method(&self, id: usize)

Restores the original method at the specified index in the VTable.

Source

pub unsafe fn restore_all_methods(&self)

Restores all methods in the VTable to their original address.

Source

pub fn object(&self) -> &T

Returns the original object.

Trait Implementations§

Source§

impl<T> Drop for VTableHook<T>

Source§

fn drop(&mut self)

Restoring the original VTable.

Auto Trait Implementations§

§

impl<T> !Freeze for VTableHook<T>

§

impl<T> !RefUnwindSafe for VTableHook<T>

§

impl<T> Send for VTableHook<T>
where T: Send,

§

impl<T> !Sync for VTableHook<T>

§

impl<T> Unpin for VTableHook<T>
where T: Unpin,

§

impl<T> UnwindSafe for VTableHook<T>
where T: UnwindSafe,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.