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:
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