Gameisover的文章

  • 使用mouse_event函数实现鼠标点击模拟

    背景如果你对外挂有过一些了解,那么鼠标、键盘的模拟功能,肯定是学外挂的入门必修技术。所谓的鼠标模拟、键盘模拟,就是不需要物理点击、物理按键,纯粹使用编程手段,实现和物理点击、物理按键相同功能的操作。
    当然,根据使用的编程技术,不同模拟效果也不同。初学者必修的当然是在应用层使用mouse_event、keybd_event、SendMessage等函数实现,厉害的大牛,就会在内核层里进行操作。本文就不深入介绍了,先讲解简单介绍的使用mouse_event函数实现鼠标模拟。现在把实现思路和实现过程,写成文档分享给大家。
    函数介绍SetCursorPos 函数
    把光标移到屏幕的指定位置。
    函数声明
    BOOL SetCursorPos( int X, int Y );
    参数

    X
    指定光标的新的X坐标,以屏幕坐标表示。
    Y
    指定光标的新的Y坐标,以屏幕坐标表示。

    返回值

    如果成功,返回非零值;如果失败,返回值是零,若想获得更多错误信息,请调用GetLastError函数。

    mouse_event 函数
    综合鼠标移动和按钮点击。
    函数声明
    VOID mouse_event( DWORD dwFlags, // motion and click options DWORD dx, // horizontal position or change DWORD dy, // vertical position or change DWORD dwData, // wheel movement ULONG_PTR dwExtraInfo // application-defined information);
    参数

    dwFlags标志位集,指定点击按钮和鼠标动作的多种情况。此参数可以是下列值的某种组合:



    VALUE
    MEANING




    MOUSEEVENTF_ABSOLUTE
    dX和dY参数含有规范化的绝对坐标。如果不设置,这些参数含有相对数据:相对于上次位置的改动位置。此标志可设置,也可不设置,不管鼠标的类型或与系统相连的类似于鼠标的设备的类型如何。要得到关于相对鼠标动作的信息,参见下面备注部分


    MOUSEEVENTF_MOVE
    这表示鼠标移动


    MOUSEEVENTF_LEFTDOWN
    这表示鼠标左键按下


    MOUSEEVENTF_LEFTUP
    这表示鼠标左键松开


    MOUSEEVENTF_RIGHTDOWN
    这表示鼠标右键按下


    MOUSEEVENTF_RIGHTUP
    这表示鼠标右键松开


    MOUSEEVENTF_MIDDLEDOWN
    这表示鼠标中键按下


    MOUSEEVENTF_MIDDLEUP
    这表示鼠标中键松开


    MOUSEEVENTF_WHEEL
    这表示鼠标轮被滚动,如果鼠标有一个滚轮。滚动的数量由dwData给出




    dx指定鼠标沿x轴的绝对位置或者从上次鼠标事件产生以来移动的数量,依赖于MOUSEEVENTF_ABSOLUTE的设置。给出的绝对数据作为鼠标的实际X坐标;给出的相对数据作为移动的mickeys数。一个mickey表示鼠标移动的数量,表明鼠标已经移动。
    dy指定鼠标沿y轴的绝对位置或者从上次鼠标事件产生以来移动的数量,依赖于MOUSEEVENTF_ABSOLUTE的设置。给出的绝对数据作为鼠标的实际y坐标,给出的相对数据作为移动的mickeys数。
    dwData如果dwFlags为MOUSEEVENTF_WHEEL,则dwData指定鼠标轮移动的数量。正值表明鼠标轮向前转动,即远离用户的方向;负值表明鼠标轮向后转动,即朝向用户。一个轮击定义为WHEEL_DELTA,即120。如果dwFlagsS不是MOUSEEVENTF_WHEEL,则dWData应为零。
    dwExtralnfo指定与鼠标事件相关的附加32位值。应用程序调用函数GetMessageExtraInfo来获得此附加信息。

    返回值

    无返回值。

    实现原理我们正常使用鼠标进行操作的时候,都是先将鼠标移动到要操作的位置,然后进行操作。
    同样的,编码实现也是一样的,我们先要使用 SetCursorPos 函数,把光标移动到屏幕指定的位置坐标上,然后再使用 mouse_event 设置并执行操作的动作,例如鼠标左键按下、鼠标左键弹起等。这样,便完成模拟的操作。
    其中,我们需要注意的是 mouse_event 函数的每个操作都要检查是否符合逻辑,例如,鼠标点击下去后,一定要有弹起操作,这样才不影响下面的操作。
    编码实现鼠标左键单击// 鼠标左键单击: 按下 和 弹起BOOL SimulateMouse_LeftClick(int x, int y){ BOOL bRet = ::SetCursorPos(x, y); if (bRet) { // 鼠标左键按下 ::mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0); // 时间间隔 Sleep(20); // 鼠标左键弹起 ::mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0); } return bRet;}
    鼠标左键双击// 鼠标左键双击: 按下 和 弹起BOOL SimulateMouse_LeftDoubleClick(int x, int y){ BOOL bRet = FALSE; // 双击就是两个频率较快的单击组成 // 第一个单击操作 bRet = SimulateMouse_LeftClick(x, y); // 时间间隔 Sleep(40); // 第二个单击操作 bRet = SimulateMouse_LeftClick(x, y); return bRet;}
    鼠标右键单击// 鼠标右键单击: 按下 和 弹起BOOL SimulateMouse_RightClick(int x, int y){ BOOL bRet = ::SetCursorPos(x, y); if (bRet) { // 鼠标右键按下 ::mouse_event(MOUSEEVENTF_RIGHTDOWN, 0, 0, 0, 0); // 时间间隔 Sleep(20); // 鼠标右键弹起 ::mouse_event(MOUSEEVENTF_RIGHTUP, 0, 0, 0, 0); } return bRet;}
    鼠标右键双击// 鼠标右键双击: 按下 和 弹起BOOL SimulateMouse_RightDoubleClick(int x, int y){ BOOL bRet = FALSE; // 双击就是两个频率较快的单击组成 // 第一个单击操作 bRet = SimulateMouse_RightClick(x, y); // 时间间隔 Sleep(40); // 第二个单击操作 bRet = SimulateMouse_RightClick(x, y); return bRet;}
    程序测试由于是一个功能性较强的程序,不能用截图的方式进行展示,所以,在此就没有贴图了,大家可以自己按照上面的原理和代码,自己写一个来感受感受吧。
    总结这个程序,主要是理解 SetCursorPos 和 mouse_event 这两个API函数的使用方式。其中,要注意的是 mouse_event 函数的每个操作都要检查是否符合逻辑,例如,鼠标点击下去后,一定要有弹起操作,这样才不影响下面的操作。
    在测试程序的时候,鼠标的双击操作一直测试不成功,后来,以管理员权限运行程序,测试双击操作,这时就成功了。所以,如果,测试程序的时候,达不到效果,可以试试以管理员权限运行程序测试看看。
    参考参考自《Windows黑客编程技术详解》一书
    1  留言 2018-11-21 09:10:54

发送私信

修行的路总是孤独的,因为智慧必然来自孤独

8
文章数
11
评论数
eject