Hpmason / retour-rs

A cross-platform detour library written in Rust
Other
99 stars 18 forks source link

Crash while hookin on win #47

Closed shevernitskiy closed 7 months ago

shevernitskiy commented 7 months ago

I'm trying to reimplement c++ hook in rust. Main process loads plugin-manager.dll which loads some other dll (plugins). So here we talk about a plugin (last one in this calling chain).

C++ version based on Microsoft Detours library. There is a DllMain where on dll_process_attach hook attached.

I'm trying to reimplement it in rust. I trigger attach function with static_init::constructor (works well), And app crashed even if i just call original function in my hook. What i miss?

PS: if I load my plugin from main app process directly - it works

pub static MODULE: usize = unsafe { winapi::um::libloaderapi::GetModuleHandleW(std::ptr::null()) as usize };
pub fn address(offset: usize) -> usize {
  *MODULE + offset
}

pub unsafe fn attach_string_copy_n() -> Result<()> {
  let target = std::mem::transmute(address(CONFIG.offset.as_ref().unwrap().string_copy_n.unwrap()));
  handle_string_copy_n.initialize(target, string_copy_n)?;
  handle_string_copy_n.enable()?;
  Ok(())
}

static_detour! { static handle_string_copy_n : unsafe fn( *mut c_char, *const u8, usize) -> *mut c_char ; }

fn string_copy_n(dst: *mut c_char, src: *const u8, size: usize) -> *mut c_char {
  unsafe { handle_string_copy_n.call(dst, src, size) }
}
Hpmason commented 7 months ago

It looks like your usage of retour is fine.

Some things that may be an issue:

If the crash is happening on the rust side, you could try panic::set_hook to catch the panic and print some sort of output either through a logger or to a file if you don't have control over the output of the program.

shevernitskiy commented 7 months ago

Thanks for the answer!

I have pretty the same suspicious and already check it.

  1. Base address in c++ and rust libs are the same (it is main process base), even if it called from another dll in chain.
  2. Yeah, IDA shows that the original function has cdecl call convention. I checked it - the same result. Also I checked C and fastcall. But if i load directly from main app - it works well without any explicit convention. I assume that the calls of the hooked function is the same.

I was able to catch the stacktrace and it is points to offset of hook function inside my lib. And it points at the signature (the very begin), not the code inside.

I assume, that retour-rs and Microsoft Detour may have some differences in small details of implementation.

Hpmason commented 7 months ago

Were you able to solve your issue?

shevernitskiy commented 7 months ago

Unfortunately no. I decided leave it for now and comaback later to make a proper investigation.