2010-10-22

One Hell of an Anti-Debug! HideFromDebugger

A target appears to have no protection whatsoever, allowing debug attach, stepping, breakpoint, etc. When a critical area is reached, however, the debugger seems to not work at all - the breakpoint instruction and single-step exceptions (C0000003, C0000004) get passed right over the debugger and to the target, where it displays an error message.

Since my breakpoints were at User32's WaitMessageWhatever return, this would happen if my mouse went over the window, giving the cool effect that the frozen target was still alive, detecting my efforts in real time. So what to do now?

  1. checked windbg on another machine, then olly - all tests exhibit same behavior
  2. compared PEB and TIB before and after the protection looking for some magical flag setting crap that the target may be doing.... no big differences
  3. the target loads drivers, so fearing some rootkit behavior, compared nt!KiTrap03 before and after the protection, no changes
  4. continuing this way, compared nt!CommonDispatchException and then nt!KiDispatchException, still no differences
  5. using the leaked Windows 2000 source (from torrent), omeg's fine comments on KiDispatchException (http://omeg.pl/code/XP_32_KiDispatchException.txt) and ReactOS (http://doxygen.reactos.org/blah/blah) it was easy to create an annotated IDA listing of my particular ontkrnlpa.exe
  6. traced the difference to a call to nt!DbgkForwardException which would return 0 during the protection - tracing is a little complicated by the way: KiDispatchException is part of the logic path that eventually communicates with KD itself - it splits into two paths several times depending on whether the exception came from user or kernel mode - obviously you can only use KD (insert BP, single-step) on the user mode paths otherwise the CPU will loop, interrupting on the same BP continuously
  7. tracing into this, found this crap:
    nt!DbgkForwardException+0x2b:
    80639e31 64a124010000    mov     eax,dword ptr fs:[00000124h] 
    80639e37 f6804802000004  test    byte ptr [eax+248h],4
    80639e3e 7404            je      nt!DbgkForwardException+0x3e (80639e44) ; success
    80639e40 33c0            xor     eax,eax ; zero return value, indicating failure
    
    this value was 4 during the protection, so the je/jz was skipped and the failure path taken - patching this in memory allowed breakpoints and stepping to happen!
  8. so wtf is this check? ReactOS again is indispensible, with its code for DbgkForwardException - didn't take much to match this up:
    00338     /* Check if this is to be sent on the debug port */
    00339     if (DebugPort)
    00340     {
    00341         /* Use the debug port, unless the thread is being hidden */
    00342         Port = PsGetCurrentThread()->HideFromDebugger ?
    00343                NULL : Process->DebugPort;
    00344     }
    
  9. finally, googled for this HideFromDebugger and found ivanlef0u's page (http://www.ivanlef0u.tuxfamily.org/?p=48) where he explains this protection completely over 3 years ago! man am I behind!
Anyways, two days lost to a protection that amounts to a single NtSetInformationThread() call from the target. Am I upset? No, I'm lucky these more skilled reversers published their findings otherwise this would have taken so much longer.

Oct 22, 2010 EDIT: upb sent me this rootkit.com link dating back to 2005 so this may not be news to anybody

1 comment:

  1. very interesting post! talk about it later. greetings!

    ReplyDelete

thanks for commenting!