Saturday, 5 October 2013

How to undetour NtOpenProcess


This is going to be a pretty small blog, today we will be discussing on how to undetour functions - mostly NT (Kernel-Related Functions), undetouring is a pretty simple objective to follow. The steps to follow in order to undetour NT functions.

We will be using NtOpenProcess as a example - this is the most common function to be detoured by various Malware & security utilities running in usermode (Ring3).
We will not be using kernel-mode drivers or such fancy equipment - just a usual application (.exe) but with tricks and techniques.

Now, the start of NtOpenProcess is more or less easy to guess the first few bytes:

mov eax, 23
xor ecx,ecx
lea edx, DWORD PTR SS:[esp+4]

If the function has been detoured this is how the first few bytes would look:

lea edx, DWORD PTR SS:[esp+4]

This means the 1st and 2nd instructions are overwritten as the size of the jump is 5 bytes, so to unhook this function all we need to do is replace the jmp with the overwritten instructions. The technique is same as detouring but patching different opcodes.

I will first discuss the steps needed to implement a "Anti-Rootkit" software:

  • Grab the Address of target function, in our case it is NtOpenProcess 
  • Compare if the prologue contains jmps
  • If so unprotect the prologue of the target function
  • patch the original instructions\opcodes into original spaces
  • re-protect the prologue of the target function 
We will grab the Address of the target function via calling GetProcAddress to grab the address of sleep, then save the address onto a LPVOID then to compare it we will typecast the address into a byte and check. If so we will use VirtualProtect to unprotect the memory region\layer then patch the entire original instructions which have been overwritten. Then re-protect it wil VirtualProtect .

First we will grab the address of NtOpenProcess:

Now we will use compare and see if the prologue contains tell-tale signs of any detour being placed:

Now we will unprotect the prologue of the function:

Now use the hot-patching\detouring method in order to patch undetour code onto function:

All we are doing now is re-protect it back to it's original format:

Now we have successfully undetoured the function, the code above were all snippets so this is the whole code to successfully undetour NtOpenProcess without using kernel-mode drivers, all in all we did a simpler job. Complete Code:

 This code would unhook NtOpenProcess without much trouble or problem, however this could fail on other Windows (apart from 7 x64) as I have tested this code on only Windows 7 x64. 
Anyway in my conclusion, I want to say that this code itself is not very fool-proof, as if a Malware or Sandbox detoured GetProcAddress or equivalent on a lower level, and blocked or filtered you call it would be disastrous, mainly being they could give you a wrong address. 

If this is the case why not call KiFastSystemCall or X86SwitchTo64BitMode directly by moving addresses into eax, and moving parameters on to esp. This would be a better idea as not many malwares detour vital system call stubs, or on x64 you can try perform a code segment change and directly call Wow64ServicesEx to bypass this or detour this it takes a lot of work so not many malwares will be able to protect themselves from un-hooking. 

Anyway, it is getting too long so lets wrap things quickly - If you understand how we unhooked NtOpenProcess, you can unhook all functions using a little bit logic and debugging. 

Thanks! Please Comment and Share - Hope You enjoyed and learned.


  1. I keep getting errors, I am using Dev-C++

    Any help?

    1. Hi,

      This code works on VS as far as I know as I had many E-Mails pertaining its success and personally tested by me, as for Dev-C++ it may have something to do with Code-Generation and such, can you show me any Debugging reports or any sort of disassembly of this.

      It may point me in correct direction to solve your issue as currently your error is extremely Ambiguous.

      Next, Using VS is always a good-option due to its high-level debugging options nevertheless I never use Dev-C++ therefore cannot test it properly but your information may help me, make this code much better.

    2. When I mean better I mean make it more globalised code and be able to generate few circumstance of catastrophic failure.