**Prolouge:** Well basically, the title shouted out all what's my intention, this blog will likely my talking and discussing stuff about several window anti-debugger technique using WinAPI that I have so far collected and suffered from many CTF challenges --- ### IsDebuggerPresent This is kind of the most convenience one cause it is a built-in function The root mechanism of this is using PEB (Process Environment Block structures) which is created by Window, every process has its own PEB struct And in offset 0x02 it stores a BeingDebugged variable, a flag which is marked by window if there is a debugger attach its process script ```C typedef struct _PEB { BYTE Reserved1[2]; BYTE BeingDebugged; BYTE Reserved2; PVOID Reserved3[2]; ULONG NtGlobalFlag; } PEB, *PPEB; BOOL IsBeingDebugged() { PPEB peb = (PPEB) __readgsqword(0x60); return peb->BeingDebugged; } ``` ### Heap Flag Check So you have to understand the concept that debugging is a window feature, window itself consider debug is a normal behavior, if user wants to debug, the window will assume that we want to find and work on memory leak like buffer overflow, use-after-free and so on So the window decide to turn on some protecting measurement such as it activates some heap flag check `FLG_HEAP_ENABLE_TAIL_CHECK` `FLG_HEAP_ENABLE_FREE_CHECK` `FLG_HEAP_VALIDATE_PARAMETERS` In term of working with this you won't have to necessarily remember these kind of flag, you just need to know window will activate these and the value of NtGlobalFlag will equal to `0x70` Script ```C typedef struct _PEB { BYTE Reserved1[2]; BYTE BeingDebugged; BYTE Reserved2; PVOID Reserved3[2]; ULONG NtGlobalFlag; } PEB, *PPEB; BOOL IsDebugHeapEnabled() { PPEB peb = (PPEB) __readgsqword(0x60); return peb->NtGlobalFlag == 0x70; } ``` ### CheckRemoteDebuggerPresent The kernel manage our debugging process, so this is just simply as the kernel `am i debugged?` ```C PBOOL check = 0; CheckRemoteDebuggerPresent(GetCurrentProcess(), check); if (check) { // ur debugged } else { // free } ``` ### Driver Artifacts check Aside from checking via flags or enumerating process, this approach provides a very different solution, it detect analysis by accessing driver artifacts that are created when monitoring tools load their kernel driver. Script for checking Window Sysinternal Process Monitoring: ```C BOOL driverArtifactCheck() { LPCSTR lpName = "\\\\.\\Global\\ProcmonDebugLogger"; if (CreateFileA(lpName, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL) != INVALID_HANDLE_VALUE) { return 1; } return 0; } ``` ### Structured Exception Handler This method relies on the difference between how exception is deliveried under the debugger environment In term of normal execution, a runtime exception (such as divide-by-zero) will pass directly to the program and trigger the `__except` handler to execute the exception by some logic defined by the developer However, when a debugger is attached, the exception will first report to the debugger to decide the following moves. If the debugger decide to consume the exception instead of fowarding it, the program exception handlers will never be executed and some intended logic embedded in handler part could not be peformed Script ```C BOOL SEHChecker() { BOOL flag = TRUE; volatile int zero = 0; volatile int dummy = 1; __try { int x = dummy / zero; } __except (EXCEPTION_EXECUTE_HANDLER) { flag = FALSE; } if (flag) { return 1; } return 0; } ```