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.
Name in Import Directory (Image_Import_Data) 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_Data.
We need to know that when the PE file is loaded into memory, the PE loader will look at the IMAGE_THUNK_DATAs and IMAGE_IMPORT_BY_NAMEs and determine the addresses of the import functions. Then it replaces the IMAGE_THUNK_DATAs in the array pointed to by FirstThunk with the real addresses of the functions. Thus when the PE file is ready to run. The array of RVAs pointed to by OriginalFirstThunk remains unchanged so that if the need arises to find the names of import functions, the PE loader can still find them.
Related
I am not sure if I am phrasing the question correctly, but basically I want to know how the call instruction is generated when calling an imported function from another library.
For example
GetModuleFileName(...)
is compiled to
call 0x4D0000
where 0x4D0000 is the address of the imported function which is dynamic.
How does windows set those calls and would it be possible to circumvent it and set a custom address instead.
The address used in the call statement isn't dynamic. It's a relative address that's fixed at link time like a call to any other function. That's because the call is actually to a stub, and the stub performs an indirect jump to the real function. The indirect jump uses a memory operand that refers to location in the import table. When the executable (or DLL) is loaded by Windows it updates the import table with addresses of all the functions the executable or DLL uses in any DLLs it's linked to.
So if an executable a call instruction like this:
call _GetModuleFileNameA#12
Then somewhere else in the same executable is astub like this:
_GetModuleFileNameA#12:
jmp [__imp__GetModuleFileNameA#12]
And somewhere in the import table there is a definition like this:
__imp__GetModuleFileNameA#12:
DD ?
Windows sets the value of __imp_GetModuleFileName#12 in the import table when the executable (or DLL) is loaded. There's not much you can do change this, though it's not too hard to change the value after the executable (or DLL) has been loaded. Note that the import table might be located in a read-only section, meaning you may need to change the virtual memory protections in order to do this.
To my knowledge the import address table (IAT) is a table of
import functions. But lately I found that in some executables the
IAT is empty: in IAT's directory, both VirtualAddress and Size are
zero. To my surprise, An executable without IAT could run.
Then I found some code in MS detours:
// If the file doesn't have an IAT_DIRECTORY, we create it...
if (inh.IAT_DIRECTORY.VirtualAddress == 0) {
inh.IAT_DIRECTORY.VirtualAddress = obBase;
inh.IAT_DIRECTORY.Size = cbNew;
}
There is an API called DetourCreateProcessWithDllExA in MS
detours, as its name said, it could launch an executable with
specified DLLs - it will create a process in suspended mode,
modify the import table (add DLLs), and resume the main thread to
run. The code above is a part of this procedure.
Depending on my test, if you comment the code above, process will
crash at very beginning. But even more amazing is that you could
modify the VirtualAddress and Size freely, for example:
// If the file doesn't have an IAT_DIRECTORY, we create it...
if (inh.IAT_DIRECTORY.VirtualAddress == 0) {
inh.IAT_DIRECTORY.VirtualAddress = 123;
inh.IAT_DIRECTORY.Size = 456;
}
And it works ! I don't know why. It seems that obBase and cbNew do
not make any sence too.
Q1: Why the IAT can be empty
Q2: Why MS detours must modify the IAT, what's going on
Edit:
An executable with empty IAT may be a packed executable. Although I still don't know the questions.
Q1:
IAT directory can be empty because the information it contains is useless for windows loader. All needed information is in Import Table. See IMAGE_IMPORT_DESCRIPTOR -> FirstThunk in WinNT.h
I had browsed internet, but hadn't found an answer.
Previously we used static linking using def file.
Currently this approach is not suitable, because there are cases when dll is not accessible.
So now we need to load dynamically function with unlimited function arguments.
Is there a common approach? Just push in right direction or some topic related for that is OK.
GetProcAddress does not care about the number of arguments the function has. If you use C++ and your problem is name mangling, you can either mark the functions with extern "C" or pass the mangled name to GetProcAddress.
How to know if the exported symbol from a dll is actually variable or a function ?
One way may be to look whether the destination address of the symbol resides in the .code section or not.
Another method could be to check the memory protection attributes of the selected section.
But all these methods seem to be unreliable.
What is the best way ?
I have recently written a simple test program to call a few private functions in a DLL that ships with Windows. Since private functions are not exported, their address cannot be found with GetProcAddress(), and I am looking for a way to achieve the same without it.
With IDA Pro, I took note of the offset of an exported function, DllRegisterServer in this case. Since this function is exported, I can query its address with GetProcAddress. By knowing its offset from the beginning of the .text section of the PE executable, I can then dynamically query the address of the .text section after loading the DLL with LoadLibrary.
Again, still using IDA Pro, I took note of the offsets of each of the private functions of interest. Once I have the address of the .text section, I only need to add the offset for the known private functions and I now have the correct address to call those functions. There is only one problem, however: since the offset has been hardcoded, this will only work with this exact version of the DLL.
I know there are many tools that can read PE and give addresses of private functions. I assume that the debug symbols are used to query the names of those private functions. What I'm looking for is a simple library that can read PE and debug symbols and allow me to query by name the address of a private function.
Does anybody know of such a library that can help find the addresses of private function by names, making use if debug symbols when available?