stevemk14ebr / PolyHook_2_0

C++20, x86/x64 Hooking Libary v2.0
MIT License
1.58k stars 222 forks source link

Non DS segment relative memory operands crash reading destination #158

Closed eyali123 closed 1 year ago

eyali123 commented 1 year ago

Hello I ran into what seems to be a bug or an unhandled case.

I am trying to hook a function in ntdll, it was working fine on Windows 10 machine. However on older machine the ntdll code looks different:

ntdll_code

The problem occurs while disassembling the call instruction in the hook function in x86Detour. It seems both Zydis and Capstone parse it properly however in Instruction.hpp in getDestination func, it tries to deref invalid address, line 73: dest = *(uint32_t*)dest;

dest is 0xC0 (parsed from the call instruction, however FS register is used to access TIB (thread information block) and 0xC0 is the offset to get to the sys call).

This is the ntdll which causes the issue (uploaded it inside a zip because dll extension is not allowed...):

ntdll_from_VM.zip

This is the code I use for hooking (also inside a zip, couldn't add it here in proper formatiing):

sample_code.zip

Would appreciate any insights or workarounds :)

stevemk14ebr commented 1 year ago

Thanks! The issue was that in Intruction.hpp I had to read the actual indirect displacement to resolve the final destination. While doing this I had assumed the displacement for these mem types would always be the data segment, as I couldn't imagine others. Clearly that was a bad assumption! I've added a guard so that only DS relative displacements are read as indirect: https://github.com/stevemk14ebr/PolyHook_2_0/commit/cdaf786373cb588832c9356264561e0ad07850e0#diff-c2490438ad37329c45ed14bfc6b0af645ab171e2a48815ea5a389a0cdd249512R87

You're on an older version btw if you still need to pass the disassembler as an argument to the hook.