Can I unload a DLL from another process? (Win32) - winapi

I want to unload a DLL from another process. Is it possible?
If yes, how to do that? (I'm using Win32 API)
Thank you very much.

Yes, this is possible. It is called DLL ejection and is featured by some DLL injectors. The way a DLL is usually loaded is via LoadLibrary and it is subsequently unloaded via FreeLibrary. FreeLibrary takes only one parameter which is a handle to the module to be unloaded. If you injected the DLL in the first place, you should be able to find this very easily. Otherwise there are ways of obtaining the handle such as CreateToolHelp32Snapshot with further enumeration with Module32First/Module32Next. Suppose you have obtained the handle through some means, then the steps to eject the DLL are simple:
Get the address of FreeLibrary with GetProcAddress. This address will match the one for the same function in the target because of how Windows works.
Call CreateRemoteThread on the target process, specifying lpStartAddress as the address of FreeLibrary, and with lpParameter as the module's handle
There are several caveats to DLL ejection.
You should only ever eject a DLL which you are certain no code is going to make use of again in the future. If any dynamically linked code attempts to make a call to your code after it has been freed, it will most likely trigger some form of page access violation.
You should ensure that no threads are executing within the code of the DLL whilst ejection is being performed for similar reasons.
DLL ejection should be avoided with general. If the library wants to have the option of being freed, it should supply some interface which users can access it through which eventually calls FreeLibraryAndExitThread.
If you require a code example for this, I have written an ejector as part of an injector I wrote in the past in C. I can search it up and find it but it's from many years ago and the code quality is not likely to be good.

You don't want to do this.
"Loading" a DLL is much more than simply opening (and locking) a file. When the NT loader starts an executable, it processes all the DLLs referenced by the image (recursively) and wires up the function calls (recursively): loading the DLLs, calling the DLL initialization code, etc.
Unloading a DLL would mean that you'd need to stop all processes that loaded your DLL, load the new DLL, and perform all the operations the NT loader would. Of course, unloading and re-loading a DLL would need to restore that old DLL's state (initialized variables etc), an operation which is not specified in Win32.
For a bit of background information, see this article on MSDN and this Under the Hood article in MSJ.

Short answer: No, it is impossible.
Win32 doesn't provide an API to unload a DLL of another process. If a library is freed unexpectedly, the process will crash. This leads to a serious security hole as it breaks process protection mechanism.
If you can modify both of the processes, you can modify the application and add routines to free a library, and let the other application to send the message.

I would instead look to change the function called when the process tries to invoke the functions in that dll. I know this is possible in theory.
It would mean a bit of memory hacking and knowing where the pointers to the functions are stored, but all of that can be found easily enough (ollydbg manages to do it), it would be harder if they use ordinals, even harder if they hard code the pointers, but no one does that nowadays. You could then inject your own code that (ideally) mimics the functions they mask, but does not actually do anything. They will probably have to be injected into the process, and that way you could get it to work without the process ever knowing, and without any crashes.

Related

Windows: How to intercept Win32 disk I/O API

On Windows, all disk I/O ultimately happens via Win32 API calls like CreateFile, SetFilePointer, etc.
Now, is it possible to intercept these disk I/O Win32 calls and hook in your own code, at run time, for all dynamically-linked Windows applications? That is, applications that get their CreateFile functionality via a Windows DLL instead of a static, C library.
Some constraints that I have are:
No source code: I won't have the source code for the processes I'd like to intercept.
Thread safety: My hook code may dynamically allocate its own memory. Further, because this memory is going to be shared with multiple intercepted processes (and their threads), I'd like to be able to serialize access to it.
Conditional delegation and overriding : In my hook code, I would like to be able to decide whether to delegate to the original Win32 API functionality, or to use my own functionality, or both. (Much like the optional invocation of the super class method in the overriding method of the subclass in C++ or Java.)
Regular user-space code: I want to be able to accomplish the above without having to write any device-driver, mainly due to the complexity involved in writing one.
If this is possible, I'd appreciate some pointers. Source code is not necessary, but is always welcome!
You may want to look into mhook if Detours isn't what you want.
Here are a couple of problems you may run into while working with hooks:
ASLR can prevent injected code from intercepting the intended calls.
If your hooks are global (using AppInit_DLLs for example), only Kernel32.dll and User32.dll are available when your DLL is loaded. If you want to target functions outside of those modules, you'll need to manually make sure they're available.
I suggest you start with Microsoft Detours. It's free edition also exists and its rather powerful stable as well. For injections you will have to find which injection method will work for your applications in target. Not sure whether you need to code those on your own or not, but a simple tool like "Extreme Injector" would serve you well for testing your approaches. And you definitely do not need any kernel-land drivers to be developed for such a simple task, in my opinion at least. In order to get the full help of me and others, I'd like to see your approach first or list more constraints to the problem at hand or where have you started so far, but had problems. This narrows down a lot chit-chats and can save your time as well.
Now, if you are not familiar with Detours from Microsoft (MSFT) please go ahead and download it from the following link: http://research.microsoft.com/en-us/projects/detours/ once you download it. You are required to compile it yourself. It's very straightforward and it comes with a compiled HTML help file and samples. So far your profiles falls under IAT (Import Address Table) and EAT (Export Address Table).
I hope this non-snippet answer helps you a little bit in your approach to the solution, and if you get stuck come back again and ask. Best of luck!

Substituting a dll, to monitor dll usage

Let's say i have a console application that writes to a file. If I understand correctly, C++ uses some dll, to create and write to the file.
Is it possible, to create a dll with the same name, having the same function signatures, and forward these calls to the real api? The application would not see any change, and it would be possible to notify, or restrict certain calls.
My worry is - is there any security signature that the applications check in a dll?
Would there be any conflicts with the libary names?
You don't need to create a new DLL to replace the original, nor should you. That would have global repercussions on the entre OS. What you should do instead is have your app use Detours to hook the particular DLL functions you are interested in. That way, you are not modifying any DLLs at all, and the OS can do its normal work, while still allowing your custom code to run and deciding whether to call the original DLL functions or not.
yes, entirely possible you can already figure out what the function signatures are and re-implement them (heh, Google already did this with Java JRE :) )
The problem you have is loading a different dll with the same name, though its entirely possible you can do this explicitly with a fixed directory. you can load the dll and then hook up all its functions.
At least that's what I think will happen - having 2 dlls of the same name in the same process might be troublesome (but I think, different path, all's ok).
Security generally isn't done when loading dlls, however MS does this with some .NET assemblies, but the cost is that it takes a long time to load them as there's a significant delay caused by the decryption required to secure the dll. this is why a lot of .NET applications (especially those that use dlls installed in the GAC) are perceived as slow to start - there can be a significant amount of security checking occurring.
I think, generally, if someone has enough access to your computer to install a dll, he could do a lot worse. A skilled hacker woudl just replace the original dll with a new one that does all of the above - and then you wouldn't be able to see a new, rogue dll lying around your system.
If you are security-conscious and worried about this kind of think, the correct way to resolve it is with an intrusion-detection system like AIDE. This scans your computer and builds a database of all the files present, with a secure hash of each. You then re-scan at regular intervals and compare the results with the original DB: any changes will be obvious and can be flagged for investigation or ignored as legitimate changes. Many Linux servers do this regularly as part of their security hardening. For more info, go to ServerFault.

Questions about SetWindowsHookEx() and hooking

Here is a little background information. I'm working on replacing a dll that has been used in a dll injection technique via the AppInit_DLLs registry entry. Its purpose was to be present in every process and set hooks into the GDI32.dll to gather information about printing. This is kind of a funky way to get what we want. The .dll itself is over 10 years old (written in Visual Studio 97) and we'd like to replace it with something a little less invasive than an injected dll.
It appears SetWindowsHookEx() maybe what we are looking for. I've been having some trouble with it, but I've also had some discussions with co-workers about whether or not this tree is worth barking up. Here are some questions that we could not determine:
When we hook a routine out of a dll, for example StartDoc() from GDI32.dll, do we really get a notification every time any other process uses that rotuine out of that dll? This is kind of the functionality we were getting with our injected .dll and we need the same functionality going forward.
When the hook is triggered, does the hook handling procedure run in the process space of the process that initiated the actual call, or in the process space of the process that set up the hook? My opinion is that it has to run in the process space of the process that called the routine. For example, if a program calls StartDoc() from GDI32.dll, it will have the hook handling procedure code "injected" into its space and executed. Otherwise, there would have to be some inter-process communication that automatically gets set up between the calling process and the process that set up the hook, and I just don't see that as being the case. Also, its kind of necessary that this hook handling routine run in the process space of the calling process since one of the things it needs to know is the name of that calling process, and I'm not sure on how to get that information if it wasn't actually running in that process.
If the hook handling routine is written using the .NET managed environment, will it break when getting hooked into a process not utilizing the .NET managed environment? We'd really like to move away from C++ here and use C#, but what would happen if we our hook gets called from a process that isn't managed? As stated before, I think that our hook handling procedure will run in the process that originally called the routine that was hooked. But if this is true, than I would think that we'd run into trouble if this process was not using the .NET run time environment, but the incoming hooked handling code is.
Yes.
Generally, it's the former: it executes in the context of the process whose event it is hooking.
After a successful call to SetWindowsHookEx, the operating system automatically injects the hook DLL (the one that contains the callback function) into the address space of all target processes that meet the requirements for the specified hook type. (Of course, the hooking code is not necessarily injected immediately.)
The exception to this general rule are the low-level keyboard and mouse hooks (WH_LL_KEYBOARD and WH_LL_MOUSE). Since those hook types are not injected into the client processes, the callback is called in the same thread that originally called SetWindowsHookEx.
That last point is important to keep in mind to answer your third question. Because the low-level keyboard and mouse hooks are the only two global hooks that do not require DLL injection, they are also the only two types of hooks that can be written in managed .NET code.
For the other hook types, your concerns expressed in the question are precisely correct. You would need to write these hook DLLs in C or C++. Of course, the rest of your application's pieces could still be written in a managed language. The only thing that matters is the hook DLL.
You might consider looking into either Microsoft Detours or EasyHook.

CreateRemoteThread, WriteProcessMemory, VirtualAllocEx - why use them?

Recently I have been reading up articles about DLL injection and I understand them fairly well.
However, what I don't understand is why APIs such as CreateRemoteThread, WriteProcessMemory(in being able to write to the memory of another process) and VirtualAllocEx(in being able to allocat memory in the context of another process) were implemented in the first place.
What was the original need for such APIs? Just curious.
WriteProcessMemory was made for ring3 debuggers that need to securely write process memory, most commonly for INT 3 breakpoints or user provided memory edits.
along the same line, CreateRemoteThread can also be used for debugging purposes, however, MSDN can enlighten us on CreateRemoteThread a bit more:
A common use of this function is to inject a thread into a process
that is being debugged to issue a break. However, this use is not
recommended, because the extra thread is confusing to the person
debugging the application and there are several side effects to using
this technique:
It converts single-threaded applications into
multithreaded applications.
It changes the timing and memory layout of
the process.
It results in a call to the entry point of each DLL in
the process.
IIRC, CreateRemoteThread is also used by debuggers to hook application native expection handlers, commonly set by SetExceptionHandler, which requires call from the target process as the handler is stored in the PEB.
VirtualAllocEx is just how windows virtual memory system operates, it needs a context to allocate in, be it in the current process, a child process or a remote process. VirtualAlloc in fact is nothing more than a pass through wrapper of the Ex variant, it just passes a special constant that indicates the handle of the caller process is to be used.

What exactly is the risk when using TerminateProcess?

My Win32 console applicaton uses a third-party library. After it exits WinMain global objects destruction begins and an AV happens somewhere deep inside. I'm really tempted to just write
TerminateProcess( GetCurrentProcess(), 0 );
somewhere near the end of WinMain. If I do this the application ends gracefully.
But MSDN says that doing so can compromise the state of global data maintained by dynamic-link libraries (DLLs) which is not clear. I understand that if I have some global object its destructor is not run and I risk not finalizing a database connection or something similar. I don't have anything like that in my program.
What exactly is the risk when using TerminateProcess? How do I determine if I can use it for my purpose?
Based on the documentation for that and ExtiProcess it seems the primary concern is that DLL's are unloaded without a call to DllMain with the flag DLL_PROCESS_DETACH.
My 2cents: The documentation is being paranoid that you will upset some critical operation which runs in DllMain + DLL_PROCESS_DETACH. Anyone who depends on that to maintain critical state is already at the mercy of task manager so I don't see a huge risk in using this API.
Generally the bad things will happen when interacting with objects outside of your process. For an example say you have some shared memory used by multiple processes that your process will write to and other processes read and or write to. Typically to synchronize the reading and writing a mutex is used. If a thread in your process has acquired the mutex and is in the middle of making changes when TerminatePorcess is called, the mutex will be abandoned and the shared memory potentially left in an inconsistent state.
I suspect you are miss using one of the third party libraries. DllMain is somewhat limiting so the library may have initialize and uninitialize functions that you are supposed to call.
AFAIK, if you're not doing anything "fancy" (which includes but is not limited to: creating threads, locks, DB connections, using COM objects), nothing terrible will happen. But as Earwicker says, you don't know what OS-wide stuff a DLL is doing, and you certainly don't know if that will change in the future, so relying on this is very fragile.
Aren't you curious to know why this access violation is occurring? It may well be the sign of something that became corrupted much earlier on. Please at least confirm that the bug is caused by this 3rd-party library, e.g. by writing a program that links with the library but whose main() does nothing, and confirming that this causes the same crash.
It depends how you interpret "global data". If you take it to mean (as I normally would) data stored in the process's address space, then the advice makes no sense - we know that memory is going to disappear, so who cares what happens to that?
So it may be referring to OS-wide stuff that a DLL may have done, that persists outside the lifetime of any process. A simple example would be a temporary file that might need to be cleaned up; crash the process too many times and you'll run out of disk space, so probably best not to make a habit of it.

Resources