Как определить, что процесс переместил курсор мыши, а не пользователя? - PullRequest
1 голос
/ 09 ноября 2019

Можно перемещать мышь, вызывая функцию mouse_event или используя свойство System.Windows.Forms.Cursor.Position . Что я хочу знать, так это то, можно ли узнать, использует ли пользователь, использующий мое программное обеспечение, один из этих методов или нет.

Я знаю, что можно проверить движение мыши пользователя и, например, посмотретьесли это произошло слишком быстро или нет. Но мне интересно, есть ли другие более точные способы, такие как проверка, вызывается ли определенная функция WinApi или нет.

Когда мышь перемещается физически, вызывается ли функция mouse_event?

Или вызов функции mouse_event выполняет другой системный вызов и вызывает фактическую функцию, которую использует «физическое движение мыши»?

Ответы [ 2 ]

0 голосов
/ 09 ноября 2019

Можно определить, был ли ввод мыши с помощью кода, используя вызовы API SendInput() или mouse_event(). Для этого используйте SetWindowsHookEx(), чтобы настроить низкоуровневый хук мыши . Эта подключаемая процедура передается MSLLHOOKSTRUCT , чей член flags указывает, были ли события мыши результатом внедрения кода или результатом ввода данных пользователем.

В случае отправки злоумышленникомсообщения мыши для вашего приложения, вы можете вызвать InSendMessage из ваших обработчиков сообщений мыши. Подлинные сообщения мыши отправляются в очередь сообщений. Поддельные сообщения мыши обычно отправляются. Если InSendMessage возвращает TRUE, вы можете быть уверены, что получили фальшивое входное сообщение. Если злоумышленник действительно отправляет сообщения, вам придется полагаться на выявление несоответствий между фактическим состоянием устройства ввода и ожидаемым состоянием. GetKeyState может использоваться для этого.

Не существует немедленного способа обнаружения вызовов на SetCursorPos. В отдельности эти вызовы не генерируют пользовательский ввод и не могут использоваться для автоматизации приложения. Они всегда сопровождаются другими схемами для ввода данных, и вы знаете, как их идентифицировать.

0 голосов
/ 09 ноября 2019

Не думаю, что следует предупреждать, если другой процесс изменил позицию курсора по коду, и это не пользователь, который переместил его, возможно, если какой-то WinAPI для его перемещения по коду не имеет события, которое можно зарегистрировать.

Я проверил, что если код изменяет позицию курсора, MouseMove не вызывается в WinForm или с помощью глобальной ловушки.

Так что использование GetLastInputInfo не работает, и кажется, что вы не можете определить,процесс изменил позицию перемещения.

Тем не менее, вы можете использовать таймер с этим глобальным хуком MouseMove.

https://www.codeproject.com/Articles/7294/Processing-Global-Mouse-and-Keyboard-Hooks-in-C

  • ВклПри запуске приложения вы сохраните положение мыши, как и раньше.

  • Вы запускаете таймер, например, с интервалом 100 мс.

  • При MouseMove вы обновитеэтой предыдущей позиции и установите для условной переменной значение true.

  • На тике таймера вы получите текущую позицию и сравните ее с предыдущей и условной переменной: если это не same, это не пользователь, который двигается.

Это тяжело, но это работает.

Если пользователь перемещает мышь одновременно с процессом, вы получите толькочто пользователь перемещается.

Использование таймера WinForms

public partial class FormTest : Form
{
  Point PreviousMousePosition;
  bool UserMovedMouse;
  public FormTest()
  {
    InitializeComponent();
    PreviousMousePosition = Cursor.Position;
    TimerCheckMouseMove.Start();
    TimerMoveMouse.Start();
    HookManager.MouseMove += HookManager_MouseMove;
  }
  private void HookManager_MouseMove(object sender, MouseEventArgs e)
  {
    PreviousMousePosition = Cursor.Position;
    UserMovedMouse = true;
  }
  private void TimerCheckMouseMove_Tick(object sender, EventArgs e)
  {
    TimerCheckMouseMove.Enabled = false;
    try
    {
      var pos = Cursor.Position;
      if ( !UserMovedMouse && pos != PreviousMousePosition)
        MessageBox.Show("Mouse moved by a process");
      PreviousMousePosition = Cursor.Position;
      UserMovedMouse = false;
    }
    finally
    {
      TimerCheckMouseMove.Enabled = true;
    }
  }
  private void TimerMoveMouse_Tick(object sender, EventArgs e)
  {
    Cursor.Position = new Point(100, 100);
  }
}

Использование резьбового таймера

System.Threading.Timer TimerCheckMouseMove;

TimerCheckMouseMove = new System.Threading.Timer(TimerCheckMouseMove_Tick, null, 0, 100);

private bool TimerCheckMouseMoveMutex;

private void TimerCheckMouseMove_Tick(object state)
{
  if ( TimerCheckMouseMoveMutex ) return;
  TimerCheckMouseMoveMutex = true;
  try
  {
    var pos = Cursor.Position;
    if ( !UserMovedMouse && pos != PreviousMousePosition)
      MessageBox.Show("Mouse moved by a process");
    PreviousMousePosition = Cursor.Position;
    UserMovedMouse = false;
  }
  finally
  {
    TimerCheckMouseMoveMutex = false;
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...