darfink / detour-rs

A cross-platform detour library written in Rust
Other
406 stars 75 forks source link

unwrap fails on value: RegionFailure(FreeMemory). #26

Closed kickturn closed 3 years ago

kickturn commented 3 years ago
thread '<unnamed>' panicked at 'called `Result::unwrap()` on an `Err` value: RegionFailure(FreeMemory)', src\lib.rs:59:89

I'm making a dll exploit with rust and detour-rs, I'm using it to manipulate lua vms and so far this library is great. I got it working on other version of the executable but this one i'm trying to do right now isn't working

Line 59 (causing the error) is this

// static mut variable
static mut GETTOP_HOOK: Option<GenericDetour<fn(i32) -> i32>> = None;
...
// LUA_GETTOP is an address
    let orig_lua_gettop =
            std::mem::transmute::<*const usize, fn(i32) -> i32>(LUA_GETTOP as *const usize);
...
// fails on here, hooked_function is a function.
  GETTOP_HOOK =
            Some(GenericDetour::<fn(i32) -> i32>::new(orig_lua_gettop, hooked_function).unwrap());

The unwrap fails for something giving me the RegionFailure error, I don't know why. This same code works with a different exe with different addresses. Also, i checked and LUA_GETTOP is the right addresses.

Compiled for i686-pc-windows-msvc and release, is there something that could be relating to this problem?

darfink commented 3 years ago

Hmm... Interesting. This should be caused by an address referencing a memory page that is not allocated (i.e. the address/pointer is invalid). Are you able to provide a stack trace, and/or view the address in question using a debugger?

kickturn commented 3 years ago

I checked about the pointer not being vaild and it seems like I found the problem. The new executable had ALSR enabled

So i had to make my addr from

let lua_pcall: u32 = 0x0080BE80

to

// in C++ it would be like
// (ADDR - 0x00400000) + (DWORD)GetModuleHandle(NULL)

let base_addr = unsafe { winapi::um::libloaderapi::GetModuleHandleA(0 as *const i8) } as u32;

let lua_pcall: u32 = (0x0080BE80 - 0x00400000) + base_addr;

After doing this, it works! So I'm closing this. Thanks for the clue on that.