TEB和PEB

1、这篇文章主要对Windows XP SP3和Windows 7 SP1中的TEB和PEB结构进行对比分析。
2、当时对Windows 7下的堆管理算法逆向的时候,涉及到TEB和PEB中的某些结构,所以做了一下总结。
3、还没总结完,主要是太费时间了,一些结构可能暂时用不到,后续接触到的时候再补充。

TEB

Geoff Chappell, Software Analyst - TEB

Windows XP SP3 x86

_TEB

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
0:000> dt _TEB
ntdll!_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
+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
+0x0c4 CurrentLocale : Uint4B
+0x0c8 FpSoftwareStatusRegister : Uint4B
+0x0cc SystemReserved1 : [54] Ptr32 Void
+0x1a4 ExceptionCode : Int4B
+0x1a8 ActivationContextStack : _ACTIVATION_CONTEXT_STACK
+0x1bc SpareBytes1 : [24] UChar
+0x1d4 GdiTebBatch : _GDI_TEB_BATCH
+0x6b4 RealClientId : _CLIENT_ID
+0x6bc GdiCachedProcessHandle : Ptr32 Void
+0x6c0 GdiClientPID : Uint4B
+0x6c4 GdiClientTID : Uint4B
+0x6c8 GdiThreadLocalInfo : Ptr32 Void
+0x6cc Win32ClientInfo : [62] Uint4B
+0x7c4 glDispatchTable : [233] Ptr32 Void
+0xb68 glReserved1 : [29] Uint4B
+0xbdc glReserved2 : Ptr32 Void
+0xbe0 glSectionInfo : Ptr32 Void
+0xbe4 glSection : Ptr32 Void
+0xbe8 glTable : Ptr32 Void
+0xbec glCurrentRC : Ptr32 Void
+0xbf0 glContext : Ptr32 Void
+0xbf4 LastStatusValue : Uint4B
+0xbf8 StaticUnicodeString : _UNICODE_STRING
+0xc00 StaticUnicodeBuffer : [261] Uint2B
+0xe0c DeallocationStack : Ptr32 Void
+0xe10 TlsSlots : [64] Ptr32 Void
+0xf10 TlsLinks : _LIST_ENTRY
+0xf18 Vdm : Ptr32 Void
+0xf1c ReservedForNtRpc : Ptr32 Void
+0xf20 DbgSsReserved : [2] Ptr32 Void
+0xf28 HardErrorsAreDisabled : Uint4B
+0xf2c Instrumentation : [16] Ptr32 Void
+0xf6c WinSockData : Ptr32 Void
+0xf70 GdiBatchCount : Uint4B
+0xf74 InDbgPrint : UChar
+0xf75 FreeStackOnTermination : UChar
+0xf76 HasFiberData : UChar
+0xf77 IdealProcessor : UChar
+0xf78 Spare3 : Uint4B
+0xf7c ReservedForPerf : Ptr32 Void
+0xf80 ReservedForOle : Ptr32 Void
+0xf84 WaitingOnLoaderLock : Uint4B
+0xf88 Wx86Thread : _Wx86ThreadState
+0xf94 TlsExpansionSlots : Ptr32 Ptr32 Void
+0xf98 ImpersonationLocale : Uint4B
+0xf9c IsImpersonating : Uint4B
+0xfa0 NlsCache : Ptr32 Void
+0xfa4 pShimData : Ptr32 Void
+0xfa8 HeapVirtualAffinity : Uint4B
+0xfac CurrentTransactionHandle : Ptr32 Void
+0xfb0 ActiveFrame : Ptr32 _TEB_ACTIVE_FRAME
+0xfb4 SafeThunkCall : UChar
+0xfb5 BooleanSpare : [3] UChar
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
//0xfb8 bytes (sizeof)
struct _TEB
{
struct _NT_TIB NtTib; //0x0
VOID* EnvironmentPointer; //0x1c
struct _CLIENT_ID ClientId; //0x20
VOID* ActiveRpcHandle; //0x28
VOID* ThreadLocalStoragePointer; //0x2c
struct _PEB* ProcessEnvironmentBlock; //0x30
ULONG LastErrorValue; //0x34
ULONG CountOfOwnedCriticalSections; //0x38
VOID* CsrClientThread; //0x3c
VOID* Win32ThreadInfo; //0x40
ULONG User32Reserved[26]; //0x44
ULONG UserReserved[5]; //0xac
VOID* WOW32Reserved; //0xc0
ULONG CurrentLocale; //0xc4
ULONG FpSoftwareStatusRegister; //0xc8
VOID* SystemReserved1[54]; //0xcc
LONG ExceptionCode; //0x1a4
struct _ACTIVATION_CONTEXT_STACK ActivationContextStack; //0x1a8
UCHAR SpareBytes1[24]; //0x1bc
struct _GDI_TEB_BATCH GdiTebBatch; //0x1d4
struct _CLIENT_ID RealClientId; //0x6b4
VOID* GdiCachedProcessHandle; //0x6bc
ULONG GdiClientPID; //0x6c0
ULONG GdiClientTID; //0x6c4
VOID* GdiThreadLocalInfo; //0x6c8
ULONG Win32ClientInfo[62]; //0x6cc
VOID* glDispatchTable[233]; //0x7c4
ULONG glReserved1[29]; //0xb68
VOID* glReserved2; //0xbdc
VOID* glSectionInfo; //0xbe0
VOID* glSection; //0xbe4
VOID* glTable; //0xbe8
VOID* glCurrentRC; //0xbec
VOID* glContext; //0xbf0
ULONG LastStatusValue; //0xbf4
struct _UNICODE_STRING StaticUnicodeString; //0xbf8
USHORT StaticUnicodeBuffer[261]; //0xc00
VOID* DeallocationStack; //0xe0c
VOID* TlsSlots[64]; //0xe10
struct _LIST_ENTRY TlsLinks; //0xf10
VOID* Vdm; //0xf18
VOID* ReservedForNtRpc; //0xf1c
VOID* DbgSsReserved[2]; //0xf20
ULONG HardErrorsAreDisabled; //0xf28
VOID* Instrumentation[16]; //0xf2c
VOID* WinSockData; //0xf6c
ULONG GdiBatchCount; //0xf70
UCHAR InDbgPrint; //0xf74
UCHAR FreeStackOnTermination; //0xf75
UCHAR HasFiberData; //0xf76
UCHAR IdealProcessor; //0xf77
ULONG Spare3; //0xf78
VOID* ReservedForPerf; //0xf7c
VOID* ReservedForOle; //0xf80
ULONG WaitingOnLoaderLock; //0xf84
struct _Wx86ThreadState Wx86Thread; //0xf88
VOID** TlsExpansionSlots; //0xf94
ULONG ImpersonationLocale; //0xf98
ULONG IsImpersonating; //0xf9c
VOID* NlsCache; //0xfa0
VOID* pShimData; //0xfa4
ULONG HeapVirtualAffinity; //0xfa8
VOID* CurrentTransactionHandle; //0xfac
struct _TEB_ACTIVE_FRAME* ActiveFrame; //0xfb0
UCHAR SafeThunkCall; //0xfb4
UCHAR BooleanSpare[3]; //0xfb5
};
  • 0x000 NtTib:“_NT_TIB”结构体指针,TIB(Thread Information Block: 线程信息块)。
  • 0x01c EnvironmentPointer:EnvironmentPointer对于OS2.EXE是与意义的,即用户模式“OS2 Subsystem Client”,随Windows3.10~5.0一起发布。OS2.EXE包含在Windows 2000中,使NT系统可以运行OS/2应用程序。在以后的任何Windows版本中都不知道该成员的用途。
  • 0x020 ClientId:“_CLIENT_ID”结构。ClientId是提供存储每个线程最简单的特有信息的结构。Windows中的每个线程都有一个标识符。线程应该很容易的获得其自己的标识符以及它属于的进程的标识符。文档化的函数GetCurrentProcessId和GetCurrentThreadId除了从ClientId获得相应的标识符外,什么也不做。
  • 0x028 ActiveRpcHandle:Windows版本3.10在偏移量0x28处保存的是CSR_QLPC_TEB结构的地址。在版本3.51中,该结构被改为位于TEB本身的偏移量0x01AC处。当某个客户端进程中的线程连接到CSRSS服务器时,客户端线程和服务器线程均获得此结构。每个结构都有一个共享节的句柄和一个事件对,一个指向该节视图的指针,以及该视图的线程地址之间的差异。每个结构的句柄和指针都是相对于相应进程的句柄和地址空间的。该节和视图被用于在客户端和服务器之间传递请求和应答。delta允许消息包含指针。事件对提供同步。这在当时是非常重要的,不仅因为事件对是它自己的内核对象,而且等待和信号已经为到达内核提供了专用的中断号。对于服务器线程,该结构以指向客户端线程的CSRSRV表示的指针开始。当它变为偏移量为0x3C的CsrClientThread时,这个指针是4.0版本中存在的东西。
      在任何版本中都不知道偏移量0x28处的指针的其他用途。也许它从一开始就被命名为ActiveRpcHandle,远程过程调用(RPC)这个名称从来没有泛指过,而总是特定于嵌入任意客户端进程NTDLL中的CSRDLL和CSRSS服务器进程中的CSRSRV之间的调用。
  • 0x02c ThreadLocalStoragePointer:通过ThreadLocalStoragePointer提供的线程本地存储(TLS)与TlsAlloc等API函数无关。通过TlsSlots数组和TlsExpansionSlots指针进一步深入到TEB中,并通过诸如TlsBitmap这样的PEB成员,可以支持这些功能。相反,ThreadLocalStoragePointer处理可能显示在模块的“PE Header”的“Thread Local Storage Directory”中的线程本地存储。这样的存储通常存在,因为程序有用Microsoft特有的__declspec(thread)存储类修饰符定义的数据。微软的编译器将所有这些数据保存在一个名为.tls的节中。C运行时(CRT)头定义了一个IMAGE_TLS_DIRECTORY来描述此数据及其特殊要求。链接器(Linker)可通过PE头将此描述提供给加载器(Loader)。一旦设置,ThreadLocalStoragePointer指向的是一个指向每个包含模块的线程本地数据的指针数组。至少理论上是这样。在早期,特别是在6.0版本之前,这种做法已经大大减少了,因为这种形式的线程本地存储仅支持与进程一起加载的模块,而不支持稍后加载的dll。关于这个问题可以单独写一篇文章,尤其是因为Microsoft总是以它特有的的风格进行解释,Microsoft倾向于只是间接地解释它,例如“在Windows Vista之前的版本中,您将无法使用LoadLibrary显式加载DLL”或该功能“可能会干扰DLL导入的延迟加载”。
  • 0x030 ProcessEnvironmentBlock:“_PEB”结构指针。
  • 0x034 LastErrorValue:LastErrorValue通常是线程最近对系统调用进行调用的隐藏结果。NTDLL在内核中调用的本地API函数大多返回NTSTATUS作为错误代码。这也适用于NTDLL导出的大多数用于低层Win32 Dlls(如KERNEL32)的函数。许多Win32 API函数(例如在KERNEL32中实现的)都会返回BOOL值以指示成功或失败。其原理似乎是,在Win32 API函数失败后(在某些情况下,即使函数成功了),调用线程可以通过调用GetLastError获取Win32错误代码。文档化的函数仅仅从LastErrorValue中获取错误代码。当然,所获取的错误代码与任何最近调用的API函数的相关性取决于在所有失败情况下都已将错误代码设置到位的API函数,并且在设置和获取之间,调用者不能做任何可能调用其他API函数的事情。奇怪的是,许多程序员,甚至是那些认为自己是优秀的或有经验的优雅代码作者的程序员,都愿意冒险让LastErrorValue保持不变,即使在他们调用其他代码时,例如C运行时库中的函数。
  • 0x038 CountOfOwnedCriticalSections:对于一些目前未知的目的,SetLastError的3.10版本实现还清除了偏移量0x38处的字节。尽管更高版本的符号文件将此空间命名为CountOfOwnedCriticalSections,目前还不知道它在这方面或其他方面的用途。按照字面意思,应该是当前线程拥有的CriticalSections数量。
  • 0x03c CsrClientThread:CSR(Certificate Signing Request)。在3.50~3.51版本的Windows中,此字段被命名为Win32ProcessInfo。参考“ActiveRpcHandle”。
  • 0x040 Win32ThreadInfo:Win32ProcessInfo和Win32ThreadInfo指向的分别是“PROCESSINFO”和“THREADINFO”结构。在版本4.0和更高版本中,WIN32K.SYS在内核模式下创建这些结构。是的,尽管微软近年来关注阻止内核模式地址泄漏到用户模式空间中,但Win32ThreadInfo指针保留了一个公开的内核模式地址,甚至Windows 10的原始发行版中也是如此。微软的PROCESSINFO和THREADINFO的名称以及它们的成员在Windows 7中WIN32K的符号文件中作为类型信息公开提供(但显然既不是以前也不是以后)。
  • 0x044 User32Reserved:在4.0版本的Windows中,此字段为Win32ClientInfo。0x7C字节Win32ClientInfo的前0x60字节在WIN32K.SYS和USER32.DLL之间共享,当然是作为CLIENTINFO结构共享的。这里假设User32Reserved在所有后来的符号文件中都保留了CLIENTINFO在5.0版本开发期间增长到的大小,在它的进一步增长(到0x84字节)需要重新定位之前,需要判断CurrentLocale(紧随其后)是否被干扰。但谁知道呢?
  • 0x0ac UserReserved
  • 0x0c0 WOW32Reserved:用户模式32bit(WOW64)->内核模式转换之前的64位上下文切换函数的指针。
  • 0x0c4 CurrentLocale:CurrentLocale就是文档化的GetThreadLocale和SetThreadLocale函数获取和设置的内容。看到对于最早版本中的先前成员的所有修订,似乎有人确定CurrentLocale在整个历史记录中保持相同的偏移量。为此,它的与众不同之处可能是内核知道它,这将使其在线程初始执行的内核模式部分被设置。
  • 0x0c8 FpSoftwareStatusRegister:尽管FpSoftwareStatusRegister被显示为永久存在,但尚未在任何版本中使用它。值得注意的是,它并没有被Windows Vista之前(包括Windows Vista)的内核和NTDLL保留的用于浮点仿真的代码所使用(但它确实使用了后面的大部分保留区域)。
  • 0x0cc SystemReserved1:在6.1版之前,在任何情况下都不会保留前面的空间以备将来使用:内核和NTDLL都在实际使用它的前0xA0字节来支持浮点仿真。从符号文件中无法得知此结构。即使在该区域正在使用时,也被称为SystemReserved1的原始标签。
  • 0x1a4 ExceptionCode:根据早期DDK中.LIB文件的类型信息,无论如何,保留的空间后面是两个备用空间。当4.0版本引入KiRaiseUserExceptionDispatcher函数时,其中的第二个用作ExceptionCode。NTDLL导出此函数,不是由其他用户模式模块导入,而是由内核找到。内核模式KeRaiseUserException,也随4.0版本一起引入,将异常代码放入TEB中,然后重新定位内核从Ring0退出的目标,以便正在进行的任何系统服务都不会按预期返回,而是由KiRaiseUserExceptionDispatcher获得。然后,这个Stub让NTDLL继续处理,就像在用户模式下调用NTDLL函数RtlRaiseException引发异常一样。该机制的最初目的是帮助调试用户模式的句柄关闭。几乎没有任何程序(包括我的程序)检查它们对诸如CloseHandle之类的函数的调用的成功或失败 - 是的,即使失败可能意味着丢失尚未写入文件的数据。如果在NtGlobalFlag中设置了0x00400000位,或者如果当前进程正在被调试,那么NtClose的用户模式调用者会显示一个无效的句柄或一个被保护不被关闭的句柄,就可以从处理异常中了解到它。目前还不知道5.0版从转移ExceptionCode中得到了什么,除了可能要放弃Spare1的用途之外。
  • 0x1a8 ActivationContextStack:_ACTIVATION_CONTEXT_STACK结构。随着窗口功能从用户模式CSRSS到版本4.0的内核模式WIN32K的重定位,前述的的成员被停止使用或向前转移。他们所占用的空间成为显着的备用空间(如SpareBytes1)。当为Windows XP引入激活上下文时,这些备用字节的开始部分已被用于ACTIVATION_CONTEXT_STACK结构。但是,这种情况很快就改变了。在x86和x64版本的Windows中,TEB仅具有一个指向ACTIVATION_CONTEXT_STACK的指针。起初,几乎ActivationContextStack的所有字节都恢复为备用状态。除了Windows Vista在末尾定义了一个成员外,这些备用字节一直保持备用状态,直到Windows 10将一些用于检测回调,可以通过NtSetInformationProcess的ProcessInstrumentationCallback案例设置。
  • 0x1bc SpareBytes1:备用字节。
  • 0x1d4 GdiTebBatch:_GDI_TEB_BATCH结构。
  • 0x6b4 RealClientId:_CLIENT_ID结构。实际的客户端ID。
  • 0x6bc GdiCachedProcessHandle:GDI缓存进程句柄。
  • 0x6c0 GdiClientPID:GDI客户端PID。
  • 0x6c4 GdiClientTID:GDI客户端TID。
  • 0x6c8 GdiThreadLocalInfo:GdiThreadLocalInfo在版本3.10中指向的是一个0x2C字节的结构,其第一个成员指向服务器中的本地线程信息。在版本3.51中,GdiThreadLocalInfo直接指向此相同的本地线程信息。该信息也指向版本3.10中0x28偏移量(CSR_QLPC_TEB)指向的0x14字节结构中的0x0C偏移量,版本3.51嵌入到0x01AC偏移量(CSR_QLPC_TEB)。
  • 0x6cc Win32ClientInfo:参见User32Reserved。

    随后的几个成员(其名称均以gl开头,Graphics Library)对OPENGL32.DLL和GLSRV.DLL有意义。我知道的最旧的版本都来自Windows NT 3.51,但是我怀疑glDispatchTable支持的许多函数在某个地方存在较早,或者即使没有实现也已计划好了。

  • 0x7c4 glDispatchTable:版本3.51中的glDispatchTable被指向函数的指针填满,没有为后面称为glReserved1的留下空间。后面标记为glReserved2的指针在3.51版本中似乎未使用,但可能不需要编号后缀。由于后来的版本引入了更多的函数,glDispatchTable显然不能扩展。以后的版本不会填充缩减后的glDispatchTable。
  • 0xb68 glReserved1
  • 0xbdc glReserved2
  • 0xbe0 glSectionInfo
  • 0xbe4 glSection
  • 0xbe8 glTable
  • 0xbec glCurrentRC
  • 0xbf0 glContext
  • 0xbf4 LastStatusValue:LastStatusValue是最后提供给古老的RtlNtStatusToDosError函数的值。现在这个函数被记录为一个内核导出。这也是一个未文档化的NTDLL导出。该函数与RtlNtStatusDosErrorNoTeb(这也是一个同样古老的内核导出,并且始终存在于NTDLL中,但仅在5.1版本和更高版本中导出)之间的区别在于,后者不会影响TEB中的LastStatusValue。这两个函数都将NTSTATUS转换为Win32错误代码,但仅作为查找:LastErrorValue被单独保留。强烈建议不要通过普通的RtlNtStatusToDosError查找NTSTATUS,而无意继续从该NTSTATUS或另一个NTSTATUS设置Win32错误代码。在5.1版本和更高版本中,NTDLL导出了另一个未文档化的函数,它被命名为RtlSetLastWin32ErrorAndNtStatusFromNtStatus。不知道为什么保存NTSTATUS为LastStatusValue会使其从有符号变为无符号。
  • 0xbf8 StaticUnicodeString:_UNICODE_STRING结构。StaticUnicodeString及其缓冲区似乎为几乎所有临时需要路径名大小缓冲区的API函数提供了便利。
  • 0xc00 StaticUnicodeBuffer
  • 0xe0c DeallocationStack
  • 0xe10 TlsSlots
  • 0xf10 TlsLinks:_LIST_ENTRY结构双链表。TlsLinks成员大概在所有版本的TEB中都有定义,但我不知道它在任何版本中的用法。
  • 0xf18 Vdm
  • 0xf1c ReservedForNtRpc:RPCRT4.DLL从一开始就使用ReservedForNtRpc成员来保存每个线程的数据(从版本4.0到10.0的符号文件显示为一个名为THREAD的类)。
  • 0xf20 DbgSsReserved:DbgSsReserved是两个句柄的数组,这可能是原始实现的残余,在原始实现中,一个成为调试器的线程连接到由SMSS进程创建的指定端口。在版本5.1及更高版本中,此连接改为一个内核模式的调试对象。调试对象的句柄被保留为数组的第二个元素,但第一个元素被认为是未使用的。
  • 0xf28 HardErrorsAreDisabled
  • 0xf2c Instrumentation
  • 0xf6c WinSockData
  • 0xf70 GdiBatchCount
  • 0xf74 InDbgPrint:在版本4.0中,尚不知道接下来的四个字节的用途。版本5.0将第一个用作布尔值,5.1版本定义了两个以上的布尔值和一个8位处理器编号,版本6.0使这三个布尔值显式备用,然后版本6.1将处理器编号扩展为所有四个字节。然而,布尔值并没有全部消失。InDbgPrint成员保护NTDLL函数vDbgPrintExWithPrefix(以及一系列的函数,如DbgPrint和DbgPrintEx)防止同一线程的非平凡重新进入。版本6.0在偏移量0x0FCA和0x17EE的SameTebFlags中将此布尔值修改为DbgInDebugPrint位字段。
  • 0xf75 FreeStackOnTermination:版本6.0中FreeStackOnTermination成员不会继续存在。无论如何,这是线程终止期间古老的防御遗物。在版本5.1之前,如果ExitThread函数仅从当前线程退出,它将切换到TEB本身的用户模式堆栈,释放栈所使用的虚拟内存,然后进入NtTerminateThread。目前还不清楚这能起到多大的作用。内核似乎不太需要大量的用户模式堆栈,但是版本5.0在TEB中将堆栈指针设置得非常低,特别是偏移0xAC。版本5.1不去管堆栈,而是设置FreeStackOnTermination,然后内核释放包含用户模式堆栈的任何虚拟内存。
  • 0xf76 HasFiberData:非零的HasFiberData记录该线程已转换为fiber,并且NtTib的Version成员改为FiberData。它在版本6.0中继续作为SameTebFlags中的DbgHasFiberData位字段。Fiber(纤程)是一种最轻量化的线程。
  • 0xf77 IdealProcessor:在为该线程的第一个用户模式执行做好准备,然后当它的理想处理器(ideal processor)通过NtSetInformationThread案例的ThreadIdealProcessor(0x0D)或ThreadIdealProcessorEx(0x21)更改时,内核首先在TEB中设置IdealProcessor。注意,内核导出KeSetIdealProcessorThread本身并没有在TEB中设置IdealProcessor。
      4字节联合会准确地建模,在版本6.1及更高版本中内核为ideal processor设置的内容有些混乱。内核确实设置了一个PROCESSOR_NUMBER,其中16位组和8位数字作为前三个字节,但是0可能会被保留为第四个字节,内核会复制这个数字。这样做的好处是,从版本5.1或更高版本开始,一个8位的IdealProcessor就可以保持相同的偏移量。直到10.0版本,NTDLL仍然有使用它的代码!
  • 0xf78 Spare3:备用字节。
  • 0xf7c ReservedForPerf
  • 0xf80 ReservedForOle:Windows 2000 only。winternl.h
  • 0xf84 WaitingOnLoaderLock:被称为NTDLL加载器锁的特殊临界区对一些程序员造成了无穷无尽的焦虑,但对另一些程序员来说可能还不够。顾名思义,WaitingOnLoaderLock通常为零,但是,NTDLL不只是“spin”争用的临界区,实际上会等待,结果是临界区为加载器锁时,WaitingOnLoaderLock会递增。
  • 0xf88 Wx86Thread:目前还不知道Wx86Thread的用途。无论它的用途是什么,无论何时它被首次定义,当Windows为32位和64位构建时,它无论如何都会被丢弃。
  • 0xf94 TlsExpansionSlots
  • 0xf98 ImpersonationLocale
  • 0xf9c IsImpersonating
  • 0xfa0 NlsCache
  • 0xfa4 pShimData
  • 0xfa8 HeapVirtualAffinity:与LFH(低碎片堆)相关。
  • 0xfac CurrentTransactionHandle
  • 0xfb0 ActiveFrame
  • 0xfb4 SafeThunkCall
  • 0xfb5 BooleanSpare

_NT_TIB

  TIB(Thread Information Block: 线程信息块)是保存线程基本信息的数据结构。在用户模式下,其位于TEB(Thread Environment Block: 线程环境块)的头部,而TEB是操作系统为了保存每个线程的私有数据创建的,每个线程都有自己的TEB。

1
2
3
4
5
6
7
8
9
10
0:000> dt _NT_TIB
ntdll!_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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//0x1c bytes (sizeof)
struct _NT_TIB
{
struct _EXCEPTION_REGISTRATION_RECORD* ExceptionList; //0x0
VOID* StackBase; //0x4
VOID* StackLimit; //0x8
VOID* SubSystemTib; //0xc
union
{
VOID* FiberData; //0x10
ULONG Version; //0x10
};
VOID* ArbitraryUserPointer; //0x14
struct _NT_TIB* Self; //0x18
};
  • 0x000 ExceptionList:ExceptionList成员指向_EXCEPTION_REGISTRATION_RECORD结构体组成的链表,它用于Windows的SEH。SEH链表的链表头就放在此成员中,当程序发生异常时,会从此结构中得到SEH链表的表头,然后通过遍历SEH链表找到一个合适的异常处理程序进行异常处理。
  • 0x004 StackBase:当前线程所使用的栈的栈底(高地址)。
  • 0x008 StackLimit:当前线程所使用的栈的栈底(低地址)。
  • 0x00c SubSystemTib
  • 0x010 FiberData:纤程数据。
  • 0x010 Version
  • 0x014 ArbitraryUserPointer
  • 0x018 Self:指向TIB结构自身。通过fs:[0x18]可以得到TEB结构的地址,NtCurrentTeb()函数中就是通过这种方法获取TEB结构的地址的。

_CLIENT_ID

1
2
3
4
0:000> dt _CLIENT_ID
ntdll!_CLIENT_ID
+0x000 UniqueProcess : Ptr32 Void
+0x004 UniqueThread : Ptr32 Void
1
2
3
4
5
6
//0x8 bytes (sizeof)
struct _CLIENT_ID
{
VOID* UniqueProcess; //0x0
VOID* UniqueThread; //0x4
};
  • 0x000 UniqueProcess:PID(Process Identifier),GetCurrentProcessId()获取的值。
  • 0x004 UniqueThread:TID(Thread Identifier),GetCurrentThreadId()获取的值。

_PEB

  见下方。

_ACTIVATION_CONTEXT_STACK

1
2
3
4
5
6
0:000> dt _ACTIVATION_CONTEXT_STACK
ntdll!_ACTIVATION_CONTEXT_STACK
+0x000 Flags : Uint4B
+0x004 NextCookieSequenceNumber : Uint4B
+0x008 ActiveFrame : Ptr32 Void
+0x00c FrameListCache : _LIST_ENTRY
1
2
3
4
5
6
7
8
//0x14 bytes (sizeof)
struct _ACTIVATION_CONTEXT_STACK
{
ULONG Flags; //0x0
ULONG NextCookieSequenceNumber; //0x4
VOID* ActiveFrame; //0x8
struct _LIST_ENTRY FrameListCache; //0xc
};

_GDI_TEB_BATCH

1
2
3
4
5
0:000> dt _GDI_TEB_BATCH
ntdll!_GDI_TEB_BATCH
+0x000 Offset : Uint4B
+0x004 HDC : Uint4B
+0x008 Buffer : [310] Uint4B
1
2
3
4
5
6
7
//0x4e0 bytes (sizeof)
struct _GDI_TEB_BATCH
{
ULONG Offset; //0x0
ULONG HDC; //0x4
ULONG Buffer[310]; //0x8
};

_UNICODE_STRING

  存储Unicode字符串的结构。

1
2
3
4
5
0:000> dt _UNICODE_STRING
ntdll!_UNICODE_STRING
+0x000 Length : Uint2B
+0x002 MaximumLength : Uint2B
+0x004 Buffer : Ptr32 Uint2B
1
2
3
4
5
6
7
//0x8 bytes (sizeof)
struct _UNICODE_STRING
{
USHORT Length; //0x0
USHORT MaximumLength; //0x2
USHORT* Buffer; //0x4
};
  • 0x000 Length:存储的Unicode字符串的长度。
  • 0x002 MaximumLength:能够存储的Unicode字符串的最大长度。
  • 0x004 Buffer:存储Unicode字符串的缓冲区。

_LIST_ENTRY

  双链表结构体。

1
2
3
4
0:000> dt _LIST_ENTRY
ntdll!_LIST_ENTRY
+0x000 Flink : Ptr32 _LIST_ENTRY
+0x004 Blink : Ptr32 _LIST_ENTRY
1
2
3
4
5
6
//0x8 bytes (sizeof)
struct _LIST_ENTRY
{
struct _LIST_ENTRY* Flink; //0x0
struct _LIST_ENTRY* Blink; //0x4
};
  • 0x000 Flink:双链表的前向指针。
  • 0x004 Blink:双链表的后向指针。

_Wx86ThreadState

1
2
3
4
5
6
0:000> dt _Wx86ThreadState
ntdll!_Wx86ThreadState
+0x000 CallBx86Eip : Ptr32 Uint4B
+0x004 DeallocationCpu : Ptr32 Void
+0x008 UseKnownWx86Dll : UChar
+0x009 OleStubInvoked : Char
1
2
3
4
5
6
7
8
//0xc bytes (sizeof)
struct _Wx86ThreadState
{
ULONG* CallBx86Eip; //0x0
VOID* DeallocationCpu; //0x4
UCHAR UseKnownWx86Dll; //0x8
CHAR OleStubInvoked; //0x9
};

_TEB_ACTIVE_FRAME

1
2
3
4
5
0:000> dt _TEB_ACTIVE_FRAME
ntdll!_TEB_ACTIVE_FRAME
+0x000 Flags : Uint4B
+0x004 Previous : Ptr32 _TEB_ACTIVE_FRAME
+0x008 Context : Ptr32 _TEB_ACTIVE_FRAME_CONTEXT
1
2
3
4
5
6
7
//0xc bytes (sizeof)
struct _TEB_ACTIVE_FRAME
{
ULONG Flags; //0x0
struct _TEB_ACTIVE_FRAME* Previous; //0x4
struct _TEB_ACTIVE_FRAME_CONTEXT* Context; //0x8
};
1
2
3
4
0:000> dt _TEB_ACTIVE_FRAME_CONTEXT
ntdll!_TEB_ACTIVE_FRAME_CONTEXT
+0x000 Flags : Uint4B
+0x004 FrameName : Ptr32 Char
1
2
3
4
5
6
//0x8 bytes (sizeof)
struct _TEB_ACTIVE_FRAME_CONTEXT
{
ULONG Flags; //0x0
CHAR* FrameName; //0x4
};

Windows 7 SP1 x86

_TEB

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
0:001> dt _TEB
ntdll!_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
+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
+0x0c4 CurrentLocale : Uint4B
+0x0c8 FpSoftwareStatusRegister : Uint4B
+0x0cc SystemReserved1 : [54] Ptr32 Void
+0x1a4 ExceptionCode : Int4B
+0x1a8 ActivationContextStackPointer : Ptr32 _ACTIVATION_CONTEXT_STACK
+0x1ac SpareBytes : [36] UChar
+0x1d0 TxFsContext : Uint4B
+0x1d4 GdiTebBatch : _GDI_TEB_BATCH
+0x6b4 RealClientId : _CLIENT_ID
+0x6bc GdiCachedProcessHandle : Ptr32 Void
+0x6c0 GdiClientPID : Uint4B
+0x6c4 GdiClientTID : Uint4B
+0x6c8 GdiThreadLocalInfo : Ptr32 Void
+0x6cc Win32ClientInfo : [62] Uint4B
+0x7c4 glDispatchTable : [233] Ptr32 Void
+0xb68 glReserved1 : [29] Uint4B
+0xbdc glReserved2 : Ptr32 Void
+0xbe0 glSectionInfo : Ptr32 Void
+0xbe4 glSection : Ptr32 Void
+0xbe8 glTable : Ptr32 Void
+0xbec glCurrentRC : Ptr32 Void
+0xbf0 glContext : Ptr32 Void
+0xbf4 LastStatusValue : Uint4B
+0xbf8 StaticUnicodeString : _UNICODE_STRING
+0xc00 StaticUnicodeBuffer : [261] Wchar
+0xe0c DeallocationStack : Ptr32 Void
+0xe10 TlsSlots : [64] Ptr32 Void
+0xf10 TlsLinks : _LIST_ENTRY
+0xf18 Vdm : Ptr32 Void
+0xf1c ReservedForNtRpc : Ptr32 Void
+0xf20 DbgSsReserved : [2] Ptr32 Void
+0xf28 HardErrorMode : Uint4B
+0xf2c Instrumentation : [9] Ptr32 Void
+0xf50 ActivityId : _GUID
+0xf60 SubProcessTag : Ptr32 Void
+0xf64 EtwLocalData : Ptr32 Void
+0xf68 EtwTraceData : Ptr32 Void
+0xf6c WinSockData : Ptr32 Void
+0xf70 GdiBatchCount : Uint4B
+0xf74 CurrentIdealProcessor : _PROCESSOR_NUMBER
+0xf74 IdealProcessorValue : Uint4B
+0xf74 ReservedPad0 : UChar
+0xf75 ReservedPad1 : UChar
+0xf76 ReservedPad2 : UChar
+0xf77 IdealProcessor : UChar
+0xf78 GuaranteedStackBytes : Uint4B
+0xf7c ReservedForPerf : Ptr32 Void
+0xf80 ReservedForOle : Ptr32 Void
+0xf84 WaitingOnLoaderLock : Uint4B
+0xf88 SavedPriorityState : Ptr32 Void
+0xf8c SoftPatchPtr1 : Uint4B
+0xf90 ThreadPoolData : Ptr32 Void
+0xf94 TlsExpansionSlots : Ptr32 Ptr32 Void
+0xf98 MuiGeneration : Uint4B
+0xf9c IsImpersonating : Uint4B
+0xfa0 NlsCache : Ptr32 Void
+0xfa4 pShimData : Ptr32 Void
+0xfa8 HeapVirtualAffinity : Uint4B
+0xfac CurrentTransactionHandle : Ptr32 Void
+0xfb0 ActiveFrame : Ptr32 _TEB_ACTIVE_FRAME
+0xfb4 FlsData : Ptr32 Void
+0xfb8 PreferredLanguages : Ptr32 Void
+0xfbc UserPrefLanguages : Ptr32 Void
+0xfc0 MergedPrefLanguages : Ptr32 Void
+0xfc4 MuiImpersonation : Uint4B
+0xfc8 CrossTebFlags : Uint2B
+0xfc8 SpareCrossTebBits : Pos 0, 16 Bits
+0xfca SameTebFlags : Uint2B
+0xfca SafeThunkCall : Pos 0, 1 Bit
+0xfca InDebugPrint : Pos 1, 1 Bit
+0xfca HasFiberData : Pos 2, 1 Bit
+0xfca SkipThreadAttach : Pos 3, 1 Bit
+0xfca WerInShipAssertCode : Pos 4, 1 Bit
+0xfca RanProcessInit : Pos 5, 1 Bit
+0xfca ClonedThread : Pos 6, 1 Bit
+0xfca SuppressDebugMsg : Pos 7, 1 Bit
+0xfca DisableUserStackWalk : Pos 8, 1 Bit
+0xfca RtlExceptionAttached : Pos 9, 1 Bit
+0xfca InitialThread : Pos 10, 1 Bit
+0xfca SpareSameTebBits : Pos 11, 5 Bits
+0xfcc TxnScopeEnterCallback : Ptr32 Void
+0xfd0 TxnScopeExitCallback : Ptr32 Void
+0xfd4 TxnScopeContext : Ptr32 Void
+0xfd8 LockCount : Uint4B
+0xfdc SpareUlong0 : Uint4B
+0xfe0 ResourceRetValue : Ptr32 Void
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
//0xfe4 bytes (sizeof)
struct _TEB
{
struct _NT_TIB NtTib; //0x0
VOID* EnvironmentPointer; //0x1c
struct _CLIENT_ID ClientId; //0x20
VOID* ActiveRpcHandle; //0x28
VOID* ThreadLocalStoragePointer; //0x2c
struct _PEB* ProcessEnvironmentBlock; //0x30
ULONG LastErrorValue; //0x34
ULONG CountOfOwnedCriticalSections; //0x38
VOID* CsrClientThread; //0x3c
VOID* Win32ThreadInfo; //0x40
ULONG User32Reserved[26]; //0x44
ULONG UserReserved[5]; //0xac
VOID* WOW32Reserved; //0xc0
ULONG CurrentLocale; //0xc4
ULONG FpSoftwareStatusRegister; //0xc8
VOID* SystemReserved1[54]; //0xcc
LONG ExceptionCode; //0x1a4
struct _ACTIVATION_CONTEXT_STACK* ActivationContextStackPointer; //0x1a8
UCHAR SpareBytes[36]; //0x1ac
ULONG TxFsContext; //0x1d0
struct _GDI_TEB_BATCH GdiTebBatch; //0x1d4
struct _CLIENT_ID RealClientId; //0x6b4
VOID* GdiCachedProcessHandle; //0x6bc
ULONG GdiClientPID; //0x6c0
ULONG GdiClientTID; //0x6c4
VOID* GdiThreadLocalInfo; //0x6c8
ULONG Win32ClientInfo[62]; //0x6cc
VOID* glDispatchTable[233]; //0x7c4
ULONG glReserved1[29]; //0xb68
VOID* glReserved2; //0xbdc
VOID* glSectionInfo; //0xbe0
VOID* glSection; //0xbe4
VOID* glTable; //0xbe8
VOID* glCurrentRC; //0xbec
VOID* glContext; //0xbf0
ULONG LastStatusValue; //0xbf4
struct _UNICODE_STRING StaticUnicodeString; //0xbf8
WCHAR StaticUnicodeBuffer[261]; //0xc00
VOID* DeallocationStack; //0xe0c
VOID* TlsSlots[64]; //0xe10
struct _LIST_ENTRY TlsLinks; //0xf10
VOID* Vdm; //0xf18
VOID* ReservedForNtRpc; //0xf1c
VOID* DbgSsReserved[2]; //0xf20
ULONG HardErrorMode; //0xf28
VOID* Instrumentation[9]; //0xf2c
struct _GUID ActivityId; //0xf50
VOID* SubProcessTag; //0xf60
VOID* EtwLocalData; //0xf64
VOID* EtwTraceData; //0xf68
VOID* WinSockData; //0xf6c
ULONG GdiBatchCount; //0xf70
union
{
struct _PROCESSOR_NUMBER CurrentIdealProcessor; //0xf74
ULONG IdealProcessorValue; //0xf74
struct
{
UCHAR ReservedPad0; //0xf74
UCHAR ReservedPad1; //0xf75
UCHAR ReservedPad2; //0xf76
UCHAR IdealProcessor; //0xf77
};
};
ULONG GuaranteedStackBytes; //0xf78
VOID* ReservedForPerf; //0xf7c
VOID* ReservedForOle; //0xf80
ULONG WaitingOnLoaderLock; //0xf84
VOID* SavedPriorityState; //0xf88
ULONG SoftPatchPtr1; //0xf8c
VOID* ThreadPoolData; //0xf90
VOID** TlsExpansionSlots; //0xf94
ULONG MuiGeneration; //0xf98
ULONG IsImpersonating; //0xf9c
VOID* NlsCache; //0xfa0
VOID* pShimData; //0xfa4
ULONG HeapVirtualAffinity; //0xfa8
VOID* CurrentTransactionHandle; //0xfac
struct _TEB_ACTIVE_FRAME* ActiveFrame; //0xfb0
VOID* FlsData; //0xfb4
VOID* PreferredLanguages; //0xfb8
VOID* UserPrefLanguages; //0xfbc
VOID* MergedPrefLanguages; //0xfc0
ULONG MuiImpersonation; //0xfc4
union
{
volatile USHORT CrossTebFlags; //0xfc8
USHORT SpareCrossTebBits:16; //0xfc8
};
union
{
USHORT SameTebFlags; //0xfca
struct
{
USHORT SafeThunkCall:1; //0xfca
USHORT InDebugPrint:1; //0xfca
USHORT HasFiberData:1; //0xfca
USHORT SkipThreadAttach:1; //0xfca
USHORT WerInShipAssertCode:1; //0xfca
USHORT RanProcessInit:1; //0xfca
USHORT ClonedThread:1; //0xfca
USHORT SuppressDebugMsg:1; //0xfca
USHORT DisableUserStackWalk:1; //0xfca
USHORT RtlExceptionAttached:1; //0xfca
USHORT InitialThread:1; //0xfca
USHORT SpareSameTebBits:5; //0xfca
};
};
VOID* TxnScopeEnterCallback; //0xfcc
VOID* TxnScopeExitCallback; //0xfd0
VOID* TxnScopeContext; //0xfd4
ULONG LockCount; //0xfd8
ULONG SpareUlong0; //0xfdc
VOID* ResourceRetValue; //0xfe0
};
  • 0x1a8 ActivationContextStackPointer
  • 0x1d0 TxFsContext
  • 0xf28 HardErrorMode
  • 0xf50 ActivityId
  • 0xf60 SubProcessTag
  • 0xf64 EtwLocalData
  • 0xf68 EtwTraceData
  • 0xf74 CurrentIdealProcessor
  • 0xf74 IdealProcessorValue
  • 0xf74 ReservedPad0
  • 0xf75 ReservedPad1
  • 0xf76 ReservedPad2
  • 0xf78 GuaranteedStackBytes
  • 0xf88 SavedPriorityState
  • 0xf8c SoftPatchPtr1
  • 0xf90 ThreadPoolData
  • 0xf98 MuiGeneration
  • 0xfb4 FlsData
  • 0xfb8 PreferredLanguages
  • 0xfbc UserPrefLanguages
  • 0xfc0 MergedPrefLanguages
  • 0xfc4 MuiImpersonation
  • 0xfc8 CrossTebFlags
  • 0xfc8 SpareCrossTebBits
  • 0xfca SameTebFlags
  • 0xfca SafeThunkCall
  • 0xfca InDebugPrint
  • 0xfca HasFiberData
  • 0xfca SkipThreadAttach
  • 0xfca WerInShipAssertCode
  • 0xfca RanProcessInit
  • 0xfca ClonedThread
  • 0xfca SuppressDebugMsg
  • 0xfca DisableUserStackWalk
  • 0xfca RtlExceptionAttached
  • 0xfca InitialThread
  • 0xfca SpareSameTebBits
  • 0xfcc TxnScopeEnterCallback
  • 0xfd0 TxnScopeExitCallback
  • 0xfd4 TxnScopeContext
  • 0xfd8 LockCount
  • 0xfdc SpareUlong0
  • 0xfe0 ResourceRetValue

_NT_TIB

  未变化。

_CLIENT_ID

  未变化。

_PEB

  见下方。

_ACTIVATION_CONTEXT_STACK

1
2
3
4
5
6
7
0:000> dt _ACTIVATION_CONTEXT_STACK
ole32!_ACTIVATION_CONTEXT_STACK
+0x000 ActiveFrame : Ptr32 _RTL_ACTIVATION_CONTEXT_STACK_FRAME
+0x004 FrameListCache : _LIST_ENTRY
+0x00c Flags : Uint4B
+0x010 NextCookieSequenceNumber : Uint4B
+0x014 StackId : Uint4B
1
2
3
4
5
6
7
8
9
//0x18 bytes (sizeof)
struct _ACTIVATION_CONTEXT_STACK
{
struct _RTL_ACTIVATION_CONTEXT_STACK_FRAME* ActiveFrame; //0x0
struct _LIST_ENTRY FrameListCache; //0x4
ULONG Flags; //0xc
ULONG NextCookieSequenceNumber; //0x10
ULONG StackId; //0x14
};

_GDI_TEB_BATCH

  未变化。

_UNICODE_STRING

  未变化。

_LIST_ENTRY

  未变化。

_GUID

  GUID(Globally Unique Identifier: 全局唯一标识符)是一种由算法生成的二进制长度为128位的数字标识符。在理想情况下,任何计算机和计算机集群都不会生成两个相同的GUID。在Windows平台上,GUID广泛应用于微软的产品中,用于标识如注册表项、类及接口标识、数据库、系统目录等对象。

  GUID的格式为“xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx”,其中每个x是0-9或a-f范围内的一个十六进制数。例如:6F9619FF-8B86-D011-B42D-00C04FC964FF即为有效的GUID值。

1
2
3
4
5
6
0:000> dt _GUID
ole32!_GUID
+0x000 Data1 : Uint4B
+0x004 Data2 : Uint2B
+0x006 Data3 : Uint2B
+0x008 Data4 : [8] UChar
1
2
3
4
5
6
7
8
//0x10 bytes (sizeof)
struct _GUID
{
ULONG Data1; //0x0
USHORT Data2; //0x4
USHORT Data3; //0x6
UCHAR Data4[8]; //0x8
};

_PROCESSOR_NUMBER

1
2
3
4
5
0:000> dt _PROCESSOR_NUMBER
ole32!_PROCESSOR_NUMBER
+0x000 Group : Uint2B
+0x002 Number : UChar
+0x003 Reserved : UChar
1
2
3
4
5
6
7
//0x4 bytes (sizeof)
struct _PROCESSOR_NUMBER
{
USHORT Group; //0x0
UCHAR Number; //0x2
UCHAR Reserved; //0x3
};

_TEB_ACTIVE_FRAME

  未变化。

PEB

Geoff Chappell, Software Analyst - PEB

Windows XP SP3 x86

_PEB

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
0:000> dt _PEB
ntdll!_PEB
+0x000 InheritedAddressSpace : UChar
+0x001 ReadImageFileExecOptions : UChar
+0x002 BeingDebugged : UChar
+0x003 SpareBool : UChar
+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 FastPebLockRoutine : Ptr32 Void
+0x024 FastPebUnlockRoutine : Ptr32 Void
+0x028 EnvironmentUpdateCount : Uint4B
+0x02c KernelCallbackTable : Ptr32 Void
+0x030 SystemReserved : [1] Uint4B
+0x034 AtlThunkSListPtr32 : Uint4B
+0x038 FreeList : Ptr32 _PEB_FREE_BLOCK
+0x03c TlsExpansionCounter : Uint4B
+0x040 TlsBitmap : Ptr32 Void
+0x044 TlsBitmapBits : [2] Uint4B
+0x04c ReadOnlySharedMemoryBase : Ptr32 Void
+0x050 ReadOnlySharedMemoryHeap : 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 Void
+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 ImageProcessAffinityMask : 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 Void
+0x1fc ProcessAssemblyStorageMap : Ptr32 Void
+0x200 SystemDefaultActivationContextData : Ptr32 Void
+0x204 SystemAssemblyStorageMap : Ptr32 Void
+0x208 MinimumStackCommit : Uint4B
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
//0x210 bytes (sizeof)
struct _PEB
{
UCHAR InheritedAddressSpace; //0x0
UCHAR ReadImageFileExecOptions; //0x1
UCHAR BeingDebugged; //0x2
UCHAR SpareBool; //0x3
VOID* Mutant; //0x4
VOID* ImageBaseAddress; //0x8
struct _PEB_LDR_DATA* Ldr; //0xc
struct _RTL_USER_PROCESS_PARAMETERS* ProcessParameters; //0x10
VOID* SubSystemData; //0x14
VOID* ProcessHeap; //0x18
struct _RTL_CRITICAL_SECTION* FastPebLock; //0x1c
VOID* FastPebLockRoutine; //0x20
VOID* FastPebUnlockRoutine; //0x24
ULONG EnvironmentUpdateCount; //0x28
VOID* KernelCallbackTable; //0x2c
ULONG SystemReserved[1]; //0x30
ULONG AtlThunkSListPtr32; //0x34
struct _PEB_FREE_BLOCK* FreeList; //0x38
ULONG TlsExpansionCounter; //0x3c
VOID* TlsBitmap; //0x40
ULONG TlsBitmapBits[2]; //0x44
VOID* ReadOnlySharedMemoryBase; //0x4c
VOID* ReadOnlySharedMemoryHeap; //0x50
VOID** ReadOnlyStaticServerData; //0x54
VOID* AnsiCodePageData; //0x58
VOID* OemCodePageData; //0x5c
VOID* UnicodeCaseTableData; //0x60
ULONG NumberOfProcessors; //0x64
ULONG NtGlobalFlag; //0x68
union _LARGE_INTEGER CriticalSectionTimeout; //0x70
ULONG HeapSegmentReserve; //0x78
ULONG HeapSegmentCommit; //0x7c
ULONG HeapDeCommitTotalFreeThreshold; //0x80
ULONG HeapDeCommitFreeBlockThreshold; //0x84
ULONG NumberOfHeaps; //0x88
ULONG MaximumNumberOfHeaps; //0x8c
VOID** ProcessHeaps; //0x90
VOID* GdiSharedHandleTable; //0x94
VOID* ProcessStarterHelper; //0x98
ULONG GdiDCAttributeList; //0x9c
VOID* LoaderLock; //0xa0
ULONG OSMajorVersion; //0xa4
ULONG OSMinorVersion; //0xa8
USHORT OSBuildNumber; //0xac
USHORT OSCSDVersion; //0xae
ULONG OSPlatformId; //0xb0
ULONG ImageSubsystem; //0xb4
ULONG ImageSubsystemMajorVersion; //0xb8
ULONG ImageSubsystemMinorVersion; //0xbc
ULONG ImageProcessAffinityMask; //0xc0
ULONG GdiHandleBuffer[34]; //0xc4
VOID (*PostProcessInitRoutine)(); //0x14c
VOID* TlsExpansionBitmap; //0x150
ULONG TlsExpansionBitmapBits[32]; //0x154
ULONG SessionId; //0x1d4
union _ULARGE_INTEGER AppCompatFlags; //0x1d8
union _ULARGE_INTEGER AppCompatFlagsUser; //0x1e0
VOID* pShimData; //0x1e8
VOID* AppCompatInfo; //0x1ec
struct _UNICODE_STRING CSDVersion; //0x1f0
VOID* ActivationContextData; //0x1f8
VOID* ProcessAssemblyStorageMap; //0x1fc
VOID* SystemDefaultActivationContextData; //0x200
VOID* SystemAssemblyStorageMap; //0x204
ULONG MinimumStackCommit; //0x208
};

  偏移量0x03的字节是否与在偏移量0x01和0x02的两个布尔值的定义的同时被显式标记为备用布尔值并不确定,但至少是可信的。无论如何,它从未被用作布尔值,而是开始在版本5.2中用作位字段,该版本首次使CPU对大页面的支持,以提高可执行映像的效率。各个位分开显示,描述很复杂,因为Windows 8.1删除了其中一个位(IsLegacyProcess),因此更改了用于访问其他位的掩码。

  如果仅出于有限的目的,PEB的前八个字节曾经具有单独的标识。微软为Windows NT 4.0提供的设备驱动程序工具包(DDK)中的USERKDX调试器扩展将它们作为INITIAL_PEB呈现。Windows 2000的调试器扩展也具有这种结构,并在PEB起始位置重复其成员。无论INITIAL_PEB是做什么的,它的痕迹都不会在公共符号文件中显示。

  • 0x000 InheritedAddressSpace
  • 0x001 ReadImageFileExecOptions
  • 0x002 BeingDebugged:指示当前进程当前是否正在被调试。内核设置BeingDebugged以指示该进程具有调试端口。KERNEL32函数IsDebuggerPresent(已文档化)所做的只是从当前PEB读取“BeingDebugged”。然而,PEB结构是一种内部操作系统结构,其布局在未来可能会发生变化。最好使用CheckRemoteDebuggerPresent函数代替。
  • 0x003 SpareBool
  • 0x004 Mutant

  在最初的PEB成员中,Ldr和ProcessParameters可以说是微软高层模块中使用最多的,微软最终在WINTERNL.H发布的精简版PEB中包含了它们,让全世界都知道。然而,在任何具有自我一致性的出版物中,ProcessHeap也不会落后太多:古老的KERNEL32函数GetProcessHeap(已文档化)只是从当前PEB读取ProcessHeap,但有许多Microsoft程序和DLL是自己读取ProcessHeap(就像内联使用GetProcessHeap一样)。

  • 0x008 ImageBaseAddress:开始加载Image(exe,dll)的基地址。exe文件就被加载到此处。可以通过GetModuleHandle()来获取ImageBaseAddress。
  • 0x00c Ldr:“_PEB_LDR_DATA”结构体指针。该结构体包含进程已加载模块的信息。
  • 0x010 ProcessParameters:“_RTL_USER_PROCESS_PARAMETERS”结构体指针。该结构体包含进程参数信息,比如命令行。
  • 0x014 SubSystemData:SubSystemData就像普通Windows编程中得到的任何东西一样晦涩难懂。顾名思义,它是为那些没有得到微软足够重视,无法在PEB中定义自己成员的子系统设计的。一个子系统,比如PSXDLL.DLL所支持的子系统,可以将SubSystemData指向它自己的每个进程数据集合。
  • 0x018 ProcessHeap:进程的进程默认堆的地址。也是“_HEAP”结构的地址。

  在早期版本中,NTDLL通过在PEB中不仅存储NTDLL数据中FastPebLock变量的地址,而且还提供用于获取和释放锁的两个例程的地址,来支持其导出的RtlAcquirePebLock和RtlReleasePebLock函数(未文档化)。尽管确实发生了锁是临界区并且例程只是预期的RtlEnterCriticalSection和RtlLeaveCriticalSection的情况,但是直到版本5.1才在PEB中正式化了锁的性质,直到版本5.2时NTDLL才停止将例程的地址保存在PEB中。

  您可能想知道为什么将它们保存在PEB中。毕竟,RtlAcquirePebLock和RtlReleasePebLock函数应该足以满足NTDLL之外的微软用户模式代码,并希望通过同一进程中的其他线程同步对PEB的访问。让我疑惑的是,我所知道的FastPebLock在NTDLL之外的唯一用途是在内核模式下的。此外,它还使用了早已消失的FastPebLockRoutine和FastPebUnlockRoutine成员。回溯到足够远,这是通过将RtlAcquirePebLock和RtlReleasePebLock函数的完全相同的实现链接到NTDLL和内核来实现的 - 是的,如上所述,内核从TEB中找到PEB,而TEB是通过fs寄存器找到的。版本5.1进行了重新实现,以便内核可以通过没有用户模式敏感性的结构进行转换,从而从fs寄存器到KPCR到KTHREAD到EPROCESS来指向PEB的指针。如果这种更改是出于安全考虑,那么它比毫无意义更糟糕,因为内核不仅遵循PEB中的FastPebLockRoutine和FastPebUnlockRoutine指针,而且调用它们在其用户模式地址上执行(正如它所希望的那样)NTDLL代码。不要忘记,这里无论什么都是用ring0特权执行的。

  这种对任何人都太过聪明的技巧在2003年被版本5.2去除,这当然是每个人的收获 ,然而它甚至在2008年的版本5.1的最后一个持久的服务包中被保留了下来,显然微软从未警告过任何人。在最早的版本中,它得到了广泛的使用。内核访问PEB的方式需要与其他线程(最有可能是在用户模式下)的访问同步,原因之一是内核从进程堆中分配和释放。甚至到版本5.1,对于导出的函数RtlQueryRegistryValues(文档化),这种以内核模式特权执行用户模式代码的情况仍在进行中,以扩展环境变量,其名称位于具有REG_EXPAND_SZ类型的注册表数据的百分号之间。

  • 0x01c FastPebLock:“_RTL_CRITICAL_SECTION”结构体指针。
  • 0x020 FastPebLockRoutine:RtlEnterCriticalSection函数地址。
  • 0x024 FastPebUnlockRoutine:RtlLeaveCriticalSection函数地址。
  • 0x028 EnvironmentUpdateCount:在那些拥有它的版本中,当尝试设置当前目录的距离达到NTDLL的RtlSetCurrentDirectory_U函数时,EnvironmentUpdateCount就会增加。这与任何类型的环境有什么关系尚不清楚。无论如何,Windows Vista都会用一组标志替换此计数器。
  • 0x02c KernelCallbackTable:KernelCallbackTable指向的是一个函数指针数组,以支持导出的KiUserCallbackDispatcher函数(未文档化)。这是NTDLL导出的为数不多的几个函数之一,这些函数不是由其他用户模式模块导入的,而是由内核找到的。当驱动程序(典型为WIN32K.SYS)调用内核导出KeUserModeCallback时,内核将调用该函数。当然,此NTDLL函数实际上不是由内核调用的。相反,它成为内核从Ring0到Ring3退出的目标地址。KiUserCallbackDispatcher感知到它已被调用,并且其参数中有一个KernelCallbackTable的索引。这样可以选择将执行进一步分配到更深的用户模式的位置。返回到内核模式并显示从一个调用返回到用户模式是非常重要的,因此需要有一个专用的中断号0x2B。
      USER32.DLL会在初始化期间将函数指针数组KernelCallbackTable设置到位,但要等到USER32连接到CSRSS服务器之后才能进行设置。从版本6.0开始,如果该进程是所谓的受保护进程,则首先将KernelCallbackTable指针作为UserSharedInfoPtr承担双重责任。就在连接时,它成为直接从WIN32K.SYS接收SHAREDINFO结构的辅助通道。
  • 0x030 SystemReserved
  • 0x034 AtlThunkSListPtr32
  • 0x038 FreeList:“_PEB_FREE_BLOCK”结构体指针。_PEB_FREE_BLOCK只是一个指向其类型的Next指针,可能是为了创建一个单链表和一个32位的无符号大小。建议缓存已释放的内存,但尽管FreeList是在符号文件中定义的,但在任何版本中都不知道它的用途。替代它的ApiSetMap是进程的指针,其指向NTDLL在加载dll时应用的重定向的API集模式的内核表示。内核将ApiSetMap指向的是一个进程地址空间中的只读映射。将ApiSetMap指向其他地方似乎不仅是可行的,而且是有吸引力的,无论是为了恶作剧,还是为了安全工具作为通过修补代码等技术Hook API函数的替代手段的所谓善意入侵。
  • 0x03c TlsExpansionCounter:TLS(Thread Local Storage)扩展计数。
  • 0x040 TlsBitmap
  • 0x044 TlsBitmapBits
  • 0x04c ReadOnlySharedMemoryBase
  • 0x050 ReadOnlySharedMemoryHeap:只读共享内存堆。
  • 0x054 ReadOnlyStaticServerData
  • 0x058 AnsiCodePageData
  • 0x05c OemCodePageData
  • 0x060 UnicodeCaseTableData
  • 0x064 NumberOfProcessors:处理器数量。
  • 0x068 NtGlobalFlag:NtGlobalFlag成员最初是进程对内核导出的NtGlobalFlag变量的拷贝,就像内核创建PEB时一样。在版本5.0之前,这似乎只是一个方便NTDLL来初始化它自己的(内部的)NtGlobalFlag变量的成员,而不必通过NtQuerySystemInformation调用。
  • 0x070 CriticalSectionTimeout:“_LARGE_INTEGER”有符号64位整数。
  • 0x078 HeapSegmentReserve:HeapSegment预留内存大小,以字节为单位。在该进程中创建堆时,如果RtlCreateHeap函数的参数Parameters中的SegmentReserve未设置时,所使用的默认值,默认为1MB=0x100000。
  • 0x07c HeapSegmentCommit:HeapSegment提交内存大小,以字节为单位。在该进程中创建堆时,如果RtlCreateHeap函数的参数Parameters中的SegmentCommit未设置时,所使用的默认值,默认为8KB=PAGE_SIZE*2=0x2000。
  • 0x080 HeapDeCommitTotalFreeThreshold:解除提交的总空闲空间阈值,以字节为单位。在该进程中创建堆时,如果RtlCreateHeap函数的参数Parameters中的DeCommitTotalFreeThreshold未设置时,所使用的默认值,默认为64KB=0x10000。
  • 0x084 HeapDeCommitFreeBlockThreshold:解除提交的空闲块的单块阈值,以字节为单位。在该进程中创建堆时,如果RtlCreateHeap函数的参数Parameters中的DeCommitFreeBlockThreshold未设置时,所使用的默认值,默认为4KB=PAGE_SIZE=0x1000。
  • 0x088 NumberOfHeaps:本进程中堆的数量。
  • 0x08c MaximumNumberOfHeaps:本进程中堆的最大数量。
  • 0x090 ProcessHeaps:本进程中的堆的列表。
  • 0x094 GdiSharedHandleTable
  • 0x098 ProcessStarterHelper
  • 0x09c GdiDCAttributeList
  • 0x0a0 LoaderLock:“_RTL_CRITICAL_SECTION”体结构指针,ntdll!LdrpLoaderLock。

  从OSMajorVersion开始的几个成员的关键在于,它们并不需要真正的操作系统版本号。取而代之的是,它们可以是进程中用户模式代码可以识别的任何版本号。这是否会发生取决于进程的可执行文件的IMAGE_OPTIONAL_HEADER中的Win32VersionValue。直到今天,也就是2019年3月30日,微软的文档中都写着“此成员是保留的,必须为0”。然而,如果它是非零的,就像使用链接器的未文档化的“/win32version”开关所安排的那样,则内核会使用真实的Windows版本号覆盖这些PEB成员中的值:

OsMajorVersion:Win32VersionValue的0~7位。
OSMinorVersion:Win32VersionValue的8~15位。
OSBuildNumber:Win32VersionValue的16~29位。
OSCSDVersion:IMAGE_LOAD_CONFIG_DIRECTORY的CSDVersion成员(如果非零),在版本5.0或更高版本中。
OSPlatformId:Win32VersionValue的30~31位,0、1、2和3分别映射到2(VER_PLATFORM_WIN32_NT)、3、0和1。

  • 0x0a4 OSMajorVersion:Windows的主版本号。
  • 0x0a8 OSMinorVersion:Windows的次版本号。
  • 0x0ac OSBuildNumber:Windows的构建号。
  • 0x0ae OSCSDVersion:与Windows安装的Service Pack版本有关。

HKLM\system\CurrentControlSet\control\windows\CSDVersion
未安装Service Pack:OSCSDVersion = 0
安装了Service Pack 1:OSCSDVersion = 0x100
安装了Service Pack 2:OSCSDVersion = 0x200
安装了Service Pack 3:OSCSDVersion = 0x300
以此类推。

  • 0x0b0 OSPlatformId
  • 0x0b4 ImageSubsystem
  • 0x0b8 ImageSubsystemMajorVersion
  • 0x0bc ImageSubsystemMinorVersion
  • 0x0c0 ImageProcessAffinityMask
  • 0x0c4 GdiHandleBuffer
  • 0x14c PostProcessInitRoutine
  • 0x150 TlsExpansionBitmap
  • 0x154 TlsExpansionBitmapBits
  • 0x1d4 SessionId:与当前进程相关联的终端服务会话标识符。SessionId是Microsoft在需要公开所谓的中间件对内部API的使用时文档化的两个PEB成员之一。

  AppCompatFlags和AppCompatFlagsUser成员是由APPHELP.DLL从TAG_FLAG_MASK_KERNEL(0x5005)和TAG_FLAG_MASK_USER(0x5008)标记设置的,用于SDB文件中的进程描述。在编译SDB文件所用的XML中,这两个变量分别从类型属性为KERNEL或USER的\标记中的MASK属性计算。

  • 0x1d8 AppCompatFlags:“_ULARGE_INTEGER”无符号64位整数。
  • 0x1e0 AppCompatFlagsUser:“_ULARGE_INTEGER”无符号64位整数。
  • 0x1e8 pShimData
  • 0x1ec AppCompatInfo
  • 0x1f0 CSDVersion:“_UNICODE_STRING”结构Unicode字符串,指示当前系统安装的最新Service Pack版本。如:“Service Pack 3”。
  • 0x1f8 ActivationContextData
  • 0x1fc ProcessAssemblyStorageMap
  • 0x200 SystemDefaultActivationContextData
  • 0x204 SystemAssemblyStorageMap
  • 0x208 MinimumStackCommit

_PEB_LDR_DATA

  这个结构用于存储当前进程中已加载的模块的链表。该结构拥有三个双链表(_LIST_ENTRY),InLoadOrderModuleList、InMemoryOrderModuleList、InInitializationOrderModuleList。链表中的存储的指针为_LDR_DATA_TABLE_ENTRY结构体指针,其保存一个已加载模块的信息。

1
2
3
4
5
6
7
8
9
0:000> dt _PEB_LDR_DATA
ntdll!_PEB_LDR_DATA
+0x000 Length : Uint4B
+0x004 Initialized : UChar
+0x008 SsHandle : Ptr32 Void
+0x00c InLoadOrderModuleList : _LIST_ENTRY
+0x014 InMemoryOrderModuleList : _LIST_ENTRY
+0x01c InInitializationOrderModuleList : _LIST_ENTRY
+0x024 EntryInProgress : Ptr32 Void
1
2
3
4
5
6
7
8
9
10
11
//0x28 bytes (sizeof)
struct _PEB_LDR_DATA
{
ULONG Length; //0x0
UCHAR Initialized; //0x4
VOID* SsHandle; //0x8
struct _LIST_ENTRY InLoadOrderModuleList; //0xc
struct _LIST_ENTRY InMemoryOrderModuleList; //0x14
struct _LIST_ENTRY InInitializationOrderModuleList; //0x1c
VOID* EntryInProgress; //0x24
};
  • 0x000 Length:此结构体的大小。
  • 0x004 Initialized:是否已初始化。如果设置了,则当前进程的加载器数据段已被初始化。
  • 0x008 SsHandle
  • 0x00c InLoadOrderModuleList:以加载顺序形成的已加载模块双链表。
  • 0x014 InMemoryOrderModuleList:以模块在进程虚拟地址空间中的布局顺序形成的已加载模块双链表。
  • 0x01c InInitializationOrderModuleList:以初始化顺序形成的已加载模块双链表。
  • 0x024 EntryInProgress

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
0:015> dt _LDR_DATA_TABLE_ENTRY
ntdll!_LDR_DATA_TABLE_ENTRY
+0x000 InLoadOrderLinks : _LIST_ENTRY
+0x008 InMemoryOrderLinks : _LIST_ENTRY
+0x010 InInitializationOrderLinks : _LIST_ENTRY
+0x018 DllBase : Ptr32 Void
+0x01c EntryPoint : Ptr32 Void
+0x020 SizeOfImage : Uint4B
+0x024 FullDllName : _UNICODE_STRING
+0x02c BaseDllName : _UNICODE_STRING
+0x034 Flags : Uint4B
+0x038 LoadCount : Uint2B
+0x03a TlsIndex : Uint2B
+0x03c HashLinks : _LIST_ENTRY
+0x03c SectionPointer : Ptr32 Void
+0x040 CheckSum : Uint4B
+0x044 TimeDateStamp : Uint4B
+0x044 LoadedImports : Ptr32 Void
+0x048 EntryPointActivationContext : Ptr32 Void
+0x04c PatchInformation : Ptr32 Void
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
//0x50 bytes (sizeof)
struct _LDR_DATA_TABLE_ENTRY
{
struct _LIST_ENTRY InLoadOrderLinks; //0x0
struct _LIST_ENTRY InMemoryOrderLinks; //0x8
struct _LIST_ENTRY InInitializationOrderLinks; //0x10
VOID* DllBase; //0x18
VOID* EntryPoint; //0x1c
ULONG SizeOfImage; //0x20
struct _UNICODE_STRING FullDllName; //0x24
struct _UNICODE_STRING BaseDllName; //0x2c
ULONG Flags; //0x34
USHORT LoadCount; //0x38
USHORT TlsIndex; //0x3a
union
{
struct _LIST_ENTRY HashLinks; //0x3c
struct
{
VOID* SectionPointer; //0x3c
ULONG CheckSum; //0x40
};
};
union
{
ULONG TimeDateStamp; //0x44
VOID* LoadedImports; //0x44
};
VOID* EntryPointActivationContext; //0x48
VOID* PatchInformation; //0x4c
};
  • 0x000 InLoadOrderLinks:以加载顺序形成的已加载模块双链表。
  • 0x008 InMemoryOrderLinks:以模块在进程虚拟地址空间中的布局顺序形成的已加载模块双链表。
  • 0x010 InInitializationOrderLinks:以初始化顺序形成的已加载模块双链表。
  • 0x018 DllBase:本模块加载到进程中的基址。
  • 0x01c EntryPoint:本模块的入口点地址(例如:DllMain)。
  • 0x020 SizeOfImage:本模块占用进程虚拟地址空间内存的大小。
  • 0x024 FullDllName:_UNICODE_STRING结构,本模块在硬盘上的全路径名称。
  • 0x02c BaseDllName:_UNICODE_STRING结构,本模块的模块名。
  • 0x034 Flags:针对该模块的加载器状态标志。如:LDRP_STATIC_LINK = 0x00000002
  • 0x038 LoadCount:本模块的引用计数(即它被加载的次数)
  • 0x03a TlsIndex:与本模块相关联的线程本地存储槽(Thread Local Storage Slot)。
  • 0x03c HashLinks:在进程启动和关闭期间使用的链表,以便更快地查找。
  • 0x03c SectionPointer
  • 0x040 CheckSum
  • 0x044 TimeDateStamp:当本模块被链接时由链接器写入的时间戳,加载器从该模块的映像文件的PE头中获得此时间戳信息。IMAGE_FILE_HEADER->TimeDateStamp。
  • 0x044 LoadedImports
  • 0x048 EntryPointActivationContext:包含了当调用初始化例程时的SxS/Fusion激活环境。
  • 0x04c PatchInformation:在此模块上进行热补丁操作相关的信息。

  “_PEB_LDR_DATA”结构中的InLoadOrderModuleList、InMemoryOrderModuleList、InInitializationOrderModuleList分别是以三种顺序形成的已加载模块链表的头结点,之后的链表结点中的指针都是“_LDR_DATA_TABLE_ENTRY”结构指针。每个链表结点中的指针指向的是相应结构体中的特定位置,不全是结构体的起始地址。如:“_PEB_LDR_DATA”的InLoadOrderModuleList中的指针指向的是“以加载顺序形成的已加载模块双链表”的第一个结点和最后一个结点的结构体“_LDR_DATA_TABLE_ENTRY”中的InLoadOrderLinks成员所在地址。“_PEB_LDR_DATA”的InInitializationOrderModuleList中的指针指向的是“以初始化顺序形成的已加载模块双链表”的第一个结点和最后一个结点的结构体“_LDR_DATA_TABLE_ENTRY”中的InInitializationOrderLinks成员所在地址。

_RTL_USER_PROCESS_PARAMETERS

RtlCreateProcessParameters(),RtlCreateProcessParametersEx()
RtlpInitEnvironmentBlock()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
0:000> dt _RTL_USER_PROCESS_PARAMETERS
ntdll!_RTL_USER_PROCESS_PARAMETERS
+0x000 MaximumLength : Uint4B
+0x004 Length : Uint4B
+0x008 Flags : Uint4B
+0x00c DebugFlags : Uint4B
+0x010 ConsoleHandle : Ptr32 Void
+0x014 ConsoleFlags : Uint4B
+0x018 StandardInput : Ptr32 Void
+0x01c StandardOutput : Ptr32 Void
+0x020 StandardError : Ptr32 Void
+0x024 CurrentDirectory : _CURDIR
+0x030 DllPath : _UNICODE_STRING
+0x038 ImagePathName : _UNICODE_STRING
+0x040 CommandLine : _UNICODE_STRING
+0x048 Environment : Ptr32 Void
+0x04c StartingX : Uint4B
+0x050 StartingY : Uint4B
+0x054 CountX : Uint4B
+0x058 CountY : Uint4B
+0x05c CountCharsX : Uint4B
+0x060 CountCharsY : Uint4B
+0x064 FillAttribute : Uint4B
+0x068 WindowFlags : Uint4B
+0x06c ShowWindowFlags : Uint4B
+0x070 WindowTitle : _UNICODE_STRING
+0x078 DesktopInfo : _UNICODE_STRING
+0x080 ShellInfo : _UNICODE_STRING
+0x088 RuntimeData : _UNICODE_STRING
+0x090 CurrentDirectores : [32] _RTL_DRIVE_LETTER_CURDIR
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
//0x290 bytes (sizeof)
struct _RTL_USER_PROCESS_PARAMETERS
{
ULONG MaximumLength; //0x0
ULONG Length; //0x4
ULONG Flags; //0x8
ULONG DebugFlags; //0xc
VOID* ConsoleHandle; //0x10
ULONG ConsoleFlags; //0x14
VOID* StandardInput; //0x18
VOID* StandardOutput; //0x1c
VOID* StandardError; //0x20
struct _CURDIR CurrentDirectory; //0x24
struct _UNICODE_STRING DllPath; //0x30
struct _UNICODE_STRING ImagePathName; //0x38
struct _UNICODE_STRING CommandLine; //0x40
VOID* Environment; //0x48
ULONG StartingX; //0x4c
ULONG StartingY; //0x50
ULONG CountX; //0x54
ULONG CountY; //0x58
ULONG CountCharsX; //0x5c
ULONG CountCharsY; //0x60
ULONG FillAttribute; //0x64
ULONG WindowFlags; //0x68
ULONG ShowWindowFlags; //0x6c
struct _UNICODE_STRING WindowTitle; //0x70
struct _UNICODE_STRING DesktopInfo; //0x78
struct _UNICODE_STRING ShellInfo; //0x80
struct _UNICODE_STRING RuntimeData; //0x88
struct _RTL_DRIVE_LETTER_CURDIR CurrentDirectores[32]; //0x90
};
  • 0x000 MaximumLength
  • 0x004 Length
  • 0x008 Flags
  • 0x00c DebugFlags
  • 0x010 ConsoleHandle
  • 0x014 ConsoleFlags
  • 0x018 StandardInput
  • 0x01c StandardOutput
  • 0x020 StandardError
  • 0x024 CurrentDirectory
  • 0x030 DllPath
  • 0x038 ImagePathName
  • 0x040 CommandLine
  • 0x048 Environment
  • 0x04c StartingX
  • 0x050 StartingY
  • 0x054 CountX
  • 0x058 CountY
  • 0x05c CountCharsX
  • 0x060 CountCharsY
  • 0x064 FillAttribute
  • 0x068 WindowFlags
  • 0x06c ShowWindowFlags
  • 0x070 WindowTitle
  • 0x078 DesktopInfo
  • 0x080 ShellInfo
  • 0x088 RuntimeData
  • 0x090 CurrentDirectores
1
2
3
4
0:000> dt _CURDIR
ntdll!_CURDIR
+0x000 DosPath : _UNICODE_STRING
+0x008 Handle : Ptr32 Void
1
2
3
4
5
6
//0xc bytes (sizeof)
struct _CURDIR
{
struct _UNICODE_STRING DosPath; //0x0
VOID* Handle; //0x8
};
1
2
3
4
5
6
0:000> dt _RTL_DRIVE_LETTER_CURDIR
ntdll!_RTL_DRIVE_LETTER_CURDIR
+0x000 Flags : Uint2B
+0x002 Length : Uint2B
+0x004 TimeStamp : Uint4B
+0x008 DosPath : _STRING
1
2
3
4
5
6
7
8
//0x10 bytes (sizeof)
struct _RTL_DRIVE_LETTER_CURDIR
{
USHORT Flags; //0x0
USHORT Length; //0x2
ULONG TimeStamp; //0x4
struct _STRING DosPath; //0x8
};

_RTL_CRITICAL_SECTION

ReactOS分析CriticalSection
RtlInitializeCriticalSection
RtlInitializeCriticalSectionAndSpinCount
RtlSetCriticalSectionSpinCount
RtlpCreateCriticalSectionSem
RtlpWaitForCriticalSection
RtlEnterCriticalSection
RtlLeaveCriticalSection
RtlDeleteCriticalSection

1
2
3
4
5
6
7
8
0:000> dt _RTL_CRITICAL_SECTION
ntdll!_RTL_CRITICAL_SECTION
+0x000 DebugInfo : Ptr32 _RTL_CRITICAL_SECTION_DEBUG
+0x004 LockCount : Int4B
+0x008 RecursionCount : Int4B
+0x00c OwningThread : Ptr32 Void
+0x010 LockSemaphore : Ptr32 Void
+0x014 SpinCount : Uint4B
1
2
3
4
5
6
7
8
9
10
//0x18 bytes (sizeof)
struct _RTL_CRITICAL_SECTION
{
struct _RTL_CRITICAL_SECTION_DEBUG* DebugInfo; //0x0
LONG LockCount; //0x4
LONG RecursionCount; //0x8
VOID* OwningThread; //0xc
VOID* LockSemaphore; //0x10
ULONG SpinCount; //0x14
};
1
2
3
4
5
6
7
8
9
0:000> dt _RTL_CRITICAL_SECTION_DEBUG
ntdll!_RTL_CRITICAL_SECTION_DEBUG
+0x000 Type : Uint2B
+0x002 CreatorBackTraceIndex : Uint2B
+0x004 CriticalSection : Ptr32 _RTL_CRITICAL_SECTION
+0x008 ProcessLocksList : _LIST_ENTRY
+0x010 EntryCount : Uint4B
+0x014 ContentionCount : Uint4B
+0x018 Spare : [2] Uint4B
1
2
3
4
5
6
7
8
9
10
11
//0x20 bytes (sizeof)
struct _RTL_CRITICAL_SECTION_DEBUG
{
USHORT Type; //0x0
USHORT CreatorBackTraceIndex; //0x2
struct _RTL_CRITICAL_SECTION* CriticalSection; //0x4
struct _LIST_ENTRY ProcessLocksList; //0x8
ULONG EntryCount; //0x10
ULONG ContentionCount; //0x14
ULONG Spare[2]; //0x18
};

_PEB_FREE_BLOCK

1
2
3
4
0:000> dt _PEB_FREE_BLOCK
ntdll!_PEB_FREE_BLOCK
+0x000 Next : Ptr32 _PEB_FREE_BLOCK
+0x004 Size : Uint4B
1
2
3
4
5
6
//0x8 bytes (sizeof)
struct _PEB_FREE_BLOCK
{
struct _PEB_FREE_BLOCK* Next; //0x0
ULONG Size; //0x4
};

_LARGE_INTEGER

1
2
3
4
5
6
0:000> dt _LARGE_INTEGER
ntdll!_LARGE_INTEGER
+0x000 LowPart : Uint4B
+0x004 HighPart : Int4B
+0x000 u : __unnamed
+0x000 QuadPart : Int8B
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//0x8 bytes (sizeof)
union _LARGE_INTEGER
{
struct
{
ULONG LowPart; //0x0
LONG HighPart; //0x4
};
struct
{
ULONG LowPart; //0x0
LONG HighPart; //0x4
} u; //0x0
LONGLONG QuadPart; //0x0
};

_ULARGE_INTEGER

1
2
3
4
5
6
0:000> dt _ULARGE_INTEGER
ntdll!_ULARGE_INTEGER
+0x000 LowPart : Uint4B
+0x004 HighPart : Uint4B
+0x000 u : __unnamed
+0x000 QuadPart : Uint8B
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//0x8 bytes (sizeof)
union _ULARGE_INTEGER
{
struct
{
ULONG LowPart; //0x0
ULONG HighPart; //0x4
};
struct
{
ULONG LowPart; //0x0
ULONG HighPart; //0x4
} u; //0x0
ULONGLONG QuadPart; //0x0
};

_UNICODE_STRING

  见上方。

Windows 7 SP1 x86

_PEB

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
0:001> dt 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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
//0x248 bytes (sizeof)
struct _PEB
{
UCHAR InheritedAddressSpace; //0x0
UCHAR ReadImageFileExecOptions; //0x1
UCHAR BeingDebugged; //0x2
union
{
UCHAR BitField; //0x3
struct
{
UCHAR ImageUsesLargePages:1; //0x3
UCHAR IsProtectedProcess:1; //0x3
UCHAR IsLegacyProcess:1; //0x3
UCHAR IsImageDynamicallyRelocated:1; //0x3
UCHAR SkipPatchingUser32Forwarders:1; //0x3
UCHAR SpareBits:3; //0x3
};
};
VOID* Mutant; //0x4
VOID* ImageBaseAddress; //0x8
struct _PEB_LDR_DATA* Ldr; //0xc
struct _RTL_USER_PROCESS_PARAMETERS* ProcessParameters; //0x10
VOID* SubSystemData; //0x14
VOID* ProcessHeap; //0x18
struct _RTL_CRITICAL_SECTION* FastPebLock; //0x1c
VOID* AtlThunkSListPtr; //0x20
VOID* IFEOKey; //0x24
union
{
ULONG CrossProcessFlags; //0x28
struct
{
ULONG ProcessInJob:1; //0x28
ULONG ProcessInitializing:1; //0x28
ULONG ProcessUsingVEH:1; //0x28
ULONG ProcessUsingVCH:1; //0x28
ULONG ProcessUsingFTH:1; //0x28
ULONG ReservedBits0:27; //0x28
};
};
union
{
VOID* KernelCallbackTable; //0x2c
VOID* UserSharedInfoPtr; //0x2c
};
ULONG SystemReserved[1]; //0x30
ULONG AtlThunkSListPtr32; //0x34
VOID* ApiSetMap; //0x38
ULONG TlsExpansionCounter; //0x3c
VOID* TlsBitmap; //0x40
ULONG TlsBitmapBits[2]; //0x44
VOID* ReadOnlySharedMemoryBase; //0x4c
VOID* HotpatchInformation; //0x50
VOID** ReadOnlyStaticServerData; //0x54
VOID* AnsiCodePageData; //0x58
VOID* OemCodePageData; //0x5c
VOID* UnicodeCaseTableData; //0x60
ULONG NumberOfProcessors; //0x64
ULONG NtGlobalFlag; //0x68
union _LARGE_INTEGER CriticalSectionTimeout; //0x70
ULONG HeapSegmentReserve; //0x78
ULONG HeapSegmentCommit; //0x7c
ULONG HeapDeCommitTotalFreeThreshold; //0x80
ULONG HeapDeCommitFreeBlockThreshold; //0x84
ULONG NumberOfHeaps; //0x88
ULONG MaximumNumberOfHeaps; //0x8c
VOID** ProcessHeaps; //0x90
VOID* GdiSharedHandleTable; //0x94
VOID* ProcessStarterHelper; //0x98
ULONG GdiDCAttributeList; //0x9c
struct _RTL_CRITICAL_SECTION* LoaderLock; //0xa0
ULONG OSMajorVersion; //0xa4
ULONG OSMinorVersion; //0xa8
USHORT OSBuildNumber; //0xac
USHORT OSCSDVersion; //0xae
ULONG OSPlatformId; //0xb0
ULONG ImageSubsystem; //0xb4
ULONG ImageSubsystemMajorVersion; //0xb8
ULONG ImageSubsystemMinorVersion; //0xbc
ULONG ActiveProcessAffinityMask; //0xc0
ULONG GdiHandleBuffer[34]; //0xc4
VOID (*PostProcessInitRoutine)(); //0x14c
VOID* TlsExpansionBitmap; //0x150
ULONG TlsExpansionBitmapBits[32]; //0x154
ULONG SessionId; //0x1d4
union _ULARGE_INTEGER AppCompatFlags; //0x1d8
union _ULARGE_INTEGER AppCompatFlagsUser; //0x1e0
VOID* pShimData; //0x1e8
VOID* AppCompatInfo; //0x1ec
struct _UNICODE_STRING CSDVersion; //0x1f0
struct _ACTIVATION_CONTEXT_DATA* ActivationContextData; //0x1f8
struct _ASSEMBLY_STORAGE_MAP* ProcessAssemblyStorageMap; //0x1fc
struct _ACTIVATION_CONTEXT_DATA* SystemDefaultActivationContextData; //0x200
struct _ASSEMBLY_STORAGE_MAP* SystemAssemblyStorageMap; //0x204
ULONG MinimumStackCommit; //0x208
struct _FLS_CALLBACK_INFO* FlsCallback; //0x20c
struct _LIST_ENTRY FlsListHead; //0x210
VOID* FlsBitmap; //0x218
ULONG FlsBitmapBits[4]; //0x21c
ULONG FlsHighIndex; //0x22c
VOID* WerRegistrationData; //0x230
VOID* WerShipAssertPtr; //0x234
VOID* pContextData; //0x238
VOID* pImageHeaderHash; //0x23c
union
{
ULONG TracingFlags; //0x240
struct
{
ULONG HeapTracingEnabled:1; //0x240
ULONG CritSecTracingEnabled:1; //0x240
ULONG SpareTracingBits:30; //0x240
};
};
};

_PEB_LDR_DATA

1
2
3
4
5
6
7
8
9
10
11
0:001> dt _PEB_LDR_DATA
uxtheme!_PEB_LDR_DATA
+0x000 Length : Uint4B
+0x004 Initialized : UChar
+0x008 SsHandle : Ptr32 Void
+0x00c InLoadOrderModuleList : _LIST_ENTRY
+0x014 InMemoryOrderModuleList : _LIST_ENTRY
+0x01c InInitializationOrderModuleList : _LIST_ENTRY
+0x024 EntryInProgress : Ptr32 Void
+0x028 ShutdownInProgress : UChar
+0x02c ShutdownThreadId : Ptr32 Void
1
2
3
4
5
6
7
8
9
10
11
12
13
//0x30 bytes (sizeof)
struct _PEB_LDR_DATA
{
ULONG Length; //0x0
UCHAR Initialized; //0x4
VOID* SsHandle; //0x8
struct _LIST_ENTRY InLoadOrderModuleList; //0xc
struct _LIST_ENTRY InMemoryOrderModuleList; //0x14
struct _LIST_ENTRY InInitializationOrderModuleList; //0x1c
VOID* EntryInProgress; //0x24
UCHAR ShutdownInProgress; //0x28
VOID* ShutdownThreadId; //0x2c
};

_RTL_USER_PROCESS_PARAMETERS

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
0:001> dt _RTL_USER_PROCESS_PARAMETERS
uxtheme!_RTL_USER_PROCESS_PARAMETERS
+0x000 MaximumLength : Uint4B
+0x004 Length : Uint4B
+0x008 Flags : Uint4B
+0x00c DebugFlags : Uint4B
+0x010 ConsoleHandle : Ptr32 Void
+0x014 ConsoleFlags : Uint4B
+0x018 StandardInput : Ptr32 Void
+0x01c StandardOutput : Ptr32 Void
+0x020 StandardError : Ptr32 Void
+0x024 CurrentDirectory : _CURDIR
+0x030 DllPath : _UNICODE_STRING
+0x038 ImagePathName : _UNICODE_STRING
+0x040 CommandLine : _UNICODE_STRING
+0x048 Environment : Ptr32 Void
+0x04c StartingX : Uint4B
+0x050 StartingY : Uint4B
+0x054 CountX : Uint4B
+0x058 CountY : Uint4B
+0x05c CountCharsX : Uint4B
+0x060 CountCharsY : Uint4B
+0x064 FillAttribute : Uint4B
+0x068 WindowFlags : Uint4B
+0x06c ShowWindowFlags : Uint4B
+0x070 WindowTitle : _UNICODE_STRING
+0x078 DesktopInfo : _UNICODE_STRING
+0x080 ShellInfo : _UNICODE_STRING
+0x088 RuntimeData : _UNICODE_STRING
+0x090 CurrentDirectores : [32] _RTL_DRIVE_LETTER_CURDIR
+0x290 EnvironmentSize : Uint4B
+0x294 EnvironmentVersion : Uint4B
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
//0x298 bytes (sizeof)
struct _RTL_USER_PROCESS_PARAMETERS
{
ULONG MaximumLength; //0x0
ULONG Length; //0x4
ULONG Flags; //0x8
ULONG DebugFlags; //0xc
VOID* ConsoleHandle; //0x10
ULONG ConsoleFlags; //0x14
VOID* StandardInput; //0x18
VOID* StandardOutput; //0x1c
VOID* StandardError; //0x20
struct _CURDIR CurrentDirectory; //0x24
struct _UNICODE_STRING DllPath; //0x30
struct _UNICODE_STRING ImagePathName; //0x38
struct _UNICODE_STRING CommandLine; //0x40
VOID* Environment; //0x48
ULONG StartingX; //0x4c
ULONG StartingY; //0x50
ULONG CountX; //0x54
ULONG CountY; //0x58
ULONG CountCharsX; //0x5c
ULONG CountCharsY; //0x60
ULONG FillAttribute; //0x64
ULONG WindowFlags; //0x68
ULONG ShowWindowFlags; //0x6c
struct _UNICODE_STRING WindowTitle; //0x70
struct _UNICODE_STRING DesktopInfo; //0x78
struct _UNICODE_STRING ShellInfo; //0x80
struct _UNICODE_STRING RuntimeData; //0x88
struct _RTL_DRIVE_LETTER_CURDIR CurrentDirectores[32]; //0x90
volatile ULONG EnvironmentSize; //0x290
volatile ULONG EnvironmentVersion; //0x294
};

_RTL_CRITICAL_SECTION

  见上方。

_ULARGE_INTEGER

  未变化。

_UNICODE_STRING

  见上方。

_ACTIVATION_CONTEXT_DATA

1
2
3
4
5
6
7
8
9
10
0:001> dt _ACTIVATION_CONTEXT_DATA
ole32!_ACTIVATION_CONTEXT_DATA
+0x000 Magic : Uint4B
+0x004 HeaderSize : Uint4B
+0x008 FormatVersion : Uint4B
+0x00c TotalSize : Uint4B
+0x010 DefaultTocOffset : Uint4B
+0x014 ExtendedTocOffset : Uint4B
+0x018 AssemblyRosterOffset : Uint4B
+0x01c Flags : Uint4B
1
2
3
4
5
6
7
8
9
10
typedef struct _ACTIVATION_CONTEXT_DATA {
ULONG Magic;
ULONG HeaderSize;
ULONG FormatVersion;
ULONG TotalSize;
ULONG DefaultTocOffset;
ULONG ExtendedTocOffset;
ULONG AssemblyRosterOffset;
ULONG Flags;
} ACTIVATION_CONTEXT_DATA, *PACTIVATION_CONTEXT_DATA;

_ASSEMBLY_STORAGE_MAP

  未知。

_FLS_CALLBACK_INFO

  未知。

_LIST_ENTRY

  见上方。

Reference

1、Geoff Chappell, Software Analyst - TEB
2、Geoff Chappell, Software Analyst - PEB
3、Windows Internals, 6ed, Part 1 - 3.10 Image Loader
4、Windows DLL Loader

文章目录
  1. TEB
    1. Windows XP SP3 x86
      1. _TEB
      2. _NT_TIB
      3. _CLIENT_ID
      4. _PEB
      5. _ACTIVATION_CONTEXT_STACK
      6. _GDI_TEB_BATCH
      7. _UNICODE_STRING
      8. _LIST_ENTRY
      9. _Wx86ThreadState
      10. _TEB_ACTIVE_FRAME
    2. Windows 7 SP1 x86
      1. _TEB
      2. _NT_TIB
      3. _CLIENT_ID
      4. _PEB
      5. _ACTIVATION_CONTEXT_STACK
      6. _GDI_TEB_BATCH
      7. _UNICODE_STRING
      8. _LIST_ENTRY
      9. _GUID
      10. _PROCESSOR_NUMBER
      11. _TEB_ACTIVE_FRAME
  2. PEB
    1. Windows XP SP3 x86
      1. _PEB
      2. _PEB_LDR_DATA
      3. _RTL_USER_PROCESS_PARAMETERS
      4. _RTL_CRITICAL_SECTION
      5. _PEB_FREE_BLOCK
      6. _LARGE_INTEGER
      7. _ULARGE_INTEGER
      8. _UNICODE_STRING
    2. Windows 7 SP1 x86
      1. _PEB
      2. _PEB_LDR_DATA
      3. _RTL_USER_PROCESS_PARAMETERS
      4. _RTL_CRITICAL_SECTION
      5. _ULARGE_INTEGER
      6. _UNICODE_STRING
      7. _ACTIVATION_CONTEXT_DATA
      8. _ASSEMBLY_STORAGE_MAP
      9. _FLS_CALLBACK_INFO
      10. _LIST_ENTRY
  3. Reference