6

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.

Jack Bui
  • 160
  • 1
  • 2
  • 9
  • 1
    because I want to stop the other process's DLL from excuting – Jack Bui Jan 12 '12 at 09:05
  • 1
    What is executed is not a DLL, it is the process itself in its entire address space. DLL are not "executed" but "loaded". – Basile Starynkevitch Jan 12 '12 at 09:07
  • yeah, some threads use some functions in this DLL and I want to stop them from running these function. (i guess maybe it will crash if I unload the DLL ^^!) – Jack Bui Jan 12 '12 at 09:13
  • 3
    Don't bother trying to do this. Just terminate the process instead. – David Heffernan Jan 12 '12 at 09:26
  • If you know assembler a little you could modify this *.dll and change this function so it doesn't do anything - for example just return 0. But this will require some reverse engineering knowledge and good debugger (like ollydbg). This is a safer way that will not cause crash. It is even possible to do such modification on running application using WriteProcessMemory API, but that way or another you have to know what to change. – Zuljin Jan 12 '12 at 09:56
  • @JackBui If a thread already calls a function from the DLL then unloading it won't help. It would be like hoping to prevent a function from reading from a pointer by calling delete/free on the memory it points to - it would cause an access violation, or memory corruption, but it won't stop the code from dereferencing the memory. Here we assume that another thread already holds pointers to functions in the DLL - even if you unload it it won't stop the other thread from making the CALL/JMP instruction. – sashoalm Jan 12 '12 at 09:58

4 Answers4

9

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.

Mike Kwan
  • 24,123
  • 12
  • 63
  • 96
3

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.

devio
  • 36,858
  • 7
  • 80
  • 143
2

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.

yuryu
  • 47
  • 3
0

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.

Matt
  • 7,100
  • 3
  • 28
  • 58