1

Тема: AHK: Проверка на эмуляцию передвижения мыши.

Привет всем.

У меня есть программа, которая перетаскивает курсор мыши в определенные координаты (не АХК) и хочу сделать так, чтобы мой АХК скрипт мог понять, реально ли я вожу мышкой или это делает другая программа, тем самым предпринимал затем какие-то действия.

Реализуемо?

2 (изменено: teadrinker, 2021-03-23 05:12:57)

Re: AHK: Проверка на эмуляцию передвижения мыши.

Такой скрипт будет выдавать информацию о событиях мыши. Если событие эмулированное, INJECTED: 1.

#Persistent
Setbatchlines, -1

hHook := new WindowsHook(WH_MOUSE_LL := 14, "LowLevelMouseProc")

LowLevelMouseProc(nCode, wParam, lParam)  {
   static oMem := [], lpData, size := VarSetCapacity(lpData, 16 + A_PtrSize*2, 0)

   DllCall("msvcrt\memmove", Ptr, &lpData, Ptr, lParam, Ptr, size)
   oMem.Push([wParam, &lpData])
   timer := Func("EventHandling").Bind(oMem)  ; во избежание фризов мыши обработка событий должна
   SetTimer, % timer, -10                     ; происходить по таймеру, а не в теле этой функции
   Return DllCall("CallNextHookEx", "Ptr", 0, "Int", nCode, "Ptr", wParam, "Ptr", lParam)
}

EventHandling(oMem)  {
   static oMsg := { 0x200: "WM_MOUSEMOVE"
                  , 0x201: "WM_LBUTTONDOWN", 0x202: "WM_LBUTTONUP"
                  , 0x204: "WM_RBUTTONDOWN", 0x205: "WM_RBUTTONUP"
                  , 0x207: "WM_MBUTTONDOWN", 0x208: "WM_MBUTTONUP"
                  , 0x20B: "WM_XBUTTONDOWN", 0x20C: "WM_XBUTTONUP"
                  , 0x20A: "WM_MOUSEWHEEL" , 0x20E: "WM_MOUSEHWHEEL" }
                
        , oMouseData := { 0: "0", 1: "XBUTTON1", 2: "XBUTTON2"
                        , 120: "WHEEL_DELTA forward", -120: "WHEEL_DELTA backward" }
                        
   prevTTCoordMode := A_CoordModeToolTip
   CoordMode, ToolTip
   while event := oMem.RemoveAt(1)  {
      msg       := oMsg[ event[1] ]
      mouse_x   := NumGet(event[2] + 0, "Int")
      mouse_y   := NumGet(event[2] + 4, "Int")
      ext       := NumGet(event[2] + 10, "Short")
      flags     := NumGet(event[2] + 12, "UInt")
      time      := NumGet(event[2] + 16, "UInt")
      INJECTED  := flags & 1
      LOWER_IL_INJECTED := flags >> 1
      mouseData := oMouseData[ext]
      
      ToolTip % "Msg: "  . A_Tab . A_Tab . msg               . "`n"
              . "MouseData: "    . A_Tab . mouseData         . "`n"
              . "MouseX: "       . A_Tab . mouse_x           . "`n"
              . "MouseY: "       . A_Tab . mouse_y           . "`n"
              . "INJECTED: "     . A_Tab . INJECTED          . "`n"
              . "LIL_INJECTED: " . A_Tab . LOWER_IL_INJECTED . "`n"
              . "Time: " . A_Tab . A_Tab . time, 0, 0, 20
   }
   CoordMode, ToolTip, % prevTTCoordMode
}

class WindowsHook {
   __New(type, callback, eventInfo := "", isGlobal := true) {
      this.pCallback := RegisterCallback(callback, "Fast", 3, eventInfo)
      this.hHook := DllCall("SetWindowsHookEx", "Int", type, "Ptr", this.pCallback
                                              , "Ptr", !isGlobal ? 0 : DllCall("GetModuleHandle", "UInt", 0, "Ptr")
                                              , "UInt", isGlobal ? 0 : DllCall("GetCurrentThreadId"), "Ptr")
   }
   __Delete() {
      DllCall("UnhookWindowsHookEx", "Ptr", this.hHook)
      DllCall("GlobalFree", "Ptr", this.pCallback, "Ptr")
   }
}
Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

3

Re: AHK: Проверка на эмуляцию передвижения мыши.

teadrinker пишет:

Такой скрипт будет выдавать информацию о событиях мыши. Если событие эмулированное, INJECTED: 1.

#Persistent
Setbatchlines, -1

hHook := new WindowsHook(WH_MOUSE_LL := 14, "LowLevelMouseProc")

LowLevelMouseProc(nCode, wParam, lParam)  {
   static oMem := [], lpData, size := VarSetCapacity(lpData, 16 + A_PtrSize*2, 0)

   DllCall("msvcrt\memmove", Ptr, &lpData, Ptr, lParam, Ptr, size)
   oMem.Push([wParam, &lpData])
   timer := Func("EventHandling").Bind(oMem)  ; во избежание фризов мыши обработка событий должна
   SetTimer, % timer, -10                     ; происходить по таймеру, а не в теле этой функции
   Return DllCall("CallNextHookEx", "Ptr", 0, "Int", nCode, "Ptr", wParam, "Ptr", lParam)
}

EventHandling(oMem)  {
   static oMsg := { 0x200: "WM_MOUSEMOVE"
                  , 0x201: "WM_LBUTTONDOWN", 0x202: "WM_LBUTTONUP"
                  , 0x204: "WM_RBUTTONDOWN", 0x205: "WM_RBUTTONUP"
                  , 0x207: "WM_MBUTTONDOWN", 0x208: "WM_MBUTTONUP"
                  , 0x20B: "WM_XBUTTONDOWN", 0x20C: "WM_XBUTTONUP"
                  , 0x20A: "WM_MOUSEWHEEL" , 0x20E: "WM_MOUSEHWHEEL" }
                
        , oMouseData := { 0: "0", 1: "XBUTTON1", 2: "XBUTTON2"
                        , 120: "WHEEL_DELTA forward", -120: "WHEEL_DELTA backward" }
                        
   prevTTCoordMode := A_CoordModeToolTip
   CoordMode, ToolTip
   while event := oMem.RemoveAt(1)  {
      msg       := oMsg[ event[1] ]
      mouse_x   := NumGet(event[2] + 0, "Int")
      mouse_y   := NumGet(event[2] + 4, "Int")
      ext       := NumGet(event[2] + 10, "Short")
      flags     := NumGet(event[2] + 12, "UInt")
      time      := NumGet(event[2] + 16, "UInt")
      INJECTED  := flags & 1
      LOWER_IL_INJECTED := flags >> 1
      mouseData := oMouseData[ext]
      
      ToolTip % "Msg: "  . A_Tab . A_Tab . msg               . "`n"
              . "MouseData: "    . A_Tab . mouseData         . "`n"
              . "MouseX: "       . A_Tab . mouse_x           . "`n"
              . "MouseY: "       . A_Tab . mouse_y           . "`n"
              . "INJECTED: "     . A_Tab . INJECTED          . "`n"
              . "LIL_INJECTED: " . A_Tab . LOWER_IL_INJECTED . "`n"
              . "Time: " . A_Tab . A_Tab . time, 0, 0, 20
   }
   CoordMode, ToolTip, % prevTTCoordMode
}

class WindowsHook {
   __New(type, callback, eventInfo := "", isGlobal := true) {
      this.pCallback := RegisterCallback(callback, "Fast", 3, eventInfo)
      this.hHook := DllCall("SetWindowsHookEx", "Int", type, "Ptr", this.pCallback
                                              , "Ptr", !isGlobal ? 0 : DllCall("GetModuleHandle", "UInt", 0, "Ptr")
                                              , "UInt", isGlobal ? 0 : DllCall("GetCurrentThreadId"), "Ptr")
   }
   __Delete() {
      DllCall("UnhookWindowsHookEx", "Ptr", this.hHook)
      DllCall("GlobalFree", "Ptr", this.pCallback, "Ptr")
   }
}

Ого код, спасибо большое, только я не особо понимаю как с ним работать..

4

Re: AHK: Проверка на эмуляцию передвижения мыши.

Jester пишет:

хочу сделать так, чтобы мой АХК скрипт мог понять, реально ли я вожу мышкой или это делает другая программа

В скрипте есть переменная INJECTED, можете сделать её глобальной, и по её содержанию ваш скрипт всегда сможет понять, были ли последние действия мыши человеческими или программными.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

5

Re: AHK: Проверка на эмуляцию передвижения мыши.

teadrinker пишет:
Jester пишет:

хочу сделать так, чтобы мой АХК скрипт мог понять, реально ли я вожу мышкой или это делает другая программа

В скрипте есть переменная INJECTED, можете сделать её глобальной, и по её содержанию ваш скрипт всегда сможет понять, были ли последние действия мыши человеческими или программными.

Понял! Спасибо большое

6 (изменено: Botsy, 2021-03-24 18:00:34)

Re: AHK: Проверка на эмуляцию передвижения мыши.

teadrinker Получается если эмуляция была с помощью сторонней библиотеки, то этот метод его не обнаружит? Просто интересно.

https://i.ibb.co/kmD6mGq/emul.png
Скрипт нарисовал линию*

GD

7

Re: AHK: Проверка на эмуляцию передвижения мыши.

Смотря, какая эмуляция. Вариант, что я привёл, может определить эмуляцию на программном уровне. Если на уровне драйвера, то не сможет, но в таком случае можно определить, что события произошли не от конкретного устройства.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

8

Re: AHK: Проверка на эмуляцию передвижения мыши.

а можно сделать так:

If INJECTED = 1
{
Send, 123
}
return

?

9

Re: AHK: Проверка на эмуляцию передвижения мыши.

Jester, ознакомьтесь, пожалуйста, с правилами форума, отредактируйте свой пост.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder