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