IsDebuggerPresent()   该函数读取当前进程的PEBBeingDebugged的值用于判断自己是否处于调试状态

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] } }

 

posted on 2017-09-28 23:22  CrisCzy  阅读(811)  评论(0编辑  收藏  举报