【旧文章搬运】《从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: 好像遍历这个链表得到的模块列表并不全面...