【Frida】06_分析扫雷游戏的数据,显示地雷位置

🛫 系列文章导航

🛫 导读

开发环境

版本号描述
文章日期2024-03-17
操作系统Win11 - 22H222621.2715
node -vv20.10.0
npm -v10.2.3
yarn -v3.1.1
frida-compile10.2.1高版本各种异常
扫雷程序下载地址https://download.csdn.net/download/kinghzking/88979919
课程源码https://gitcode.net/kinghzking/MyOpen所在目录:/course/frida

1️⃣ 分析

游戏开始之前

每次点击笑脸都会重置游戏,这个时候,右边的计时器LED为0,我们称之为游戏开始之前
这个时候,我们可以看到,扫雷数据中,包含大量0F,还有少量的8F,而且8F的个数刚好是地雷的个数。
由此不难分析出:

  • 8F:地雷
  • 0F:不是雷(初始状态)
    在这里插入图片描述

游戏标记状态

我们以下图为例,第一排第一列(以后称为0101)没有雷,第二排第一列(以后称为0201)有雷。
在这里插入图片描述

当我们分别标记为雷的时候,数值发生了如下变化,可确定下面结论:

  • 8E:做了雷标记(有雷)
  • 0E:做了雷标记(没有雷)
    在这里插入图片描述

当我们分别标记为问号的时候,数值发生了如下变化,可确定下面结论:

  • 8D:做了问号标记(有雷)
  • 0D:做了问号标记(没有雷)
    在这里插入图片描述

游戏结束状态

我们继续点击一些点,然后故意让游戏结束,然后分析对应点的含义如下:

  • CC:爆掉的地雷
  • 8A:未爆的地雷(游戏结束)
  • 41~48:数字1~8
    在这里插入图片描述

结论

经过上面的分析,我们可以知道各种状态下每个的含义,界面会根据的值的不同,显示不同的内容。
那么我们在游戏一开始,改变8F:地雷8E:做了雷标记(有雷),就可以轻松的完成关卡了。

2️⃣ 编码验证

有了上面的分享,逻辑就很简单了,遍历所有的时候,我们判断是8F,则改为8E即可。

class L06 {
  private module_name_winmine = "winmine.exe";
  private module_winmine: Module;
  private offset地雷数量: number = 0x56a4;
  private offset棋盘高度: number = 0x56a8;
  private offset棋盘宽度: number = 0x56ac;
  private height: number = 0;
  private width: number = 0;
  private mine_count: number = 0;
  private head: NativePointer = ptr(0);

  constructor() {
    console.log(
      "======================",
      new Date().toISOString(),
      "=========================="
    );
    console.log("Frida.version", Frida.version);
    //获取模块基址
    this.module_winmine = Process.getModuleByName(this.module_name_winmine);

    // 初始化游戏相关数据
    this.height = this.module_winmine.base.add(this.offset棋盘高度).readU32();
    this.width = this.module_winmine.base.add(this.offset棋盘宽度).readU32();
    this.mine_count = this.module_winmine.base.add(this.offset地雷数量).readU32();
    this.head = this.module_winmine.base.add(0x5340);
  }

  run() {
    //遍历棋盘,按行遍历
    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.head.add(j + 0x20 * i).writeU8(0x8E);
        }
      }
      console.log(data.join(" "));
    }
  }
}

let l06 = new L06();
l06.run();

ps: 修改完后,我们运行脚本D:/Python/Python371/Scripts/frida.exe -n winmine.exe -l ./build/06.js -q,查看页面并不会显示出标记,这是因为页面未强制刷新的原因。
我们需要最小化窗口后,再次打开才能看到雷的标记。
在这里插入图片描述

最后,把所有的点,点开即可完成关卡
在这里插入图片描述

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

  • 20
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

夜猫逐梦

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值