tags:

views:

428

answers:

3

Hello. If an application (mine, or in an external process, for example) called SetWindowsHookEx, would it be possible for me to unhook the hook? Remember that it wasn't me who made the hook first place, so I don't have any kind of variables or pointers to the original hooks.

A: 

I don't think you can. You need the handle to the hook that was registered with SetWindowsHookEx() so you can unhook it with UnhookWindowsHookEx()

Hmms btw, if you somehow could create your own hook before any other hook is registered (i.e. during application start up), you could in that hook choose to not call CallNextHookEx() and thus prevent subsequent hooks to be called. Might be worth checking out. I suspect that this might not be possible for all types of hooks.

Magnus Skog
+3  A: 

No, there isn't.

Back in the day (pre-NT era) you might have gotten away with playing some games with an HHOOK you obtained, as the returned HHOOK was a link in the chain of hooks to be called. Even then I'm not sure it was possible.

Today, Windows doesn't delegate the invocation of the next hook in the chain to you (thus the deprecated parameter to CallNextHookEx) and HHOOKs don't let you reach out to hooks you didn't register anymore.


More properly, there is no good and supported way to do this.
You could install a rootkit, dig deep into Windows internals and find the hook chain that way; but that's obviously going to ridiculous - and dangerous - lengths.

Hooking (via one of the myriad API hooking solutions out there, Detours seems popular) SetWindowsHookEx and CallNextHookEx can get you most of the way there for applications that conform to pre-NT conventions. The gist is to immediately unhook new hooks after calls to SetWindowsHookEx, unhook any passed hooks (that aren't your own) to CallNextHookEx. To guarantee a "clean" application, you'd also have to simulate a number of events to force any already called hooks to be invoked so they can be unhooked. Also, this regime will fail as soon as you encounter any of the applications written in the last 8+ years that pass NULL to CallNextHookEx.

So even though it is technically possible (maybe) to unhook HHOOKs your app didn't register, you're probably better off trying to accomplish whatever it is you're after a different, less horribly brittle way.

Kevin Montrose
A: 

Actually, I think I discovered that yes, it is possible. Hooking CallNextHook will give you the hook id of the hook, which you can use to unhook.

Jorge Branco
Out of both professional curiousity and a desire for a "proper" answer; can we get some code to this effect in this answer?
Kevin Montrose
Just used an API called Deviare, you can google it. It let's you hook functions in like 5 lines, so you just have to hook CallNextHook, and if hook != 0, call UnhookWindowsEx() on it.
Jorge Branco
You haven't been required to pass in hook to CallNextHookEx since Windows Me, so I this is going to break for some apps. Also, the hook has to run at least once before you can unhook it so you can't reliably say "this application is not hooked by [hook type here]".Regardless, I'll update my answer to make it more "complete".
Kevin Montrose