kwytay
kwytay

Reputation: 131

Import Table (IT) vs Import Address Table (IAT)

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

Answers (2)

Kevin
Kevin

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

Eric Rahm
Eric Rahm

Reputation: 688

It looks like you're heading the right direction. Some notes:

  • The DataDirectory gives you an offset to an array of IMAGE_IMPORT_DESCRIPTOR which is terminated by an entry of all zeros. There will be one IMAGE_IMPORT_DESCRIPTOR for each DLL that is imported
  • The IMAGE_IMPORT_DESCRIPTOR has offsets to 2 arrays of IMAGE_THUNK_DATA, one that maintains offsets to the names of the imported functions (OriginalFirstThunk) and another that now has the actual addresses of the functions (FirstThunk)

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

Related Questions