What's the difference between the Import Table and the Import Address Table?
As general, I recommend reading the PE Format documentation on MSDN regarding the PE structure.
The Import Table is actually called "Import Directory Table" and contains entries for every DLL which is loaded by the executable. Each entry contains, among other, Import Lookup Table (ILT) and Import Address Table (IAT)
To quote from the PE format specs about Import Directory Table:
Import Directory Table
The import information begins with the import directory table, which describes the remainder of the import information. The import directory table contains address information that is used to resolve fixup references to the entry points within a DLL image. The import directory table consists of an array of import directory entries, one entry for each DLL to which the image refers. The last directory entry is empty (filled with null values), which indicates the end of the directory table. Each import directory entry has the following format:
Offset Size Field 0 4 Import Lookup Table RVA 4 4 Time/Date Stamp 8 4 Forwarder Chain 12 4 Name RVA 16 4 Import Address Table RVA
Import Address Table
The Import Address Table is comprised of function pointers, ans is used to get the addresses of functions when the DLLs are loaded. A compiled application was designed so that all API calls will not use direct hardcoded addresses but rather work through a function pointer. The pointer table can be accessed in several ways -- either directly by a call to
[pointer address] or by the "Import Lookup Table" and the "Hint/Name Table".
Let's quote again from the PE specs about the "Import Address Table":
Import Address Table
The structure and content of the import address table are identical to those of the import lookup table, until the file is bound. During binding, the entries in the import address table are overwritten with the 32-bit (for PE32) or 64-bit (for PE32+) addresses of the symbols that are being imported. These addresses are the actual memory addresses of the symbols, although technically they are still called "virtual addresses." The loader typically processes the binding.
First, beside “yours” two tables, I introduce a third one, the Import Lookup Table.
Side by side with the Import Address Table, these two tables look like in this simplified picture:
This picture shows the situation in your executable file on disk. They are totally identical, with the exactly same lists of the API function names (more precisely, pointers to the displayed names), in the exactly same order.
Now, the loader loads your executable and maps all required DLLs (Dynamic-Link Libraries) into your virtual memory space.
After finishing it and some calculations, the loader already knows addresses of all your imported functions.
So it replaces the names of your imported functions in the second table (Import Address Table) with their addresses, and the situation in memory becomes different:
On the other hand, the Import Table, more precisely Import Directory Table, is a gateway to these 2 tables.
It is an array (a table) of entries, one entry (a row) for every imported library.
A simplified picture of it is here:
Every row consist of 5 double words (pointers). Important are only 3 of them, the first (a pointer to the ILT), the last (a pointer to the IAT), and the last but one (identifying the row by the name of DLL; so it's a pointer to the DLL's name in the fourth involved table, the Hint/Name Table).
So its cooperation with other two tables looks like this:
(I omitted the fourth table, the mentioned Hint/Name Table with names of all imported functions and names of all imported libraries, too.)
Note: I intentionally omitted zero-filled separating rows in my pictures, and I didn't deal with imports by ordinal (for the sake of simplicity to emphasize ideas).