Reputation: 131
I've been trying to parse/display the information in the Import Address Table (IAT) of a process after it is loaded and running. I understand API calls in programs jump to the relevant point in the IAT, which then jumps to the actual function in the loaded DLL's.
Is it correct that the IAT can be found by reading the PE header and following the OptionalHeader.DataDirectory[1] pointer, to the array of IMAGE_IMPORT_DESCRIPTORs. Then following the FirstThunk pointers. Whereas the OriginalFirstThunk pointers here, will give you the original Import Table (IT)?
I have also tried following the OptionalHeader.DataDirectory[12] pointer in the PE header, but this was even less successful.
I've been testing this by trying to parse this structure for notepad.exe (32bit), using ReadProcessMemory from another process.
Here's the rough C-psuedocode for what I'm doing:
char buf[128];
// get first import descriptor
readMemory(&import, procImgBase + DataDirectory[1].VirtualAddress, sizeof(IMAGE_IMPORT_DESCRIPTOR));
// get dll name
readMemory(buf, import.Name + procImgBase, 127);
printf("libname: %s\n", buf);
// get first function name
DWORD iltAddress = 0;
readMemory(&iltAddress, import.FirstThunk + procImgBase, 4);
readMemory(buf, iltAddress + procImgBase, 127);
printf("fname: %s\n", libName + 2); // <-- the +2 for the 2byte 'hint' of import lookup table entries
If, on the 3rd to last line, i replace it with import.OriginalFirstThunk instead of FirstThunk, it will print everything as expected. I must be missing something conceptually, and so I was wondering if anyone could clarify what this is, for me?
Many thanks!
Upvotes: 11
Views: 11522
Reputation: 233
Eric gave a good answer, here are some additional clarifications:
I understand API calls in programs jump to the relevant point in the IAT, which then jumps to the actual function in the loaded DLL's.
The program uses a CALL PTR DS:[IAT-ADDRESS] that reads from an address in the IAT to determine where the program is at runtime.
Whereas the OriginalFirstThunk pointers here, will give you the original Import Table (IT)?
The OriginalFirstThunk pointers point you at the Import Lookup table (ILT). If you open up the binary on disk, the ILT and the IAT are identical; both contain RVA's to function name strings. Once the program has been loaded, the IAT's entries (in memory) are overwritten with the addresses of the imported functions.
In my experience, the best source of information on the import table and all of its attendant data structures is the PE specification itself. If you read patiently through the section on imports, all will be made clear.
http://msdn.microsoft.com/en-us/windows/hardware/gg463125
Upvotes: 4
Reputation: 688
It looks like you're heading the right direction. Some notes:
Since your executable is running, the IAT should contain the actual address of the function rather than an RVA to a name entry.
You could do something like this instead:
DWORD rva_to_name_of_function = 0;
DWORD address_of_function = 0;
// get the RVA of the IMAGE_IMPORT_BY_NAME entry
readMemory(&rva_to_name, import.OriginalFirstThunk + procImgBase, 4);
// copy the name of the import
readMemory(buf, rva_to_name + procImgBase + 2, 127);
// get the actual address that was filled in by the loader
readMemory(&address_of_function, import.FirstThunk + procImgBase, 4);
printf("fname: %s address: %X", buf, address_of_function);
Take a look at this article for some helpful details: http://msdn.microsoft.com/en-us/magazine/cc301808.aspx
Upvotes: 7