12 Nov

API hook systems that change DLL load order.

All Windows API/code hook systems (out of the many I’ve studied) force map DLLs when hooking them except for my favorite madCodeHook.
An application will have a native way DLLs are loaded. Some might be delayed and some might loaded dynamically at various times.  Loading them in to hook before the application it’s self does changes this load order.

Probably most of the time other then an inconvenience this won’t be much of a problem in practicality.
Mainly if at all, something to consider when you are creating and injecting/loading your own DLL at the same time and less so when you are attaching to an already running process.
Furthermore DLLs like the system ones load in the same space in each process further narrowing down any possible adverse effects to mostly custom/proprietary DLLs.
One particular case where it’s noticeable is if you debug the target process with or with out your DLL. Some modules might load at different bases when your DLL is injected thus making things inconsistent and harder to debug.

Looking at a process memory map in Ollydbg ALT-M:
Memory map showing mapped DLL example

One factor is if you use the default base address of 10000000h for your hook DLL(s) then you might cause some proprietary DLL that would normally be there to relocate some place else.
That’s why it’s a good idea to set your own base to some other address normally not used by the target.
In MS Visual studio the setting for this is “Base address” under Advanced linker options. Or the command line version is “/BASE”.
See: MSDN “/BASE (Base Address)”
According to MS documentation this should normally be in the range of 60000000h through 68000000h and must have 64kb alignment. At first glance it doesn’t look like much but that’s actually a 128mb range.  Related article: Dr.Dobbs “Rebasing Win32 DLLs”
Another nice thing it will be easier to track exceptions in your DLL since it’s base address will be constant.

To make our hook engine more robust and not have this dreaded order changing (at least less anyhow) is pretty easy and probably how madCodeHook is doing it.
We’ll put a hook internally on ntdll.dll‘s LdrLoadDll() function to catch further DLLs as they are loaded. It’s the ideal spot as it’s the last in the call chain of exported functions in the “LoadLibrary()” line, and it’s the same from Windows XP on up to Windows 7 (32bit). And by having it so low in the chain there is less chance of conflicts if the user wants to look upper level functions like LoadLibraryA, LoadLibraryW, and LoadLibraryExW et al.

LdrLoadDLL() XP SP3 in IDA Pro

When we go to do an API hook we first look if the target DLL is mapped in already. If it is then we can just hook it now, else we’ll store the DLL name, and API name (or ordinal number), and user hook function pointer into a queue for later.
To make things yet more robust and catch errors (IE: An API export that doesn’t exist, exports we can’t hook, etc.) before the target DLL loads we’ll temporarily map it in as data with LoadLibraryEx() using the LOAD_LIBRARY_AS_DATAFILE flag.
From here we will use a custom GetProcAddress() like function (that parses the raw import section from the DLL PE header) and analyze the API function’s entry point for hooking.
As long as the export exists and it can be hooked we add it to our “to be hooked queue”, else we will return an error right then.
Then as we monitor DLLs loaded (via LdrLoadDll() hook) we’ll catch if and when a queued target actually gets loaded. From inside there we’ll apply the requested hook, then remove the API from the queue.

Now the relative order of DLL loading is mostly unaltered..

Leave a Reply