IsDebuggerPresent() 该函数读取当前进程的PEB里BeingDebugged的值用于判断自己是否处于调试状态
windows2000上是这样定义这个函数的
BOOL APIENTRY IsDebuggerPresent(VOID) { return NtCurrentPeb()->BeingDebugged; }
在x86下用windbg查看PEB结构
可知在PEB(进程环境块)偏移0x002处获得BeingDebugged
kd> dt _PEB nt!_PEB +0x000 InheritedAddressSpace : UChar +0x001 ReadImageFileExecOptions : UChar +0x002 BeingDebugged : UChar +0x003 BitField : UChar +0x003 ImageUsesLargePages : Pos 0, 1 Bit +0x003 IsProtectedProcess : Pos 1, 1 Bit +0x003 IsLegacyProcess : Pos 2, 1 Bit +0x003 IsImageDynamicallyRelocated : Pos 3, 1 Bit +0x003 SkipPatchingUser32Forwarders : Pos 4, 1 Bit +0x003 SpareBits : Pos 5, 3 Bits +0x004 Mutant : Ptr32 Void +0x008 ImageBaseAddress : Ptr32 Void +0x00c Ldr : Ptr32 _PEB_LDR_DATA +0x010 ProcessParameters : Ptr32 _RTL_USER_PROCESS_PARAMETERS +0x014 SubSystemData : Ptr32 Void +0x018 ProcessHeap : Ptr32 Void ......
PEB(进程环境块)结构体地址存储在TEB(线程环境块)中,TEB结构如下
kd> dt _teb nt!_TEB +0x000 NtTib : _NT_TIB +0x01c EnvironmentPointer : Ptr32 Void +0x020 ClientId : _CLIENT_ID +0x028 ActiveRpcHandle : Ptr32 Void +0x02c ThreadLocalStoragePointer : Ptr32 Void +0x030 ProcessEnvironmentBlock : Ptr32 _PEB //PEB(进程环境块)结构体地址存储在TEB(线程环境块)中 +0x034 LastErrorValue : Uint4B +0x038 CountOfOwnedCriticalSections : Uint4B +0x03c CsrClientThread : Ptr32 Void +0x040 Win32ThreadInfo : Ptr32 Void +0x044 User32Reserved : [26] Uint4B +0x0ac UserReserved : [5] Uint4B +0x0c0 WOW32Reserved : Ptr32 Void ......
其中_NT_TIB结构如下
kd> dt _NT_TIB nt!_NT_TIB +0x000 ExceptionList : Ptr32 _EXCEPTION_REGISTRATION_RECORD +0x004 StackBase : Ptr32 Void +0x008 StackLimit : Ptr32 Void +0x00c SubSystemTib : Ptr32 Void +0x010 FiberData : Ptr32 Void +0x010 Version : Uint4B +0x014 ArbitraryUserPointer : Ptr32 Void +0x018 Self : Ptr32 _NT_TIB // 其中+0x018 Self 是一个指向TIB的指针.同时也是TEB结构体的首地址
......
一般在FS段寄存器 地址FS:0指向当前线程TEB数据。
当我们需要TEB地址时,可以利用 mov eax, fs:[0x18]得到。且从上文可知在TEB偏移0x30处得到PEB地址。
固可以通过fs:[30h}获得当前进程的PEB地址。
两个模拟实现的函数
BOOL IsDebuggerPresentPEB() { #if defined (ENV64BIT) PPEB pPeb = (PPEB)__readgsqword(0x60); #elif defined(ENV32BIT) PPEB pPeb = (PPEB)__readfsdword(0x30); #endif if (pPeb->BeingDebugged == 1) return TRUE; else return FALSE; }
//内联汇编版本
BOOL MYIsDebuggerPresent() { __asm{ mov eax, fs:[0x30] movz eax, byte ptr [eax+2] } }