Anti Debugging unleashed series # Part 2
September 29th, 2011
No comments
NTGlobalFlag NTGlobalFlag lies at an offset 0x68 from PEB. The value of NTGlobalFlag
is 0 when the process is not bein debugged. However, if the process is
being debugged, the value of this flag is 0x70.
First we see the starting of PEB in windbg:
0:000> !peb
PEB at 7ffd6000
InheritedAddressSpace: No
ReadImageFileExecOptions: No
BeingDebugged: Yes
ImageBaseAddress: 00400000
Lets parse the PEB:
0:000> dt _PEB 7ffd6000
ntdll!_PEB
+0x000 InheritedAddressSpace : 0 ''
+0x001 ReadImageFileExecOptions : 0 ''
+0x002 BeingDebugged : 0x1 ''
+0x003 SpareBool : 0 ''
+0x004 Mutant : 0xffffffff
+0x008 ImageBaseAddress : 0x00400000
+0x00c Ldr : 0x00271ea0 _PEB_LDR_DATA
+0x010 ProcessParameters : 0x00020000 _RTL_USER_PROCESS_PARAMETERS
+0x014 SubSystemData : (null)
+0x018 ProcessHeap : 0x00170000
+0x01c FastPebLock : 0x7c980600 _RTL_CRITICAL_SECTION
+0x020 FastPebLockRoutine : 0x7c901000
+0x024 FastPebUnlockRoutine : 0x7c9010e0
+0x028 EnvironmentUpdateCount : 1
+0x02c KernelCallbackTable : (null)
+0x030 SystemReserved : [1] 0
+0x034 AtlThunkSListPtr32 : 0
+0x038 FreeList : (null)
+0x03c TlsExpansionCounter : 0
+0x040 TlsBitmap : 0x7c9805c0
+0x044 TlsBitmapBits : [2] 1
+0x04c ReadOnlySharedMemoryBase : 0x7f6f0000
+0x050 ReadOnlySharedMemoryHeap : 0x7f6f0000
+0x054 ReadOnlyStaticServerData : 0x7f6f0688 -> (null)
+0x058 AnsiCodePageData : 0x7ffb0000
+0x05c OemCodePageData : 0x7ffc1000
+0x060 UnicodeCaseTableData : 0x7ffd2000
+0x064 NumberOfProcessors : 2
+0x068 NtGlobalFlag : 0x70
As you can see, the NtGlobalFlag is set to 0x70.
Following is the assembly code to detect the same:
MOV EAX, fs:[0x30] ;PEB in eax
MOV EAX, dword ptr[EAX+0x68] ;Value of NTGlobalFlag in EAX
CMP EAX,0x70 ;If equal, means debugger present
HeapFlags
As a side effect of NtGlobalFlags being set, heaps that are created
will have some flags turned on that can be used for anti debugging.
Every process has a default process heap. Flags and ForceFlags for
a heap are 0x02(means the heap can grow) and 0 respectively. However,
when debugging, they are set to 0x50000062 and 0x40000060 Lets see the whole picture in windbg: 0:000> dt _PEB 7ffd6000 ntdll!_PEB +0x000 InheritedAddressSpace : 0 '' +0x001 ReadImageFileExecOptions : 0 '' +0x002 BeingDebugged : 0x1 '' +0x003 SpareBool : 0 '' +0x004 Mutant : 0xffffffff +0x008 ImageBaseAddress : 0x00400000 +0x00c Ldr : 0x00271ea0 _PEB_LDR_DATA +0x010 ProcessParameters : 0x00020000 _RTL_USER_PROCESS_PARAMETERS +0x014 SubSystemData : (null) +0x018 ProcessHeap : 0x00170000 +0x01c FastPebLock : 0x7c980600 _RTL_CRITICAL_SECTION So, we know that the default process heap gets created at address
0x00170000. Lets parse the heap at this address: 0:000> dt _HEAP 170000 ntdll!_HEAP +0x000 Entry : _HEAP_ENTRY +0x008 Signature : 0xeeffeeff +0x00c Flags : 0x50000062 +0x010 ForceFlags : 0x40000060 +0x014 VirtualMemoryThreshold : 0xfe00 +0x018 SegmentReserve : 0x100000 +0x01c SegmentCommit : 0x2000 So, malware authors can check these values for detecting the debuggers. Following is the assembly code to find the same(consider the debugger running): MOV EAX, FS:[0x30] ;Go to PEB MOV EAX, dword ptr[EAX+0x18] ;EAX holds the address of default
;process heap MOV EBX, dword ptr[EAX+0xc] ;EBX holds the value of Flags MOV ECX, dword ptr[EAX+0x10] ;ECX holds the ForceFlags