evilcry

Inside DeleteFiber() as Anti Debug Trick

Rating: 3 votes, 1.67 average.
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'

Submit "Inside DeleteFiber() as Anti Debug Trick" to Digg Submit "Inside DeleteFiber() as Anti Debug Trick" to del.icio.us Submit "Inside DeleteFiber() as Anti Debug Trick" to StumbleUpon Submit "Inside DeleteFiber() as Anti Debug Trick" to Google

Comments