In this article, the definitions are
DWORD VirtualAddress
In EXEs, this field holds the RVA to where the loader should map the section. To calculate the real starting address of a given section in memory, add the base address of the image to the section's VirtualAddress stored in this field.
DWORD PointerToRawData
This is the file-based offset of where the raw data emitted by the compiler or assembler can be found. If your program memory maps a PE or COFF file itself (rather than letting the operating system load it), this field is more important than the VirtualAddress field. You'll have a completely linear file mapping in this situation, so you'll find the data for the sections at this offset, rather than at the RVA specified in the VirtualAddress field
Also RVA
is defined as
Many fields in PE files are specified in terms of RVAs. An RVA is simply the offset of some item, relative to where the file is memory-mapped
and
To convert an RVA into a usable pointer, simply add the RVA to the base address of the module. The base address is the starting address of a memory-mapped EXE or DLL
The problem in hand is to reach the import section
of a PE file.
hFile = CreateFile(..);
hFileMapping = CreateFileMapping(..);
lpFileBase = MapViewOfFile(..);
ImageBase = (PIMAGE_DOS_HEADER)lpFileBase;
PEHeader = (ImageBase + ImageBase->e_lfanew);
Now to get hold of import table
PIMAGE_OPTIONAL_HEADER PEImageOptionalHeader = &(PEHeader->OptionalHeader);
IMAGE_DATA_DIRECTORY importTable = PEImageOptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT];
Since importTable.VirtualAddress
is an RVA, to get a usable pointer, i can add the base of the image file.
So ImageBase + importTable.virtualAddress
should get me to import section.But it does not.Why?
Then, if i reach at the correct section header(generally .idata
) and do this.
ImageBase + pointerToSection->PointerToRawData;
The above correctly takes me to array of IMAGE_IMPORT_DESCRIPTORS
.I understand that using pointerToSection->virtualAddress
instead of PointerToRawData
above, would not work as i am mapping the PE file myself.
Now to get the name
of the item, the loaded module is dependent on,I can use pointer to IMAGE_IMPORT_DESCRIPTORS
using the field name
which is again anRVA
.To convert an RVA
, i just have to add the ImageBase
..
LPSTR libname = (PCHAR)((DWORD)ImageBase+ImageimportDescriptor->Name);
But it does not work.Why?To convert an RVA
, we simply add base address of image.The below works
ImageBase+ImageimportDescriptor->Name + pointerToSection->PointerToRawData - pointerToSection->virtualAddress
And every time i need some info within a section, i need to make this adjustment
pointerToSection->PointerToRawData - pointerToSection->virtualAddress
Why is this adjustment required?