Wednesday, August 8, 2007

ThreadHideFromDebugger! But Why?

At BlackHat last week Mark Vincent Yason talked about the art of unpacking. One of the techniques used by some packers is to hide their threads from the debugger so it can't be easily debugged.

It is really easy to hide a thread from the debugger, you just have to call :

NtSetInformationThread(hThread, ThreadHideFromDebugger, NULL, 0);

At this point the debugger will stop receiving debug information or exceptions from this thread. But be careful! If you are debugging the process and you set a breakpoint and it happens to hit in the hidden thread, the process will crash and windbg won't even realize it.

After the presentation I was not able to stop asking myself why did Microsoft implemented this feature. It seems like the only usage is to make "malicious" code harder to debug. Maybe they implemented it to mute some noisy threads? Or maybe they wanted to protect some system threads? If you know the answer, please let me know!

The next thing to do was to check if Microsoft is in fact using this feature. I put a conditional breakpoint on NtSetInformationThread to hit when the ThreadInformationClass is equal to ThreadHideFromDebugger.
Unfortunately it never hit. (Tested on XPSP2 and Vista). There is also the possibility that they are changing the ETHREAD structure manually, but I doubt so. I'll try to check that later.

On the other hand, something interesting came up during this experiment. On Vista it seems like NtSetInformationThread is called really often with an invalid (or undocumented) ThreadInformationClass. I'll try to investigate that and write my results in another post. In the mean time, I dumped the number of occurrences of each ThreadInformationClass during the boot of windows. I haven't found any use for that yet, but anyway:

Windows XP SP2
   4 ThreadPriority
16 ThreadBasePriority
2 ThreadAffinityMask
2069 ThreadImpersonationToken
16 ThreadQuerySetWin32StartAddress
16 ThreadZeroTlsCell

Windows VISTA
  16 ThreadPriority
490 ThreadBasePriority
4 ThreadAffinityMask
6293 ThreadImpersonationToken
71 ThreadZeroTlsCell
1 ThreadPriorityBoost
460 Unknown - 0x16
481 Unknown - 0x18
10 Unknown - 0x19


Alex Ionescu said...

It's actually used by RtlQueryProcessDebugInformation when you're querying remote information... the routine creates a remote thread and hides it from the debugger, supposedly to stop the deadlock that would otherwise happen once the debugger receives the thread start routine.

Best regards,
Alex Ionescu

nsylvain said...

Thanks for the info!