Detect if keyboard or mouse events are triggered by a software
Asked Answered
J

1

5

Is there a way to determine whether the keyboard or mouse events are triggered from a hardware rather than an application like TeamViewer, Steam or some other remote desktop software in a desktop application running on Windows?

My purpose is not to prevent bots, but to prevent remote access to the application.

It seems that RawInput API lets me detect fake events sent using SendInput API. Is it correct?

Jacobian answered 24/5, 2016 at 10:55 Comment(4)
Your lateral question (raw input) is not discussed in the post that your question is closed as a duplicate. If you want it to be answered (if it's not already elsewhere) try asking only about it.Symon
The answers to the duplicate question don't cover another possible detection route - low-level keyboard/mouse hooks from SetWindowsHookEx() do report if input is real or simulated. AFAIK, the Raw Input API does not.Princeling
@Remy - The older documentation for GetRawInputDeviceInfo had a note for 'hDevice': "Handle to the raw input device. [...] It can also be NULL if an application inserts input data, for example, by using SendInput. ". Can find it in for instance XE2's api docs. This note is removed from the documentation now, I don't know why, but GetRawInputDeviceInfo should normally be able to tell the difference.Symon
I reopened the question. The comments and answers in the marked duplicate, all of them, somehow, seems to me that they've approached the problem in a quite roundabout way.Symon
P
11

The low-level keyboard/mouse hooks provided by SetWindowsHookEx() report if input was generated by actual devices or injected by application code.

For a low-level keyboard hook, the hook provides a pointer to a KBDLLHOOKSTRUCT structure, which has a flags member that contains a LLKHF_INJECTED flag for fake input.

For a low-level mouse hook, the hook provides a pointer to a MSLLHOOKSTRUCT structure, which has a flags member that contains either a LLMHF_INJECTED or LLMHF_LOWER_IL_INJECTED flag for fake input.

Either hook can return a non-zero value to block the input from being passed to the rest of the hook chain, and consequently to the target window.

Regarding the Raw Input API, according to (an older version of 1) the documentation for the GetRawInputDeviceInfo() function:

hDevice [in, optional]
Type: HANDLE

A handle to the raw input device. This comes from the lParam of the WM_INPUT message, from the hDevice member of RAWINPUTHEADER, or from GetRawInputDeviceList. It can also be NULL if an application inserts input data, for example, by using SendInput.

1: the highlighted note has been removed in the current version of the documentation, I do not know why.

So, the hDevice that is reported by a WM_INPUT message will be NULL for fake input.

however, it is not possible to block input with the Raw Input API. You still need a low-level hook for that.

Princeling answered 24/5, 2016 at 20:8 Comment(2)
I tried using the SetWindowsHookEx() but the KBDLLHOOKSTRUCT.flags value was always 128 (whether I ran it locally or through Remote Desktop). Any idea why?Viminal
@SamGoldberg you would have to show your actual code (in a new post). 128 means bit 7 (the transition state) is 1, ie when a key is being released.Princeling

© 2022 - 2024 — McMap. All rights reserved.