Let me summarize a lot of things for you here. When you load a Library, for example, Milad.dll and then try to call a function from that like MPrint, dynamic loader of the windows operating system has to resolve the address of the MPrint function and then call it.
How can OS resolve the address of that function?
Windows go through some really complicated stuff which I want to tell you those steps with a simple tongue. The dynamic loader of windows OS to resolve the address of the function in DLLs has to check Import Name Table (INT), Import Ordinal Table (IOT) and Import Address Table (IAT) table.
These table pointed by AddressOfNames, AddressOfNamesOrdinal and AddressOfFunction member in Export directory a PE structure (DLLs).
After OS load Milad.dll in address space of target process with help of LoadLibrary, it’s going to fill INT, IOT and IAT table with their RVA in target address space of the process with GetProcAddress and doing some calculation.
There is an array of Import Directory in the process structure that has OriginalFirstThunk, TimeDateStamp, ForwarderChain, Name, FirstThunk which these members point to some important addresses.
- Name in Import Directory (Image_Import_Descriptor) pointed to the name of the DLL which process tries to call, in this example this DLL is Milad.dll.
- OriginalFirstThunk pointed to Import Name Table which includes Names of functions that exported by the Milad.Dll. Functions in this table have a unique index which loader takes that index and go to the next step and reference to Import Ordinal Table with that index and takes the value which there is into that index of Import Ordinal Table which It’s another integer value.
- FirstThunk is another important member which point to IAT. in the previous step dynamic loader takes an integer value via IOT. this value is an index number which dynamic loader refer to IAT with that value. In this table, there is an address in index value which dynamic loader gets from INT-IOT. After these steps when dynamic loader finds out the correct address of the function, it puts that address to Import Address Table for MPrint function. So the process can call that function with its address.
This is a simple explanation for complicated stuff which loader does to resolve the address of the functions in DLLs via Name, OFT(INT) and FT(IAT) members in Image_Import_Descriptor.