regomne / ilhook-rs

A library that provides methods to inline hook binary codes in x86 and x86_64 architecture
MIT License
69 stars 10 forks source link

Add support for 64-bit hook long jumps. #9

Closed edsky closed 1 year ago

edsky commented 1 year ago

8

In order to support 64-bit long jumps, I used 14 bytes for the jump. I made judgments at the destination, specifically modifying 5 bytes and 14 bytes. On the way back, I did not optimize, simply treated it as a 14-byte jump back. There might be better ways to optimize this. However, it's important to note that a 5-byte jump has significant limitations and the program can become uncontrollable (exceeding range). I believe it's safer to primarily use 14 bytes. If there isn't enough space, we should find a nearby empty location to perform multiple jumps.

I have tested this on a 64-bit Linux process and it works as expected. It should also work as expected on 64-bit Windows, but it's important to note that the function header being executed may need to be aligned. If this is indeed a problem, the following code can be used to fix it:

use std::alloc::{alloc, dealloc, Layout};
use std::ptr;

let layout = Layout::from_size_align(4096, 8).unwrap();
let raw_ptr = unsafe { alloc(layout) };
let mut raw_buffer = unsafe { std::slice::from_raw_parts_mut(raw_ptr, 4096) };
let stub_addr = raw_buffer.as_ptr() as u64;
let mut buf = Cursor::new(&mut raw_buffer[..]);
edsky commented 1 year ago

https://github.com/regomne/ilhook-rs/blob/efb33ec9fb0dd5683cb57efc47b09f1c48c47763/src/x64.rs#L331C24-L331C24

I did not make any changes here. If it is necessary to be the same as the original 5 bytes, you can determine the jump address and then change the bytes copied here to 5 bytes. This way, it will be the same as before.

regomne commented 1 year ago

Thanks for your working. But the most important thing in long-jump hooking is the code relocation for some new REX instructions, which I didn't see in the PR. If you are not good at that, maybe you could wait for some time, and I will support it recently.

regomne commented 1 year ago

I committed version 2.1 which supports instructions moving across >2GB, and this PR is being closed. Tell me advices if have.