Several programs crash when unhooking with UnhookWindowsHookEx() - c++

I am doing a global hook to add my DLL to the hook chain:
HHOOK handle = SetWindowsHookEx(WH_CALLWNDPROC, addr, dll, 0);
Inside my DLL I am using Detours to intercept several WINAPI function calls. Everything works fine, except for WaitForSingleObject calls. Whenever I add WaitForSingleObject to the detoured functions, several programs crash when I unhook my DLL (Chrome, Skype, ...).
Here is how the DLL looks:
DWORD (WINAPI* Real_WaitForSingleObject)( HANDLE hHandle, DWORD dwMilliseconds) = WaitForSingleObject;
DWORD WINAPI Mine_WaitForSingleObject(HANDLE hHandle, DWORD dwMilliseconds);
INT APIENTRY DllMain(HMODULE hDLL, DWORD Reason, LPVOID Reserved) {
switch(Reason) {
case DLL_PROCESS_ATTACH:
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourAttach(&(PVOID&)Real_WaitForSingleObject, Mine_WaitForSingleObject);
DetourTransactionCommit();
break;
case DLL_PROCESS_DETACH:
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourDetach(&(PVOID&)Real_WaitForSingleObject, Mine_WaitForSingleObject);
DetourTransactionCommit();
break;
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
}
return TRUE;
}
DWORD WINAPI Mine_WaitForSingleObject(HANDLE hHandle, DWORD dwMilliseconds) {
return Real_WaitForSingleObject(hHandle, dwMilliseconds);
}
extern "C" __declspec(dllexport) int meconnect(int code, WPARAM wParam, LPARAM lParam) {
return CallNextHookEx(NULL, code, wParam, lParam);
}
Could someone help me to understand why this is happening and how I can get around that Problem? Thanks!

I think this is happening because many programs (Chrome, Skype, ...) have a thread pool, where background thread[s] are waiting on WaitForSingleObject() for something interesting for them to happen, and when it does happen, that thread[s] wake up and do something.
So, your thread A is calling DetourDetach while another thread B of the same process is currently inside Mine_WaitForSingleObject() Then DLL unloads, and everything crashes. You can verify by using debugger, attach to that problematic process, set breakpoint in DLL_PROCESS_DETACH, and when the breakpoint will hit, look through the stacks of another threads for Mine_WaitForSingleObject.
I’m not sure how to fix.
But, one way that you might try — enumerate threads, and call DetourUpdateThread() for every thread of the process. This way, maybe the Detours will do something about that.

You are detouring a function that almost any process uses. And it is particularly dangerous since it is very likely that such a process has a call on that function active. A blocking call in almost any case. As soon as it unblocks, the code will resume into your detour that is no longer there.
Kaboom.
Realistically, the only way to unload your detour is by logging out so that every process that could have been detoured is no longer running.

Related

Is it safe to call std::thread::join function under Win32 DLL_PROCESS_DETACH? [duplicate]

I've stumbled upon an unexpected behavior of Windows thread mechanism when DLL is unloaded. A have a pack of worker thread objects and I'm trying to finish them graciously when DLL is unloaded (via DllMain DLL_PROCESS_DETACH). The code is very simple (I do send an event to finish the thread's wait loop):
WaitForSingleObject( ThrHandle, INFINITE );
CloseHandle( ThrHandle );
Yet the WaitForSingleObject hangs the whole thing. It works fine if I perform it before DLL is unloaded. How this behavior can be fixed?
You can't wait for a thread to exit in DllMain(). Unless the thread had already exited by the time the DLL_PROCESS_DETACH was received, doing so will always deadlock. This is the expected behaviour.
The reason for this is that calls to DllMain() are serialized, via the loader lock. When ExitThread() is called, it claims the loader lock so that it can call DllMain() with DLL_THREAD_DETACH. Until that call has finished, the thread is still running.
So DllMain is waiting for the thread to exit, and the thread is waiting for DllMain to exit, a classic deadlock situation.
See also Dynamic-Link Library Best Practices on MSDN.
The solution is to add a new function to your DLL for the application to call before unloading the DLL. As you have noted, your code already works perfectly well when called explicitly.
In the case where backwards compatibility requirements make adding such a function impossible, and if you must have the worker threads, consider splitting your DLL into two parts, one of which is dynamically loaded by the other. The dynamically loaded part would contain (at a minimum) all of the code needed by the worker threads.
When the DLL that was loaded by the application itself receives DLL_PROCESS_DETACH, you just set the event to signal the threads to exit and then return immediately. One of the threads would have to be designated to wait for all the others and then free the second DLL, which you can do safely using FreeLibraryAndExitThread().
(Depending on the circumstances, and in particular if worker threads are exiting and/or new ones being created as part of regular operations, you may need to be very careful to avoid race conditions and/or deadlocks; this would likely be simpler if you used a thread pool and callbacks rather than creating worker threads manually.)
In the special case where the threads do not need to use any but the very simplest Windows APIs, it might be possible to use a thread pool and work callbacks to avoid the need for a second DLL. Once the callbacks have exited, which you can check using WaitForThreadpoolWorkCallbacks(), it is safe for the library to be unloaded - you do not need to wait for the threads themselves to exit.
The catch here is that the callbacks must avoid any Windows APIs that might take the loader lock. It is not documented which API calls are safe in this respect, and it varies between different versions of Windows. If you are calling anything more complicated than SetEvent or WriteFile, say, or if you are using a library rather than native Windows API functions, you must not use this approach.
I have such problem when I try to inject code into another desktop process, WaitForSingleObject will cause the deadlock inside my thread. I solved the issue by trapping the window's default message procedure, hope it helps for others.
#define WM_INSIDER (WM_USER + 2021)
WNDPROC prev_proc = nullptr;
HWND FindTopWindow(DWORD pid)
{
struct Find { HWND win; DWORD pid; } find = { nullptr, pid };
EnumWindows([](HWND hwnd, LPARAM lParam) -> BOOL {
auto p = (Find*)(lParam);
DWORD id;
if (GetWindowThreadProcessId(hwnd, &id) && id == p->pid) {
// done
p->win = hwnd;
return FALSE;
}
// continue
return TRUE;
}, (LPARAM)&find);
return find.win;
}
// thread entry
int insider(void *)
{
// do whatever you want as a normal thread
return (0);
}
LRESULT CALLBACK insider_proc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
HANDLE t;
switch (uMsg) {
case WM_INSIDER:
t = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)insider, 0, 0, NULL);
CloseHandle(t);
break;
}
return CallWindowProc(prev_proc, hwnd, uMsg, wParam, lParam);
}
void setup() {
auto pid = GetCurrentProcessId();
auto win = FindTopWindow(pid);
prev_proc = (WNDPROC)SetWindowLongPtr(win, GWL_WNDPROC, (LONG_PTR)&insider_proc);
// signal to create thread later
PostMessage(win, WM_INSIDER, 0, 0);
}
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
setup();
break;
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}

C++ Windows: Access same variable from main process and CallWndProc process

I have a single-file DLL that receives and stores a _bstr_t as a global variable, then sets a Windows hook for the WH_CALLWNDPROC procedure.
In the CallWndProc function, I attempt to read the _bstr_t, but it has no value.
I printed out the variable's address from both functions and they are different.
This is not surprising as I think that the CallWndProc function is called in a different process' thread.
My question is, what is the easiest and best way to share the variable between them?
I am trying to avoid having to use ATL COM to store it for inter-process access.
Example code:
// foo.cpp
#include <comutil.h>
static HHOOK g_hook = NULL;
static _bstr_t shared = "";
static LRESULT WINAPI CallWndProc(int nHookCode, WPARAM wParam, LPARAM lParam) {
if (nHookCode == 12345) {
// Do something with '_bstr_t shared'
shared += " bar";
return 0;
}
return CallNextHookEx(g_hook, nHookCode, wParam, lParam);
}
extern "C" __declspec(dllexport) void _stdcall Do(char* someStr, long handle) {
shared = someStr;
DWORD threadId = GetWindowThreadProcessId((HWND) handle, &process);
HINSTANCE hInst = GetModuleHandle("foo.dll");
g_hook = SetWindowsHookEx(WH_CALLWNDPROC, CallWndProc, hInst, thread);
// Check value of '_bstr_t shared', or call a COM function to store it somewhere.
// However, the value of 'shared' does not include the string appended in CallWndProc.
}
Extra info:
DLL is called by Java using JNI.
DLL is built as a multi-threaded DLL.
I went with the ATL COM approach to act as a global store of values.
Not my ideal solution, but a workable one.
However, I think Hans Passant's comment on the question is a better way of doing it since it does not require a separate process to be running.

How to use SetTimer replace Sleep()?

I have a application that needs do something step by step, serially, like this:
...
func1();
Sleep(2000);
func2();
Sleep(3000);
func3();
...
As we know, calling Sleep() will cause the user interface to "freeze", so for example there is no response when trying to move the application window.
So, I tried using SetTimer() instead, as it seems that it would not cause the UI to freeze, but my question is how can I implement the same "waiting" function as Sleep() when using SetTimer()?
...
func1();
SetTimer(hwnd, ID_Timer2s,2000, Timerfunc2s);// how to make sure 2seconds waiting happen between func1 and func2?
func2();
SetTimer(hwnd, ID_Timer3s,3000, Timerfunc3s);
func3();
...
// my intention is kill the timer once timeout, then go back next func2(), how?
VOID CALLBACK Timerfunc2s(
HWND hwnd,
UINT message,
UINT idTimer,
DWORD dwTime)
{
KillTimer(hwnd, ID_Timer2s);
}
VOID CALLBACK Timerfunc3s(
HWND hwnd,
UINT message,
UINT idTimer,
DWORD dwTime)
{
KillTimer(hwnd, ID_Timer3s);
}
Thanks for any suggestions.
You want to run func2() only after ID_Timer2s expires, so run it when ID_Timer2s expires. Don't run it immediately.
...
func1();
SetTimer(hwnd, ID_Timer2s,2000, Timerfunc2s);
...
VOID CALLBACK Timerfunc2s(
HWND hwnd,
UINT message,
UINT idTimer,
DWORD dwTime)
{
KillTimer(hwnd, ID_Timer2s);
func2();
SetTimer(hwnd, ID_Timer3s,3000, Timerfunc3s);
}
VOID CALLBACK Timerfunc3s(
HWND hwnd,
UINT message,
UINT idTimer,
DWORD dwTime)
{
KillTimer(hwnd, ID_Timer3s);
func3();
}
As pointed out in the comments, this is not usually an appropriate design for a GUI application.
However, it can be appropriate for some very simple applications, e.g., those that perform a task that requires no user interaction, with a GUI that does nothing but provide feedback as to the progress of the task.
In such cases, and assuming that the code is not being called in the context of a window procedure, something like this should work:
...
func1();
MySleep(hwnd, 2000);
func2();
MySleep(hwnd, 3000);
func3();
...
BOOL MySleepTimerFlag;
void MySleep(HWND hwnd, DWORD timeout)
{
MySleepTimerFlag = FALSE;
SetTimer(hwnd, ID_MySleepTimer, timeout, MySleepTimerFunc);
while (MySleepTimerFlag == FALSE)
{
if (!GetMessage(&Msg, NULL, 0, 0)) fail();
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
}
VOID CALLBACK MySleepTimerFunc(
HWND hwnd,
UINT message,
UINT idTimer,
DWORD dwTime)
{
MySleepTimerFlag = TRUE;
KillTimer(hwnd, ID_MySleepTimer);
}
Note that this code was written off the cuff; I haven't attempted to compile it, never mind test it. But it should at least give you the idea.
Also, note that you can eliminate the global if it upsets you - attach a pointer as a window property or suchlike - but again, globals aren't really all that bad when used in very simple applications. :-)
Finally, the proviso that the call to MySleep() must not be in the context of a window procedure is important. That means that the first part of the code above must not, for example, be triggered by selecting a menu item. If it is, then you must use the approach outlined in Raymond's answer instead, or create a new thread as David suggested.
... also, as Raymond pointed out, you have to be careful that the GUI doesn't have any modal elements such as menus or dialog boxes, or at least that they are disabled while this code is running.
There are (at least) 3 options to do what you want. The first, using timers, Raymond Chen covered. The second, using a customized wait function, Harry Johnston covered. The third option is to create a thread, and do the work using that thread.
For example:
DWORD WINAPI ThreadProc(LPVOID lpThreadParameter)
{
func1();
Sleep(2000);
func2();
Sleep(3000);
func3();
...
return 0;
}
...
DWORD threadId = 0;
HANDLE hThread = CreateThread(NULL, 255, &ThreadProc, NULL, 0, &threadId);
The trouble comes when you need to interact with the UI. You can't directly do things to the UI from the alternate thread, but one technique you can use is to post messages to your UI and/or use shared state variables to affect the behavior of your UI thread.
Of course, it also should go without saying that as soon as you introduce threading, you also introduce the potential for hard to diagnose bugs, like race conditions and deadlocks. If func1, func2 or funcN modify global state you will need to synchronize access, either through critical sections, or some other synchronization method.

WaitForSingleObject for thread object does not work in DLL unload

I've stumbled upon an unexpected behavior of Windows thread mechanism when DLL is unloaded. A have a pack of worker thread objects and I'm trying to finish them graciously when DLL is unloaded (via DllMain DLL_PROCESS_DETACH). The code is very simple (I do send an event to finish the thread's wait loop):
WaitForSingleObject( ThrHandle, INFINITE );
CloseHandle( ThrHandle );
Yet the WaitForSingleObject hangs the whole thing. It works fine if I perform it before DLL is unloaded. How this behavior can be fixed?
You can't wait for a thread to exit in DllMain(). Unless the thread had already exited by the time the DLL_PROCESS_DETACH was received, doing so will always deadlock. This is the expected behaviour.
The reason for this is that calls to DllMain() are serialized, via the loader lock. When ExitThread() is called, it claims the loader lock so that it can call DllMain() with DLL_THREAD_DETACH. Until that call has finished, the thread is still running.
So DllMain is waiting for the thread to exit, and the thread is waiting for DllMain to exit, a classic deadlock situation.
See also Dynamic-Link Library Best Practices on MSDN.
The solution is to add a new function to your DLL for the application to call before unloading the DLL. As you have noted, your code already works perfectly well when called explicitly.
In the case where backwards compatibility requirements make adding such a function impossible, and if you must have the worker threads, consider splitting your DLL into two parts, one of which is dynamically loaded by the other. The dynamically loaded part would contain (at a minimum) all of the code needed by the worker threads.
When the DLL that was loaded by the application itself receives DLL_PROCESS_DETACH, you just set the event to signal the threads to exit and then return immediately. One of the threads would have to be designated to wait for all the others and then free the second DLL, which you can do safely using FreeLibraryAndExitThread().
(Depending on the circumstances, and in particular if worker threads are exiting and/or new ones being created as part of regular operations, you may need to be very careful to avoid race conditions and/or deadlocks; this would likely be simpler if you used a thread pool and callbacks rather than creating worker threads manually.)
In the special case where the threads do not need to use any but the very simplest Windows APIs, it might be possible to use a thread pool and work callbacks to avoid the need for a second DLL. Once the callbacks have exited, which you can check using WaitForThreadpoolWorkCallbacks(), it is safe for the library to be unloaded - you do not need to wait for the threads themselves to exit.
The catch here is that the callbacks must avoid any Windows APIs that might take the loader lock. It is not documented which API calls are safe in this respect, and it varies between different versions of Windows. If you are calling anything more complicated than SetEvent or WriteFile, say, or if you are using a library rather than native Windows API functions, you must not use this approach.
I have such problem when I try to inject code into another desktop process, WaitForSingleObject will cause the deadlock inside my thread. I solved the issue by trapping the window's default message procedure, hope it helps for others.
#define WM_INSIDER (WM_USER + 2021)
WNDPROC prev_proc = nullptr;
HWND FindTopWindow(DWORD pid)
{
struct Find { HWND win; DWORD pid; } find = { nullptr, pid };
EnumWindows([](HWND hwnd, LPARAM lParam) -> BOOL {
auto p = (Find*)(lParam);
DWORD id;
if (GetWindowThreadProcessId(hwnd, &id) && id == p->pid) {
// done
p->win = hwnd;
return FALSE;
}
// continue
return TRUE;
}, (LPARAM)&find);
return find.win;
}
// thread entry
int insider(void *)
{
// do whatever you want as a normal thread
return (0);
}
LRESULT CALLBACK insider_proc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
HANDLE t;
switch (uMsg) {
case WM_INSIDER:
t = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)insider, 0, 0, NULL);
CloseHandle(t);
break;
}
return CallWindowProc(prev_proc, hwnd, uMsg, wParam, lParam);
}
void setup() {
auto pid = GetCurrentProcessId();
auto win = FindTopWindow(pid);
prev_proc = (WNDPROC)SetWindowLongPtr(win, GWL_WNDPROC, (LONG_PTR)&insider_proc);
// signal to create thread later
PostMessage(win, WM_INSIDER, 0, 0);
}
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
setup();
break;
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}

CreateThread in 64bit DLL won't work

I have a 32 bit and a 64 bit executable. Both load a DLL that is of the same bit, as in the 64 bit executable loads a 64bit dll. Anyway, the 32 bit DLL works perfectly, it creates a thread and pops a hello world messagebox. The 64bit DLL however, that piece of code never executes. It's like the createthread fails.
case DLL_PROCESS_ATTACH:
myFunc();
break;
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
void myFunc()
{
HANDLE hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)&MyThread, NULL, 0, NULL);
}
DWORD WINAPI MyThread(LPVOID param)
{
MessageBoxA(0, "HELLO 64", 0,0);
ExitThread(0);
}
Those are the some snippets from the DLL. I've googeled and all I can come up with is that it's the stack alignment failing? If that is the reason, how do I properly call CreateThread to make it work? If that isnt the reason, does anyone know what might be wrong?
I'd be outmost grateful for any help, thanks in advance!
You have the wrong signature for MyThread. You should not cast it you should make sure your function matches the signature. The correct code would be:
CreateThread(NULL, 0, MyThread, NULL, 0, NULL);
DWORD WINAPI MyThread(LPVOID param)
{
// etc
}
Apart from that you should not do anything in your DllMain as #GSerg comments because there is a lock that is held while you are in there. By doing anything complex you can inadvertently load another DLL causing a deadlock.
Instead you would usually have a separate initialization function in your DLL that your calling code can call after it has loaded the DLL.
Ok the solve was simple, the thread exited too early. Adding WaitForSingleObject(hThread, INFINITE); solved the issue. Wasn't necessary in 32bit for some reason. :)