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

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

A simple approach to generate Fibonacci series via multi-threading

T his is a very simple approach taken to generate the Fibonacci series through multithreading. Here instead of a function, used a function object. The code is very simple and self-explanatory.  #include <iostream> #include <mutex> #include <thread> class Fib { public:     Fib() : _num0(1), _num1(1) {}     unsigned long operator()(); private:     unsigned long _num0, _num1;     std::mutex mu; }; unsigned long Fib::operator()() {     mu.lock(); // critical section, exclusive access to the below code by locking the mutex     unsigned long  temp = _num0;     _num0 = _num1;     _num1 = temp + _num0;     mu.unlock();     return temp; } int main() {     Fib f;          int i = 0;     unsigned long res = 0, res2= 0, res3 = 0;     std::cout << "Fibonacci series: ";     while (i <= 15) {         std::thread t1([&] { res = f(); }); // Capturing result to respective variable via lambda         std::thread t2([&] { res2 = f(); });         std::thread t3(

Close a Window Application from another application.

 This is just a demo application code to show how the WM_CLOSE message can be sent to the target process which has a titled window to close the application. To achieve this, either we can use SendMessage or PostMessage APIs to send required Windows messages to the target application. Though both the APIs are dispatching WM_XXXXX message to target application two APIs has some differences, these are as below: 1. SendMessage () call is a blocking call but PostMessage is a non-blocking call(Asynchronous) 2. SendMessage() APIs return type is LRESULT (LONG_PTR) but PostMessage() APIs return type is BOOL(typedef int). In Short, SendMessage () APIs return type depends on what message has been sent to the Windowed target process. For the other one, it's always a non-zero value, which indicates the message has been successfully placed on the target process message queue. Now let's see how can I close a target windowed application "Solitaire & Casual Games" from my custom-