ce逆向修改——扫雷
- 实验目的
为熟悉CE的使用和对软件逆向分析有进一步的了解,以扫雷为例切入主题,学会使用CE查询地址、修改数值、判断存放内存等等,分析出地雷存放的算法,最终了解“扫雷”游戏软件的工作原理。
- 实验设备
Cheat Engine 6.8、扫雷
- 实验内容
(1)分析“初级”、“中级”和“高级”的棋盘内存地址范围;
(2)找出“雷数”、“笑脸”和“计时器”的内存地址;
(3)分析地雷存放的算法;
(4)利用思维导图分析“扫雷”游戏软件的工作原理(设计原理)。
- 实验步骤
(1)分析“初级”、“中级”和“高级”的棋盘内存地址范围;
①选择雷数右键点击浏览相关内存区域
②开始扫雷,发现点击时内存区域变红,以此判断棋盘内存地址范围
③初级棋盘内存区域:点击第一行第一列,观察红色区域,确定起始地址(01005361)。点击最后一行最后一列,观察红色区域,确定结束地址(01005469)。
④中级棋盘内存区域:点击第一行第一列,观察红色区域,确定起始地址(01005361)。点击最后一行最后一列,观察红色区域,确定结束地址(01005550)。
⑤高级棋盘内存区域:点击第一行第一列,观察红色区域,确定起始地址(01005361)。点击最后一行最后一列,观察红色区域,确定结束地址(0100555E)。
最终结果为
初级棋盘: 01005361-01005469
中级棋盘: 01005361-01005550
高级棋盘: 01005361-0100555E
(2)找出“雷数”、“笑脸”和“计时器”的内存地址;
雷数:
①地雷的数目是固定的,可以用精确扫描的方法找雷数的内存地址
②打开游戏的自定义,可以看到雷的默认数量默认为10,所以扫描精确数值10
③因为扫描到的结果过多,所以通过自定义将雷数修改为20,再次精确扫描20,最终扫描出了3个基址
④要判断哪一个基址才是雷数的内存地址,可以在CE上修改地址的数值,观察扫雷中的雷数是否会发生相应的改变
⑤最终可以判断出010056A4为雷数的内存地址
笑脸:
①笑脸只有两种状态:一个是游戏进行的时候,一个是还原游戏的时候,所以可以通过0和1进行扫描,游戏进行状态输入1进行扫描,还原游戏之后输入0进行扫描
②首先是未开始游戏状态,输入0进行扫描
③点击一个小方块,输入1进行扫描,结果46个
④点击笑脸,将游戏还原,输入0进行扫描,结果15个
⑤点击一个小方块,输入1进行扫描,结果7个
⑥点击笑脸,将游戏还原,输入0进行扫描,结果2个,可以看出笑脸的内存地址为01005164
⑦验证结果是否正确,将这个地址添加到地址栏中观察他的数值是否在游戏初始阶段为0,在游戏进行阶段为1
计时器:
①计数器的时间也是一个具体的值,所以可以通过精确数值扫描出来
②游戏开始之前计时器上的数是0,所以精确扫描0
③因为第一次扫描的结果太多,选择介于什么数值之间再次扫描
④最终确定时间的内存地址为0100579C
结果:
“雷数”的内存地址:010056A4
“笑脸”的内存地址:01005164
“计时器”的内存地址:0100579C
(3)分析地雷存放的算法;
首先要布雷函数被主函数调用的时机,根据观察可以得出一个结论:主函数在第一次点击棋盘上任意一个格子之前没有调用布雷函数,也就是说无论玩家第一次点击棋盘上任一格子都不会踩到雷,因为此时的棋盘上还不存在地雷,而在玩家点击第一个格子之后到点击第二个格子之前已经调用布雷函数,这时棋盘上的地雷才布置好。
随机埋雷,使用随机函数来实现雷区的随机化,尽量保证每个格子生成雷的概率相等;每次从当前坐标点之后的二维数组中随机选择一个坐标,并将生成的随机坐标(randx,randy)与当前选择的坐标互换,实现一次随机选择;
计算每个格子周围的雷的数量,以当前坐标点为中心,对周围八个点进行遍历,每个雷的位置L[x][y]值为1,设置一个函数用于判断当前遍历的坐标点是否在二维数组范围内,将每个点周围的雷的数量存储在一个新的二维数组numbers中;
点击格子,定义一个周边格子的的数组类将当前格子传给它。先计算左右、上下四个角,并返回一个值。定义打开格子的三种情况:一是有雷,二是空的,三将格子周边的地雷数显示到这个格子上。对当前是空白的坐标点,对其周围上下左右四个方向进行深度优先遍历,碰到数字或者雷时停止向下的遍历。
- 利用思维导图分析“扫雷”游戏软件的工作原理(设计原理)。