DInput and global key hooks (Vista/Win7)

Started by
14 comments, last by mattd 14 years, 6 months ago
Here are some links with info that might help you to write a hack to keep your hook at the beginning of the chain.

Reversing Windows hook chains (with Softice and breakpoints revisited - the info here is more useful, imo).

Any application-defined hook procedure on my machine?

hook chain is invoked in lifo order
"I thought what I'd do was, I'd pretend I was one of those deaf-mutes." - the Laughing Man
Advertisement
From what I've been reading the only way to modify the hook chain is using undocumented "hacks" which seem to work differently based on the OS. This is probably not a feasable route to take.

I guess another way would be to API hook GetVersion/GetVersionEx to trick dinput.dll into using Raw Input. I'm not even sure if it's possible to attach a dll to another dll's to hook it's API calls.

Any more suggestions?
Quote:Original post by Headkaze
From what I've been reading the only way to modify the hook chain is using undocumented "hacks" which seem to work differently based on the OS. This is probably not a feasable route to take.

I guess another way would be to API hook GetVersion/GetVersionEx to trick dinput.dll into using Raw Input. I'm not even sure if it's possible to attach a dll to another dll's to hook it's API calls.

Any more suggestions?


From what I could tell from the info on those pages, the hook chain can be accessed in user space, that is, on 32 bit systems, addresses below 0x80000000. It's still a hack.

To hook API calls you don't attach a dll to another dll, you have to attach your dll to the process that has loaded the dll with the API's that you're interested in hooking. From there you would read the pe file header, searching for the dll you're after, and from there hook the api call through the export table of the dll, and if that doesn't work then hook the call directly. It's a lot of set up work and it's still a hack.
"I thought what I'd do was, I'd pretend I was one of those deaf-mutes." - the Laughing Man
Quote:Original post by Headkaze
Incidently how did you discover that info?

Poking around the disassembly with the freeware version of IDA. Start off looking for CreateThread calls to see where the listening thread code is, seeing that it has different behaviour depending on the value of a 'g_fRawInput' variable, finding where it gets set and how and voila.

Quote:So the question now is; is it possible to always stay at the beginning of a hook chain?

Not that I know of, except for constantly rehooking but that's completely impractical.

Quote:If they are forcing DInput to use hooks then how are they staying at the beginning of the hook chain to block the key presses?

I don't think they are, note that your second quote says:
Quote:allowing previous keyboard hooks to attempt to process the keyboard events before the fix processes them out.

Seems to be clearly indicating that all hooks before it in the chain do whatever processing they want. If the input survives to the end of the chain, only then is it filtered out by this special hook before Windows gets to do its thing, transforming it into the event that launches the Alt-Tab window for example.

Quote:
I guess another way would be to API hook GetVersion/GetVersionEx

You'd need be involved pretty early, the version check is in its DllMain. By the time your code establishes a program uses DInput you'd already be too late. You'd need a driver to monitor process creation and a user program to check the exe file's import tables and to modify the versioning info. It's an approach, but permanently changing a process' system version to 5.x could lead to all kinds of odd behaviour.

A more reasonable alternative is something like this. You might not be able to stop the hook from receiving key presses, but you might be able to prevent dinput from reporting them.
I have done API hooking in the past using IAT hooking as well as hooking DInput like that link you gave. I was just hoping for an easier way to do things because it needs to be system wide key blocking I would have to create proxy functions for every version of DInput.

Quote:Seems to be clearly indicating that all hooks before it in the chain do whatever processing they want. If the input survives to the end of the chain, only then is it filtered out by this special hook before Windows gets to do its thing, transforming it into the event that launches the Alt-Tab window for example.


What I don't understand though is if this program "intercepts the RegisterRawInputDevices API ... (which) forces the included hooks to be ignored and forces DInput to use Windows-specific hooks." and that it supports dinput.dll, dinput8.dll, dinput9.dll then they are saying that it's possible to block keypresses in DInput using this method. I think what you mention is related to other global key hooks and not DInput afterall the purpose of this program is to block keys in games. If this program can do it then it would be interesting to know how although I don't think the source to this app is available to the public.
Thread has kind of gone to sleep, but..

Quote:Original post by Headkaze
I have done API hooking in the past using IAT hooking as well as hooking DInput like that link you gave. I was just hoping for an easier way to do things because it needs to be system wide key blocking I would have to create proxy functions for every version of DInput.


FWIW I took a look using IDA at versions of dinput.dll from an XP machine (5.03.2600.2180) and a Vista one w/ latest DirectX runtime (6.0.6000.16386). Funnily enough the XP one had a proper version check routine, while the later Vista one didn't. I couldn't see any way apart from intercepting the call to GetVersionEx to ensure the Is-At-Least-Win2k flag is correctly set, and therefore stopping the low-level keyboard (and mouse) hooks from being installed. (at least without using even more hacky techniques)

Quote:Seems to be clearly indicating that all hooks before it in the chain do whatever processing they want. If the input survives to the end of the chain, only then is it filtered out by this special hook before Windows gets to do its thing, transforming it into the event that launches the Alt-Tab window for example.

What I don't understand though is if this program "intercepts the RegisterRawInputDevices API ... (which) forces the included hooks to be ignored and forces DInput to use Windows-specific hooks." and that it supports dinput.dll, dinput8.dll, dinput9.dll then they are saying that it's possible to block keypresses in DInput using this method. I think what you mention is related to other global key hooks and not DInput afterall the purpose of this program is to block keys in games. If this program can do it then it would be interesting to know how although I don't think the source to this app is available to the public.


You kind of answered your question with the first paragraph.. DirectInput still receives the ALT+TAB keypresses - so no blocking occurs here. The only blocking is at the lowest point in the low-level keyboard hook chain, where the keys are discarded to stop Windows from showing its ALT+TAB dialog. You can verify this for yourself by using the Application Compatibility Toolkit to apply that IgnoreAltTab fix to, say, the Keyboard DirectInput example app, and seeing that it still sees the keys, just no dialog appears.

This topic is closed to new replies.

Advertisement