C/C++/C#/Asm Coding

  1. Debugging the Debugger - Reversing kldbgdrv.sys and Potential Usages

    After various articles on malware analysis I decided to talk about a little different topic, due to the fact that I'm involved into Kernel Mode Coding the Windows Internals Research become a truly important aspect of my Research. As the title suggests, this time I'm going to Study and Reverse a particular component used by the Windows Debugging System, more precisely a Device Driver involved into Local Kernel Debugging.

    Not many people is aware that is possible to perform Local Kernel Debugging, one of the most used Debugging Configurations is the Remote Debugging. Local Kernel Debugging can offer many important vantages, like valuable informations on the Status of the Kernel and Inspect Kmode Components. LKD (Local Kernel Debugging) can be acheived by booting in Debug Mode, both kd and windbg fully supports LKD.

    The essential question now is, How the Debugging Engine, let's consider for example Windbg, is able to obtain informations about the kernel by running from usermode?

    The reply to this question not only will uncover the problem itself but also will open new interesting questions and possibilities, such as:

    #1 - "It's possible to develop an application that can use the same
    technology ?"

    #2 - "How to access the involved components and what are parameter to
    have access?"

    To begin the study of this problem, we have in first instance to reproduce the environement necessary to start a Local Debugging Session.

    I've used for these tests Windows 7 32-Bits Ultimate Edition and Windbg.

    First step is to enable debug mode by running:

    bcdedit -debug on then reboot.

    At this point we have literally to debug our debugger to be able to reveal the mechanism and component involved in communication between the Debug Engine and Kernel.

    In the past Windows Editions, the function used was NtSystemDebugControl, but from Windows Vista to Higher Versions this function is not immediately available.

    To trace windbg activities I've used a great tool for professional API Tracing, called Blade API Monitor.

    The hypothesis was, if windbg runs at usermode and accesses a kernel component it's obvious that will be used a Device Driver, by assuming true this statement, every application that deals directly with Device Drivers will use:

    * CreateFile -> For Driver Opening
    * ReadFile / WriteFile -> Device Driver Communication
    * DeviceIoControl -> Data exchange between Driver and umode application
    * NtSystemDebugControl


    After setting the proper filter for these functions, let's run a Local Kernel Debugging Session and watch the results from API Monitor.

    When debugger is loaded, we can launch some command, like:

    !drvobj
    !irpfind
    !isr

    From API Log emerges an important result, we have two threads:

    #- First Thread

    DeviceIoControl(...)
    DeviceIoControl(...)
    CreateFileW(wchar_t* lpFileName = C:\Windows\Fonts\staticcache.dat,...)

    #- Second Thread

    CreateFileW( wchar_t* lpFileName = C:\Windows\system32\kldbgdrv.sys )
    return value -> void* return = 0x00000128

    WriteFile(void* hFile = 0x00000128, .., unsigned long nNumberOfBytesToWrite = 0x000031F0 )

    CreateFileW(wchar_t* lpFileName = \\.\kldbgdrv)
    return value -> void* return = 0x00000170

    DeviceIoControl(void* hDevice = 0x00000170)
    IOCTL -> unsigned long dwIoControlCode = 0x0022C007
    As you can see, from the second thread we obtain a valuable amount of informations.

    WinDbg creates a driver called kldbgdrv.sys placed in %\system32\ this file is 0x31F0 long.

    Successively this driver is openened and windbg starts to send IOCTL to this driver.

    The IO Control Code used is 0x0022C007.

    When debugging session finishes, kldbgdrv.sys it's deleted.

    To reverse this driver we have obviously to dump it, so the first operation is to locate where is placed and successively carve out this.

    The most probable location where can be located are the resources of windbg or kd executables, so let's explore their PE.

    Between resources of windbg.exe we can see that the last one called "17476" which contains another subdir called "30583" by opening also this last directory finally appears our wldbgdrv.sys (can be easly detected by watching between strings)

    From the starting address of this resource if we add the len of bytes ( nNumberOfBytesToWrite = 0x000031F0) we can easly into a new file kldbgdrv.sys

    Now let's reverse this driver.

    INIT:00010D1F push offset aKdsystemdebugc ; "KdSystemDebugControl"
    INIT:00010D24 lea eax, [ebp+DestinationString]
    INIT:00010D27 push eax ; DestinationString
    INIT:00010D28 call ds:RtlInitUnicodeString
    INIT:00010D2E lea ecx, [ebp+DestinationString]
    INIT:00010D31 push ecx ; SystemRoutineName
    INIT:00010D32 call ds:MmGetSystemRoutineAddress
    INIT:00010D38 mov [ebp+var_1C], eax
    INIT:00010D3B cmp [ebp+var_1C], 0
    INIT:00010D3F jnz short loc_10D4B
    INIT:00010D41 mov eax, STATUS_PROCEDURE_NOT_FOUND
    INIT:00010D46 jmp loc_10DF5

    this is a really interesting piece of code, here the driver attempts to obtain the Routine Address of the function KdSystemDebugControl()

    INIT:00010D4B mov edx, [ebp+DriverObject]
    INIT:00010D4E mov dword ptr [edx+34h], offset sub_10A10 ;DriverUnload
    INIT:00010D55 mov eax, [ebp+DriverObject]
    INIT:00010D58 mov dword ptr [eax+38h], offset sub_10A50 ;DriverObject->MajorFunction[0] = (PDRIVER_DISPATCH)sub_10A50
    INIT:00010D5F mov ecx, [ebp+DriverObject]
    INIT:00010D62 mov dword ptr [ecx+40h], offset sub_10A50 ;DriverObject->MajorFunction[0] = (PDRIVER_DISPATCH)sub_10A50
    INIT:00010D69 mov edx, [ebp+DriverObject]
    INIT:00010D6C mov dword ptr [edx+70h], offset sub_10A80 ;DriverObject->MajorFunction[14] = (PDRIVER_DISPATCH)sub_10A80
    INIT:00010D73 push offset aDeviceKldbgdrv ; "\\Device\\kldbgdrv"
    INIT:00010D78 lea eax, [ebp+DeviceName]
    INIT:00010D7B push eax ; DestinationString
    INIT:00010D7C call ds:RtlInitUnicodeString
    ..
    INIT:00010D96 call ds:IoCreateDevice

    Here the device it's created \\Device\\kldbgdrv and

    There are also four MajorFunctions associations:

    DriverObject->DriverUnload = (PDRIVER_UNLOAD)sub_10A10;
    DriverObject->MajorFunction[0] = (PDRIVER_DISPATCH)sub_10A50; // IofCompleteRequest(Irp, 0)
    DriverObject->MajorFunction[2] = (PDRIVER_DISPATCH)sub_10A50; // IofCompleteRequest(Irp, 0)
    DriverObject->MajorFunction[14] = (PDRIVER_DISPATCH)sub_10A80; // Suddenly Reversed
    Let's check the latest Dispatch Routine:

    PAGE:00010AEE push edx
    PAGE:00010AEF push eax ; PrivilegeValue
    PAGE:00010AF0 call ds:SeSinglePrivilegeCheck
    PAGE:00010AF6 movzx ecx, al
    PAGE:00010AF9 test ecx, ecx
    PAGE:00010AFB jnz short loc_10B09
    PAGE:00010AFD mov [ebp+var_3C], STATUS_ACCESS_DENIED
    PAGE:00010B04 jmp loc_10C5B
    PAGE:00010B09 mov [ebp+var_4], 0
    PAGE:00010B10 mov edx, [ebp+var_30]
    PAGE:00010B13 mov [ebp+var_48], edx
    PAGE:00010B16 cmp [ebp+var_48], 22C007h ; IOCTL = 22C007h
    PAGE:00010B1D jz short loc_10B24
    PAGE:00010B1F jmp loc_10C2B


    When the IOCTL = 22C007h it's sent the first operation is to check if the action has the proper privileges "SeSinglePrivilegeCheck", successively this dispatch routine validates and sanitizes parameters sent with the IOCTL, by using MmUserProbeAddress and ProbeForWrite.

    Finally we can say that kldbgdrv.sys works as wrapper for KdSystemDebugControl.

    This function belongs to NtSystemDebugControl but can be accessed only at kernel mode.

    Here it's prototipe:

    NTSTATUS
    NTAPI
    KdSystemDebugControl(
    SYSDBG_COMMAND Command,
    PVOID InputBuffer,
    ULONG InputBufferLength,
    PVOID OutputBuffer,
    ULONG OutputBufferLength,
    PULONG ReturnLength,
    KPROCESSOR_MODE PreviousMode
    );
    _SYSDBG_COMMAND it's an enum, let's suppose we want SysDbgReadVirtual we have the corresponding struct:

    typedef struct _SYSDBG_VIRTUAL
    {
    PVOID Address;
    PVOID Buffer;
    ULONG Request;
    } SYSDBG_VIRTUAL, *PSYSDBG_VIRTUAL;
    At this point we have all elements to use with success kldbgdrv.sys, that means the possibility to have access to the kernel ...
  2. EventPair Reversing, EventPairHandle as Anti-Dbg Trick

    Hello,

    Here my little paper on EventPairs, and EventPairHandle as Anti-Dbg Trick

    http://evilcry.netsons.org/tuts/EventPairsHandle.pdf

    Have a nice read,
    Giuseppe 'Evilcry' Bonfa'
  3. NtSetDebugFilterState as Anti-Dbg Trick

    The following paper will uncover some intersting Undocumented functions relative to Windows Debugging Support. NT is capable of generating and collecting text Debug Messages with an high grade of customization. User-mode and kernel-mode drivers use different routines to send output to the debugger.

    User Mode: Uses OutputDebugString, that sends a null-terminated string to the debugger of the calling process. In a user-mode driver, OutputDebugString displays the string in the Debugger Command window. If a debugger is not running, this routine has no effect. OutputDebugString does not support the variable arguments of a printf formatted string.

    Kernel Mode: Uses DbgPrint, that displays output in the debugger window. This routine supports the basic printf format parameters. Only kernel-mode drivers can call DbgPrint. There is also DbgPrintEx that is similar to DbgPrint, but it allows you to "tag" your messages. When running the debugger, you can permit only those messages with certain tags to be sent. This allows you to view only those messages that you are interested in.

    This operation is called Filtering Debug Messages, how it works is a little bit undocumented, to understand how to go inside this aspect, let's start from DbgPrint / DbgPrintEx.

    In Windows XP, DbgPrint has been extended by adding _vDbgPrintExWithPrefix, in this way DbgPrint and DbgPrintEx became wrappers of this function.

    Code:
    ULONG
      vDbgPrintExWithPrefix	(
    	IN PCCH	Prefix,
    	IN ULONG    ComponentId,
    	IN ULONG    Level,
    	IN PCCH     Format,
    	IN va_list  arglist
    	);
    vDbgPrintExWithPrefix routine sends a string to the kernel debugger if certain conditions are met. This routine can append a prefix to debugger output to help organize debugging results.

    Let's see what ComponentId means:

    The component that is calling this routine. This parameter must be one of the component name filter IDs that are defined in Dpfilter.h. Each component is referred to in different ways, depending on the context. In the ComponentId parameter of DbgPrintEx, the component name is prefixed with DPFLTR_ and suffixed with _ID. In the registry, the component filter mask has the same name as the component itself. In the debugger, the component filter mask is prefixed with Kd_ and suffixed with _Mask.

    Now let's see Level parameter:

    The severity of the message that is being sent. This parameter can be any 32-bit integer. Values between 0 and 31 (inclusive)) are treated differently than values between 32 and 0xFFFFFFFF.
    Filter masks that are created by the debugger take effect immediately and persist until Windows is restarted.

    The debugger can override a value that is set in the registry, but the component filter mask returns to the value that is specified in the registry if the computer is restarted. There is also a system-wide mask called WIN2000. By default, this mask is equal to 0x1, but you can change it through the registry or the debugger like all other components. When filtering is performed, each component filter mask is first combined with the WIN2000 mask by using a bitwise OR. In particular, this combination means that components whose masks have never been specified default to 0x1.

    By inspecting deeply vDbgPrintExWithPrefix we can see that it represent a wrap around NtQueryDebugFilterState that retrieves the state of the selected Debug Filter Mask. By inspecting xRefs we discover that NtQueryDebugFilterState is also used by DbgQueryDebugFilterState()

    Code:
    NTSTATUS __stdcall DbgQueryDebugFilterState(ULONG ComponentId, ULONG Level)
    0045000C 	ComponentId     = dword ptr  8
    0045000C 	Level           = dword ptr  0Ch
    0045000C
    0045000C     mov     edi, edi
    0045000E     push    ebp
    0045000F     mov     ebp, esp
    00450011     pop     ebp
    00450012     jmp     NtQueryDebugFilterState
    00450012 _DbgQueryDebugFilterState end proc
    As is obvious, DbgQueryDebugFilterState asks for the actual state of Debug Filters. Near the Query function we can see DbgSetFilterState()

    Code:
    NTSTATUS __stdcall DbgSetDebugFilterState(ULONG ComponentId, ULONG Level, BOOLEAN State)
    0045001C     mov     edi, edi
    0045001E     push    ebp
    0045001F     mov     ebp, esp
    00450021     pop     ebp
    00450022     jmp     NtSetDebugFilterState
    00450022     DbgSetDebugFilterState endp
    DbgSetDebugFilterState is a wrapper of a native NtSetDebugFilterState(ULONG ComponentId, ULONG Level, BOOLEAN State)
    As you can understand this is an intersting API cause attempts to modify the Debug Filter Mask:

    Code:
    0056384C NtSetDebugFilterState(ULONG ComponentId, unsigned int Level, char State)
    0056384C	  mov     edi, edi
    0056384E      push    ebp
    0056384F      mov     ebp, esp
    00563851      mov     eax, large fs:124h       ;KTHREAD
    00563857      movsx   eax, byte ptr [eax+140h] ;KTHREAD->PreviousMode
    0056385E      push    eax             
    0056385F      push    ds:_SeDebugPrivilege.HighPart
    00563865      push    ds:_SeDebugPrivilege.LowPart ;PrivilegeValue
    0056386B      call    SeSinglePrivilegeCheck
    00563870      test    al, al
    00563872      jz      short loc_5638BE ;If PrivilegeValue does not match, exit 							and return 0xC00000022 error
    SeSinglePrivilegeCheck checks for the passed privilege value in the context of the current thread, If PreviousMode is KernelMode, the privilege check always succeeds. Otherwise, this routine uses the token of the user-mode thread to determine whether the current (user-mode) thread has been granted the given privilege.
    Here the rest of the function

    Code:
    v3 = &Kd_WIN2000_Mask;
     if ( ComponentId >= KdComponentTableSize )
        {
          if ( ComponentId != 0xFFFFFFFF )
            return 0xC00000EF;
        }
    else
        {
          v3 = (int *)*(&KdComponentTable + ComponentId);
        }
        if ( Level <= 0x1F )
          v4 = 1 << (char)Level;
        else
          v4 = Level;
        v6 = v4;
        if ( !State )
          v6 = 0;
        *v3 = v6 | *v3 & ~v4;
        result = STATUS_SUCCESS;
    Now we can implement a little Anti-Debug trick based on Debug State Awareness, indeed with NtSetDebugFilterState we are able to determine if the process is debugged or not:

    Code:
    #define WIN32_LEAN_AND_MEAN
    #include <Windows.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include "ntDefs.h"
    
    #pragma comment(lib,"ntdll.lib")
    
    int main(void)
    {
    	NTSTATUS ntStatus;
    	
    	ntStatus = NtSetDebugFilterState(0,0,TRUE);
    
    	if (ntStatus != STATUS_SUCCESS)
    		MessageBoxA(NULL,"Not Debugged","Warning",MB_OK);		
    
    	else
    		MessageBoxA(NULL,"Debugged","Warning",MB_OK);
    
    	return (EXIT_SUCCESS);
    -> ntDefs.h

    Code:
    typedef LONG NTSTATUS;
    #define STATUS_SUCCESS ((NTSTATUS)0x00000000L)
    
    extern "C"
    __declspec(dllimport) 
    ULONG __stdcall 
    NtSetDebugFilterState(
    					 ULONG ComponentId,
    					 ULONG Level,
    					 BOOLEAN State					 
    					 );
    Trick is really basilar if the Process is Debugged NtSetDebugFilterState returns STATUS_SUCCESS else returns 0xC00000022 Error Code. May be that this trick is already used, but for sure I haven's seen nothing about NtQueryDebugFilterState/NtSetDebugFilterState =)



    Refs:
    http://msdn.microsoft.com/en-us/library/ms792789.aspx
    http://msdn.microsoft.com/en-us/library/ms804344.aspx


    Thanks to #bug channel especially ratsoul 'n swirl

    Regards,
    Giuseppe 'Evilcry' Bonfa'
  4. Debugger Detection Via NtSystemDebugControl

    Hi,
    NtSystemDebugControl() is a really powerful undocumented function, that allows you Direct Manipulation of System's Structures.

    Here a definition of NtSystemDebugControl:

    http://undocumented.ntinternals.net/UserMode/Undocumented%20Functions/Debug/NtSystemDebugControl.html

    The use of this function is only limited to the fancy of the coder

    I've rewritten some basical Anti Debugging Techniques with Direct Structure Reading with NtSystemDebugControl. Obviously there are shorter ways to implement these Anti-Dbg Apps, but I think that more reimplementations exists and more are possibilities to trick an attacker, that may not know/understands the application..especially if embedded in many..many.. Junk Code

    Here you can download the Source Code sample:

    http://evilcry.netsons.org/other/ntsd.zip

    Have a nice Day,
    Evilcry
  5. Inside DeleteFiber() as Anti Debug Trick

    Hi,

    Malware is often really boring to reverse because in high percentage they implements basical well known mechanisms of infection and self protection.
    But sometimes there are really intersting malware that implements innovative techniques, this is the case of a trojan borned into 2006 that implemented DeleteFiber() as AntiĖDebug Trick in a really easy and smart way.

    To understand how it works, let's see whar DeleteFiber is, directly from MSDN:

    Deletes an existing fiber.

    Syntax

    Code:
    VOID WINAPI DeleteFiber(
      __in  LPVOID lpFiber
    );
    lpFiber is the address of the fiber to be deleted.

    Important to say that the DeleteFiber function deletes all data associated with the fiber. This data includes the stack, a subset of the registers, and the fiber data.

    Now let's see a basical use of DeleteFiber():

    Code:
    #define _WIN32_WINNT 0x0400
    #include <windows.h>
    
    int main(void)
    {
    	char fiber[1024] = {0};		
    	DeleteFiber(fiber);	
    	return EXIT_SUCCESS;
    }
    After showing the basical use of DeleteFiber let's see how can be implemented as Anti-Debug Trick, I insert here direcly the code:

    Code:
    #define _WIN32_WINNT 0x0400
    #include <windows.h>
    #include <stdio.h>
    
    int main(void)
    {
          char fib[1024] = {0};	
    	DeleteFiber(fib);
    
    	if(GetLastError() == 0x00000057)
    		MessageBoxA(NULL,"This process is NOT debugged","Info",MB_OK);
    	else
    		MessageBoxA(NULL,"This process IS debugged","Info",MB_OK);
    	
    	
    	return EXIT_SUCCESS;
    }
    As you can understant we can resume this trick into two cases:

    If the process is NOT debugged DeleteFiber give us an Error Code of 0x00000057 that corresponds to ERROR_INVALID_PARAMETER
    If the process IS debugged the error code is differs from 0x00000057

    What to say it's really easy to implement and really effective for all kind of debuggers, with a bit of junk code that confuses ideas the conditional check could be placed really distant from the DeleteFiber() itself.

    Inside DeleteFiber()


    Now we will see how DeleteFiber internally works to understand why this should be used as Anti-Debug trick.

    This is the Dead List:

    Code:
    00401000  PUSH DF.00403370
    00401005  CALL DWORD PTR DS:[<&KERNEL32.DeleteFiber>;  kernel32.DeleteFiber
    
    inside DeleteFiber()
    
    7C825A9F >   MOV EDI,EDI          ; DF.00403778
    7C825AA1     PUSH EBP
    7C825AA2     MOV EBP,ESP
    7C825AA4     PUSH ECX
    7C825AA5     PUSH ESI
    7C825AA6     MOV EAX,DWORD PTR FS:[18]     ;_TEB Struct
    7C825AAC     MOV ECX,DWORD PTR DS:[EAX+10] ;pointer to _TIB.FiberData field
    7C825AAF     MOV ESI,DWORD PTR SS:[EBP+8]  ;lpFiber
    7C825AB2     CMP ECX,ESI
    7C825AB4     JE kernel32.7C826596          ;ExitThread if( FiberData == lpfiber)
    7C825ABA     AND DWORD PTR SS:[EBP-4],0    ;Clears this Stack location
    7C825ABE     PUSH 8000                     ;MEM_RELEASE
    7C825AC3     LEA EAX,DWORD PTR SS:[EBP-4]  
    7C825AC6     PUSH EAX
    7C825AC7     LEA EAX,DWORD PTR DS:[ESI+10]
    7C825ACA     PUSH EAX
    7C825ACB     PUSH -1
    7C825ACD     CALL DWORD PTR DS:[<&ntdll.NtFreeVirtual>  ntdll.ZwFreeVirtualMemory
    7C825AD3     MOV EAX,DWORD PTR FS:[18]        ;_TEB Struct
    7C825AD9     MOV EAX,DWORD PTR DS:[EAX+30]    ;points to _PEB Struct
    7C825ADC     PUSH ESI                         ;lpFiber
    7C825ADD     PUSH 0                           ;0x00000000
    7C825ADF     PUSH DWORD PTR DS:[EAX+18]       ;PEB.ProcessHeap
    7C825AE2     CALL DWORD PTR DS:[<&ntdll.RtlFreeHeap>] ; ntdll.RtlFreeHeap
    7C825AE8     POP ESI
    7C825AE9     LEAVE
    7C825AEA     RETN 4

    In the first part of DeleteFiber is retrived the _TEB structure and specifically a member of _TIB structure located at 10h

    0:003> dt nt!_TEB -b
    ntdll!_TEB
    +0x000 NtTib : _NT_TIB
    +0x000 ExceptionList : Ptr32
    ...
    +0x00c SubSystemTib : Ptr32
    +0x010 FiberData : Ptr32

    and next if FiberData is equal to our Fiber's Address it means that Fiber is suicinding itself and system calls ExitThread(), next we can notice a NtFreeVirtualMemory call with the following parameters:

    Code:
    NtFreeVirtualMemory(NtCurrentProcess(), &pStackAllocBase,&nSize,MEM_RELEASE);
    The system deallocates the used stack and finally calls RtlFreeHeap in this manner:

    Code:
    RtlFreeHeap(GetProcessHeap(), 0, lpFiber);
    This last call clarifies totally the presence of ERROR_INVALID_PARAMETER because has we have seen DeleteFiber is directly correlated with Heap, and Heap Memory presents a set of Flags that characterize the Heap itself.
    These Flags differs in case the process IS debugged or NOT, so we can suppose that these flags are created when the exe itself is executed, in other words at Process Creation Time. Under Windows NT processes are created through PspUserThreadStartup and inside it we can found LdrInitializeThunk, that as Russinovich sais The LdrInitializeThunk routine initializes the loader, heap manager, NLS tables, thread-local storage (TLS) array, and critical section structures. By going more deep we can see that there is a specific function that fill the PEB Struct of the new process MmCreatePeb(), PEB is important because between his various fields are stored Heap Flags of our process. I'm talking about NtGlobalFlag, for a debugged process these flags are:

    #define FLG_HEAP_ENABLE_TAIL_CHECK 0x00000010
    #define FLG_HEAP_ENABLE_FREE_CHECK 0x00000020
    #define FLG_HEAP_VALIDATE_PARAMETERS 0x00000040


    Now if a process has these flags enabled ( HeapDebug ) RtlFreeHeap will fail the Heap freeing and this error will be propagated to DeleteFiber() that will exit with an ERROR_INVALID_PARAMETER.

    Anti Anti-Debug


    Due to the fact that the Heap Validation is accomplished at Processs Creation Time, one countermeasure against Anti-Debug will be to attach the debugger after that the process is created.
    If you are using WinDbg could be used the HeapDebug option ( -hd )
    Between the function involved in process creation we have also LdrQueryImageFileExecutionOptions that mantains trace of IFEO ( Image File Execution Options structure) this struct is located into Registry under the path [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\]
    The various possible values are:
    Debugger
    DisableHeapLookaside
    ShutdownFlags
    MinimumStackCommitInBytes
    ExecuteOptions
    GlobalFlag
    DebugProcessHeapOnly
    ApplicationGoo
    RpcThreadPoolThrottle
    GlobalFlag can be used to modify NtGlobalFlag, so if you set this key entry to NULL, Heap of the debugged program will looks as an undebugged one, read this as an Anti-Anti Debug Trick .

    [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\Target.exe]
    "GlobalFlag"=""



    Regards,
    Giuseppe 'Evilcry' Bonfa'
  6. Inside SetUnhandledExceptionFilter

    Hi,

    SetUnhandledExceptionFilter()
    is frequently used as Anti Debug Trick, especially in Malware Applications. Around here there are various plugins for Olly that allows the Reverser to trasparently debug this kind of protection, so there is not a real necessity add other words about the mere practical part of trick overcoming.

    Due to the fact that today, too many young reversers uses a ton of plugins anti - anti - xxx without knowing how internally they works, I decided to expose here a little summary of SetUnhandledExceptionFilter Internal characteristics.

    First of all, what SetUnhandledExceptionFilter is? according to MSDN documentation:

    Enables an application to supersede the top-level exception handler of each thread of a process.

    After calling this function, if an exception occurs in a process that is not being debugged, and the exception makes it to the unhandled exception filter, that filter will call the exception filter function specified by the lpTopLevelExceptionFilter parameter.


    And this is the Syntax:

    Code:
    LPTOP_LEVEL_EXCEPTION_FILTER WINAPI SetUnhandledExceptionFilter(
    __in  LPTOP_LEVEL_EXCEPTION_FILTER lpTopLevelExceptionFilter
    );
    lpTopLevelExceptionFilter is a pointer to top-level exception filter function that will be called whenever the UnhandledExceptionFilter function gets control, and the process is not being debugged. A value of NULL for this parameter specifies default handling within UnhandledExceptionFilter.

    Usually, in absence of an UnhandledExceptionFilter the topmost handler called when an uncatched exception occours, is the default one provided by Windows Itself, the classical MessageBox that advices the user that an Unhandled Exception has occured.

    But Windows allow programs to use custom Handlers for UnhandledException. The core of the trick is here, if the application is NOT debugged, the application is able to call the Custom Handler, but if the application IS debugged the Custom Handler will be never called.

    The possibility of cognitive differentiation make obviously able the target application to apply a series of countemeasures against debugging, from detection to code hidding.

    Just remember that due to the architecture of Windows Exception Handling, in every case is called UnhlandledExceptionFilter() function, and this will our point of attack (for anti - anti dbg trick).

    This is the general inner meccanism of SetUnhandledExceptionFilter(), going more deep we observe the call stack of the first thread of any Win32 application, we can see that execution in every case is reported to BaseProcess, here the pseudo definition:

    Code:
    VOID BaseProcessStart( PPROCESS_START_ROUTINE pfnStartAddr )
    {
        __try
        {
            ExitThread( (pfnStartAddr)() );
        }
        __except( UnhandledExceptionFilter( GetExceptionInformation()) )
        {
            ExitProcess( GetExceptionCode() );
        }
    }
    The same thing happens for threads, by referencing to BaseThreadStart:

    Code:
    VOID BaseThreadStart( PTHREAD_START_ROUTINE pfnStartAddr, PVOID pParam )
    {
        __try
        {
            ExitThread( (pfnStartAddr)(pParam) );
        }
        __except( UnhandledExceptionFilter(GetExceptionInformation()) )
        {
            ExitProcess( GetExceptionCode() );
        }
    }
    All that happens inside BaseProcessStart() and BaseThreadStart() for what previously said, will be passed to the UnhandledExceptionFilter().

    Itís now time to see what really is UnhandledExceptionFilter(), according to MSDN:

    An application-defined function that passes unhandled exceptions to the debugger, if the process is being debugged. Otherwise, it optionally displays an Application Error message box and causes the exception handler to be executed. This function can be called only from within the filter expression of an exception handler.

    Syntax:


    Code:
    LONG WINAPI UnhandledExceptionFilter(
      __in  struct _EXCEPTION_POINTERS *ExceptionInfo
    );
    Became clear that UnhandledExceptionFilter represents the last choise for processing unhandled exceptions, so the Check Debugger Presence surely is located inside this function, letís see a simplified version of this function:

    Code:
    LONG UnhandledExceptionFilter( EXCEPTION_POINTERS* pep )
    {
        DWORD rv;
    
        EXCEPTION_RECORD* per = pep->ExceptionRecord;
    
        if( ( per->ExceptionCode == EXCEPTION_ACCESS_VIOLATION ) &&
             ( per->ExceptionInformation[0] != 0 ) )
        {
            rv = BasepCheckForReadOnlyResource( per->ExceptionInformation[1] );
    
            if( rv == EXCEPTION_CONTINUE_EXECUTION )
                return EXCEPTION_CONTINUE_EXECUTION;
        }
    
        DWORD DebugPort = 0;
    
        rv = NtQueryInformationProcess( GetCurrentProcess(), ProcessDebugPort,
                                        &DebugPort, sizeof( DebugPort ), 0 );
    
        if( ( rv >= 0 ) && ( DebugPort != 0 ) )
        {
            // Yes, it is -> Pass exception to the debugger
            return EXCEPTION_CONTINUE_SEARCH;
        }
    
        // Is custom filter for unhandled exceptions registered ?
    
        if( BasepCurrentTopLevelFilter != 0 )
        {
            // Yes, it is -> Call the custom filter
    
            rv = (BasepCurrentTopLevelFilter)(pep);
    
            if( rv == EXCEPTION_EXECUTE_HANDLER )
                return EXCEPTION_EXECUTE_HANDLER;
    
            if( rv == EXCEPTION_CONTINUE_EXECUTION )
                return EXCEPTION_CONTINUE_EXECUTION;
        }   
    
    }
    As you can see, inside UnhandledExceptionFilter() is called NtQueryInformationProcess() that has as first parameter our process and next DebugPort, this is done to know if the process is debugged.

    All that we have to do to obtain an apparently undebugged process is to modify the first parameter (last pushed at debugging time), in other words we have to change the retur value of GetCurrentProcess() from 0xFFFFFFFF to 0◊00000000.

    So remember, when you have to overcome a SetUnhandledExceptionFilter() just put a Breakpoint for UnhandledExceptionFilter() and go inside this function to modify the previously exposed parameter

    Thanks to Oleg Starodumov for pseudocodes

    See you to the next blog post..