PEB结构体定义
PEB是存放进程信息的结构体,尺寸非常大,大部分内容都已被文档化
PEB (winternl.h) - Win32 apps | Microsoft Learn
MSDN
typedef struct _PEB {
BYTE Reserved1[2];
BYTE BeingDebugged;
BYTE Reserved2[1];
PVOID Reserved3[2];
PPEB_LDR_DATA Ldr;
PRTL_USER_PROCESS_PARAMETERS ProcessParameters;
PVOID Reserved4[3];
PVOID AtlThunkSListPtr;
PVOID Reserved5;
ULONG Reserved6;
PVOID Reserved7;
ULONG Reserved8;
ULONG AtlThunkSListPtr32;
PVOID Reserved9[45];
BYTE Reserved10[96];
PPS_POST_PROCESS_INIT_ROUTINE PostProcessInitRoutine;
BYTE Reserved11[128];
PVOID Reserved12[1];
ULONG SessionId;
} PEB, *PPEB;
Window 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;
win7
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
重要成员
+0x002 BeingDebugged : UChar
+0x008 ImageBaseAddress : Ptr32 Void
+0x00c Ldr : Ptr32 _PEB_LDR_DATA
+0x018 ProcessHeap : Ptr32 Void
+0x068 NtGlobalFlag : Uint4B
BeingDebugged
kernel32.dll中有个名Kernel32!IsDebuggerPresent()
的API,但普通的应用程序开发中并不常用:
提示:
Windows 7中,IsDebuggerPresent()
API是在Kernelbase.dll
中实现的。而在Windows XP 及以前版本的操作系统中,它是在kernel32.dll
中。
该API就是用来判断当前进程是否处于调试状态,并返回判断结果。而该API就是通过检测PEB.BeingDebugged成员来确定是否正在调试程序(是,则返回1;否,则返回0)。
PEB.ImageBaseAdress
GetModuleHandle()
API用来获取ImageBase
。
HMODULE WINAPI GetModuleHandle(
__in_opt LPCTSTR lpModuleName
)
向lpModuleName
参数赋值为NULL,调用GetModuleHandle()
函数将返回进程被加载的ImageBase
。
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结构体指针。如下
typedef 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成员一样)应用于反调试技术。若处于被调试状态,则它们会被赋于特定的值。
PEB访问方法
从之前学习TEB可以得知
FS:[30]=TEB.ProcessEnvironmentBlock=address of PEB
用汇编表示
MOV EAX,DWORD PTR FS:[30]
OR
MOV EAX,DWORD PTR FS:[18];FS:[18]=address of TEB
MOV EAX,DWORD PTR DS:[EAX+30];