Winapi PEB_LDR_数据结构具有不同的成员和大小

Winapi PEB_LDR_数据结构具有不同的成员和大小,winapi,Winapi,PEB结构包含过程信息,PEB_LDR_DATA结构的指针(包含过程加载模块的信息)是PEB成员之一 从MSDN中,PEB结构语法如下: typedef struct _PEB { BYTE Reserved1[2]; BYTE BeingDebugged; BYTE Reserved2[1]; PVOID

PEB
结构包含过程信息,
PEB_LDR_DATA
结构的指针(包含过程加载模块的信息)是
PEB
成员之一

从MSDN中,
PEB
结构语法如下:

typedef struct _PEB {
    BYTE                          Reserved1[2];
    BYTE                          BeingDebugged;
    BYTE                          Reserved2[1];
    PVOID                         Reserved3[2];
    PPEB_LDR_DATA                 Ldr;                 <-- I'm curious about this one.
    PRTL_USER_PROCESS_PARAMETERS  ProcessParameters;
    BYTE                          Reserved4[104];
    PVOID                         Reserved5[52];
    PPS_POST_PROCESS_INIT_ROUTINE PostProcessInitRoutine;
    BYTE                          Reserved6[128];
    PVOID                         Reserved7[1];
    ULONG                         SessionId;
} PEB, *PPEB;

它们怎么可能有不同的成员和大小?

这些基本上是内部未记录的数据结构,可以在版本之间甚至服务包之间更改。开始时,只有TEB/TIB的前几个字段是可用的,因为编译器使用它们来实现SEH和TLS

随着时间的推移,人们发现了一些其他字段,并开始使用它们,这实际上迫使微软对它们进行记录。所有其他成员都有保留名称,因为Microsoft不希望您使用这些名称,因为可能有一个文档化的API用于此名称,或者将来可能会更改

在32位Windows 8上,PEB_LDR_数据结构如下所示:

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
符号并非总是100%正确,但在处理这些类型的结构时,符号通常是最好的来源。这与您发布的结构的内存布局相匹配(表单#2除外,它错误地将DWORD用作布尔值)。必须在检查长度成员(或Windows版本)后才能访问列表项之外的任何内容,因为它们在旧版本中不存在

大小可以不同,因为随着时间的推移已添加了新字段。成员可以是不同的,因为字段实际上随着时间的推移而改变,但更可能是一个bug,因为有人对字段使用了不同的名称/类型


如果您的目标是列出已加载的模块,那么您可以使用文档化的…

不同的表格来表示不同的机器体系结构。请阅读条件句。@DavidHeffernan您能再解释一下吗?我知道结构的大小可以根据机器的结构而变化。但我不明白如何才能将表2中的成员之一
LPVOID lpEntryInProgress
排除在表3之外。请阅读您从本文中删除的条件。它们根据体系结构定义各种形式。初始化的
布尔值
-1字节,而不是
DWORD
(4字节),如形式2所示。同样在xp和vista中,在结构的末尾添加了额外的成员(当某些结构被扩展时,这通常适用于windows)。正确的定义,例如这里-@ChangUk-不,这是一个严重的错误<代码>已初始化
正好占用1个字节。接下来的3或7个字节是垃圾,未定义。将其读作DWORD,可能会产生错误的结果(假设1字节为0,但4字节不能为0)。这是一般说明
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