簡體   English   中英

向應用程序發送擊鍵,SendKeys.Send()vs SendMessage()

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM