Thread Hide From Debugger

This nasty anti-debugging trick thwarted me for years, I honestly though my debugger was broken and actively switched between them (OllyDbg, WinDbg, x64dbg, SoftIce). It’s used everywhere because it’s simple and very effective.

Has this ever happened to you? You attach to a process with a debugger and place a breakpoint and it immediately crashes when it gets hit? God, I hate this trick. You find it everywhere because it’s simple and effective at thwarting reverse engineering.

Here’s what it looks like. I have a C++ program called NoBreakpointsAllowed.exe and when I place a breakpoint on a call the Sleep it gets hit and dies.


Ubiquity

I won’t go into the super technical details because they’re well explained elsewhere, but the code is effectively

#include <windows.h>

int main() {
    ...
    // Hide from debugger 0x11
    NtSetInformationThread(GetCurrentThread(), 0x11, 0, 0);
    ...
}

It’s really that simple. The real annoyance is once this has been set, you can’t unset it and only in the kernel can you tell it’s been set. Essentially you have a couple options to neutralizing this trick:

So I went and did option 3.


KWorld

https://github.com/colinsenner/KWorld

KWorld goes through all threads in the process and removes the ThreadHideFromDebugger flag from each thread. This allows the process to be debugged without crashing.

Since offsets in the kernel _ETHREAD and _EPROCESS structures can differ between Windows versions, I lookup the offsets once at runtime. We need to find the offset of the ThreadHideFromDebugger flag in the _ETHREAD structure. I do this by finding the function PsIsThreadTerminating in ntoskrnl.exe. The first instruction of this function is

PsIsThreadTerminating

Where 560h is the offset of the CrossThreadFlags in the _ETHREAD structure. Bit 3 of CrossThreadFlags is the HideFromDebugger flag.

CrossThreadFlags

Once we have this information we can enumerate all process threads and clear the flag. This should be relatively robust to offset changes in the kernel structures.

Demo