一.阳光基址
1.阳光地址
通过不断改变阳光值,用CE在内存中搜索这个值,定位到修改阳光的地址。
1.打开游戏,看到左上角的阳光是150,CE中按下图设置,点“First Scan”按钮
Scan Type:Exact Value (精确值)
Value Type:4 Bytes (4字节)
2.通过种植植物来改变阳光值
种植一个植物,阳光值变为50,CE中按下图设置,点“Next Scan”按钮
Scan Type:Exact Value (精确值)
Value Type:4 Bytes (4字节)
不断改变阳光值,直到找到只有一个结果,找到地址0x19182990,在左边列中双击这个地址,该地址添加到下面的列表中,修改这个地址的值,发现阳光值跟着改变。0x19182990就是我们要的阳光的值的地址。
重新打开游戏加载CE,发现0x19182990存的不是阳光值了。
重新用CE进行搜索,找到阳光地址为0x17F8B838,阳光的内存地址发现了变化。
说明:这是C/C++语言通常用到的一个做法:动态内存分配。
2.CE找阳光基址
如上图,在找到的地址0x17F8B838上右键,选择 Find out what writes to this address(谁改写了这个地址),弹出的窗口里面是空白的
此时,切换回游戏,点击拾取一个新的阳光之后会出现下图
(目的是让阳光变少,好找出哪些代码修改了此内存)
再回到CE,会看到刚才的空白对话框中已经有内容了,双击或点“More information”弹出扩展信息窗口“Extra info”,出现下图内容:
注意看红色汇编代码 : add [edi+00005578],eax
EAX=00000019(十六进制),等于十进制的25,刚好为捡取的阳光值
EDI=17F862C0,加上00005578,刚好等于阳光地址17F8B838
红色代码那行,很显然就是当前阳光数加上捡取的阳光数。
记住EDI的值“17F862C0“,将上面的搜索框前的Hex(16进制)勾选上—>将EDI的值填进去—>首次扫描,如下图所示:
搜索出一堆地址,选择一个地址(这里选择01089BA0,因为这种0012或0018开头的是堆栈中的值不用管他),添加到地址列表—>右键—>查找所有访问此地址的代码,稍等一下就出一大堆代码出来了,如下图:
双击第一个mov 指令查看更多信息,如下图:
原来EDI的值是ESI+868得来的,ESI的值是01089338,我们继续搜索01089338,如下图:
大功告成,查找到了绿色内存地址,绿色内存地址表明该地址在游戏中是静态的,它就是我们要找的基址了。
下面我们试着把这些内存地址连接起来,内存地址007794F8(值为01089338)+偏移 868 = 01089338,地址01089338+偏移5578=17F8B838(此地址就是我们第二步搜索出来的阳光地址)。
好了,我们用CE测试一下是否正确,如下图,手动填加地址进行测试:
结果完全正确,最终地址指向的内存值为1099。
3.OD找阳光基址
用CE重新打开游戏,找到阳光的动态地址0x17F6E3D0
打开OD选择文件->附加->植物大战僵尸,并点击运行
在数据区域 Ctrl + G 跳转到重新找到的局部变量地址
或者 用 dd 命令显示数据,如下 十六进制0x00000032转换为十进制为 50(当前阳光值)
在该地址处右键,下一个内存访问断点,查看谁访问了该地址
此时,改变阳光值(拾取一个阳光或种植植物)
下面由于重新打开了游戏,阳光(动态地址)变为 0x17F798E0,下面都以这个地址截图
此时,内存断点已经断下:
00433FC0 /$ E8 CBFEFFFF call 00433E90
00433FC5 |. 0382 78550000 add eax, dword ptr [edx+0x5578]
在Command中输入 ? edx + 5578,回车,发现值为 0x17F798E0,为阳光(动态地址)
记录EDX的值 0x17F74368
EDX中记录的值同样可能会变化,因此需要继续寻找0x17F74368的数据来源
删除所有内存断点后,在 call 00433E90 处下一个断点,并运行程序,此时断下后,去掉 call 00433E90 处的断点,在堆栈窗口中,返回到那行,按下回车键,程序来到上一层的call
OD找相对比较麻烦,因此改用CE来找