您的位置:首页 > 其它

JIURL玩玩Win2k进程线程篇 PEB

2015-08-03 20:46 417 查看

PEB,Process Environment Block ,进程环境块。位于用户地址空间。在地址 0x7FFDF000 处。所以用户进程可以直接访问自己的 PEB 结构。Win2k Build 2195 中进程的 EPROCESS 结构偏移+1b0 处的 *Peb 也指向 PEB 结构。在 undocumented.ntinternals.net (需要注意的是这是个非官方的站点)我们可以找到 PEB 及其相关结构的定义。我们首先列出结构的定义,然后对一些内容进行说明。

typedef struct _PEB {

BOOLEAN InheritedAddressSpace;

BOOLEAN ReadImageFileExecOptions;

BOOLEAN BeingDebugged;

BOOLEAN Spare;

HANDLE Mutant;

PVOID ImageBaseAddress;

PPEB_LDR_DATA LoaderData;

PRTL_USER_PROCESS_PARAMETERS ProcessParameters;

PVOID SubSystemData;

PVOID ProcessHeap;

PVOID FastPebLock;

PPEBLOCKROUTINE FastPebLockRoutine;

PPEBLOCKROUTINE FastPebUnlockRoutine;

ULONG EnvironmentUpdateCount;

PPVOID KernelCallbackTable;

PVOID EventLogSection;

PVOID EventLog;

PPEB_FREE_BLOCK FreeList;

ULONG TlsExpansionCounter;

PVOID TlsBitmap;

ULONG TlsBitmapBits[0x2];

PVOID ReadOnlySharedMemoryBase;

PVOID ReadOnlySharedMemoryHeap;

PPVOID ReadOnlyStaticServerData;

PVOID AnsiCodePageData;

PVOID OemCodePageData;

PVOID UnicodeCaseTableData;

ULONG NumberOfProcessors;

ULONG NtGlobalFlag;

BYTE Spare2[0x4];

LARGE_INTEGER CriticalSectionTimeout;

ULONG HeapSegmentReserve;

ULONG HeapSegmentCommit;

ULONG HeapDeCommitTotalFreeThreshold;

ULONG HeapDeCommitFreeBlockThreshold;

ULONG NumberOfHeaps;

ULONG MaximumNumberOfHeaps;

PPVOID *ProcessHeaps;

PVOID GdiSharedHandleTable;

PVOID ProcessStarterHelper;

PVOID GdiDCAttributeList;

PVOID LoaderLock;

ULONG OSMajorVersion;

ULONG OSMinorVersion;

ULONG OSBuildNumber;

ULONG OSPlatformId;

ULONG ImageSubSystem;

ULONG ImageSubSystemMajorVersion;

ULONG ImageSubSystemMinorVersion;

ULONG GdiHandleBuffer[0x22];

ULONG PostProcessInitRoutine;

ULONG TlsExpansionBitmap;

BYTE TlsExpansionBitmapBits[0x80];

ULONG SessionId;

} PEB, *PPEB;

typedef void (*PPEBLOCKROUTINE)(PVOID PebLock);

typedef struct _PEB_LDR_DATA {

ULONG Length;

BOOLEAN Initialized;

PVOID SsHandle;

LIST_ENTRY InLoadOrderModuleList;

LIST_ENTRY InMemoryOrderModuleList;

LIST_ENTRY InInitializationOrderModuleList;

} PEB_LDR_DATA, *PPEB_LDR_DATA;

typedef struct _LDR_MODULE {

LIST_ENTRY InLoadOrderModuleList;

LIST_ENTRY InMemoryOrderModuleList;

LIST_ENTRY InInitializationOrderModuleList;

PVOID BaseAddress;

PVOID EntryPoint;

ULONG SizeOfImage;

UNICODE_STRING FullDllName;

UNICODE_STRING BaseDllName;

ULONG Flags;

SHORT LoadCount;

SHORT TlsIndex;

LIST_ENTRY HashTableEntry;

ULONG TimeDateStamp;

} LDR_MODULE, *PLDR_MODULE;

typedef struct _UNICODE_STRING {

USHORT Length;

USHORT MaximumLength;

PWSTR Buffer;

} UNICODE_STRING, *PUNICODE_STRING;

typedef struct _RTL_USER_PROCESS_PARAMETERS {

ULONG MaximumLength;

ULONG Length;

ULONG Flags;

ULONG DebugFlags;

PVOID ConsoleHandle;

ULONG ConsoleFlags;

HANDLE StdInputHandle;

HANDLE StdOutputHandle;

HANDLE StdErrorHandle;

UNICODE_STRING CurrentDirectoryPath;

HANDLE CurrentDirectoryHandle;

UNICODE_STRING DllPath;

UNICODE_STRING ImagePathName;

UNICODE_STRING CommandLine;

PVOID Environment;

ULONG StartingPositionLeft;

ULONG StartingPositionTop;

ULONG Width;

ULONG Height;

ULONG CharWidth;

ULONG CharHeight;

ULONG ConsoleTextAttributes;

ULONG WindowFlags;

ULONG ShowWindowFlags;

UNICODE_STRING WindowTitle;

UNICODE_STRING DesktopName;

UNICODE_STRING ShellInfo;

UNICODE_STRING RuntimeData;

RTL_DRIVE_LETTER_CURDIR DLCurrentDirectory[0x20];

} RTL_USER_PROCESS_PARAMETERS, *PRTL_USER_PROCESS_PARAMETERS;

typedef struct _RTL_DRIVE_LETTER_CURDIR {

USHORT Flags;

USHORT Length;

ULONG TimeStamp;

UNICODE_STRING DosPath;

} RTL_DRIVE_LETTER_CURDIR, *PRTL_DRIVE_LETTER_CURDIR;

typedef struct _PEB_FREE_BLOCK {

_PEB_FREE_BLOCK *Next;

ULONG Size;

} PEB_FREE_BLOCK, *PPEB_FREE_BLOCK;

我写了一个叫
JiurlPebSee 的程序来分析指定进程的 PEB。下面我结合
JiurlPebSee 的输出来对 PEB 及其相关结构的一些内容进行说明。

ProcessId(Decimal): 516

Explorer.exe:

PEB at 0x7ffdf000

LoaderData: 0x00071e90

ProcessParameters: 0x00020000

ProcessHeap: 0x00070000

NumberOfHeaps: 11

MaximumNumberOfHeaps: 16

*ProcessHeaps: 0x77fce380

7ffdf000: 00000000 ffffffff 00400000 00071e90

7ffdf010: 00020000 00000000 00070000 77fcd170

7ffdf020: 77f8aa4c 77f8aa7d 00000001 77e14380

7ffdf030: 00000000 00000000 00000000 00000000

7ffdf040: 77fcd1a8 03cfffff 00000000 7f6f0000

7ffdf050: 7f6f0000 7f6f0688 7ffa0000 7ffa0000

7ffdf060: 7ffd1000 00000001 00000000 00000000

7ffdf070: 079b8000 ffffe86d 00100000 00002000

7ffdf080: 00010000 00001000 0000000b 00000010

7ffdf090: 77fce380 00350000 00000000 00000014

7ffdf0a0: 77fcd348 00000005 00000000 00000893

7ffdf0b0: 00000002 00000002 00000004 00000000

7ffdf0c0: 00000000 00000000 00000002 00000000

7ffdf0d0: 00000004 00000000 b51003ba 391001e4

7ffdf0e0: 00000000 00000000 00000000 00000000

7ffdf0f0: 00000000 00000000 00000000 00000000

7ffdf100: 00000000 00000000 00000000 00000000

7ffdf110: 00000000 00000000 00000000 00000000

7ffdf120: 8204019c 7004019b cf04019e a104019d

7ffdf130: 00000000 00000000 00000000 00000000

7ffdf140: 00000000 00000000 00000000 00000000

7ffdf150: 77fcdcc0 00000000 00000000 00000000

7ffdf160: 00000000 00000000 00000000 00000000

7ffdf170: 00000000 00000000 00000000 00000000

7ffdf180: 00000000 00000000 00000000 00000000

7ffdf190: 00000000 00000000 00000000 00000000

7ffdf1a0: 00000000 00000000 00000000 00000000

7ffdf1b0: 00000000 00000000 00000000 00000000

7ffdf1c0: 00000000 00000000 00000000 00000000

7ffdf1d0: 00000000 00000000 00000000 00020000

7ffdf1e0: 7f6f06c2 00000000 00000000 00000000

7ffdf1f0: 00000000 00000000 00000000 00000000

7ffdf200: 00000000 00000000 00000000 00000000

...

我们以进程 Explorer.exe 进行分析。

LoaderData 是指向 PEB_LDR_DATA 的指针,通过 PEB_LDR_DATA ,我们可以找到进程载入的所有模组。

ProcessParameters 是指向 RTL_USER_PROCESS_PARAMETERS 的指针,RTL_USER_PROCESS_PARAMETERS 中是一些进程的参数。

进程通常有多个用户堆。ProcessHeap 是进程堆(默认的那个)的首地址。NumberOfHeaps 是当前进程的堆的个数。MaximumNumberOfHeaps 是进程的堆的最大个数。*ProcessHeaps 是一个堆指针数组的首地址,每个数组元素长4个字节,是一个堆的指针。

LoaderData at 0x00071e90

Length: 36 Bytes

Initialized: 1

SsHandle: 0x00000000

InLoadOrderModuleList

Flink: 0x00071ec0 Blink: 0x000a0508

InMemoryOrderModuleList

Flink: 0x00071ec8 Blink: 0x000a0510

InInitializationOrderModuleList

Flink: 0x00071f48 Blink: 0x000a0518

Module at 0x00071ec0

FullDllName: D:/WINNT/Explorer.exe

BaseDllName: Explorer.exe

BaseAddress: 0x00400000

SizeOfImage: 0x0003c000

Module at 0x00071f38

FullDllName: D:/WINNT/System32/ntdll.dll

BaseDllName: ntdll.dll

BaseAddress: 0x77f80000

SizeOfImage: 0x00079000

Module at 0x00072470

FullDllName: D:/WINNT/system32/ADVAPI32.DLL

BaseDllName: ADVAPI32.DLL

BaseAddress: 0x77d90000

SizeOfImage: 0x0005a000

...

从PEB可以找到 PEB_LDR_DATA ,PEB_LDR_DATA 中有三个双向循环链表的表头,分别是 InLoadOrderModuleList,InMemoryOrderModuleList,InInitializationOrderModuleList。

每个链表项都是一个 LDR_MODULE 结构。

ProcessParameters at 0x00020000

MaximumLength: 0x00001000

Length: 0x00000838

...

Environment at 0x00010000

00010000: 004c0041 0055004c 00450053 00530052 A.L.L.U.S.E.R.S.

00010010: 00520050 0046004f 004c0049 003d0045 P.R.O.F.I.L.E.=.

00010020: 003a0049 0044005c 0063006f 006d0075 I.:./.D.o.c.u.m.

00010030: 006e0065 00730074 00610020 0064006e e.n.t.s. .a.n.d.

00010040: 00530020 00740065 00690074 0067006e .S.e.t.t.i.n.g.

...

00010340: 00640075 00000065 0069006c 003d0062 u.d.e...l.i.b.=.

00010350: 003a0047 004d005c 00630069 006f0072 G.:./.M.i.c.r.o.

00010360: 006f0073 00740066 00560020 00730069 s.o.f.t. .V.i.s.

00010370: 00610075 0020006c 00740053 00640075 u.a.l. .S.t.u.d.

...

00010a70: 005c0031 00650054 0070006d 00540000 1./.T.e.m.p...T.

...

00010b80: 003a0044 0057005c 004e0049 0054004e D.:./.W.I.N.N.T.

00010b90: 00000000 00000000 00000000 00000000 ................

...

00010ff0: 00000000 00000000 00000000 00000000 ................

RTL_USER_PROCESS_PARAMETERS 中的 PVOID Environment; 指明了环境变量的地址。

从结构定义中就可以看出 是象 StdInputHandle,ImagePathName 这样的参数。

ProcessHeaps at 0x77fce380

ProcessHeaps[0]: 0x00070000

ProcessHeaps[1]: 0x00170000

ProcessHeaps[2]: 0x008c0000

ProcessHeaps[3]: 0x00cd0000

ProcessHeaps[4]: 0x00ed0000

ProcessHeaps[5]: 0x00f10000

ProcessHeaps[6]: 0x01290000

ProcessHeaps[7]: 0x013e0000

ProcessHeaps[8]: 0x01ce0000

ProcessHeaps[9]: 0x01f50000

ProcessHeaps[10]: 0x03bf0000

77fce380: 00070000 00170000 008c0000 00cd0000

77fce390: 00ed0000 00f10000 01290000 013e0000

77fce3a0: 01ce0000 01f50000 03bf0000 00000000

77fce3b0: 00000000 00000000 00000000 00000000

从 ProcessHeaps 数组,我们可以找到进程的每一个堆。
为了方便观察某个进程地址空间中内容,我写了一个叫
JiurlProcessMemSee 的程序,可以获得指定进程地址空间中的内容。

使用 KD(内核调试器) 我们也可以找到 PEB 及其相关结构的定义。

kd> !strct PEB

!strct PEB

struct _PEB (sizeof=488)

+000 byte InheritedAddressSpace

+001 byte ReadImageFileExecOptions

+002 byte BeingDebugged

+003 byte SpareBool

+004 void *Mutant

+008 void *ImageBaseAddress

+00c struct _PEB_LDR_DATA *Ldr

+010 struct _RTL_USER_PROCESS_PARAMETERS *ProcessParameters

+014 void *SubSystemData

+018 void *ProcessHeap

+01c void *FastPebLock

+020 void *FastPebLockRoutine

+024 void *FastPebUnlockRoutine

+028 uint32 EnvironmentUpdateCount

+02c void *KernelCallbackTable

+030 uint32 SystemReserved[2]

+038 struct _PEB_FREE_BLOCK *FreeList

+03c uint32 TlsExpansionCounter

+040 void *TlsBitmap

+044 uint32 TlsBitmapBits[2]

+04c void *ReadOnlySharedMemoryBase

+050 void *ReadOnlySharedMemoryHeap

+054 void **ReadOnlyStaticServerData

+058 void *AnsiCodePageData

+05c void *OemCodePageData

+060 void *UnicodeCaseTableData

+064 uint32 NumberOfProcessors

+068 uint32 NtGlobalFlag

+070 union _LARGE_INTEGER CriticalSectionTimeout

+070 uint32 LowPart

+074 int32 HighPart

+070 struct __unnamed3 u

+070 uint32 LowPart

+074 int32 HighPart

+070 int64 QuadPart

+078 uint32 HeapSegmentReserve

+07c uint32 HeapSegmentCommit

+080 uint32 HeapDeCommitTotalFreeThreshold

+084 uint32 HeapDeCommitFreeBlockThreshold

+088 uint32 NumberOfHeaps

+08c uint32 MaximumNumberOfHeaps

+090 void **ProcessHeaps

+094 void *GdiSharedHandleTable

+098 void *ProcessStarterHelper

+09c uint32 GdiDCAttributeList

+0a0 void *LoaderLock

+0a4 uint32 OSMajorVersion

+0a8 uint32 OSMinorVersion

+0ac uint16 OSBuildNumber

+0ae uint16 OSCSDVersion

+0b0 uint32 OSPlatformId

+0b4 uint32 ImageSubsystem

+0b8 uint32 ImageSubsystemMajorVersion

+0bc uint32 ImageSubsystemMinorVersion

+0c0 uint32 ImageProcessAffinityMask

+0c4 uint32 GdiHandleBuffer[34]

+14c function *PostProcessInitRoutine

+150 void *TlsExpansionBitmap

+154 uint32 TlsExpansionBitmapBits[32]

+1d4 uint32 SessionId

+1d8 void *AppCompatInfo

+1dc struct _UNICODE_STRING CSDVersion

+1dc uint16 Length

+1de uint16 MaximumLength

+1e0 uint16 *Buffer

kd> !strct PEB_LDR_DATA

!strct PEB_LDR_DATA

struct _PEB_LDR_DATA (sizeof=36)

+00 uint32 Length

+04 byte Initialized

+08 void *SsHandle

+0c struct _LIST_ENTRY InLoadOrderModuleList

+0c struct _LIST_ENTRY *Flink

+10 struct _LIST_ENTRY *Blink

+14 struct _LIST_ENTRY InMemoryOrderModuleList

+14 struct _LIST_ENTRY *Flink

+18 struct _LIST_ENTRY *Blink

+1c struct _LIST_ENTRY InInitializationOrderModuleList

+1c struct _LIST_ENTRY *Flink

+20 struct _LIST_ENTRY *Blink

kd> !strct RTL_USER_PROCESS_PARAMETERS

!strct RTL_USER_PROCESS_PARAMETERS

struct _RTL_USER_PROCESS_PARAMETERS (sizeof=656)

+000 uint32 MaximumLength

+004 uint32 Length

+008 uint32 Flags

+00c uint32 DebugFlags

+010 void *ConsoleHandle

+014 uint32 ConsoleFlags

+018 void *StandardInput

+01c void *StandardOutput

+020 void *StandardError

+024 struct _CURDIR CurrentDirectory

+024 struct _UNICODE_STRING DosPath

+024 uint16 Length

+026 uint16 MaximumLength

+028 uint16 *Buffer

+02c void *Handle

+030 struct _UNICODE_STRING DllPath

+030 uint16 Length

+032 uint16 MaximumLength

+034 uint16 *Buffer

+038 struct _UNICODE_STRING ImagePathName

+038 uint16 Length

+03a uint16 MaximumLength

+03c uint16 *Buffer

+040 struct _UNICODE_STRING CommandLine

+040 uint16 Length

+042 uint16 MaximumLength

+044 uint16 *Buffer

+048 void *Environment

+04c uint32 StartingX

+050 uint32 StartingY

+054 uint32 CountX

+058 uint32 CountY

+05c uint32 CountCharsX

+060 uint32 CountCharsY

+064 uint32 FillAttribute

+068 uint32 WindowFlags

+06c uint32 ShowWindowFlags

+070 struct _UNICODE_STRING WindowTitle

+070 uint16 Length

+072 uint16 MaximumLength

+074 uint16 *Buffer

+078 struct _UNICODE_STRING DesktopInfo

+078 uint16 Length

+07a uint16 MaximumLength

+07c uint16 *Buffer

+080 struct _UNICODE_STRING ShellInfo

+080 uint16 Length

+082 uint16 MaximumLength

+084 uint16 *Buffer

+088 struct _UNICODE_STRING RuntimeData

+088 uint16 Length

+08a uint16 MaximumLength

+08c uint16 *Buffer

+090 struct _RTL_DRIVE_LETTER_CURDIR CurrentDirectores[32]

uint16 Flags

uint16 Length

uint32 TimeStamp

struct _STRING DosPath

uint16 Length

uint16 MaximumLength

char *Buffer

kd> !strct RTL_DRIVE_LETTER_CURDIR

!strct RTL_DRIVE_LETTER_CURDIR

struct _RTL_DRIVE_LETTER_CURDIR (sizeof=16)

+00 uint16 Flags

+02 uint16 Length

+04 uint32 TimeStamp

+08 struct _STRING DosPath

+08 uint16 Length

+0a uint16 MaximumLength

+0c char *Buffer

kd> !strct PEB_FREE_BLOCK

!strct PEB_FREE_BLOCK

struct _PEB_FREE_BLOCK (sizeof=8)

+0 struct _PEB_FREE_BLOCK *Next

+4 uint32 Size
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: