如何绕过应用对模拟鼠标移动的拦截?已尝试多种方案
模拟鼠标移动被目标应用拦截的解决办法
我正在编写一款为某应用模拟鼠标移动的程序,但该应用会阻止鼠标移动。尝试过以下方案,效果如下:
已尝试方案及结果
方案1:用SendMessage发送点击消息
SendMessage(hwnd, WM_LBUTTONDOWN, MK_LBUTTON, MAKELPARAM(x, y)); SendMessage(hwnd, WM_LBUTTONUP, MK_LBUTTON, MAKELPARAM(x, y));
鼠标无移动,但应用处于顶层时会向鼠标原位置发送左键点击。
方案2:用SetCursorPos移动鼠标
SetCursorPos(x,y);
鼠标能移动到目标位置,但发送的点击不会被接受,直到手动移动鼠标。
方案3:用SendMessage发送鼠标移动消息
SendMessage(hwnd, WM_MOUSEMOVE, 0, MAKELPARAM(x, y));
应用打开时鼠标无移动,但不会阻止点击操作。
方案4:用SendInput模拟移动
INPUT mouseEvent; mouseEvent.type = INPUT_MOUSE; mouseEvent.mi.dx = x; mouseEvent.mi.dy = y; mouseEvent.mi.dwExtraInfo = 0; mouseEvent.mi.mouseData = 0; mouseEvent.mi.time = 0; mouseEvent.mi.dwFlags = MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE; SendInput(1, &mouseEvent, sizeof(INPUT)); ZeroMemory(&mouseEvent, sizeof(INPUT));
应用打开时鼠标无移动,但不会阻止点击操作。
可行解决思路
修正
SendInput的坐标转换:MOUSEEVENTF_ABSOLUTE要求坐标为0-65535的绝对范围(对应屏幕分辨率占比),直接传入像素坐标会导致位置错误,需先转换:int screenWidth = GetSystemMetrics(SM_CXSCREEN); int screenHeight = GetSystemMetrics(SM_CYSCREEN); mouseEvent.mi.dx = (x * 65535) / screenWidth; mouseEvent.mi.dy = (y * 65535) / screenHeight;可额外添加
MOUSEEVENTF_VIRTUALDESK参数适配多屏幕场景。结合
SetCursorPos与SendInput触发更新:先调用SetCursorPos移动鼠标,再发送微小移动事件触发应用的鼠标位置检测更新,之后发送点击:SetCursorPos(x, y); // 发送微小移动触发应用检测 INPUT moveEvent = {0}; moveEvent.type = INPUT_MOUSE; moveEvent.mi.dwFlags = MOUSEEVENTF_MOVE; moveEvent.mi.dx = 1; moveEvent.mi.dy = 0; SendInput(1, &moveEvent, sizeof(INPUT)); // 移回目标位置 moveEvent.mi.dx = -1; SendInput(1, &moveEvent, sizeof(INPUT)); // 发送左键点击 INPUT clickEvent = {0}; clickEvent.type = INPUT_MOUSE; clickEvent.mi.dwFlags = MOUSEEVENTF_LEFTDOWN; SendInput(1, &clickEvent, sizeof(INPUT)); clickEvent.mi.dwFlags = MOUSEEVENTF_LEFTUP; SendInput(1, &clickEvent, sizeof(INPUT));改用
PostMessage替代SendMessage:部分应用会拦截同步的SendMessage,异步的PostMessage可能绕过检测,注意需自行控制消息发送时序。进程内注入模拟输入:如果应用有严格的输入来源验证,可尝试将代码注入到目标进程内部,在进程上下文发送鼠标消息,此方式需处理权限与兼容性问题。
内容的提问来源于stack exchange,提问作者Gürkan KARADAĞ
相关产品推荐
相关产品推荐

