游戏辅助原理与制作01.扫雷-01基址
1.前言
直接读取内存方式,扫雷游戏辅助制作过程。
参考:郁金香2013网授汇编逆向与外挂
2.基本工具
1.扫雷程序: https://download.csdn.net/download/music0564/10781320
2.代码注入工具CodeinEX_www.yjxsoft.com.exe:同1
3.CheatEngine681:官网自行下载
4.Microsoft Visual C++ 6.0
5.Spy++ (VC6.0自带工具)
6.OllyDBG:官网自行下载
7.VirtualBox虚拟机:Windows Server 2003 R2 Enterprise Edition 32位
3.基址
1).雷数基址
方法:使用CE,不断改变雷数,反复扫描,找到雷数地址。
运行扫雷游戏,打开CE,选择“Select a process to open”按钮,在弹出的“Process List”窗口上,选择扫雷游戏。
初始雷数为10,在CE中按照如下设置,后点击“First Scan”按钮。
Value:10
Scan Type: Exact Value
Value Type: 4 Bytes
出现很多值,在游戏中改变雷数,使之变为9,点击“Next Scan”按钮继续扫描,
此时仅剩一个地址01005194,且地址为绿色,则该地址为雷数基址。
验证:
双击该地址,把它添加到最下面的列表中(如上图)。
右键选择 Find out what writes to this address(谁改写了这个地址)
弹出的窗口里面是空白的
改变雷数后,窗口中出现一条汇编指令,鼠标单击该指令,下方窗口出现详细信息
单击 Show disassembler 按钮,显示反汇编窗口
窗口中显示雷数地址为 winmine.exe+5194 (程序基址+偏移)
OD验证(扩展阅读):
在OD的数据窗口找到地址 0x01005194处,在该处下个内存访问断点
程序将断在地址 0x010027AA处,如下图
找到指令 mov eax, dword ptr [0x1005194],为立即数,可以看到0x1005194即为雷数基址
2).棋盘基址
方法:使用CE,反复重新开始游戏,改变第一个格子的值,找到棋盘地址。
先将扫雷游戏设置为中级(每行16个格,便于内存对比)
先用CE加载扫雷进程,并按照如下设置后,点击“First Scan”按钮
Scan Type: Unknow initial value (未知初始值)
Value Type: Byte
点击第一个雷,设置 Scan Type: Changed value 后,点击“Next Scan”按钮
重新开始游戏,点第一格,反复设置
Scan Type: Changed value
Scan Type: Unchanged value
直到找到与第一个格相关的(如有多个,需要进一步判断)
可将值按照下图设置为十六进制(Show as hexadecimal),方便比对
选择右键菜单“Browse this memory region”查看该地址处内存
观察上图,分析数据如下:
雷:8A 点中的雷:CC 未点的格:0F
空格:40 1:41 2:42 3:43 结束标志:0x10
棋盘第一行数据以0x10结束,后补0x0F,一直到0x10结束
以初级扫雷验证如下:
3).棋盘高度和宽度基址
自定义雷区,设置棋盘高度999 宽度999 雷数999
再次打开自定义雷区,发现高度最大 24,宽度最大30,雷数最大667
根据这些,找出棋盘的高度和宽度的基址
winmine.exe+5361 //棋盘数组基址 即0x01005361
winmine.exe+5334 //棋盘宽度基址 (最大30) 即0x01005334
winmine.exe+5338 //棋盘高度基址 (最大24) 即0x01005338
4).棋盘及棋子单元格的尺寸
找出棋盘大小尺寸及每个棋子单元格的大小尺寸,用于辅助代码中模拟鼠标点击事件。
用VC6的Tools下的Spy++跟踪鼠标事件
启动Spy++,打开 Find Window 窗口,设置 Show 属性为 Message
将 Finder Tool 靶心拖动到扫雷游戏上,点击 OK 按钮
在扫雷游戏上点击一个格子,SPY++将捕获所有的消息
用 LBUTTONDOWN 和 LBUTTONUP这两个消息,模拟一次鼠标单击。
设置SPY++只监视这2个鼠标事件消息
分别获取棋盘左上角单元格和右下角单元格的坐标
根据这2个坐标计算棋盘每个棋子所占据的大小
双击第一条消息,查看消息属性
xPos:20 (十进制,转为十六进制14)
yPos:59 (十进制,转为十六进制3B)
lParam:003B0014 (高十六位003B表示yPos,低十六位0014表示xPos)
棋盘左上角坐标 20,59
棋盘右下角坐标 264,303
棋子大致宽度: (264 - 20) / 16 = 15.25
棋子大致高度: (303 - 59) / 16 = 15.25
可反复取点计算,求平均值 棋子宽度*高度 = 16*16