【Frida】10_用鼠标自动标记棋盘上的雷区(一键过关)

🛫 系列文章导航

🛫 导读

开发环境

版本号 描述
文章日期 2024-03-17
操作系统 Win11 - 22H2 22621.2715
node -v v20.10.0
npm -v 10.2.3
yarn -v 3.1.1
frida-compile 10.2.1 高版本各种异常
扫雷程序下载地址 https://download.csdn.net/download/kinghzking/88979919
课程源码 https://gitcode.net/kinghzking/MyOpen 所在目录:/course/frida

1️⃣ 需求分析

流程:

  • 将目标窗口切换到前台(参考历史文章)
  • 获取游戏地图区域位置(软件窗口固定偏移)
  • 遍历棋盘,按行遍历
    • 如果是地雷(0x8F),标记为地雷(右键点击)
    • 如果是无雷区(0x0F),左键点击。
  • 重绘窗口区域(参考历史文章)

获取游戏地图区域位置(软件窗口固定偏移)

  • 我们先看下从基址拿到的内存数据,地址0x01005340对应的是(0,0)元素,该元素值为0x10,表示边界,不需要点击。真正需要点击的是0x01005361,该元素才是界面上的第一个元素。
    在这里插入图片描述

有了上面的介绍,我们可以假设一个虚拟的(0,0)点,如下图所示,该点相对于窗口的坐标为(6,88),所以,起始点的计算如下(lpRect为窗口在屏幕中的左上角位置):

  • this.start_x = lpRect.readU32() + 6;
  • this.start_y = lpRect.add(4).readU32() + 88;
    在这里插入图片描述

完整的代码如下:

class L07 {
  // 设置鼠标位置_自动点击鼠标
  private start_x = 0;
  private start_y = 0;
  private step = 16;

  获取软件窗口位置_设置鼠标指针位置() {
    let lpRect = Memory.alloc(4 * 4);
    User32.GetWindowRect(this.hWnd, lpRect);
    this.start_x = lpRect.readU32() + 6;
    this.start_y = lpRect.add(4).readU32() + 88;
    console.log("start_x", this.start_x);
    console.log("start_y", this.start_y);
  }

模拟点击:mouse_click

模拟鼠标操作,我们需要使用Windows API函数MouseEvent。该函数是一个Windows API函数,用于模拟鼠标的各种操作,例如移动鼠标、点击鼠标按键等。但需要注意的是,由于其在新版本的Windows中已经被标记为过时,推荐使用更现代的方法,如SendInput函数来模拟输入事件。
函数原型:

void MouseEvent(
    DWORD dwFlags,  // 指定鼠标动作的标志,可以是以下值的组合:
                   // MOUSEEVENTF_ABSOLUTE:指定x和y参数是绝对坐标
                    // MOUSEEVENTF_LEFTDOWN:模拟鼠标左键按下
                    // MOUSEEVENTF_LEFTUP:模拟鼠标左键释放
                    // MOUSEEVENTF_RIGHTDOWN:模拟鼠标右键按下
                    // MOUSEEVENTF_RIGHTUP:模拟鼠标右键释放
                    // MOUSEEVENTF_MIDDLEDOWN:模拟鼠标中键按下
                       // MOUSEEVENTF_MIDDLEUP:模拟鼠标中键释放
                       // MOUSEEVENTF_WHEEL:模拟鼠标滚轮滚动
                       // MOUSEEVENTF_XDOWN:模拟鼠标X按钮按下
                       // MOUSEEVENTF_XUP:模拟鼠标X按钮释放
       DWORD dx,       // x坐标变化量或绝对坐标(取决于dwFlags)
       DWORD dy,       // y坐标变化量或绝对坐标(取决于dwFlags)
       DWORD dwData,   // 滚轮滚动量
    ULONG_PTR dwExtraInfo // 额外信息,一般设为0
);

mouse_click实现逻辑:

  • User32.SetCursorPos移动到指定位置
  • 当为左键时,模拟鼠标左键按下和弹起。
  • 当为右键时,模拟鼠标右键按下和弹起。
  mouse_click(x: number, y: number, left_click: boolean = true) {
    User32.SetCursorPos(this.start_x + this.step * x, this.start_y + this.step * y);
    if (left_click) {
      User32.MouseEvent(User32.Const.MOUSEEVENTF_LEFTDOWN, 0, 0, 0,  User32.GetMessageExtraInfo());
      User32.MouseEvent(User32.Const.MOUSEEVENTF_LEFTUP, 0, 0, 0, User32.GetMessageExtraInfo());
    }
    else {
      User32.MouseEvent(User32.Const.MOUSEEVENTF_RIGHTDOWN, 0, 0, 0, User32.GetMessageExtraInfo());
      User32.MouseEvent(User32.Const.MOUSEEVENTF_RIGHTUP, 0, 0, 0, User32.GetMessageExtraInfo());
    }
  }

2️⃣ 代码编写测试

核心的函数都已经封装完毕,最后我们遍历地雷数据,执行点击事件,这里需要注意几点内容:

  • for循环中的长宽范围需要+2,因为有边界0x10
  • byte_data为head的偏移j + 0x20 * i,这是因为每行数据是固定的0x20(这也是为什么扫雷最大宽为30的原因)
  • 程序只有初始的时候有两种状态:0x8F0x0F,如果已经开始游戏的情况,会出现未处理的按钮。

具体代码如下:


class L07 {
  run() {
    this.将目标窗口切换到前台()
    this.获取软件窗口位置_设置鼠标指针位置()

    //遍历棋盘,按行遍历
    for (let i = 0; i < this.height + 2; i++) {
      //按列遍历
      let data = [];
      for (let j = 0; j < this.width + 2; j++) {
        let byte_data = this.head.add(j + 0x20 * i).readU8();
        data.push(byte_data.toString(16).padStart(2, "0"));

        // 标记地雷
        if  (byte_data == 0x8F) {
          this.mouse_click(j, i, false);
        }
        // 点击无雷区
        if (byte_data == 0x0F) {
          this.mouse_click(j, i);
        }
      }
      console.log(data.join(" "));
    }

    // 重绘窗口区域
    this.board_repaint()
  }
}

let l07 = new L07();
l07.run();

代码已上传gitcode:https://gitcode.net/kinghzking/MyOpen 。 所在目录为:/course/frida/11_用鼠标自动标记棋盘上的雷区/index.ts
配置脚本如下:
在这里插入图片描述

执行npm run watch11,以监视模式编译脚本。
执行npm run runx,运行编译后的脚步,最终1秒过关。
在这里插入图片描述

🛬 文章小结

到此为止,我们通过TypeScript方式进行开发,通过扫雷程序,实战了Frida的基本使用。
当然,Frida的路途还很遥远,期待下次再见。

ps: 文章中内容仅用于技术交流,请勿用于违规违法行为。

最近更新

  1. TCP协议是安全的吗?

    2024-03-22 09:42:09       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-03-22 09:42:09       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-03-22 09:42:09       18 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-03-22 09:42:09       20 阅读

热门阅读

  1. Android仿微信视频聊天本地与远程切换功能

    2024-03-22 09:42:09       19 阅读
  2. Android 设置相关页面

    2024-03-22 09:42:09       19 阅读
  3. Linux实战笔记(四) 后台运行

    2024-03-22 09:42:09       20 阅读
  4. 富格林:谨记可信计策安全做单

    2024-03-22 09:42:09       19 阅读
  5. 复试专业前沿问题问答合集2

    2024-03-22 09:42:09       19 阅读
  6. Springboot vue elementui 电影院售票系统

    2024-03-22 09:42:09       21 阅读
  7. 【无人机综合题】+题解

    2024-03-22 09:42:09       22 阅读
  8. 云原生周刊:Istio 加入 Phippy 家族 | 2024.3.18

    2024-03-22 09:42:09       20 阅读
  9. docker各种命令的详细解释

    2024-03-22 09:42:09       19 阅读