I need to destroy some objects when my DLL is unloaded. This object contains a thread that sometimes calls the WSASocket function (for reconnecting a connection). So, I call the destructor from DllMain in response to DLL_PROCESS_DETACH, but that causes my application to hang. Specifically, the call to WSASocket locks up.
I know that some functions cannot be called from DllMain, especially functions that call LoadLibrary and FreeLibrary. But why does the WSASocket function have this same problem?
It's because you shouldn't use DllMain for that cause. Many system procs will cause a deadlock being called from DllMain. Declare an additional export proc especially for deinitialization of your dll and call it right before FreeLibrary.
Also, I recommend you to read "Best Dll Practices" by MSFT. There are a lot of reasons to stay away from DllMain.
Related
My question is really above, I will give more information on this below however:
I have a program which first takes my "false" d3d9.dll, this DLL is then loaded into the game I am reverse engineering. After the some time and the .dll is loaded, along with all the other games dependencies I want to inject my DLL which will do all the dirty work of the reverse engineering.
I think I can load this DLL into the program using LoadLibrary, however when I'm using the DLL I injected to run the main reverse engineered code. Is there a function I can use to call something from the d3d9.dll?
This is because I still need access to the d3d9 library to render things I may want to add on the screen with my injected .dll. I also don't want to just use the d3d9.dll as this will cause problems with loading times, and the point at which memory is changed.
I also don't plan on using DllMain in the DLL, this means I will also need to call a remote function from the d3d9.dll to the injected DLL in order to ensure a safe process start.
Sorry if this is a stupid question, however thanks for any answers.
Back in the old days we use to CreateRemoteThread and use LoadLibraryA as the address for lpStartAddress (This address happens to be the same in all processes). The trick was to allocate the DLL name you are injecting using VirtualAllocEx and use that as lpParameter. Effectively your thread calls LoadLibraryA with the DLL name you want to inject. When the Dll loads Dllmain gets called and you can run code in Dllmain during a time that the dll is being attached (DLL_PROCESS_ATTACH).
This link has some very good information on doing just that. However this technique relies on a Dllmain function. If you can use Dllmain then this mechanism may work. A summary of the steps from that article gives an overview:
Now, we can summarize this technique in the following steps:
Retrieve a HANDLE to the remote process (OpenProces).
Allocate memory in the remote process's address space for injected data (VirtualAllocEx).
Write a copy of the initialised INJDATA structure to the allocated memory (WriteProcessMemory).
Allocate memory in the remote process's address space for injected code.
Write a copy of ThreadFunc to the allocated memory.
Start the remote copy of ThreadFunc via CreateRemoteThread.
Wait until the remote thread terminates (WaitForSingleObject).
Retrieve the result from the remote process (ReadProcessMemory or GetExitCodeThread).
Free the memory allocated in Steps #2 and #4 (VirtualFreeEx).
Close the handles retrieved in Steps #6 and #1 (CloseHandle).
I saw your comment about too much information. Not sure I quite understand. However Dllmain has some restrictions like most Win32 API calls can't be used. There are some exceptions and one being CreateThread. Had you considered spinning off a thread to do work? If you use CreateThread in a Dllmain it effectively gets blocked until Dllmain exits. So once Dllmain returns the Thread will execute.
Loading DLLs in in DLLMAIN() / DLL_PROCESS_ATTACH may cause trouble. But may COM Objects be instanced using e.q. CoInitialize() / CoCreateInstance()?
EDIT: The question is:
Could creating COM instances cause similar errors like loading DLLs in this circumstances?
Loading DLLs an creating COM instances seem to me similar in a way.
I'm not sure where you got that quote from, but it doesn't sound right.
You should never put any code of any significance into DllMain. Especially code that invokes LoadLibrary. Many Windows APIs will call LoadLibrary under the hood, so it's best to avoid doing any complex initialization here. Use a global C++ object (for it's constructor) or better yet, export a function for initialization.
CoCreateInstance for in-proc components ultimately will call LoadLibrary or one of its variants. It would not be wise to call this function in DllMain either.
Is there a way to run a function from DLL after it loads? So it behaves exactly like main() function. I load the dll to my application, and after loading the dll itself without any calls from application it's loaded to it executes?
Just like DllMain function, but it works when I inject the dll into an application. I want it to work the same, but when I load it via LoadLibrary.
DllMain will be called in response to a LoadLibrary, but you are limited to what you can do within it reliably. It won't react well to inter-thread communication, as detailed in the MSDN DllMain documentation. Best to put such code in an Init function. In my experience the more you heap in DllMain the more problems you'll have; do as little as possible.
If you really can't use an Init function then try creating a thread in DllMain (attach) and call your function from there.
In c++ ,I want to hook more than one dll to a process. Right now I use CreateProcesswithdll() which can hook only one api at a time. What can I do to inject multiple dlls?
I came across this problem because MS detours requires us to name our custom dll the same as original dll in order to properly detour the api calls. So even though i could have different api calls handled in the same detour dll I created I need to have different names to hook calls from different apis, which means I need different detour Dlls. This also means I need to inject different DLLs. Am I right?
If I am unclear about something I will try to present it more clearly :D
Thanks!
P.S: Just to make my problem more lucid. I need to inject more than 1 dll onto the same process. CreateProcesswithdll() creates a new process with its thread in sleep state. It is woken up after the detours has finished injecting the dll and setting up the hooks. If I want to inject more than one dll I obviously cant repeatedly call CreateProcesswithdll()
so what do i do?? or Is my understanding about some aspect of this wrong?
Calling LoadLibrary() and FreeLibrary() is NOT SAFE from DLLMain(). From TFA:
"The entry-point function should
perform only simple initialization or
termination tasks. It must not call
the LoadLibrary or LoadLibraryEx
function (or a function that calls
these functions), because this may
create dependency loops in the DLL
load order. This can result in a DLL
being used before the system has
executed its initialization code.
Similarly, the entry-point function
must not call the FreeLibrary function
(or a function that calls FreeLibrary)
during process termination, because
this can result in a DLL being used
after the system has executed its
termination code."
EDIT: Apologies - this was meant as a comment for Serge's answer above.
Seems like detourattach and detourdetach will do the trick for me. Thanks everyone!
I found this blog useful!
Obviously you can load any number of DLLs from the first DLL you inject with detours.
EDIT.
When DLL is loaded system runs DllMain of your DLL (with fdwReason==DLL_PROCESS_ATTACH) and then within that function you can do whatever you like, e.g. you can call LoadLibrary to load other DLLs.
ADD:
I totally agree with comments that calling LoadLibrary from DllMain is unsafe. So you can call LoadLibrary (and all the other tricky things) from thread created in DllMain.
Is it okay to register WSACleanup through atExit function ? We have several applications that can terminate at different points in the code so we would like to avoid putting WSACleanup everywhere throughought the code. Curently we call WSAStartup / WSACleanup through DllMain since we have a dll that is used by all these applications. However, Microsoft strictly advices against the use of WSAStartup / WSACleanup via DllMain since this can cause deadlocks. We can move WSAStarup out of DllMain and call this at one point in the code for all applications before they access the Windows sockets library. And, as soon as we call WSAStartup, we would like to use the atExit function to register a call to WSACleanup. Does anyone have any experiences with this approach ? Thanks!
If you have a multi-threaded app and some of the threads are still connected, the applications at the other end may not like the way the connection is terminated. So it is preferable to close down all communication in an ordered way before main() terminates, and when you have done that, you can just as well call WSACleanup.
I agree that the RAII approach is favourable.
However a word of warning: atExit mixed with dlls and handles is broken on windows. Unfortunately this effects RAII too as this is implemented with atExit handlers by the c++ runtime.
The order that atexit handlers are called on windows:
somewhere exit is called or main() goes out of scope
atexit handlers defined in the process are called.
all handles are destroyed.
atexit handlers defined in dlls are called.
It doesn't matter if atexit handlers in dlls are registered before handlers in the process the process handlers are called first and the handles are destroyed before the dll handlers are called. This results in win32 exceptions, when the clean up code is called as all the handles owned by dlls are no longer valid.
This effects code that holds handles to threads, mutexs, files, sockets etc. If they are allocated in a dll then they must be cleaned up before exit is called or not at all.
By the way I am not anti window, if I am wrong or anyone knows any way around this I would love to know as this causes me untold pain in application clean up. I figured this out be debugging exit handling in the c++ runtime, after getting win32 exceptions when applications exit.
I had to remove all calls to exit from my code. I now ensured that no static data in a dll controls a handle. All static handles are controlled by objects that are destructed when main goes out of scope.
Well I think atExit should not be used. You should follow RAII principle of wrapping of initialization and destruction of socket library in a class.