1

I need to inject a dll into one or more external processes, from which I also want to intercept keybord events. That's why using SetWindowsHookEx with WH_KEYBOARD looks like an easy way to achieve both things in a single step.

Now I really don't want to install a global hook when I'm only interested in a few selected processes, but Windows hooks seem to be either global or thread-only.

My question is now how I would properly go about setting up a process-wide hook.

I guess one way would be to set up the hook on the target process' main thread from my application, and then doing the same from inside my dll on DLL_PROCESS_ATTACH for all other running threads (plus on DLL_THREAD_ATTACH for threads started later). But is this really a good way? And more important, aren't there any simpler ways to setup process-wide hooks? My idea looks quite cumbersome und ugly, but I wasn't able to find any information about doing this anywhere.

mfya
  • 352
  • 4
  • 9

1 Answers1

3

Check out the code in this post, it has some decent code that is doing what you seem to want. This uses a global hook, which would be the best in your case.

Edit:

In reply to Ben's comment on wondering how it could be done to inject a hook into a specific process to watch specific threads:

  • Ensure your injector process is running with administrative privs.
  • Do an OpenProcess on your injector code, and get the SeDebugPrivilege priv.
  • Use OpenProcess on your target, with PROCESS_CREATE_THREAD, VM_READ / WRITE privs.
  • VirtualAlloc some memory in your target process, make it PAGE_EXECUTE_READWRITE.
  • Write the path and name of your hook DLL into that memory.
  • Get the module handle for kernel32.
  • Get the proc address of LoadLibraryW in kernel32.
  • Call CreateRemoteThread on your target, giving it the address of LoadLibraryW, with the address of your hook dll string you allocated.
  • WaitForSingleObject on your remote thread for it to finish loading
  • Clean up

Don't forget to repeat for each process you want to hook. Also, make sure your hook code handles thread creation / deletion for your hooked processes, so you can hook those threads as well.

If you read that a global WH_KEYBOARD hook was a bad idea, you can begin to see why this approach may be even worse.

Community
  • 1
  • 1
GalacticJello
  • 11,235
  • 2
  • 25
  • 35
  • Your example uses global hooking while this is a specific request for hooking individual processes. – Ben Bryant Apr 09 '12 at 19:13
  • As hooks can be only associated either with a specific thread, or with all threads in the same desktop, what would you suggest we should use to monitor "one or more external processes"? – GalacticJello Apr 10 '12 at 21:25
  • one way could be enumerate all threads of current process and set hook for all those threads. – vicky Apr 11 '12 at 04:36
  • "But is this really a good way?" - No. A global hook on the WH_KEYBOARD is the only sensible solution. Keyboard input is limited. The event count will be minimal compared to say a WH_MOUSE hook. The complexity and plumbing required to inject into current (and future) threads of a process would be ridiculous, error-prone, and unsupportable. – GalacticJello Apr 11 '12 at 15:40
  • A global hook should be avoided when possible, but even if you choose to argue that point you are still not answering the question here. Some of us actually want to know how to implement a process-wide hook. – Ben Bryant Apr 23 '12 at 20:43
  • @Ben - pseudo code posted. I can get more specific, but googling the API calls involved should direct you to several thread injection projects. – GalacticJello Apr 23 '12 at 21:40