🛫 系列文章导航
- 【Frida】 00_简单介绍和使用 https://blog.csdn.net/kinghzking/article/details/123225580
- 【Frida】 01_食用指南 https://blog.csdn.net/kinghzking/article/details/126849567
- 【Frida】 03_初识frida-node https://blog.csdn.net/kinghzking/article/details/136685316
- 【Frida】 04_Frida中使用TypeScript脚本(采坑) https://blog.csdn.net/kinghzking/article/details/136772475
- 【Frida】 05_读取扫雷游戏的数据 https://blog.csdn.net/kinghzking/article/details/136781623
- 【Frida】 06_分析扫雷游戏的数据,显示地雷位置 https://blog.csdn.net/kinghzking/article/details/136685316
- 【Frida】 07_让系统重新绘制指定窗口 https://blog.csdn.net/kinghzking/article/details/136829854
- 【Frida】 08_将目标窗口切换到前台 https://blog.csdn.net/kinghzking/article/details/136837275
- 【Frida】 09_获取软件窗口位置,设置鼠标指针位置 https://blog.csdn.net/kinghzking/article/details/136854052
- 【Frida】10_用鼠标自动标记棋盘上的雷区(一键过关) https://blog.csdn.net/kinghzking/article/details/136854020
- 【frida-实战】“一行”代码教你获取WeGame平台中所有的lua脚本 https://blog.csdn.net/kinghzking/article/details/125590584
- 【Frida-实战】EA游戏平台的文件监控(PsExec.exe提权) https://blog.csdn.net/kinghzking/article/details/130512479
▒ 目录 ▒
- 🛫 系列文章导航
- 🛫 导读
- 开发环境
- 1️⃣ 分析
- 游戏开始之前
- 游戏标记状态
- 游戏结束状态
- 结论
- 2️⃣ 编码验证
🛫 导读
开发环境
版本号 | 描述 | |
---|---|---|
文章日期 | 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️⃣ 分析
游戏开始之前
每次点击笑脸都会重置游戏,这个时候,右边的计时器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: 文章中内容仅用于技术交流,请勿用于违规违法行为。