In PE header, there are import directory which describes where the loader should bind the imported symbols. More precisely:
typedef struct _IMAGE_IMPORT_DESCRIPTOR {
union {
DWORD Characteristics;
DWORD OriginalFirstThunk;
} DUMMYUNIONNAME;
DWORD TimeDateStamp;
DWORD ForwarderChain;
DWORD Name;
DWORD FirstThunk;
} IMAGE_IMPORT_DESCRIPTOR;
typedef IMAGE_IMPORT_DESCRIPTOR UNALIGNED *PIMAGE_IMPORT_DESCRIPTOR;
The FirstThunk field is the RVA of binding point, which is located in IAT (i.e., the .idata section).
Usually, the linker would generates some initial values on .idata. I thought that those are useless, until I realized that if I wipe the entire .idata out, the DLL would fail to load. This is because the loader did not bind the import symbols, and results in access violation when the program trying to call these imported APIs.
My question is, why there are initial values in IAT? Is it necessary for DLL loading? I thought that prodving by the import directory should be sufficient for loader to bind the imports.