作者:京东工业 宛煜昕
扫雷游戏置信很多人都从小玩过,在那个电脑游戏并不多的时代,扫雷成为玩的热度蛮高的一款游戏之一,然而就在有一次,接触到了一次不寻常的扫雷过程,使得起初我也有了这个激动,也来做一次。通过动静调试,逆向和 C 来写一个扫雷辅助工具从而进步逆向与编码技能。
动静调试(剖析)
首先进行扫雷程序的动静调试(剖析):
关上 OD(ollydebug 工具),把扫雷拖放到 OD 中,F9 运行;ctrl+ G 输出要追随的表达式,输出 rand,点击【确定】,跳转到该函数调用处,F2 设置断点,此次是想通过 API rand 函数来找寻突破口。在扫雷窗口的雷区中任意点击一个地位(图片中呈现 2 的地位),再点击还原(【笑脸】按钮 -),如下图:
此时 OD 会在刚设置的 rand 处的断点断下来,如下图:
通过找到随机函数 rand,上面进行栈回溯,回到下级函数中,来找到 push(压入栈)的参数,也就是说随机生成函数(rand)是随机生成的高,宽,雷数。点击 K(调用堆栈),弹出 K 调用堆栈窗口,查看堆栈窗口信息,找到返回地址,双击 K 调用堆栈窗口中的返回地址,返回到上一层,此过程称为栈回溯。仔细观察下图的堆栈信息 010036D2(返回地址)。
单步 F8,察看寄存器,数据窗口和堆栈窗口变动,dword ptr ss:[esp+0x4] 或 dword ptr ds:[XXX] 数据窗口跟踪数值(000DFC44 值是 09),如下图:
返回到下层函数后,剖析这外面的指令,得悉方才随机 rand 生成的宽(09),如下图,留神察看地址 010036C7。
首先从这个函数返回的后果着手剖析 eax,单步后,能够看到往堆栈中(地址 010036D2)压入了一个数字 09,如下图:
通过以上剖析,根本能够猜想失去周边的随机函数 rand 生成是高,雷数。能够试着扭转扫雷设置(自定义雷区),如下图,来精确定位 rand 函数及传参,点击【确定】,再点击【还原(笑脸 -)】按钮。
察看 OD,如下图:
发现 push 0C(000DFC84 值为 0C),能够确定这个 rand 函数 push 0C 就是雷区的高度。同时在内存区域也能明确看到一个大抵的雷区图形,通过以上办法,大抵能够猜想 0x80 就是雷。或者与 IDA 独特剖析,通过动态剖析,能够更直观的看到程序逻辑。失去如下数据:基地址,雷数等信息,如下图:
以上代码大略意思是先设置了全局宽 0x09,高 0x0C,雷数 0x0A 的变量,通过判断两层循环,随机生成了宽和高。得地图基地址:0x01005340。通过剖析下图得悉无雷是 0x0F,有雷是 0x8F,墙壁是 0x10。
通过宽,高的地址,打印出扫雷区域和雷数,并能够更直观的辨别边墙,雷。
上面开始要想如何标记雷了,通过假如 WinProc(通过栈回溯到音讯回调函数)中看到无关 GetDC 函数,大抵猜想会用到 Bitblt,在 OD 中 ctrl+ g 输出要追随的表达式,录入“BitBlt”,按 F2 设置断点,点击扫雷区域任意一个地位,OD 会断在 BitBlt 地位。
在 BitBlt 中还有一个 BitBlt 函数,初步判断感觉是用双缓冲形式绘图,
BitBlt(hDestDC,// 目标 DC XDest, // 目标 x 坐标 YDest, // 目标 y 坐标 10, // 10, // 重绘区域的高和宽 hSrcDC, // 源 DC 0, 0, SRCCOPY);// 指定操作形式计算雷的坐标(点击第一个扫雷的方块,查看坐标),须要留神边墙,如下图:
减去边墙的值:
-0x04=0x0C(12)-0x10(16)
0x27=0x37(55)-0x10(16)
失去坐标公式:x(XDest:12)=10x10(16)-0x04(4),y(YDest:55)=10x10(16)+0x27(39)。
代码编写
通过以上大抵的剖析,可进行代码的编写了,
成绩
输出 3landmine 地位,获取出 landmine(10 墙壁,8Flandmine,0F 无雷)
输出 2 主动扫雷,标记雷并开出地图
通过这个小我的项目,首先增强了对软件的一种逆向思维,如:看到这一种面板,大略猜到是用数组来实现的,其次雷的布局是随机生成的,而后通过动静调试能够理解实现办法(开发者的一种实现思路),可找到要害的基地址,几种状态(无雷,有雷,墙壁),最初编码阶段能够了解内存的操作,几个重要的 API,FindWindow 获取句柄,OpenProcess 关上句柄,ReadProcessMemory 读取内存信息,PostMessage 异步音讯模式,CloseHandle 敞开句柄。其中有一些剖析有误或不到位的中央还请拍砖。多逆向,剖析代码有很多帮忙,不仅能够拓宽本人编程与测试的思维及程度,还能发现,开发及利用程序中的破绽或给程序打补丁等。心愿小伙伴们在这条任重而道远的路上加油,互勉。