【旧文章搬运】《从PEB获取内存中模块列表》的补充

原文发表于百度空间,2008-7-26
==========================================================================

继续研究PEB,这时候才发现之前写《从PEB获取内存中模块列表》一文时出现的错误.
下面是一个结构:

typedef struct _LDR_MODULE
{
LIST_ENTRY          InLoadOrderModuleList;
LIST_ENTRY          InMemoryOrderModuleList; 
LIST_ENTRY          InInitializationOrderModuleList; 
void*               BaseAddress; 
void*               EntryPoint;   
ULONG               SizeOfImage;
UNICODE_STRING   FullDllName;
UNICODE_STRING      BaseDllName;
ULONG               Flags;
SHORT               LoadCount;
SHORT               TlsIndex;
HANDLE              SectionHandle;
ULONG               CheckSum;
ULONG               TimeDateStamp;
} LDR_MODULE, *PLDR_MODULE;

从这个结构可以知道,如果按InLoadOrderModuleList遍历,那么InLoadOrderModuleList这个结构的地址就是LDR_MODULE结构的地址,但是如果按InMemoryOrderModuleList这个链表来遍历时,得到的下一个链表地址必须减去前面InLoadOrderModuleList这个结构所占的空间,得到的地址才是LDR_MODULE的地址,相应的,如果用第三个链表遍历的话,就要减去两个LIST_ENTRY的大小了.《从PEB获取内存中模块列表》一文中的代码和结果已修正.

正确写法如下:
pListEntry=(LIST_ENTRY*)(PUCHAR)&(pPEBLDR->InInitializationOrderModuleList); //如果使用这个链表
pLdrMod=(LDR_MODULE*)( (char*) pListEntry-sizeof(LIST_ENTRY)*2); //要减去两个LIST_ENTRY大小

注意红色部分,之前就是因为没有写这个,导致一直得不到正确结果,长点教训哦~
PS: 好像遍历这个链表得到的模块列表并不全面...

原文地址:https://www.cnblogs.com/achillis/p/10179754.html