[英]Sending keystrokes to an application, SendKeys.Send() vs SendMessage()
我创建了一个简单的机器人来自动化游戏中的某些东西。 我目前通过将游戏窗口带到前台并使用SendKeys发送密钥来向游戏发送命令,如下所示:
SendKeys.Send("{ENTER}")
我想知道的是,从可检测性的角度来看,如果反作弊引擎更容易检测到这样的事情(使用SendMessage ):
public static void SendKeystroke(ushort k)
{
const uint WM_KEYDOWN = 0x100;
const uint WM_SYSCOMMAND = 0x018;
const uint SC_CLOSE = 0x053;
IntPtr WindowToFind = FindWindow(null, "Untitled1 - Notepad++");
IntPtr result3 = SendMessage(WindowToFind, WM_KEYDOWN,
((IntPtr)k), (IntPtr)0);
}
SendKeystroke(Keys.Enter);
最后,游戏会收到输入键的keydown事件,对吧?
SendKeys.Send
通常使用SendInput
。 基于日志挂钩的替代方法对于UAC是不可行的,因此我们假设SendKeys.Send
解析为SendInput
。 SendMessage
以同步方式将消息直接传递给窗口过程。 所以,这更容易检测。 好吧,肯定答案是SendMessage
。 这些是到达窗口过程的输入消息,而没有通过调用GetMessage
从队列中取出。 这很容易被发现。 您只需记录有关从队列中提取的最新消息的一些信息,并在窗口过程中,根据最新排队的消息检查消息。
现在,区分SendInput
和真实的人类输入可能比那更难。 我很确定它有可能。 一种方法是安装低级键盘钩子并查找LLKHF_INJECTED标志。 更难,但不是那么难。
这是一个概念性问题,也是技术问题。
SendKeys.Send() - 是WinAPI SendInput()函数的Windows窗体包装器。 此功能直接用于鼠标和键盘输入流。 虽然有一些限制(请阅读相关文档)。
SendMessage() - 是一个WinAPI函数。 它用于将特定消息发送到窗口。 除鼠标或键盘输入外,它还可用于发送其他消息。 这是一种更高级别的消息传递队列,其中许多其他消息被聚合,以发送到窗口。 在进程之间编组消息也存在限制。
可检测性 :这实际上取决于你可以模仿按下按钮的过程有多好,以及你所反对的反作弊引擎有多好。 当人按下按钮时,几乎没有其他消息被发送到窗口。 除WM_KEYDOWN外,还有WM_KEYUP和其他一些。 您的任务是尽可能地重新创建该序列。 您将不得不对此主题进行自己的研究。 您已经可以看到人类按下按钮,不可能创建只向窗口发送WM_KEYDOWN的情况, WM_KEYUP必须跟进。 两者之间的延迟应该是人类可能的等等......
我也相信,SendMessage()可能无法正常运行游戏,因为他们中的许多人使用DirectX DirectInput,在这种情况下,我认为WinAPI SendInput()函数可以做得更好,因为它是一个较低级别的API并且可以工作直接与输入流。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.