Sunday, July 24, 2016

Loading custom DLLs instead of original DLLs (Let's talk about Stuxnet again and forget Kapsersky...)

The question below is for educational purposes only and the discussed featured are not meant to alter registered DLLs or develop a malware but for learning and experiencing.


Recently I've been exploring few methods to load my own custom DLLs instead of an application's original DLLs. One of the methods that came up was the .local method.
After experiencing with this method a little bit and after I removed the KnownDlls entry from the registry I managed to replace some system DLLs with my patched DLLs successfully.
These are the DLLs:
enter image description here
However, the DLLs are IN the local folder:
enter image description here
However, there are still some DLLs that insist loading from the system32 directory, although they are present in the local folder.
Is there any way I can force the DLL's to load from the local folder instead of the system32 folder?





7  
Any program that tries to substitute system DLLs Ian malware by definition – David Heffernan Jun 26 at 20:17
5  
@WeatherVane there are many legitimate reasons to do so. 1. Use proxy DLLs to monitor API calls. 2. Replace functionality as I wish. 3. Because some people are enthusiastic to learn and experience. – Aviv Jun 26 at 20:20
3  
To allow for patches to 3rd party libraries. Not to replace core system libraries. – IInspectable Jun 26 at 20:29
4  
@Aviv You claim that .local redirection is possible here. What do you know that we don't. We say that's impossible because the system loader loads those DLLs. Why don't you use hooking? The reality is that you don't want to do that because you want to foist your bogus DLLs on somebody else's process. – David Heffernan Jun 26 at 21:44
6  
@Aviv: David's right with his last two comments. The MSDN page msdn.microsoft.com/en-us/library/windows/desktop/… is pretty clear that the app.exe.local file changes the behavior of LoadLibrary and LoadLibraryEx. ntdll.dll and kernel32.dll are what provide LoadLibrary(Ex), so by chicken-and-egg analysis you can see that they aren't loaded by LoadLibrary(Ex), and therefore are not affected by DLL redirection. In fact, I think you'll find that ntdll and kernel32 aren't loaded into a new process at all, they are in the initial module table. – Ben Voigt Jun 26 at 21:59

This is not an answer so much as a rambling, unsourced, brain dump.
It does serve to explain why I am not surprised at your result. This boils down, for me, to the crucial difference between CreateProcess and LoadLibrary, and how Win32 processes work.
Normally, when using LoadLibrary, you are using it from within the process you want the dll to be loaded into. As such, it can take advantage of a whole bunch of in-process context information about activation contexts, dll search paths etc. including knowledge of things like the app.local flag. All these values are specific to the current process and it is not the job of any other process (or even the Kernel) to track stuff like this.
But, if we look at CreateProcess we can see some problems. When it is initially called, it is called in the context of the launching, not destination, process, so it knows nothing of the destination processes activation context. In fact, the destination process does not exist yet.
The CreateProcess implementation needs to create a NT process, and execute some code in it asap to perform the process load as it doesn't make any sense to instantiate all that per process context stuff in the current process.
But, to do that, there needs to be at least some code in the destination process: The kernel code responsible for parsing the EXE files header, extracting the headers and building the activation contexts that will be used to load the remaining dlls.
This means that, unfortunately for you, kernel32.dll and some dependencies need to be mapped into a process long before that process is capable of building a dll search context, noticing the app.local flag etc.


    
It's indeed a bit rambling. Perhaps most importantly, CreateProcess doesn't actually do that much work. It kicks off kernel code which then creates the new process, maps a few core DLL's, and then starts running the new process. But all that isn't CreateProcess. Have a peek at NtCreateProcess –  
 

You should look at how the Windows loader works. This is OS version dependent, but some of those DLLs load before your program and the loader always looks for them on a path provided by the system. Look at the sequence by starting your program with WinDbg.

http://stackoverflow.com/questions/38042757/loading-custom-dlls-instead-of-original-dlls 

No comments: