Can anybody please read this and correct my mistakes/answer my questions? This is my understanding so far:
The imports known at compile time, are loaded in memory when the executable is loaded in memory. Pointers to these functions are stored in the import address table, when a process wants to call a function it has to retrieve the pointer from the import address table (I understand the relation between the IAT, INT, H/N table etc.).
When a function is loaded at runtime with LoadLibrary
and GetProcAddress()
the dynamic linker retrieves a pointer; so e.g. when a process calls MessageBoxA then the operating system loader loads the DLL Kernel32 in memory and returns a pointer to this specific function. Is this part so far correct?
-
As far as I know, the first library loaded by the operating system by definition is ntdll.dll and the second one is the more abstract wrapper Kernel32.dll. What I’m wondering.. when a process calls MessageBoxA or CreateFileA at runtime, the DLL does not need to be loaded in memory right? Because these functions are part of an already loaded library, namely Kernel32.
-
Does the dynamic linker store the pointer to the dynamically loaded function in some sort of a cache or..? As far as I know, it does not update the import address table, so what happens when the process calls the function again, does it needs to call
GetProcAddress
again to resolve the virtual address or is there a more efficient way? -
When I want to hook the dynamically loaded functions, do I need to hook
GetProcAddress
at runtime and alter the return pointer with a jump instruction to my shim function (and store the original function pointer to call the original function/with the original parameters afterwards).
when a process wants to call a function it has to retrieve the pointer from the import address table
Retrieve sounds a bit cumbersome, but yes: Calls to imported functions are compiled into calls to the IAT where there’s a JMP [Address] instruction, which gets patched up with the actual function address when the library is loaded.
When a function is loaded at runtime with LoadLibrary and GetProcAddress() the dynamic linker retrieves a pointer; so e.g. when a process calls MessageBoxA then the operating system loader loads the DLL Kernel32 in memory and returns a pointer to this specific function.
LoadLibrary
loads the dll into memory. GetProcAddress
returns a pointer to a specific, exported function. Not a stub like above, but the address of the actual function within the module.
when a process calls MessageBoxA or CreateFileA at runtime, the DLL does not need to be loaded in memory right?
MessageBoxA
actually resides in user32.dll, but for CreateFileA you are correct, kernel32.dll is already loaded.
Does the dynamic linker store the pointer to the dynamically loaded function in some sort of a cache or..?
The loaded module’s address is recorded in a kernel object. As far as I am aware, the addresses of individual functions are not cached.
As far as I know, it does not update the import addres table, so what happens when the process calls the function again, does it needs to call GetProcAddress again to resolve the virtual address or is there a more efficient way?
Normally you would store what GetProcAddress
returns in a variable if you need to use it more than once.
When I want to hook the dynamically loaded functions, do I need to hook GetProcAddress at runtime and alter the return pointer with a jump instruction to my hooked function (and store the original function pointer to call the original function/with the original parameters afterwards).
Yes, exactly.