我试图获得自己的PEB并获得自己的模块地址。我写了一个简单的代码:
PLIST_ENTRY myModule = (PLIST_ENTRY)pebLdr->InMemoryOrderModuleList.Flink;
PLDR_DATA_TABLE_ENTRY myImageBase = (PLDR_DATA_TABLE_ENTRY)myModule;
PIMAGE_DOS_HEADER dosHeader = (PIMAGE_DOS_HEADER)myImageBase->DllBase;
但我在dosHeader
中没有看到正确的PE标题。这就是我在dosHeader
变量e_magic=???,e_cblp=???
中的MSVC调试器中看到的内容。为什么我不能得到自己的标题?我检查了所有内容,我正在记录所有内容,我可以在pData->FullDllName
中看到我的exe名称,一切似乎都是正确的,DllBase
有意义它不是null或类似{{1} }。是否有任何特定的事情要做,可能是地址计算?
答案 0 :(得分:3)
你无法做到
PLDR_DATA_TABLE_ENTRY myImageBase = (PLDR_DATA_TABLE_ENTRY)myModule;
因为InMemoryOrderLinks
不是LDR_DATA_TABLE_ENTRY
中的第一个字段。相反,您应该参与CONTAINING_RECORD()
宏:
PLIST_ENTRY le = (PLIST_ENTRY)pebLdr->InMemoryOrderModuleList.Flink;
PLDR_DATA_TABLE_ENTRY mainModule = CONTAINING_RECORD(le, LDR_DATA_TABLE_ENTRY, InMemoryOrderLinks);
PIMAGE_DOS_HEADER dosHeader = (PIMAGE_DOS_HEADER)mainModule->DllBase;
最重要的是:您可以自由地遍历LIST_ENTRY
' es的双向链接循环列表,并获取您应该使用CONTAINING_RECORD()
的实际节点数据。请注意,驻留在PEB_LDR_DATA
中的节点是专用的,没有关联的数据。你应该只使用它作为你已经遍历整个列表的标志。