逆向作业——扫雷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这个地址的寻址方式是一个二维数组的寻址方式,所以这个地方应该是个二维数组,应该是雷区。
、
确实是雷区,并且经过游玩,雷区内数据如下:
- 0x8X 是雷区
- 0x0X 是未翻开的安全格
- 0x4X 是翻开的安全格
- 0xXE 是插上旗子的格子
现在的想法就是,让其在初始化的时候就让其给旗子插上,在游戏每次经过这个指令的时候,雷区就会多出一个雷。
所以修改这个即可,让其在初始化的时候就将雷置为 0x8E:
这么修改就行了。
当游戏胜利的时候,游戏状态进行了一次更新,这条指令被执行了:
然后就是在这里打个断点,进行动调,当执行到这里的时候,出现了弹窗:
执行到这里的时候,游戏的图标发生了变化。
执行到这里的时候发生了弹窗。
从栈帧回溯可以看到,100347C被35B0这里调用:
在这里,给上面的cmp加上断点,重开一把游戏后,第一次点击非地雷的时候,发生了一次判定,之后每一次点击都进行了一次判定,且只有当游戏胜利时候,才会运行这里:
所以,估计这个判定跟游戏是否胜利有关系:
直接修改,让他自己跟自己比较:
只点击一次非地雷之后,游戏胜利,实现完全的0秒完成游戏。