CPP to Rust convert

Hi, please help convert this code

void InstallCallHook(DWORD dwInstallAddress, DWORD dwHookFunction)
{
 	Unprotect(dwInstallAddress, 5);
 	*(BYTE *)dwInstallAddress = 0xE8;
	*(DWORD *)(dwInstallAddress + 1) = (dwHookFunction - (dwInstallAddress + 5));
}

Hi! Can you please put your code between code fences? Like this:

```cpp
#include <iostream>

int main() {
    std::cout << "Hello, world!";
}
``` // end block with three backticks on its own line.

About your question, I don't know how, but it seems like WinAPI code? There is a crate with bindings you can use. https://crates.io/crates/winapi

(Sorry for the bad formatting / short answer. I'm on mobile.)

I tried to translate this using C2Rust, and here's what happened, but it doesn't work.

pub unsafe extern fn InstallCallHook(mut dwInstallAddress: libc::c_ulong,
                                         mut dwHookFunction: libc::c_ulong) {
    *(dwInstallAddress as *mut libc::c_char) = 0xe8i32 as libc::c_char;
    *(dwInstallAddress.wrapping_add(1i32 as libc::c_ulong) as
          *mut libc::c_ulong) =
        dwHookFunction.wrapping_sub(dwInstallAddress.wrapping_add(5i32 as
                                                                      libc::c_ulong));
}

I tried manually... and... doesn't work either

pub unsafe extern fn install_hook(s1: *mut u32, s2: u32)
{
	unprotect(s1, 5);
	std::ptr::write_volatile(s1, 0xE8);
	std::ptr::write_volatile(s1.add(1), s2 - *s1 + 5);
}

I use it like that:

utils::install_hook(0x1337 as *mut u32, rust_function as u32);

What errors are you receiving? Is it some kind of function not found error or another error?

I get application crash when using function:

Exception At Address: 0x70D58489; EAX: 0x70D585D0; EBX: 0x70D73640; EDX: 0x469F00

I need to redirect a function from the application by its pointer to my function from rust. Detors also crashes.
It's definitely not the function's memory address, because in C ++ this code works
I understand how it works in C ++, but I still do not fully understand how it should work in rust. I translated many other functions related to memory, but I still could not find a solution to this problem on the Internet

Are you sure you have declared the rust function properly in C++? In rust extern implicitly means extern "C". I'm not very acquainted with the winapi, nor am I in a position to do research (I'm on mobile).

Even when using extern "C", the result does not change.

Which snippet gives that error? What errors do the others give?

pub unsafe extern fn install_hook(s1: *mut u32, s2: u32)
{
    unprotect(s1, 5);
    std::ptr::write_volatile(s1, 0xE8);
    std::ptr::write_volatile(s1.add(1), s2 - *s1 + 5);
}

This snippet adds the wrong offset. (<*mut u32>::add(1) adds 4 bytes)

1 Like

ok, I need to set the value 0xE9 in the zero offset of the address, from offset 1 set the value, for example 0x1337 in the amount of 4 characters "/ x1 / x3 / x3 / x7"

1 Like

i'd use *mut u8, do arithmethic with integer instead of pointers, and write the opcode and address per byte,

pub unsafe extern fn install_hook(s1: *mut u8, s2: u32)
{
    unprotect(s1, 5);
    let addr = s2 - (s1 as u32) + 5;
    std::ptr::write_volatile(s1, 0xE8);
    std::ptr::write_volatile(s1.add(1), (addr & 0xff) as u8);
    std::ptr::write_volatile(s1.add(2), ((addr >> 8) & 0xff) as u8);
    std::ptr::write_volatile(s1.add(3), ((addr >> 16) & 0xff) as u8);
    std::ptr::write_volatile(s1.add(4), ((addr >> 24) & 0xff) as u8);
}

(there's std::ptr::write_unaligned but there's a whole slew of potential UB regarding unaligned pointers so i'm not sure it's worth it)

(my assumption here was little endian because 0xE8 is x86 call opcode)

One byte is two hexadecimal digits. I believe you mean to write \x00\x00\x13\x37. And even then, that's big endian⁠—which, frankly, is uncommon! On little endian machines you probably want to write \x37\x13\x00\x00. The last one is what the C2Rust output would write on little endian machines (it's still not clear what issue you had with that code specifically).

There is one remaining issue of alignment. Either the input pointer must not be aligned to 4-byte boundaries (it needs to be aligned to a dword boundary minus 1), or the original C code invoked UB (in which case you can fix it by changing the last line of the C2Rust output to use ptr.write_unaligned instead of *ptr =).