2.3第三次作业
“扫雷”游戏逆向分析
2.3.1棋盘内存地址范围
2.3.1.1 初级棋盘内存地址
1.取消“快速扫描”,扫描类型选择“未知的初始值”,点击棋盘第一个格子,随后点击“首次扫描”。
2.点击“笑脸”,刷新棋盘,再次点击棋盘第一个格子,若数值与上一次相同,则扫描类型选择“未变动的数值”,若数值与上次不同,则扫描类型选择“变动的数值”。
如上图所示数值未变动,则选择“未变动的数值”,点击“再次扫描”。第二步操作反复进行,最后看到绿色的基址。
3.将该记录添加到下方,右键选择“浏览相关内存区域”,相关内容如图所示。
点击“笑脸”,再点击棋盘第一个格子,观察下方内存数据的变化,我们可以得出第一个格子的地址为01005362。
4.同理找到棋盘的最后一个格子地址为01005468。
因此最后得出初级棋盘地址范围是01005362 ~ 01005468。
2.3.1.2 其他级别棋盘内存地址
同理找出中级棋盘和高级棋盘的地址范围为:
中级棋盘地址范围 01005362 ~ 01005551;
高级棋盘地址范围 01005362 ~ 0100555Frr。
2.3.2 游戏中各变量的内存地址
2.3.2.1 雷数的内存地址
1.找旗子的地址。(中级棋盘)查看左上角雷的个数共40个,右侧输入40,扫描类型选择“精确数值”,点击“首次扫描”,如图所示。
任一格子放置旗子,数量变为39,输入39进行“再次扫描”,得出找出了旗子的基址为01005194。
2.扫描雷的内存地址。因为旗子和雷的初始数据是一样的,所以先扫描旗子的数据,第一次扫初级棋盘的旗子数量10,转换到中级棋盘,再次输入旗子数量40,得出三个基址。
我们发现,这三个地址中,有一个和旗子地址一样,则排除该地址。剩余两个地址,我们分别修改数值为1,然后点击棋盘。修改01005330地址的数值发现棋盘没有变化,则排除,具体内容如图所
示。
修改010056A4地址的数值为1,刷新棋盘,点击某一格子,发现可通关,则该地址为雷数的内存地址。
2.3.2.2 笑脸的内存地址
1.选择扫描类型为“未知的初始值”,此时表情状态为“笑脸”,点击“首次扫描”。
2.点击棋盘,改变表情的状态,若表情变化,则扫描类型修改为“变动的数值”;若未变化,则选择“未变动的数值”。随后点击“再次扫描”,反复操作。最后得出地址为009759DB。
2.3.2.3 计时器的内存地址
1.输入游戏时间“0”,选择“精确数值”,开始游戏,游戏时间会开始变动,扫描类型则选择“变动的数值”,点击“再次扫描”,反复操作。最后得出地址0100579C。
2.3.3地雷存放的算法
输入参数:
int height, int width, int mineCount
输出参数:
void
初始化:
int size = height * width;
算法:
对每一个Element进行以下步骤:
1、生成一个随机数random
2、if (random * size <= mineCount){mineCount--;//设Element的状态为MINE}
3、size--
4、进入下一个Element
2.3.4 工作原理
1.n*n网格,一定数目的雷,如Windows7 Minesweeper游戏;
2.雷的位置随机分配到网格上;
3.网格上不是雷的位置上 显示的方块上显示周围上下左右四个角的有雷的个数;
4.雷数计数器显示余下的未发现的雷数。