-
-
Notifications
You must be signed in to change notification settings - Fork 223
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Incorrect x64 detour trampoline #118
Comments
Interesting, can you share either the binary or a hex dump of the function you are hooking? I will fix this, this is a big in the jump table logic. It seems to assume branching instructions in the prologue are jump - like, which obviously fails here. |
Sure, here you go: uplay_r1_loader64.zip. The troublesome function is |
I think this is the bug here: https://github.com/stevemk14ebr/PolyHook_2_0/blob/master/sources/x64Detour.cpp#L424 I made a patch a while ago to correctly handle indirect calls of the style FF 25, which just need their displacement updated instead of the jump table actually holding a jump instruction. Seems I failed to handle the non-indirect call type correctly, so the call just points to an address instead of a jump table entry as it should. Need to think about how to fix this generally and if I missed any other issues but this is an easy fix. FWIW, I never ever change the type of instructions, such as the e8 to ff 25 like you did. This works in simple cases like here but it gets really messy with more complex situtations since instruction sizes change. To avoid this, the concept of a jump table was introduced, where instructions are just re-written to point to little jump stubs that redirect the control flow. Since I control the jump table regions size, I don't have to care about instruction sizes in the prologue. The fix will look like this when it's done: trampoline
|
Please try this patch out: ce93f6f. EDIT: use master, actively fixing bugs here.
This jump table logic has been modified by other contributors, and it's gotten confusing. I may have introduced a bug by fixing this one. If you notice weird stuff please report - I may have to re-write this jump table logic entirely so I understand it again. |
Thanks a lot, I will be testing the fixes in various environments during the next day or two. |
The latest commit indeed fixes the issue at hand, and doesn't seem to break other detour hooks in both x86 and x64 environments. It actually solves another weird issue I had with a certain DLL, which took about 30 seconds to detour for each function. It now hooks instantaneously, like the rest. I can submit a PR to vcpkg if you are comfortable with the latest commit. |
sure, go for it if your tests have passed. Even if there's a new bug, it's better than the old situation. |
Hello. When trying to hook a function in an x64 DLL, an incorrect trampoline seems to be generated. More specifically, a
call
instruction in function prologue gets messed up.Log
The function to be hooked begins with a jump:
![orig_1](https://user-images.githubusercontent.com/67734819/155850501-f64f7a3e-b83d-4224-b998-3c22f60b6ec6.jpg)
After hook is applied, this part remains intact as expected:
![detour_1](https://user-images.githubusercontent.com/67734819/155850516-972176e6-14a0-4a1f-b662-236e93d6a75c.jpg)
Notice that the jump destination has a
![orig_2](https://user-images.githubusercontent.com/67734819/155850559-1b700845-cf77-4a7a-b087-1e2ce6e34505.jpg)
![detour_2](https://user-images.githubusercontent.com/67734819/155850581-a9ebfa90-8c67-4afb-9d8f-26bf3a75ec26.jpg)
call
instruction in the 2nd position:After hook is applied, the prologue gets replaced with a jump to the hooked function as expected:
Now, the trouble begins in the trampoline code. The operand to the
![err_trampoline](https://user-images.githubusercontent.com/67734819/155850659-aa0b0d45-841b-4c53-969c-b2dafd973a82.jpg)
![fix_trampoline](https://user-images.githubusercontent.com/67734819/155850703-4ba3cc4e-9c66-4022-ba10-a3028b877bbf.jpg)
call
instruction does not point to a valid instruction address. Rather, it points to a memory location which stores the correct instruction address (it is included in the bottom part of the image). The generated trampoline however does not dereference it. This also results in call instruction being 1 byte shorter. Needless to say, it results in a crash:Luckily, I could manually fix the
call
instruction by dereferencing its operand as follows:With this fix, the program execution resumes without issues.
Since I was able to fix this error manually, I think it should be fixable on PolyHook side as well. But I'm not sure I can implement a polyhook fix myself, as my experience is limited in this area.
The text was updated successfully, but these errors were encountered: