windowsreverse-engineeringportable-executablemalwareinternals

Why are the ILT and IAT separate tables?


I am learning about the PE format, specifically about the design of imports, and I have a question about the design of the IAT and ILT. why do they need to be separate tables? To my understanding, they are identical on disk, and when the PE is loaded to memory, each entry in the IAT is replaced by the loader to the actual address of the imported function. PE format:

"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."

my question is: why can't this be done to the ILT instead? instead of having two tables, remove one table, lets say we remove the IAT: so now when the PE is loaded the entries of the ILT are replaced by the actual addresses, and we save space by not having the IAT.

I've been trying to think of a need to save the values of the ILT during execution but can't think of nothing. I'm sure there is a rational behind this design. I've read the "PE format" article on msdn, various blogs and answers on here but couldn't find an answer.


Solution

  • You can bind by using BindImage API. According to BindImageEx:

    The process of binding an image consists of computing the virtual address of each imported function. The computed virtual address is then saved in the importing image's Import Address Table (IAT). As a result, the image is loaded much faster, particularly if it uses many DLLs, because the system loader does not have to compute the address of each imported function.

    Therefore, I think it's because the binding rewrites the IAT to the actual address before being loaded by the loader. If the DLL is updated, and the actual address is changed, uses ILT. That's why they have ILT and IAT, I understand.