Vlad
Vlad

Reputation: 381

PEB (Process Environment Block) invalid DllBase address

I trying to get my own PEB and get my own module address. i wrote a simple code like this:

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;

But i dont see a proper PE header in dosHeader. This is what i see in the MSVC debugger in dosHeader variable : e_magic=???,e_cblp=??? . Why cant i get my own header? I checked everything, im doing everything as documented, and i can see my exe name in a pData->FullDllName, everything seem to be correct, and the DllBase makes sense its not null or anything like ffffff. Is there any specific thing need to bee done, maybe address calculation?

Upvotes: 1

Views: 2340

Answers (1)

Sergio
Sergio

Reputation: 8209

You can't do

PLDR_DATA_TABLE_ENTRY myImageBase = (PLDR_DATA_TABLE_ENTRY)myModule;

since InMemoryOrderLinks is not the first field in LDR_DATA_TABLE_ENTRY. Instead you should involve CONTAINING_RECORD() macro:

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;

To top it off: you can freely iterate through doubly-linked circular list of LIST_ENTRY'es and to obtain actual node data you should use CONTAINING_RECORD(). Note, that node which resides in PEB_LDR_DATA is dedicated and has no associated data. You should use it only as sign that you have walked through whole list.

Upvotes: 3

Related Questions