Friday, 20 October 2017

Anti Reverse Engineering Mechanism and its Bypass - Part-2 - CheckRemoteDebuggerPresent()

This Part 2 of the Anti Reverse Engineering Mechanism Series. Here we will discuss about CheckRemoteDebuggerPresent API and how we can bypass the check.

Let us have a look at the implementation
So checkRemoteDebuggerAPI return a Non Zero Value if successful else it returns a Zero if no debugger detected.

if(IsDbgPresent) => True => Non Zero Value => Debugger Found!
if(IsDbgPresent) => False=> Zero => No Debugger Found!

So to bypass this we need to do the following

1. Give a breakpoint at CheckRemoteDebuggerPresent

2. Now we will step inside the code of CheckRemoteDebuggerApi

3. Now we will change instruction at 23. We will convert the CMP instruction to MOV instruction. I will explain it later why I will change it. Please note while we are doing this change the EAX value is 0 because in line 22 we are doing a XOR EAX, EAX, So here is the modification.
OLD =  7C85AB26 3945 08 CMP DWORD PTR SS:[EBP+8],EAX
NEW = 7C85AB26 3945 08 MOV DWORD PTR SS:[EBP+8],EAX

4. Now we will step through the functions till it exits the function and come to the actual code.

Now if you see , line 3 there is comparison again. So this DWORD PTR SS:[EBP-C] refers to the same stack segment where we did the change in instruction from CMP DWORD PTR SS:[EBP+8], EAX to MOV DWORD PTR SS:[EBP+8], EAX.  So this instruction actually pushed the value 0 to the stack segment which used to hold some non-zero value. So after coming out of the CheckRemoteDebuggerAPI this value i.e ( Zero ) is present in the SS:[EBP-C]. So the comparison of CMP DWORD PTR SS:[EBP-C],0 will lead the message box having message that "no debugger found". This condition is the IF condition of the C++ code which decides the flow based on the value returned to IsDbgPresent

Reference :