Search code examples
c++winapiportable-executable

Import address table yields incorrect RVA for import name


I'm having trouble with the Win32 NT headers giving me odd RVA's for import names. Here is the relevant code that is giving me the problem:

//Get a pointer to the import table
PIMAGE_IMPORT_DESCRIPTOR piidImportTableAddr; 
piidImportTableAddr = (PIMAGE_IMPORT_DESCRIPTOR)(pImgNtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress + (DWORD)pMemFile);

while(piidImportTableAddr->Name != 0)
{
    //Itterate over every IMAGE_IMPORT_DESCRIPTOR structure, extracting the names of the DLLs to import
    char* name = (char*)((DWORD)piidImportTableAddr->Name + (DWORD)pMemFile);

    //Do nothing for now

    piidImportTableAddr++;
}

However, the piidImportTableAddr structure's members contain addresses that are bad pointers, here is a table of the members:

Characteristics 0x42746553
OriginalFirstThunk 0x42746553
TimeDateStamp 0x646f4d6b
ForwarderChain 0x02260065
Name 0x54746547
FirstThunk 0x4d747865

These are all bad RVA's and memory locations. Is there something I'm doing wrong when looking up the DLL name by this method? I have compared the RVA of the import table to the one that is shown in PE Lord, they are the same, so I am not sure why the IMAGE_IMPORT_DESCRIPTORs are incorrect.

Here is a link to the source code in it's entirety: http://pastebin.com/32MBEvWU


Solution

  • You have the RVA of the import table, but since the module hasn't been loaded the sections are still in their physical locations. The physical offset of the import section is usually different from the RVA. You will have to iterate through the section headers (_IMAGE_SECTION_HEADER), and using the VirtualAddress and VirtualSize values find the section that contains the import table. Then get the physical address of that section from PointerToRawData.

    So the actual address you want is something like this:

    importTableRVA - importSectionRVA + importSectionPhysicalAddress + pMemFile