regomne / ilhook-rs

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

Why isn't the jmp rax method used for long jumps when hooking under a 64-bit architecture? #8

Closed whynothackme closed 1 year ago

whynothackme commented 1 year ago

As mentioned, when there are no available addresses nearby the target, errors will occur.

regomne commented 1 year ago
  1. The mov rax, xxx; jmp rax instruction demands 11 bytes of the original hook position, whereas the jmp xxx requires only 5 bytes. This makes it more plausible for the former to impact the original code placement.
  2. More crucially, if the distance between the stub's and the original code's position exceeds 0x7fffffff, some moved instructions (i.e. mov rax, [relative off]) may not be correctly relocated.
regomne commented 1 year ago

In addition, encountering "no available addresses nearby" is usually unlikely, as the operating system generally allocates memory while leaving sufficient gaps between memory addresses. If you find yourself facing this issue, there might be a bug in my code for search available addresses. I would recommend providing a reproducible environment so that I can analyze the problem for you.

whynothackme commented 1 year ago

@regomne By changing JMP_INST_SIZE to 14 and using the JMP [address] format, you can safely make calls in situations where the range exceeds 2GB. The header rarely has a mov rax, [relative off], but if there is, I think we could specifically handle the conversion instruction to read into the register. This is certainly better than a direct failure.

To support situations with addresses above 2GB, current changes need only go as far as the following points:

If FixedMemory::allocate fails, it randomly assigns an address from 0. In modify_jmp, if the length exceeds the limit, change it to a long jump. Currently, the operation is stable, the program can sometimes find addresses within 2GB, and sometimes it can't but still operates correctly.

whynothackme commented 1 year ago

In addition, encountering "no available addresses nearby" is usually unlikely, as the operating system generally allocates memory while leaving sufficient gaps between memory addresses. If you find yourself facing this issue, there might be a bug in my code for search available addresses. I would recommend providing a reproducible environment so that I can analyze the problem for you.

You could update WeChat to the latest version (64-bit), find any function or address, and attempt to hook it. Although there are gaps after searching for an address, sometimes they cannot be allocated.

regomne commented 1 year ago

To support situations with addresses above 2GB, current changes need only go as far as the following points:

Yeah, it may be a good idea, and I'll consider to make an optimization.

You could update WeChat to the latest version (64-bit), find any function or address, and attempt to hook it. Although there are gaps after searching for an address, sometimes they cannot be allocated.

I'll have a try and analyze it.

edsky commented 1 year ago

I also encountered this problem under linux. One process has an error occasionally, and the other process has an error all the time. Can I submit a PR request to fix this problem?

regomne commented 1 year ago

Of course, please submit it. And I'm planning to support for long jmp hooking recently.

edsky commented 1 year ago

By the way, when I directly randomized the address, the whole application was reduced from 2M to 600kb, and the compile options were minimized.Maybe searching the range of available addresses this function takes up a lot of space.

regomne commented 1 year ago

@whynothackme I committed version 2.1 and it supports long-jmp hooking. Hope to test it.