Is it possible for a function that is inside a DLL to unload the DLL? I need to do this so I can make sure the DLL is not in use, then write to the DLL's file.
4 Answers
As I understand it, it CAN be done and is MEANT to be done sometimes (for example in case of dll injection by CreateRemoteThread and other methods). So,
FreeLibraryAndExitThread(hModule, 0)
will do precisely that.
On the other hand, calling
FreeLibrary(hModule)
will not do here - from MSDN: "If they were to call FreeLibrary and ExitThread separately, a race condition would exist. The library could be unloaded before ExitThread is called." As a remark, ExitThread does some bookkeeping besides just returning from the thread function.
All this assumes that Your Dll obtained the hModule itself by calling LoadLibrary from inside the loaded Dll, or rather, by calling from inside the loaded Dll the following function:
GetModuleHandleEx
(
GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
(LPCTSTR)DllMain,
&hModule
)
This increments the reference count of the Dll so You know that if You free the library later using that handle and if the library is really unloaded then You had the last reference to it.
If You instead skip incrementing the Dll's reference count and obtain the hModule just from the argument to DllMain during DLL_PROCESS_ATTACH then You should not call FreeLibraryAndExitThread since the code that loaded the Dll is still using it and this module handle really isn't Yours to manage.

- 4,246
- 2
- 43
- 64
-
This does not make any sense at all... When you load DLL with `LoadLibrary` it increments reference by 1. It never decrements it. Then, you call `GetModuleHandleEx`, and it increments it again by 1 (handle is the same as in DllMain argument, btw). Now you call `FreeLibraryAndExitThread` and it decrements count by 1. You end up with reference count of 1, and DLL never gets unloaded! – ScienceDiscoverer Jul 11 '22 at 04:51
-
@ScienceDiscoverer You use either `LoadLibrary` or `GetModuleHandleEx`, no need for both. What I was talking about in the above post, was something else. I was talking that if you get the handle from `DllMain` argument, then you should not use this handle for unloading since getting handle from `DllMain` does not increase ref count at all. – Roland Pihlakas Jul 11 '22 at 12:42
Use this when the dll has done it job:
CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)FreeLibrary, &__ImageBase, 0, NULL);
// terminate if dll run in a separate thread ExitThread(0);
// or just return out the dll
And the __ImageBase is your dll's PE header structure:
EXTERN_C IMAGE_DOS_HEADER __ImageBase;

- 81
- 1
- 3
-
3This trick may help, but theoretically it could still lead to race condition if the thread calling CreateThread lingers around too long after the call to CreateThread. Please see my answer regarding FreeLibraryAndExitThread function. – Roland Pihlakas Nov 29 '13 at 07:09
If your asking if you can safely unload/unmap a DLL loaded in a process from code in the DLL itself, the answer is no - there isn't really a safe way to do this.
Think about it this way: Unloading a DLL is done by decrementing it's reference count using FreeLibrary(). The problem of course is that once the reference count of the DLL hits zero, the module is unmapped. Which means that the code in the DLL that called FreeLibrary() is gone.
Even if you could do this, you'd still need to ensure that there are no other threads executing any exported functions from the DLL.

- 3,668
- 1
- 18
- 20
I don't think it will work. Calling FreeLibrary with a handle from the outside (LoadLibrary would have been called from an area outside the DLL) as the code runs in a memory location that will not be valid anymore.
Even if this is possible, it smells like a bad design. Maybe you want to make some updater or alike. Explain a bit more what is the result you expect. Unloading a DLL from within itself is not the way to go.

- 19,700
- 6
- 57
- 97
-
5Please see my answer regarding FreeLibraryAndExitThread function – Roland Pihlakas Nov 29 '13 at 07:08
-
2Calling FreeLibrary is not the best option if you have a background thread within your DLL. It's better to use [FreeLibraryAndExitThread](https://msdn.microsoft.com/en-us/library/windows/desktop/ms683153(v=vs.85).aspx). This function is a rock that can kill 2 birds. – Hao Nguyen Jul 06 '15 at 18:32