简述
这次是实现植物大战僵尸的无限阳光功能。
原理
无限阳光的原理其实很简单,就是让阳光用不完就行了。实现的方法有很多,这次我的方法是删除阳光减少的指令,然后用上次的技术将阳光修改为9999(这是植物大战僵尸显示的最大阳光数),这样阳光不会减少,而阳光数已经最大,所以就相当于实现了无限阳光的功能。
准备
系统:Windows 7 SP1 x64 ultimate
游戏:植物大战僵尸
工具:Cheat Engine v6.7、Visual Studio 2017
分析
定位阳光减少指令
整理下思路,定位减少阳光的指令,那么需要以阳光的位置作为依据,找到哪些位置修改了阳光,因为想要修改阳光值,就必然有相应的代码来实现,否则阳光不可能无缘无故的减少。所以,我们先找到一个阳光的位置。
开启一局游戏,用上次的方法定位到阳光的位置。
在该地址上右击,查看哪些地址修改了阳光。
在收集到阳光时,首先出现了一行代码,可以判断这是增加阳光的。
在种下植物后,阳光减少,这时出现了另外一条代码,猜测就是减少阳光的。
该指令为
0041BA76 89B7 60550000 mov [edi+0x00005560],esi
可以知道指令地址为0x0041BA76,指令码为89B7 60550000,指令为mov [edi+0x00005560],esi。
现在减少阳光的指令已经找到,我们就可以对其进行修改了。
删除阳光减少指令
使用OD附加游戏进程,记得先关闭CE,否则CE的调试器开着,OD无法附加成功。
使用ctrl + G,跳转到指令地址。
用nop填充该指令,然后运行游戏,发现阳光已经不再减少。
编程实现
使用C语言实现该功能。共有两步:
删除指令
修改阳光
核心代码如下:
//修改代码
boolean ModifyCode(int flag)
{
DWORD dwCodeAddr = 0x0041BA76;
BYTE targetcode = 0x90;
BYTE srcCode[] = { 0x89, 0xB7, 0x60, 0x55, 0x00, 0x00 };
int i;
switch (flag)
{
case 0:
{
for (i = 0; i < 6; i++)
{
if (!WriteProcessMemory(hProcess, (LPVOID)(dwCodeAddr + i), (LPCVOID)(srcCode + i), sizeof(BYTE), 0))
{
MessageBox(NULL, L"指令修改失败", L"失败", MB_OK);
return false;
}
}
break;
}
case 1:
{
for (i = 0; i < 6; i++)
{
if (!WriteProcessMemory(hProcess, (LPVOID)(dwCodeAddr + i), (LPCVOID)&targetcode, sizeof(BYTE), 0))
{
MessageBox(NULL, L"指令修改失败", L"失败", MB_OK);
return false;
}
}
break;
}
}
return true;
}
运行效果如下:
开启无限阳光。
关闭无限阳光。