逆向新手,经典扫雷游戏确定雷区地址的几个方法
前言
逆向新手,经典扫雷游戏确定雷区地址的几个方法
一、通过相关的数据区来确定
结合CE实现
首先从数据结构去考虑,思考‘’雷‘’与‘’非雷‘’数据(还包括不同等级的窗口的高度和宽度)是用什么样的结构来存储的,不妨假设是以二维数组的方式进行的存储。
- 打开扫雷软件
- 打开CE附件进程选择扫雷
- 通过设置窗口的不同大小来搜索
首先修改高度为16
在PE中点击新的扫描,然后在数值一栏中输入16
然后改变自定义高度为24
在数值一栏输入24,然后点击再次扫描
结果如下
- 记录下两个地址值,01005338,010056A8
- 用OD打开扫雷.exe,刚开始代码端显示的是系统领空
然后F9运行,至弹出扫雷的窗口
在数据区用Gtrl+g跳转到地址01005338处
- 发现这一块的数据主要是10,0F和8F,猜测数多的0F是安全数字,数少的8F是雷区,10可能是边界。
二、通过Command消息定位,重点放在查找二层循环上
- 当调整游戏等级的时候,游戏会重新绘制窗口,在重新绘制窗口时,也会初始化雷区,可以通过对command消息下断点来找雷区。
什么是加速键?加速键也称为键盘快捷键,一个加速键是一个或几个按键的组合,它用于激活特定的命令,使用加速键不需要费力移动鼠标就能激活菜单项。 随着用户对应用程序越来越熟悉,加速键正是他们进一步增加应用程序使用速度所需的快捷方法。 使用者可以通过「 Alt 键」从功能表中选择「 Delete 」选项,或者只需按下加速键 Del 。
什么是command消息?https://learn.microsoft.com/zh-cn/windows/win32/menurc/wm-command
- 首先用OD打开扫雷,然后打开windows窗口,对应字母W
如果打开后什么都没有
在OD中右键选择Actualize
右键在clsProc上设置消息断点Message breakpoint onClassproc,选择WM_COMMAND
- 然后调整游戏难度,命中消息断点
因为雷区使用二维数组存储的,因此要在OD中寻找二层循环
F8 步过逐步调试代码
知道01001E93出的call指令,在该指令之前乜有循环,并且该指令之后的jmp 01001F4A是个break,所以F7步入call 0100367A
找循环在于在向上跳转的箭头
在数据窗口中跟随1005334,发现雷区
三、通过随机数定位
结合扫雷游戏,我们可以知道雷区是随机生成的(点击笑脸后雷会更新),所以可以尝试从生成随机数的函数入手定位雷区。
- 在OD中打开扫雷,点击Executable Modules模块窗口,即字母E。
选中win.exe,右键View names
在该模块中尝试搜索rand函数,定位到010011B0
右键,在每个参考上设置断点(set breakpoint on every reference)
然后点击笑脸或者更改游戏等级,使游戏初始化,命中在rand处下的断点
关键代码应该在rand函数的ret的返回地址处,f8跟进,ret 跳转到010036D2处
然后F8跟进遇到call 01003940,跟进后又跳转到01003940处,继续F8再次在ret 处跳转到了010036E0
此处与之前的利用command消息来定位的代码段重合,不再赘述。
四、通过鼠标消息来定位雷区
当使用鼠标点击雷区的时候,它会对雷区进行访问来判断是不是雷,与command消息定位类似,在Windows窗口下选中扫雷,在classProc上设置消息断点。
在此处设置为WM_LBUTTONDOWN
F9运行程序,鼠标点击触发事件
此时查看堆栈窗口
可以发现在栈中记录了鼠标的x,y坐标,程序应该是用鼠标的坐标进行寻址的,所以要在此处下硬件断点。
什么是硬件断点?https://www.52pojie.cn/thread-846934-1-1.html
在OD左下方的command处输入如下命令 :HE 00CFD80
依次选中debug-》Hardware breakpoints
刚设置的硬件断点如下:
然后F9运行重新触发左键点击事件的断点,并使用F8继续向下逐步调试
到01001FB1处,F7跟进call
调用PtInRect
PtInRect 函数确定指定的点是否位于指定的矩形内。 如果一个点位于矩形的左侧或顶部,或者位于所有四个边内,则它位于矩形内。 右侧或底部的点被视为矩形外部的点。
然后断点来到这里 发现它拿我们的鼠标坐标 做了运算 并当作参数传递进去 猜想它应该是把鼠标的XY坐标转换为数组的行和列 这个Call是个关键Call 跟进去观察参数
进入到call后,发现arg.1复制给了edx,接下来关注edx这个寄存器
,
继续向下调试,发现有一个有一个地址把edx当做偏移来寻址
尝试在数据窗口中跟随
成功找到雷区
五、通过双缓冲绘图来定位雷区
扫雷在回显的时候,有的会显示数字,有的显示旗帜,那么它是通过什么来区分区分的呢,此处猜测通过读取雷区来区分要回显的内容
什么是双缓冲绘图?双缓冲即在内存中创建一个与屏幕绘图区域一致的对象,先将图形绘制到内存中的这个对象上,再一次性将这个对象上的图形拷贝到屏幕上,这样能大大加快绘图的速度。
与双缓冲绘图有关的API如下:
- 预测可能会使用bitbltAPI,所以在BitBltAPI处下断点
- 点击模块窗口(字母E),右键View Names(Ctrl+N)
BitBlt函数:BitBlt 函数执行与从指定源设备上下文到目标设备上下文中的像素矩形对应的颜色数据的位块传输。
直接键盘输入BItBlt进行搜索
右键在每个参考上设置断点(set breakpoint on every reference)
运行程序,在第一个BitBlt断点处断掉
在数据窗口中跟随0x1005340,发现雷区