Process Environment Block(PEB)

简介

PEB(Process Environment Block,进程环境块)是存放进程信息的结构体,尺寸非常大,其大部分内容都已被文档化

PEB访问方法

TEB.ProcessEnvironmentBlock成员就是PEB 结构体的地址。TEB结构体位于FS段选择符所指的段内存的起始地址处,且ProcessEnvironmentBlock成员位于距TEB结构体Offest 30的位置。
即如下式子成立:

FS:[30]=TEB.ProcessEnvironmentBlock=address of PEB

用汇编代码表述上面式子:

代码1:

MOV EAX,DWORD PTR FS:[0x30]

代码2:

MOV EAX,DWORD PTR FS:[0x18]
MOV EAX,DWORD PTR FS:[EAX+0x30]

接下来用OD工具查看PEB结构体
在这里插入图片描述

在这里插入图片描述
执行此行代码后,查看eax
在这里插入图片描述
在这里插入图片描述

PEB结构体定义

Windows XP SP3下

typedef struct _PEB { // Size: 0x1D8
 	000h    UCHAR           InheritedAddressSpace;
    001h    UCHAR           ReadImageFileExecOptions;
    002h    UCHAR           BeingDebugged;              //Debug运行标志
    003h    UCHAR           SpareBool;
    004h    HANDLE          Mutant;
    008h    HINSTANCE       ImageBaseAddress;           //程序加载的基地址
    00Ch    struct _PEB_LDR_DATA    *Ldr                //Ptr32 _PEB_LDR_DATA
    010h    struct _RTL_USER_PROCESS_PARAMETERS  *ProcessParameters;
    014h    ULONG           SubSystemData;
    018h    HANDLE          DefaultHeap;
    01Ch    KSPIN_LOCK      FastPebLock;
    020h    ULONG           FastPebLockRoutine;
    024h    ULONG           FastPebUnlockRoutine;
    028h    ULONG           EnvironmentUpdateCount;
    02Ch    ULONG           KernelCallbackTable;
    030h    LARGE_INTEGER   SystemReserved;
    038h    struct _PEB_FREE_BLOCK  *FreeList
    03Ch    ULONG           TlsExpansionCounter;
    040h    ULONG           TlsBitmap;
    044h    LARGE_INTEGER   TlsBitmapBits;
    04Ch    ULONG           ReadOnlySharedMemoryBase;
    050h    ULONG           ReadOnlySharedMemoryHeap;
    054h    ULONG           ReadOnlyStaticServerData;
    058h    ULONG           AnsiCodePageData;
    05Ch    ULONG           OemCodePageData;
    060h    ULONG           UnicodeCaseTableData;
    064h    ULONG           NumberOfProcessors;
    068h    LARGE_INTEGER   NtGlobalFlag;               // Address of a local copy
    070h    LARGE_INTEGER   CriticalSectionTimeout;
    078h    ULONG           HeapSegmentReserve;
    07Ch    ULONG           HeapSegmentCommit;
    080h    ULONG           HeapDeCommitTotalFreeThreshold;
    084h    ULONG           HeapDeCommitFreeBlockThreshold;
    088h    ULONG           NumberOfHeaps;
    08Ch    ULONG           MaximumNumberOfHeaps;
    090h    ULONG           ProcessHeaps;
    094h    ULONG           GdiSharedHandleTable;
    098h    ULONG           ProcessStarterHelper;
    09Ch    ULONG           GdiDCAttributeList;
    0A0h    KSPIN_LOCK      LoaderLock;
    0A4h    ULONG           OSMajorVersion;
    0A8h    ULONG           OSMinorVersion;
    0ACh    USHORT          OSBuildNumber;
    0AEh    USHORT          OSCSDVersion;
    0B0h    ULONG           OSPlatformId;
    0B4h    ULONG           ImageSubsystem;
    0B8h    ULONG           ImageSubsystemMajorVersion;
    0BCh    ULONG           ImageSubsystemMinorVersion;
    0C0h    ULONG           ImageProcessAffinityMask;
    0C4h    ULONG           GdiHandleBuffer[0x22];
    14Ch    ULONG           PostProcessInitRoutine;
    150h    ULONG           TlsExpansionBitmap;
    154h    UCHAR           TlsExpansionBitmapBits[0x80];
    1D4h    ULONG           SessionId;
	1d8h AppCompatFlags   : _ULARGE_INTEGER
	1e0h AppCompatFlagsUser : _ULARGE_INTEGER
	1e8h pShimData        : Ptr32 Void
	1ech AppCompatInfo    : Ptr32 Void
	1f0h CSDVersion       : _UNICODE_STRING
	1f8h ActivationContextData : Ptr32 Void
	1fch ProcessAssemblyStorageMap :Ptr32 Void
	200h SystemDefaultActivationContextData : Ptr32 Void
	204h SystemAssemblyStorageMap : Ptr32 Void
	208h MinimumStackCommit : Uint4B
} PEB, *PPEB;

Windows 7下

ntdll!_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
   +0x01c FastPebLock      : Ptr32 _RTL_CRITICAL_SECTION
   +0x020 AtlThunkSListPtr : Ptr32 Void
   +0x024 IFEOKey          : Ptr32 Void
   +0x028 CrossProcessFlags : Uint4B
   +0x028 ProcessInJob     : Pos 0, 1 Bit
   +0x028 ProcessInitializing : Pos 1, 1 Bit
   +0x028 ProcessUsingVEH  : Pos 2, 1 Bit
   +0x028 ProcessUsingVCH  : Pos 3, 1 Bit
   +0x028 ProcessUsingFTH  : Pos 4, 1 Bit
   +0x028 ReservedBits0    : Pos 5, 27 Bits
   +0x02c KernelCallbackTable : Ptr32 Void
   +0x02c UserSharedInfoPtr : Ptr32 Void
   +0x030 SystemReserved   : [1] Uint4B
   +0x034 AtlThunkSListPtr32 : Uint4B
   +0x038 ApiSetMap        : Ptr32 Void
   +0x03c TlsExpansionCounter : Uint4B
   +0x040 TlsBitmap        : Ptr32 Void
   +0x044 TlsBitmapBits    : [2] Uint4B
   +0x04c ReadOnlySharedMemoryBase : Ptr32 Void
   +0x050 HotpatchInformation : Ptr32 Void
   +0x054 ReadOnlyStaticServerData : Ptr32 Ptr32 Void
   +0x058 AnsiCodePageData : Ptr32 Void
   +0x05c OemCodePageData  : Ptr32 Void
   +0x060 UnicodeCaseTableData : Ptr32 Void
   +0x064 NumberOfProcessors : Uint4B
   +0x068 NtGlobalFlag     : Uint4B
   +0x070 CriticalSectionTimeout : _LARGE_INTEGER
   +0x078 HeapSegmentReserve : Uint4B
   +0x07c HeapSegmentCommit : Uint4B
   +0x080 HeapDeCommitTotalFreeThreshold : Uint4B
   +0x084 HeapDeCommitFreeBlockThreshold : Uint4B
   +0x088 NumberOfHeaps    : Uint4B
   +0x08c MaximumNumberOfHeaps : Uint4B
   +0x090 ProcessHeaps     : Ptr32 Ptr32 Void
   +0x094 GdiSharedHandleTable : Ptr32 Void
   +0x098 ProcessStarterHelper : Ptr32 Void
   +0x09c GdiDCAttributeList : Uint4B
   +0x0a0 LoaderLock       : Ptr32 _RTL_CRITICAL_SECTION
   +0x0a4 OSMajorVersion   : Uint4B
   +0x0a8 OSMinorVersion   : Uint4B
   +0x0ac OSBuildNumber    : Uint2B
   +0x0ae OSCSDVersion     : Uint2B
   +0x0b0 OSPlatformId     : Uint4B
   +0x0b4 ImageSubsystem   : Uint4B
   +0x0b8 ImageSubsystemMajorVersion : Uint4B
   +0x0bc ImageSubsystemMinorVersion : Uint4B
   +0x0c0 ActiveProcessAffinityMask : Uint4B
   +0x0c4 GdiHandleBuffer  : [34] Uint4B
   +0x14c PostProcessInitRoutine : Ptr32     void 
   +0x150 TlsExpansionBitmap : Ptr32 Void
   +0x154 TlsExpansionBitmapBits : [32] Uint4B
   +0x1d4 SessionId        : Uint4B
   +0x1d8 AppCompatFlags   : _ULARGE_INTEGER
   +0x1e0 AppCompatFlagsUser : _ULARGE_INTEGER
   +0x1e8 pShimData        : Ptr32 Void
   +0x1ec AppCompatInfo    : Ptr32 Void
   +0x1f0 CSDVersion       : _UNICODE_STRING
   +0x1f8 ActivationContextData : Ptr32 _ACTIVATION_CONTEXT_DATA
   +0x1fc ProcessAssemblyStorageMap : Ptr32 _ASSEMBLY_STORAGE_MAP
   +0x200 SystemDefaultActivationContextData : Ptr32 _ACTIVATION_CONTEXT_DATA
   +0x204 SystemAssemblyStorageMap : Ptr32 _ASSEMBLY_STORAGE_MAP
   +0x208 MinimumStackCommit : Uint4B
   +0x20c FlsCallback      : Ptr32 _FLS_CALLBACK_INFO
   +0x210 FlsListHead      : _LIST_ENTRY
   +0x218 FlsBitmap        : Ptr32 Void
   +0x21c FlsBitmapBits    : [4] Uint4B
   +0x22c FlsHighIndex     : Uint4B
   +0x230 WerRegistrationData : Ptr32 Void
   +0x234 WerShipAssertPtr : Ptr32 Void
   +0x238 pContextData     : Ptr32 Void
   +0x23c pImageHeaderHash : Ptr32 Void
   +0x240 TracingFlags     : Uint4B
   +0x240 HeapTracingEnabled : Pos 0, 1 Bit
   +0x240 CritSecTracingEnabled : Pos 1, 1 Bit
   +0x240 SpareTracingBits : Pos 2, 30 Bits

据上观察Windows7下的PEB结构体更大。

PEB的重要成员

 +0x002 BeingDebugged    : UChar
 +0x008 ImageBaseAddress : Ptr32 Void
 +0x00c Ldr              : Ptr32 _PEB_LDR_DATA
 +0x018 ProcessHeap      : Ptr32 Void
 +0x068 NtGlobalFlag     : Uint4B

PEB.BeingDebugged

kernel32.dll中有个名Kernel32!IsDebuggerPresent()的API,但普通的应用程序开发中并不常用:

BOOL WINAPI IsDebuggerPresent()

该API就是用来判断当前进程是否处于调试状态,并返回判断结果。而该API就是通过检测PEB.BeingDebugged成员来确定是否正在调试程序(是,则返回1;否,则返回0)。

老办法,查看一下OD:

在这里插入图片描述
代码如下:

75074E80 >  64:A1 30000000  mov eax,dword ptr fs:[0x30]
75074E86    0FB640 02       movzx eax,byte ptr ds:[eax+0x2]
75074E8A    C3              retn

提示:
Windows 7中,IsDebuggerPresent()API是在Kernelbase.dll中实现的。而在Windows XP 及以前版本的操作系统中,它是在kernel32.dll中。

先获取FS:[30]地址,即PEB地址,然后通过[PEB+2]访问BeingDebugged
在这里插入图片描述
这里取出来的是0的原因呢,是因为吾爱破解OD太强悍了,加了很多插件。。。
在这里插入图片描述

慢慢关闭就行,用原版OD或者IDA就能返回1。

PEB.ImageBaseAddress

PEB.ImageBaseAddress成员用来表示进程的ImageBase。
**加粗样式**
GetModuleHandle()API用来获取ImageBase

HMODULE WINAPI GetModuleHandle(
__in_opt 	LPCTSTR		lpModuleName
)

lpModuleName参数赋值为NULL,调用GetModuleHandle()函数将返回进程被加载的ImageBase
在这里插入图片描述

查看了一下代码:

00821C70    55              push ebp
00821C71    8BEC            mov ebp,esp
00821C73    6A FE           push -0x2
00821C75    68 D0908200     push test1.008290D0
00821C7A    68 F0378200     push test1.008237F0
00821C7F    64:A1 00000000  mov eax,dword ptr fs:[0]
00821C85    50              push eax
00821C86    83C4 CC         add esp,-0x34
00821C89    53              push ebx
00821C8A    56              push esi                                 ; test1.<ModuleEntryPoint>
00821C8B    57              push edi                                 ; test1.<ModuleEntryPoint>
00821C8C    A1 24A08200     mov eax,dword ptr ds:[0x82A024]
00821C91    3145 F8         xor dword ptr ss:[ebp-0x8],eax
00821C94    33C5            xor eax,ebp
00821C96    50              push eax
00821C97    8D45 F0         lea eax,dword ptr ss:[ebp-0x10]
00821C9A    64:A3 00000000  mov dword ptr fs:[0],eax
00821CA0    8965 E8         mov dword ptr ss:[ebp-0x18],esp
00821CA3    6A 01           push 0x1
00821CA5    E8 EFF5FFFF     call test1.00821299


怎么说呢。。。VS编译链接出来的程序跟我想象中不太一样。。。我感觉应该是下面这样。。。

mov eax,dword ptr fs:[18]
mov eax,dword ptr fs:[eax+30]
mov eax,dword ptr fs:[eax+8]

调用GetModuleHandle()函数将执行上述代码,也就是PEB.ImageBaseAddress成员的值被设置在EAX寄存器里。(函数返回值)

PEB.Ldr

PEB.Ldr成员是指向了_ PEB _ LDR _ DATA结构体指针。如下:

ypedef struct _PEB_LDR_DATA
{
 ULONG         Length;                             // 00h
 BOOLEAN       Initialized;                        // 04h
 PVOID         SsHandle;                           // 08h
 LIST_ENTRY    InLoadOrderModuleList;              // 0ch
 LIST_ENTRY    InMemoryOrderModuleList;            // 14h
 LIST_ENTRY    InInitializationOrderModuleList;    // 1ch
 EntryInProgress  //Ptr32 Void
 ShutdownInProgress  //Uchar
 ShutdownThreadId //Ptr32 Void
}
    PEB_LDR_DATA,
    *PPEB_LDR_DATA;                                 // 24h

当模块(DLL)加载到进程后,通过PEB.ldr成员可以直接获得该模块的加载基地址。
_PEB_LDR_DATA结构体成员中有3个LIST_ENTRY类型的成员(InLoadOrderModuleList;InMemoryOrderModuleList; InInitializationOrderModuleList; ),LIST_ENTRY结构体的定义如下所示:

typedef struct _LIST_ENTRY{
	struct _LIST_ENTRY *Flink;
	struct _LIST_ENTRY *Blink;
}LIST_ENTRY,*LIST_ENTRY

从上面可看出,_LIST_ENTRY结构体提供了双向链表机制。而链表中保存了_LDR_DATA_TABLE_ENTRY结构体的信息。

	typedef struct _LDR_DATA_TABLE_EBTRY{  // Start from Windows XP
   	PVOID Reservedl[2];
    LIST_ENTRY InMemoryOrderLinks;
    PVOID Reserved2[2];
    PVOID DllBase;
    PVOID EntryPoint;
    PVOID Reserved3;
    ULONG SizeOfImage;
    UNICODE_STRING FullDllName;
    PVOID Reserved4[8];
   	PVOID Reserved5[3];
    union {
            PVOID SectionPointer;
            ULONG CheckSum;
}
	ULONG TimeDateStamp;
	}

每个加载到进程中的DLL模块都有与之对应的_LDR_DATA_TABLE_EBTRY结构体,这些结构体相互链接,最终形成_LIST_ENTRY双向链表。

需要注意的是,_PEB_LDR_DATA结构体中存在3种链表。也就说,存在多个_LDR_DATA_TABLE_ENTRY结构体,有三种链接方式可以把它们链接起来。

PEB.ProcessHeap & PEB.NtGlobalFlag

PEB.ProcessHeap & PEB.NtGlobalFlag (和PEB.BeingDebugger成员一样)应用于反调试技术。若处于被调试状态,则它们会被赋于特定的值。(反调试会讲解)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

寻梦&之璐

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值