We help IT Professionals succeed at work.

SetWindowHookEx problem

Madnik7 asked
Medium Priority
Last Modified: 2013-12-03
I want to hook all windows that create in main thread of a remote process.
I create process with CreateProcess API and get id of its main thread, but to capture all windows, process created in suspend mode (CREATE_SUSPENDED).
I don?t know why SetWindowHookEx return error if dwThreadId of its parameter was suspended thread.
How could I Hook all window in remote process?

*(I don?t want install Global hook by set dwThreadId to zero)
*I call SetWindowHookEx with idHook=WH_CBT
*My Hook procedure exist in dll
*My program work correctly when thread has not suspended
Watch Question

Well I certainly wouldn't have expected your DLL to actually get loaded until the thread was resumed, but I'm surprised that SetWindowsHookEx actualy fails just because the target thread is suspended.

What does GetLastError() return after SetWindowsHookEx returns NULL (failure).

PS If using Visual C you can check this by simply adding a watch on the following expression:   err,hr
and then step over the function call

If I understand you correctly, you want to create the process suspended so that you have time to install the cbt hook before the main window of the new process is created.  If that's the case, and SetWindowsHookEx is failing on a suspended thread, what about using an event to keep the main window from being created until after the hook is installed?  Maybe something like this?...

   HANDLE hEvent = CreateEvent (NULL, FALSE, FALSE, "MyEvent");

   CreateProcess (...);

   SetWindowsHookEx (..., idNewProcessThread);

   SetEvent (hEvent);  // signal new process to go ahead
   CloseHandle (hEvent);

Then in the new process...

      HANDLE hEvent = CreateEvent (NULL, FALSE, FALSE, "MyEvent");
      DWORD nWaitResult = WaitForSingleObject (hEvent, /* reasonable amt of time */);
      CloseHandle (hEvent);

      if (nWaitResult == WAIT_OBJECT_0)
         // go ahead and create main window


robpitt >> GetLastErr() return 87 (means theard id is invalid)
If I call ResumeThread() before Call SetWindowHookEx , it would not fail.

The Master>> I have not access to remote process source code


The concensus seems to be that you cannot hook a suspended thread.

Slso see the thread at:
There are lots of obstacles in the road you want to go down.

1. If you set a hook, others may also set hooks in the process.  Their hooks will get called before yours, and they may not call CallNextHook(), depriving you of the information you desire.

2. Even if the create suspended worked, you have no control over WHEN your library gets loaded into the process address space.  You are relying on the system to load your dll into the process and it may have loaded other dlls into the address space by then.  You would like to be loaded at the moment USER32.DLL is loaded & initialized, it's the soonest you can do any useful work.  Any later and other code may beat you to the punch.

To get more control over when your dll gets loaded, read about existing interception techniques.  I'd recommend Matt Pietrick's "Windows 95 System Programming Secrets" for a discussion of 1 interception scheme.  It suffers from the flaw of acting as a debugger, which has many unexpected negative consequences with real applications.  Jeffery Richter has an article on MSDN which discusses interception, and the Microsoft site has some code for another interception scheme which I have no experience with.

One good test case for you: Make a simple EXE which depends implicitly on a DLL which creates a message box in DLL_PROCESS_ATTACH.  Whatever scheme you choose should be able to hook that message box.

Explore More ContentExplore courses, solutions, and other research materials related to this topic.