darfink / detour-rs

A cross-platform detour library written in Rust
Other
389 stars 71 forks source link

error[E0277]: expected a `Fn<(u32, u32, *mut winapi::ctypes::c_void, u32)>` closure, found `unsafe extern "system" fn(u32, u32, *mut winapi::ctypes::c_void, u32) -> u32 {our_GetSystemFirmwareTable}` #33

Closed brandonros closed 1 year ago

brandonros commented 2 years ago
use std::ffi::c_void;
use detour::static_detour;
use winapi::shared::minwindef::{HINSTANCE, DWORD, BOOL, TRUE, LPVOID, UINT};
use winapi::um::libloaderapi::{GetModuleHandleA, GetProcAddress};

static_detour! {
  static GetSystemFirmwareTableHook: unsafe extern "system" fn(DWORD, DWORD, LPVOID, DWORD) -> UINT;
}

type GetSystemFirmwareTableFn = unsafe extern "system" fn(DWORD, DWORD, LPVOID, DWORD) -> UINT;

unsafe extern "system" fn our_GetSystemFirmwareTable(FirmwareTableProviderSignature: DWORD, FirmwareTableID: DWORD, pFirmwareTableBuffer: LPVOID, BufferSize: DWORD) -> UINT {
  unsafe { GetSystemFirmwareTableHook.disable().unwrap() };
  let ret_val = unsafe { GetSystemFirmwareTableHook.call(FirmwareTableProviderSignature, FirmwareTableID, pFirmwareTableBuffer, BufferSize) };
  unsafe { GetSystemFirmwareTableHook.enable().unwrap() };
  return ret_val;
}

fn main() {
  // hook GetSystemFirmwareTable
  let kernel32Module = GetModuleHandleA("kernel32.dll\0".as_ptr() as _);
  let GetSystemFirmwareTableAddress = GetProcAddress(kernel32Module, "GetSystemFirmwareTable\0".as_ptr() as _);
  let ori_GetSystemFirmwareTable: GetSystemFirmwareTableFn = unsafe { std::mem::transmute(GetSystemFirmwareTableAddress) };
  unsafe { GetSystemFirmwareTableHook.initialize(ori_GetSystemFirmwareTable, our_GetSystemFirmwareTable).unwrap() };
  unsafe { GetSystemFirmwareTableHook.enable().unwrap() };
}

C:\Users\Brandon\Desktop\redacted\rust>cargo +nightly-i686-pc-windows-msvc build
   Compiling redacted v0.0.1 (C:\Users\Brandon\Desktop\redacted\rust)
warning: unused import: `std::ffi::c_void`
 --> main.rs:1:5
  |
1 | use std::ffi::c_void;
  |     ^^^^^^^^^^^^^^^^
  |
  = note: `#[warn(unused_imports)]` on by default

warning: unused imports: `BOOL`, `HINSTANCE`, `TRUE`
 --> main.rs:3:33
  |
3 | use winapi::shared::minwindef::{HINSTANCE, DWORD, BOOL, TRUE, LPVOID, UINT};
  |                                 ^^^^^^^^^         ^^^^  ^^^^

error[E0277]: expected a `Fn<(u32, u32, *mut winapi::ctypes::c_void, u32)>` closure, found `unsafe extern "system" fn(u32, u32, *mut winapi::ctypes::c_void, u32) -> u32 {our_GetSystemFirmwareTable}`
   --> main.rs:24:78
    |
24  |   unsafe { GetSystemFirmwareTableHook.initialize(ori_GetSystemFirmwareTable, our_GetSystemFirmwareTable).unwrap() };
    |                                       ----------                             ^^^^^^^^^^^^^^^^^^^^^^^^^^ call the function in a closure: `|| unsafe { /* code */ }`
    |                                       |
    |                                       required by a bound introduced by this call
    |
    = help: the trait `Fn<(u32, u32, *mut winapi::ctypes::c_void, u32)>` is not implemented for `unsafe extern "system" fn(u32, u32, *mut winapi::ctypes::c_void, u32) -> u32 {our_GetSystemFirmwareTable}`
    = note: unsafe function cannot be called generically without an unsafe block
note: required by a bound in `StaticDetour::<T>::initialize`
   --> C:\Users\Brandon\.cargo\registry\src\github.com-1285ae84e5963aae\detour-0.8.1\src\detours\statik.rs:106:8
    |
106 |     D: Fn<T::Arguments, Output = T::Output> + Send + 'static,
    |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `StaticDetour::<T>::initialize`

For more information about this error, try `rustc --explain E0277`.
warning: `redacted` (bin "redacted") generated 2 warnings
error: could not compile `redacted` due to previous error; 2 warnings emitted
wackbyte commented 1 year ago

unsafe functions and those with ABIs other than "Rust" (the default one) do not implement Fn traits. Try wrapping it in a closure, e.g. |a, b, c, d| unsafe { our_GetSystemFirmwareTable(a, b, c, d) }

brandonros commented 1 year ago
error[E0277]: expected a `Fn<(*const IWbemClassObject, *const u16, i32, *mut VARIANT, *mut i32, *mut i32)>` closure, found `extern "thiscall" fn(*const IWbemClassObject, *const u16, i32, *mut VARIANT, *mut i32, *mut i32) -> i32 {our_CWbemObjectGet}`
   --> fnpss-wmi-hook\src\lib.rs:132:55
132 |     CWbemObjectGetHook.initialize(ori_CWbemObjectGet, our_CWbemObjectGet).unwrap();
    |                        ----------                     ^^^^^^^^^^^^^^^^^^ expected an `Fn<(*const IWbemClassObject, *const u16, i32, *mut VARIANT, *mut i32, *mut i32)>` closure, found `extern "thiscall" fn(*const IWbemClassObject, *const u16, i32, *mut VARIANT, *mut i32, *mut i32) -> i32 {our_CWbemObjectGet}`
    |                        |
    |                        required by a bound introduced by this call

I don't think I can do closure for thiscall, can I?

brandonros commented 1 year ago
0x180028BA0: "public: virtual long __cdecl CWbemObject::Get(unsigned short const * __ptr64,long,struct tagVARIANT * __ptr64,long * __ptr64,long * __ptr64) __ptr64" ?Get@CWbemObject@@UEAAJPEBGJPEAUtagVARIANT@@PEAJ2@Z