[英]How to detect if a process has moved the mouse cursor and not the user?
It is possible to move the mouse calling the mouse_event function or by using System.Windows.Forms.Cursor.Position property. 我想知道的是,是否有可能知道使用我的软件的用户是否正在使用这些方法之一。
我知道可以检查用户的鼠标移动,例如,查看它是否发生得太快。 但我想知道是否还有其他更准确的方法,比如检查某个 WinApi function 是否被调用。
当鼠标被物理移动时,触发的是 mouse_event function 吗?
或者对 mouse_event function 的调用是否会进行另一个系统调用并调用“物理鼠标移动”使用的实际 function?
我不认为如果另一个进程通过代码更改了 cursor position 并且这不是移动它的用户是可能的,除非某些 WinAPI 可以通过代码移动它。
我测试过,如果代码更改 cursor position,则不会在 WinForm 上或使用全局挂钩引发 MouseMove。
因此,使用 GetLastInputInfo 不起作用,并且您似乎无法检测到进程是否更改了移动 position。
也就是说,您可以使用带有此 MouseMove 全局挂钩的计时器。
https://www.codeproject.com/Articles/7294/Processing-Global-Mouse-and-Keyboard-Hooks-in-C
在应用程序启动时,您将像以前一样保存鼠标 position。
例如,您启动一个间隔为 100 毫秒的计时器。
在 MouseMove 上,您将更新之前的 position 并将条件变量设置为 true。
在计时器滴答声中,您将获得当前的 position 并将其与先前的条件变量进行比较:如果不相同,则不是用户移动。
它很重,但有效。
如果用户在一个进程的同时移动鼠标,你只会得到移动的是用户。
使用 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
,您可以确定收到了虚假的输入消息。 如果攻击者确实发布了消息,您将不得不依靠识别实际输入设备 state 和预期的 state 之间的不匹配。 GetKeyState可用于此。
没有直接的方法来检测对SetCursorPos
的调用。 单独来看,这些调用不会生成用户输入,也不能用于自动化应用程序。 它们总是伴随着其他注入输入的方案,你知道如何识别它们。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.