【问题标题】:How to detect if mouse click is legit or automated?如何检测鼠标点击是合法的还是自动的?
【发布时间】:2011-02-23 13:52:31
【问题描述】:

如何知道是否模拟了鼠标点击?当鼠标点击时由程序或真实鼠标设备发送

...我正在为游戏编写系统检测程序,以避免只接受合法鼠标点击的机器人、自动点击等

【问题讨论】:

  • 忽略点击。如果再次单击,则很可能是真正的鼠标。忽略那个,如果你得到很多点击,你可以确定有一个愤怒的用户试图点击......
  • 不可能。计算机以相同的方式解释它们,这就是重点。否则,模拟鼠标事件不可能具有与真实鼠标单击相同的功能。毫无疑问,无论您想要实现什么,都有更好的方法。
  • @T33C 如果这个(细化细节)要求出于某些有用的目的需要检测,以改变程序行为或强制用户,那么它必须完全阻止脚本的使用。否则它是一个毫无意义的练习。
  • 你让 AI 很痛苦,因为不允许两个游戏互相对抗。神经网络可能需要大量点击来训练。

标签: c++ vb.net


【解决方案1】:

这在一定程度上取决于您正在编写的应用程序类型,但如果可以的话,我会观察光标移动,而不是点击。 人类鼠标移动具有不均匀的速度、反应时间、不精确性(点击按钮的不同坐标等...)。

此外,您可以通过随机要求难以编写脚本的交互来保护 gui 免受机器人攻击。例如:如果脚本依赖于按钮始终处于相同位置,我会确保在保持直观的同时,对话框每次弹出的位置都会略有不同。

否则:无法检测鼠标是真实的还是模拟得非常好的鼠标。 Windows HID/MacOS/Linux 驱动层抽象出鼠标、轨迹笔、轨迹球、绘图板、触摸屏......当然还有脚本鼠标......

【讨论】:

    【解决方案2】:

    虽然博客文章本身是关于不同的问题,但我建议您参考 Raymond Chen 的优秀Old New Thing。在这篇具体的博客文章中,他谈到了进入应用程序的消息参数的有效性,但也指出:

    没有必要讨论消息的发送者是否在耍花招和对你撒谎,因为 (1) 你的程序应该顺着这个诡计去响应虚假的菜单消息,就好像它们是真正的菜单消息一样,因为(2) 无论如何,没有办法说你被骗了。要检测撒谎,您必须能够读懂向您发送消息的程序员的心态。

    本质上的论点是,无论这些点击是如何产生的,您都应该以鼠标点击的方式响应鼠标点击。

    【讨论】:

      【解决方案3】:

      mouse keys 是模拟鼠标输入还是合法的?模拟鼠标输入的目的是使它们看起来与真实的鼠标输入完全一样。 如果模拟正在完成它的工作,那么你的工作是不可能的。对不起,这对你来说是软件的福与祸。以下是一些更不完美的想法:

      1. 使用GetKeyboardState 并验证按钮状态是否正确。如果消息伪造者使用PostMessage,他们可能不会设置键盘状态,这表明伪造。
      2. 如果您的目标是执行输入模拟的已知应用程序,请检测它们并进行投诉。这一点都不完美,原因有很多。
      3. 模糊逻辑,正如许多其他人所建议的那样。

      您需要有创意,并找出模拟事件和真实事件之间的区别对您而言,因为没有通用的答案。

      【讨论】:

        【解决方案4】:

        无法做到(可靠(无论如何仅使用软件))

        我使用 WIN32API 调用来读取像素/操纵鼠标/发送击键来自动化大部分视频游戏和其他重复性任务。您可以编写大量代码来分析输入,但同样聪明的开发人员只会修改他们的代码以匹配。

        当我第一次尝试自动执行鼠标点击时,我会这样做。发送鼠标点击。大多数时候它都有效。您可能拥有跟踪鼠标移动的代码以及随着合法点击触发的整个鼠标事件堆栈,并说“那不是真实的 - 我们忽略它”,但没有什么能阻止开发人员实现鼠标移动。

        鼠标事件比按键事件更复杂;但这本质上是相同的想法。如果您编写代码来监控按键之间的时间,并确定我以 250 毫秒的间隔将“2”键发送到您的应用程序,您可能会认为我是机器人。但是,我要做的就是修改我的代码以在 250 毫秒内发送击键 + 一个介于 -25 到 25 毫秒之间的随机值。

        这是一场永无止境的猫捉老鼠游戏。最好的解决方案是让任务变得不平凡,因此简单的自动化形式不适用。

        【讨论】:

          【解决方案5】:

          这个问题在细节上有点薄。

          事件可以直接发送到控件而无需移动鼠标,所以当你得到点击事件时找出鼠标在哪里,看看它是否在控件上。键盘输入需要控制焦点,所以也要检查一下。

          对于鼠标移动的情况,您将无法判断鼠标移动是否被记录和回放。如果它是脚本化的,那么也许您可以在控件的父面板中监视鼠标行为,并使用这些事件和移动来确定它是否真实。自动点击可能会不知从何处出现,并导致一连串不太可能的悬停、焦点事件。

          【讨论】:

            【解决方案6】:

            唯一可行的方法是使用鼠标本身的一些专业硬件和软件来发送实际机械点击的证据。通过软件这是不可能的。

            【讨论】:

              【解决方案7】:

              虽然在我的另一个答案中我提到理想情况下您应该将点击响应为点击,但有一种可能会起作用,具体取决于“程序化”点击的生成方式。

              由于“vb.net”标签,我假设是 Windows 平台:

              使用 WinAPI,您可以向任何窗口发送消息以模拟 WM_LBUTTONDOWN 事件等。在此消息中,您将包含按下按钮时鼠标的 X 和 Y 位置 - 或者接收程序期望它的位置。当您处理消息时,您可以使用GetCursorPos 调用来获取实际的光标位置。验证当前位置是否与消息中的位置接近,并将其作为点击处理,否则忽略它。

              但是请记住,消息队列的性质是,它可能需要一些时间来处理事件,并且鼠标可以在很短的时间内移动很长一段距离。

              此解决方案仅在“点击”由简单的 Send/PostMessage 生成时才有效。如果生成点击的应用程序也模拟了鼠标的移动,那么您可能应该看到其他答案:)

              【讨论】:

              • 不幸的是,这还不够;它会导致太多的误报。消息滞后将意味着没有表现良好的“接近度”阈值。不过,这是值得深思的。
              【解决方案8】:

              您可以检查鼠标事件标志 LLMHF_INJECTED 和 LLMHF_LOWER_IL_INJECTED 或利用输入挂钩来监视鼠标输入数据,其中格式错误的数据可能表明输入已注入。

              https://docs.microsoft.com/en-us/windows/win32/api/winuser/ns-winuser-msllhookstruct https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-setwindowshookexa

              【讨论】:

                【解决方案9】:

                我不确定是否有一种方法可以完全准确地确定鼠标单击是否是自动的。我的意思是,您可以编写自己的 USB 驱动程序,该驱动程序位于本地鼠标驱动程序和操作系统之间,并且只向您传递“真实”点击。然而,即使是这种情况,也可以通过插入 USB 设备(如智能手机)来解决,该设备被编程为向主机发送 USB 数据包。

                你想要完成什么需要你区分真正的鼠标点击和虚假的点击?

                【讨论】:

                  【解决方案10】:

                  通过在程序中记录过去的 X 鼠标事件来创建统计学习解决方案。当用户点击控件时,根据最后 X 个动作确定它是真正点击的概率。

                  使用真正的点击和各种自动化场景来训练您的解决方案。

                  这显然不是一个保证工作的解决方案,而且比其他任何事情都更有趣。

                  【讨论】:

                    【解决方案11】:

                    这比您想象的要困难得多,因为输入宏程序会为您的游戏生成合法鼠标和键盘输入消息。我认为没有办法检查输入消息是否实际上是由物理硬件输入(如鼠标或键盘)触发的,除非操作系统为您提供输入驱动程序级别的可访问性。

                    由于这是专门针对游戏的,您可以了解其他游戏如何处理这种情况。一些常见的方法是,

                    1. 检查鼠标点击的频率。 (人类的点击速度不如程序。)

                    2. 在随机点或怀疑时,使用CAPTCHA进行验证。 (阅读:http://www.threadmeters.com/v-1Vvd/CAPTCHA_The_Obvious_AntiBot_Solution/

                    3. 使用外部监控工具检查机器中运行的所有进程,找出已知的作弊程序。 Steam 就是这样做的。检查Valve Anti-Cheat System 暴雪的魔兽世界也对Warden 做同样的事情。

                    我自己的建议是“使用你的游戏系统”。由于每个游戏都有自己的规则和游戏风格,因此检测玩家是否作弊并不难。这种方法不是一个通用的解决方案,它可能很愚蠢,但如果它适用于您的游戏,为什么不呢? :)

                    【讨论】:

                      【解决方案12】:

                      有两种方法可以解决这个问题。

                      1. 制作一个新按钮,其中包含一个文本,证明用户没有 AFK,如果用户没有按下按钮,则将他或她踢出去。在随机位置生成按钮。
                      2. 如果用户有一段时间没有移动,(例如,10 分钟)将他或她踢出去。

                      【讨论】:

                        猜你喜欢
                        • 2011-11-21
                        • 1970-01-01
                        • 1970-01-01
                        • 1970-01-01
                        • 2018-03-17
                        • 1970-01-01
                        • 1970-01-01
                        • 2020-04-18
                        • 1970-01-01
                        相关资源
                        最近更新 更多