检测键盘或鼠标事件是否由软件触发

5

有没有办法确定键盘或鼠标事件是来自硬件还是应用程序,比如TeamViewer、Steam或其他在Windows上运行的远程桌面软件?

我的目的不是为了防止机器人,而是为了防止远程访问应用程序。

看来RawInput API让我可以检测使用SendInput API发送的虚假事件。这是正确的吗?


你的侧面问题(原始输入)在被关闭的重复帖子中没有被讨论。如果你想得到答案(如果它还没有在其他地方被回答),请只询问关于它的问题。 - Sertac Akyuz
重复问题的答案并没有涵盖另一种可能的检测路径——从SetWindowsHookEx()中的低级键盘/鼠标钩子确实报告输入是真实还是模拟的。据我所知,原始输入API则不会 - Remy Lebeau
1
@Remy - GetRawInputDeviceInfo 的旧文档中对于'hDevice'有一个注释: *"原始输入设备的句柄。[...] 如果应用程序通过使用SendInput插入输入数据,也可以为NULL。"*。例如,可以在XE2的API文档中找到它。现在该注释已从文档中删除,我不知道为什么,但是GetRawInputDeviceInfo通常应该能够区分。 - Sertac Akyuz
我重新打开了这个问题。标记为重复的评论和答案,所有的东西,在某种程度上,似乎它们以相当迂回的方式处理了这个问题。 - Sertac Akyuz
1个回答

11

SetWindowsHookEx()提供的低级键盘/鼠标钩子会报告输入是由实际设备生成还是由应用代码注入的。

对于低级键盘钩子, 钩子提供一个指向KBDLLHOOKSTRUCT结构的指针,该结构具有一个flags成员,其中包含一个LLKHF_INJECTED标志以表示假输入。

对于一个低级别鼠标钩子,钩子提供了指向MSLLHOOKSTRUCT结构的指针,该结构具有一个flags成员,其中包含一个LLMHF_INJECTEDLLMHF_LOWER_IL_INJECTED标志用于虚拟输入。
任一钩子都可以返回非零值以阻止输入被传递到其余的钩子链,因此也就无法传递给目标窗口。
关于原始输入 API,根据旧版1GetRawInputDeviceInfo()函数文档:

hDevice [输入,可选]
类型:HANDLE

原始输入设备的句柄。它来自WM_INPUT消息的lParam,RAWINPUTHEADER的hDevice成员或GetRawInputDeviceList。如果应用程序通过使用SendInput插入输入数据,则它也可以为NULL。

1:文档的当前版本已删除了突出显示的注释,我不知道为什么。

因此,WM_INPUT消息报告的hDevice对于虚假输入将为NULL。

但是,使用原始输入API无法阻止输入。您仍然需要一个低级挂钩。


我尝试使用SetWindowsHookEx()函数,但是KBDLLHOOKSTRUCT.flags值始终为128(无论我是在本地运行还是通过远程桌面运行)。有任何想法为什么会这样吗? - Sam Goldberg
1
@SamGoldberg,您需要展示您的实际代码(在新帖子中)。128表示第7位(过渡状态)为1,即当释放键时。 - Remy Lebeau

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接