darfink / detour-rs

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

Can not compile then call original function. #3

Closed chtotut closed 6 years ago

chtotut commented 6 years ago

Hi. I try use detour for ws2_32::send. But then i try to execute original function from detour closure:

pub(super) type Function = unsafe extern "system" fn(winapi::SOCKET, *const winapi::c_char, winapi::c_int, winapi::c_int) -> winapi::c_int;

static_detours! {
    struct Send: unsafe extern "system" fn(winapi::SOCKET, *const winapi::c_char, winapi::c_int, winapi::c_int) -> winapi::c_int;
}

Send.initialize(
                ws2_32::send,
                move |socket, buffer, length, flags| {
...
let original = Send.get().expect("Get original function fail.");
let result = original.call(
    socket as u64,
    buf.as_ptr() as *const i8,
    buf.len() as i32,
    flags as i32,
);
...

Code does not compiles. Error:

error[E0599]: no method named `call` found for type `&detour::GenericDetour<unsafe extern "system" fn(u64, *const i8, i32, i32) -> i32>` in the current scope

let result = original.call(
                      ^^^^

note: the method `call` exists but the following trait bounds were not satisfied:
            `&detour::GenericDetour<unsafe extern "system" fn(u64, *const i8, i32, i32) -> i32> : std::ops::Fn<_>`

Where there can be an error?

darfink commented 6 years ago

Not quite sure why, try dropping the unsafe modifier in the macro:

static_detours! {
    struct Send: unsafe extern "system" fn(winapi::SOCKET, *const winapi::c_char, winapi::c_int, winapi::c_int) -> winapi::c_int;
}

static_detours! {
    struct Send: extern "system" fn(winapi::SOCKET, *const winapi::c_char, winapi::c_int, winapi::c_int) -> winapi::c_int;
}
chtotut commented 6 years ago

ws2_32::send define as unsafe (https://retep998.github.io/doc/ws2_32/fn.send.html).

If delete unsafe modifier in the macro - It throw this error:

Send.initialize(
                      ws2_32::send,
    |                 ^^^^^^^^^^^^ expected normal fn, found unsafe fn
    |
    = note: expected type `extern "system" fn(u64, *const i8, i32, i32) -> i32`
               found type `unsafe extern "system" fn(u64, *const i8, i32, i32) -> i32 {ws2_32::send}`
darfink commented 6 years ago

Okay, this should be fixed in latest master. You can try it now and see if your issue is resolved:

[dependencies]
detour = { git = "https://github.com/darfink/detour-rs", branch = "master" }
chtotut commented 6 years ago

Yes, latest master fixed this. Thanks.