如何检测进程是否移动了鼠标光标而不是用户



可以通过调用mouse_event函数或使用System.Windows.Forms.Cursor.Position属性来移动鼠标。我想知道的是,是否有可能知道使用我软件的用户是否使用了其中一种方法。

我知道可以检查用户的鼠标移动,例如,看看它是否发生得太快。但我想知道是否还有其他更准确的方法,比如检查是否调用了某个WinApi函数。

当鼠标被物理移动时,是否触发了mouse_event函数?

还是对mouse_event函数的调用会进行另一个系统调用,并调用"物理鼠标移动"使用的实际函数?

我认为,如果另一个进程通过代码更改了光标位置,而不是移动光标的用户,则不会发出警告,除非某些通过代码移动光标的WinAPI具有可以注册的事件。

我测试过,如果代码更改了光标位置,那么WinForm或使用全局钩子都不会引发MouseMove。

因此,使用GetLastInputInfo不起作用,而且似乎无法检测进程是否更改了移动位置。

也就是说,你可以用鼠标移动全局挂钩的定时器。

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

  • 在应用程序启动时,您将把鼠标位置保存为以前的位置。

  • 例如,您启动一个间隔为100ms的计时器。

  • 在MouseMove上,您将更新之前的位置,并将条件变量设置为true。

  • 在计时器刻度上,您将获得当前位置,并将其与上一个和条件变量进行比较:如果不相同,则不是用户移动。

它很重,但很管用。

如果用户在处理的同时移动鼠标,你只会得到移动的是用户。

使用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;
}
}

可以检测鼠标输入是由使用API调用SendInput()还是mouse_event()的代码生成的。为此,请使用SetWindowsHookEx()设置一个低级鼠标挂钩。该钩子过程传递一个MSLLHOOKSTRUCT,其flags成员指示鼠标事件是代码注入的结果,还是用户输入的结果。

如果攻击者向您的应用程序发送鼠标消息,您可以从鼠标消息处理程序调用InSendMessage。真正的鼠标消息会发布到消息队列中。通常发送虚假的鼠标信息。如果InSendMessage返回TRUE,那么您可以确定收到了一条伪输入消息。如果攻击者确实发布了消息,您将不得不依赖于识别实际输入设备状态与预期状态之间的不匹配。GetKeyState可以用于此操作。

无法立即检测对SetCursorPos的调用。孤立地说,这些调用不会生成用户输入,也不能用于自动化应用程序。它们总是伴随着其他注入输入的方案,并且您知道如何识别这些方案。

相关内容

最新更新