There is "First Thunk"(FT), which loader overwrites after execution with correct addresses.
But when PE uses OFT?
Does PE even need it?
The original first thunk is needed if the imports are bound but the imported .DLL does not match.
On a fresh unpatched version of Windows, all addresses of all functions in the base .DLLs (ntdll, kernel32, user32 etc) are known. Take shell32 for example, it links to kernel32!CreateProcess
and the true address of CreateProcess
can be stored directly in shell32. This is called import binding and lets the loader skip the step where it looks up all the addresses of the imported functions.
This does not work if the imported .DLL has not been loaded at its preferred address nor if the .DLL has changed (security update etc). If this happens then the loader has to look up the functions "the normal way" and the original first thunk array has to be used because that is the only place where the RVAs of the function names are stored.
If import binding is not used then the original first thunk array is optional and might not be present.
ASLR has probably made this optimization irrelevant.
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.
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.
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_Data.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With