Skip to main content

IsDebuggerPresent API Vs Process Environment Block

 Sometimes we've seen some application or process that can't be debugged using any debugger. As soon as we attach a debugger, either the application will terminate or pop up a message like a debugger attached with the process, so terminating the application.


What so ever, in windows world, there is an API, which detects if the process is being debugged or not. 

It's IsDebuggerPresent() Win32 API. You can refer to the MSDN link to get more details on it.

So, I've written a test sample below:

#include <Windows.h>

int _tmain(int argc, _TCHAR* argv[])
{
    if (IsDebuggerPresent() == TRUE)
    {
        MessageBox(NULL, 
        TEXT("Please close your debugging 
            application and restart the program"), 
        TEXT("Debugger Found!"), 0);
       ExitProcess(0);
    }
    MessageBox(NULL, TEXT("Hello World!"), TEXT("Bypassed"), 0);
    ExitProcess(0);
    return 0;
}

As usual, I did compile the code using VS 2013 on Windows 8 and then launched it with WinDbg and executed the command 'g'. As we can predict, it executed the if construct and displayed the following message, and eventually it executed ExitProcess(), and this process terminated.


Now, the question is how we can bypass this check and execute the Hello World part. To do so, we need to understand the process environment block. We can refer MSDN link.

The structure of PEB is like below:

typedef struct _PEB {
  BYTE                          Reserved1[2];
  BYTE                          BeingDebugged;
  BYTE                          Reserved2[1];
  PVOID                         Reserved3[2];
  PPEB_LDR_DATA                 Ldr;
  PRTL_USER_PROCESS_PARAMETERS  ProcessParameters;
  BYTE                          Reserved4[104];
  PVOID                         Reserved5[52];
  PPS_POST_PROCESS_INIT_ROUTINE PostProcessInitRoutine;
  BYTE                          Reserved6[128];
  PVOID                         Reserved7[1];
  ULONG                         SessionId;
} PEB, *PPEB;

The highlighted one is of our interest. If this is set to true (1), then IsDebuggerPresent() Win32 API will also return true. So the trick is we need to set this bit to false(0) while debugging through WinDbg.

So, let's examine first this structure through our sample application using WinDbg. So, after launching the application, execute the following command:

0:000> !peb
PEB at 7f41f000
    InheritedAddressSpace:    No
    ReadImageFileExecOptions: No
    BeingDebugged:            Yes
    ImageBaseAddress:         00a50000
    Ldr                       77b791e0
    Ldr.Initialized:          Yes
    Ldr.InInitializationOrderModuleList: 012c3760 . 012c3c40
    Ldr.InLoadOrderModuleList:           012c3850 . 012c5b38

    Ldr.InMemoryOrderModuleList:         012c3858 . 012c5b40

Now, from the above result, we can see the BeingDebugged of PEB structure is set to true(1). If we set it to false (0) and then execute, we'll see, the Hello world window will appear. 

So, I've executed the following command through WinDbg:

eb $peb+2 0 ---> Edit byte PEB+2 to 0.

Now let's see again, the PEB!BeingDebugged value:

0:000> !peb
PEB at 7f41f000
    InheritedAddressSpace:    No
    ReadImageFileExecOptions: No
    BeingDebugged:            No
    ImageBaseAddress:         00a50000
    Ldr                       77b791e0
    Ldr.Initialized:          Yes
    Ldr.InInitializationOrderModuleList: 012c3760 . 012c3c40
    Ldr.InLoadOrderModuleList:           012c3850 . 012c5b38
    Ldr.InMemoryOrderModuleList:         012c3858 . 012c5b40

So, finally, we set this value to false(0). Now I executed the program with the command 'g' and the Hello World pop-up message got displayed. Indeed we've successfully bypassed IsDebuggerPresent() win32 API while debugging the application.

Happy Debugging!

Comments

Popular posts from this blog

XOR (Exclusive OR) for branchless coding

The following example shows the array reversing using the  XOR operator . No need to take any additional variable to reverse the array.   int main(int argc, _TCHAR* argv[]) { char str[] = "I AM STUDENT"; int length = strlen(str); for(int i = 0; i < ((length/2)); i++) { str[i] ^= str[length - (1+i)]; str[length - (1+i)] ^= str[i]; str[i] ^= str[length - (1+i)]; } cout << str << endl; return 0; } The above example is one of the uses of XOR but XOR comes in handy when we can do branchless coding  methods like butterfly switch etc. Sometimes this is very effective in speeding up the execution.  Let's see one of the uses of XOR in branchless coding. I am taking a simple example of Y = | X |.  Yes, I am generating abs of a supplied number. So, my function signature/definition in C++ looks like below: int absoluteBranch( int x) {     if (x < 0 ) {         return ...

Reversing char array without splitting the array to tokens

 I was reading about strdup, a C++ function and suddenly an idea came to my mind if this can be leveraged to aid in reversing a character array without splitting the array into words and reconstructing it again by placing spaces and removing trailing spaces. Again, I wanted an array to be passed as a function argument and an array size to be passed implicitly with the array to the function. Assumed, a well-formed char array has been passed into the function. No malformed array checking is done inside the function. So, the function signature and definition are like below: Below is the call from the client code to reverse the array without splitting tokens and reconstructing it. Finally, copy the reversed array to the destination.  For GNU C++, we should use strdup instead _strdup . On run, we get the following output: Demo code

Power of Two

  I n this post will be discussing how to calculate if a number is a power of two or not. As an example, 8 is a power of two but the number 10 is not. There are many ways we can solve this. First , we will take an approach which is simple and iterative. In this case, we will calculate the power of two one by one and check with the supplied number. The below code illustrates it. bool isPowerofTwo(unsigned num) { auto y = 1; while (0 != y) { if (num == y) return true; if (num < y) return false; y <<= 1; } return false; } Second , assuming, the number is a 32-bit number, this is also an iterative solution. In this scenario, iterating all bits and counting the set bits. Any number which is a power of 2 will have only one bit set and the rest will be zeros. As an example, 8 in binary representation is 1000. Using this observation, we can implement an iterative solution. bool isPowerofTwo(unsigned num) { auto one_count = 0; for (auto index = 0; index < ...