Ricardonacif / gh-anti-debugging-bypass

A simple DLL to bypass the anti debugging methods from GH Anti Debugging with explanation

Home Page:https://github.com/guided-hacking/anti-debugging

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Guided Hacking Anti-Debugging Bypass DLL (explained)

This DLL bypasses all anti-debugging methods from my project Guided Hacking Anti-Debugging. I did both projects for learning purpose and bellow I'll explain a bit about each debugger detection method and how this DLL proceeds to bypass it. I tried to come up with a different way of bypassing each, if you are interested in anti-debugging techniques, you should follow along.

Each button above activates a detection method. We'll bypass each one of those. You can inject the DLL generated by this project using any DLL injector (or come up with your own). To generate the DLL just download and compile this project as x86. No further instructions needed.

Methods and Bypasses

- IsDebuggerPresent()

IsDebuggerPresent() is a method imported from Kernel32.dll. It checks for the BeingDebugged flag in the PEB (Process Environment Block) and will return a non-zero value if it is indeed being debugged. To bypass it, just set that specific flag to 0 (it's located on offsex 0x2 on a x86 PEB):

void setPEBDebuggerBypass() {
    auto peb = (char*) __readfsdword(0x30);
    *(peb+0x2) = 0x0;
}

- NtGlobalFlag

This method is similar to the above, but with some caveats. The PEB also contains a field called NtGlobalFlag (at offsex 0x68). This field can assume different values, but we are interested in the 5th, 6th and 7th bits (from right to left). Those are set when the process is being debugged, so here's the bypass code that simply changes unsets the 5th bit.

void bypassNtGlobalFlag() {
    auto peb = (char*) __readfsdword(0x30);
    *(peb + 0x68) = (*(peb + 0x68) &= ~(1UL << 5));
}

- PEB->BeingDebugged

The IsDebuggerPresent() from Kernel32.dll is a wrapper to this PEB field check, so our bypass specified above applies here as well.

- Check Parent Process

This method uses CreateToolhelp32Snapshot to loop thru the system processes and get the Parent Process name. Then it compares the parent process name with a list that contains the names of common debuggers (like x64dbg, ollydbg, cheat engine...). To bypass this, the DLL finds the array and replace the names with "UWONTFINDME". So unless your debugger is called UWONTFINDME, it won't find it (see file bypasses/bypassCreateToolhelp32Snapshot.h).

- CheckRemoteDebuggerPresent()

Ok, this one brought me a massive opportunity to learn about WoW64 (a subsystem of Windows capable of running 32bit applications on 64bit Windows). CheckRemoteDebuggerPresent() is a function from kernel32.dll that calls ZwQueryInformationProcess under the hood passing 7 as ProcessInformationClass which is a check for the ProcessDebugPort. A non 0 value means there is a debugger present.

Since the GH Anti Debugging application is 32bit, and we're running it on a 64bit system, it has to go thru what we call Heaven's Gate, which is a transiction from the 32bit ntdll.dll to a 64bit ntdll.dll that will call the Winapi/kernel functions. There's this amazing writeup from Hoang Bui that explains all about it. In a nutshell, all calls to Winapi/kernel functions will pass thru this transiction, so you can hook all syscalls by just hooking there. The bypass then consists in identifying the Winapi ZwQueryInformationProcess call, and returning eax as 0. If you can read thru the article I mentioned and take a look at bypasses/bypassCheckRemoteDebuggerPresent you will understand exactly how it is done. Neat stuff!

- UnhandledExceptionFilter

This is a really simple debugger detection method that uses SetUnhandledExceptionFilter, a function used to define an exception handler function. The debugger detection method works like this: it sets a beingDebugged bool variable as true, calls SetUnhandledExceptionFilter passing a function that sets that same variable to false and raises an exception (in this case using int3 instruction). On a non debugged application the function you passed to SetUnhandledExceptionFilter would be called and the beingDebugged variable would be set back to false (meaning no debugger found). If there's a debugger attached to the process tho, when the exception is raised the debugger would respond instead of the function passed to SetUnhandledExceptionFilter, so that variable would never be set to false again.

To bypass it, I got lazy and just nopped out the int3 call, and made the function that was returning 1 to return 0;

- Heaven's Gate PEB

This method works by checking the 64bit PEB->IsBeingDebugged attribute. It switches to long mode to have access to the 64bit PEB, and simply check the third byte on it (PEB64->IsBeingDebugged). To bypass it, we simply set that byte to 0. I did this in ASM just for learning purposes (and to be honest I'm still studying the long mode transition).

Disclaimer

Nothing here is new and all those methods and bypasses have been used and discussed all over the internet since the 2000s. A great reference for more anti debugging methods is this pdf from 2011 by Peter Ferrie. If you are also interested in Reverse Engineering and Game Hacking, you should check Guided Hacking.

About

A simple DLL to bypass the anti debugging methods from GH Anti Debugging with explanation

https://github.com/guided-hacking/anti-debugging


Languages

Language:C 53.8%Language:C++ 43.8%Language:Assembly 2.4%