向应用程序发送击键,SendKeys.Send()vs SendMessage()

Joh*_*han 8 c# winforms

我创建了一个简单的机器人来自动化游戏中的某些东西.我目前通过将游戏窗口带到前台并使用SendKeys发送密钥来向游戏发送命令,如下所示:

SendKeys.Send("{ENTER}")
Run Code Online (Sandbox Code Playgroud)

我想知道的是,从可检测性的角度来看,如果反作弊引擎更容易检测到这样的事情(使用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);
Run Code Online (Sandbox Code Playgroud)

最后,游戏会收到输入密钥的keydown事件,对吧?

Dav*_*nan 4

  • SendKeys.Send通常使用SendInput. 基于日志挂钩的替代方法对于 UAC 来说不可行,因此我们假设SendKeys.Send解析为SendInput.
  • SendMessage以同步方式将消息直接传递到窗口过程。

所以,哪个更容易检测到。嗯,答案肯定是SendMessage。这些是到达窗口过程的输入消息,而无需通过调用将其从队列中拉出GetMessage。这很容易被发现。您只需记录有关从队列中提取的最新消息的一些信息,然后在窗口过程中根据最新排队的消息检查该消息。

现在,区分SendInput真实的人类输入可能比这更难。我很确定这是可能的。一种方法是安装低级键盘挂钩并查找 LLKHF_INJECTED 标志。更难,但也没有那么难。