逆向作业——扫雷0秒破解

​ 这学期的逆向期末大作业是破解扫雷,由于我不是逆向这个方向的,所以对逆向破解了解不多,正好一直不知道写些啥进博客,干脆把作业写进来吧。内容不是很多,很短,但是破解这玩意儿真挺有意思的。

​ 扫雷想做到0秒通关,可以在某种意义上进行0秒通关,第一点就是让时间永恒为0,不增加;第二点就是让在游戏开始的一瞬间直接通关。

​ 但显然,这个游戏好像有点不太可能用到第二种手法了,因为游戏在开始的一瞬间,时间就变成了1。

​ 那就只有在时间上动手脚了。

​ 用CE查看时间所对应的变量所在地址:

在这里插入图片描述

​ 之后让游戏运行这,看看哪些汇编指令写入了这个地址:

在这里插入图片描述

​ 这里存在一个自增指令,地址在 0x01002FF5。

​ 在反汇编页面看到了程序大概的逻辑,就是检查时间是否为999,如果不是,就自增1。

在这里插入图片描述

​ 直接nop掉即可。

在这里插入图片描述

​ 点击笑脸之后,发现多了一条对这一内存进行操作的指令,地址为0x0100371A:

在这里插入图片描述

​ 推测这一条指令在初始化相关的函数里。

​ 而在游戏开始的时候,也就是第一次点击格子的时候,又多出来了一条新的指令写入了这一内存,地址在0x01003830:

在这里插入图片描述

​ 直接nop掉:

在这里插入图片描述

​ 另外,关于计时器,右上角那个时间会根据游戏是否进行而动,推测游戏开始的时候计时器启动状态为1,结束的或初始化之后状态为0:

在这里插入图片描述

​ 发现了两条,但是,在踩雷之后,发现这里:

在这里插入图片描述

​ Winmine.exe+5164这个地址变成了0,所以这个肯定就是计时器了,那么在初始化的时候看看有没有地址访问它:

在这里插入图片描述

​ 有,进入动调页面看看,在这里打个断点,然后进行调试:

在这里插入图片描述

​ 程序在这一段内进行了循环,lea eax, ds:[eax+esi*1+0x1005340],这里,对0x1005340这个地址的寻址方式是一个二维数组的寻址方式,所以这个地方应该是个二维数组,应该是雷区。

在这里插入图片描述

​ 确实是雷区,并且经过游玩,雷区内数据如下:

  1. 0x8X 是雷区
  2. 0x0X 是未翻开的安全格
  3. 0x4X 是翻开的安全格
  4. 0xXE 是插上旗子的格子

​ 现在的想法就是,让其在初始化的时候就让其给旗子插上,在游戏每次经过这个指令的时候,雷区就会多出一个雷。

在这里插入图片描述

​ 所以修改这个即可,让其在初始化的时候就将雷置为 0x8E:

在这里插入图片描述

​ 这么修改就行了。

在这里插入图片描述

​ 当游戏胜利的时候,游戏状态进行了一次更新,这条指令被执行了:

在这里插入图片描述

​ 然后就是在这里打个断点,进行动调,当执行到这里的时候,出现了弹窗:

在这里插入图片描述

​ 执行到这里的时候,游戏的图标发生了变化。

​ 执行到这里的时候发生了弹窗。

在这里插入图片描述

在这里插入图片描述

​ 从栈帧回溯可以看到,100347C被35B0这里调用:

在这里插入图片描述

在这里插入图片描述

​ 在这里,给上面的cmp加上断点,重开一把游戏后,第一次点击非地雷的时候,发生了一次判定,之后每一次点击都进行了一次判定,且只有当游戏胜利时候,才会运行这里:

在这里插入图片描述

​ 所以,估计这个判定跟游戏是否胜利有关系:

在这里插入图片描述

​ 直接修改,让他自己跟自己比较:

在这里插入图片描述

​ 只点击一次非地雷之后,游戏胜利,实现完全的0秒完成游戏。