Log in

View Full Version : Inside DeleteFiber() as Anti Debug Trick


evilcry
July 31st, 2008, 08:11
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'

Maximus
July 31st, 2008, 09:11
VERY nice antidebug trick!

And interesting analysis, too -thanks.

JMI
July 31st, 2008, 13:23
And, as always, thanks for sharing with our readers!

Regards,

Arcane
July 31st, 2008, 14:59
yep good stuff

evilcry
August 1st, 2008, 06:41
Thank you for your feedback ppl, are always well accepted

I'm working on other anti-dbg techniques, I'll inform you on the results!

Regards,
Evilcry

Shub-nigurrath
August 1st, 2008, 18:36
can I suggest/ask to implement them also for xADT? So as I will add to the official distribution archive. Thanks.

evilcry
August 2nd, 2008, 00:24
Yes, I'll code the plugin for xADT and next send it to You

Regards,
Evilcry

Shub-nigurrath
August 3rd, 2008, 08:36
good good, thanks. If you want you can also add to it a readme explaining the concept or just add all your tests into an unique dll.

evaluator
August 6th, 2008, 23:59
evilcry,
once playing, i was overwriting IsDebug-byte in PEB before debugged_process start;
look, if some PEB flags are "compromissed" in this case.

evilcry
August 8th, 2008, 02:00
Thank you for that observation Evaluator!

I'll check at loading time what happens

Regards,
Evilcry

evaluator
August 8th, 2008, 09:46
DebugBreak will NOT happen, sure

deroko
August 13th, 2008, 22:42
set bpx at LdrInitializeThunk from ntdll.dll, and clear PEB.BeingDebugged, as evaluator says it won't break at DebugBreak, and Heap will be as if it would be without a debugger attached

evaluator
August 14th, 2008, 14:11
LdrInitializeThunk BPX.. why so wierd?
you createprocess_suspended, clear PEB.flag & resume..

blump ~ : )

deroko
August 14th, 2008, 20:49
dunno, because I like it to be done that way when I write ring3 debugger code

forgot
August 21st, 2008, 02:56
is it same as HeapMagic?

evilcry
August 22nd, 2008, 23:38
eheh load the executable with WinDbg if you want to make NtGlobalFlags hunting into LdrXxx jungle

Code:

is it same as HeapMagic?


Yes forgot all HeapDebug Countermeasures will defeat it