C# 植物大战僵尸逆向之---实现植物无冷却 (编写植物大战僵尸辅助 二)
C# 植物大战僵尸逆向之---植物无冷却 (编写植物大战僵尸辅助 一)
本章说明:
利用CE工具找出植物道具栏冷却的地址,实现道具无冷却
一、首先还是打开CE工具,添加上游戏进程,开始搜索值,我之前已经搜到植物冷却的数据类型为字节,
在可使用的情况下为1,否则为0。 (之前我已经通过搜索未知的数据找出来了,我这里就不演示了。直接搜索1)
找出这么多数据后,我们拿起植物,它的值就会变为0, 点再次扫描
然后我们又点右键 取消种植,他就又恢复1,重复的扫描几次,就会排除很多无用的数据。
最后排查出还有这些地址。接下来判断哪一个才是对的,把数据拉下来。
上一章说到,一般内存地址很有规律规则的先不看它,我们优先看比较特别的地址,目前就只有这一个。
我们来试着把数值改一下,改成0,看植物会不会进入冷却状态
这样就是找对了,改为0后,他会进入冷却状态。 那么我们接下来就开始找它的静态地址 (每次启动游戏固定的)
跟上一章一样的。
二、找基址
在CE右键这个地址,查看是谁在写入这块数据,往上追溯。(游戏中,当你拿起植物的时候,肯定有一块地址在往冷却的这个地址写值的,我们要找到是谁在往这儿写数据)
我们会看到没有显示数据, 我们回到游戏中拿起这个植物再放下,它就会往这儿写数据了。
我们选中写入1的这个一项,点击更多信息后 会弹出额外信息框。
然后分析一下这段代码,我们看到
它再内存中从寄存器eax+edx+70偏移的地址来置为1
然后我们从寄存器信息中中看到eax 值是为0的,所以忽略掉。
然后edx是 2D5306F0
再打开计算器用这个地址+上70的偏移,发现跟我们CE最开始找出的地址是同一个。
那么我们就是找对了的。
现在我们已经知道有一层的偏移是 70了, 记住,我们还要接着往上找。
分析下edx寄存器的来源,CE十六进制 4字节搜索下这个EDX的值是哪个内存在存储着这个值。
只有一个就很省事,不用去排查其他的。 拉下来查看什么在访问这个地址,进入游戏拿起植物又放下
又发现edx的来源 是ECX寄存器+15C的偏移取的内存值。 我们点击这一项查看更多信息看看。
, 搜索这个地址值。 查出70多条数据。 老样子,我们先看比较特别一点的地址。
进入游戏拿起植物又放下,查看谁在对这个地址进行写入
发现ecx寄存器的值又来源于 ebx+868偏移,点击更多信息进去。
EBX的值是 0265A528, CE继续搜这个地址.
现在基本上已经找出来了,静态地址已经出现了。 我们来看这个静态地址是谁在访问。
现在就已经找到了,ECX寄存器的值来源于直接从00755E0C内存中取值的。 那么就用这个静态地址加上三层偏移,就ok了。
到这儿,我们会发现,也只是植物栏1 的植物无冷却了,我们还需要将 其他的找出来。
这儿就有个技巧了,游戏开发者,一般都不会将道具栏每一格都分开存储的, 大部分都是数组或者链表。 我们先试试第一种,从我们找出的第一个道具栏的地址来加一定的偏移 看看能不能找出。
三、添加偏移,找出所有植物栏的冷却地址。
我们一下一下子的加,看找出来的地址数据,是不是1和0,是的话 我们就修改下值,到游戏中看对不对。
我这边已经试出来了,点20下,每次点一下都会加4字节。
然后修改数值 到游戏测试,发现是正确的。 那么接下来的4个植物栏都是一样的在上一个基础上点20下。 那么对应十六进制每次增加的是50。 我们用计算器也可以计算出下一个偏移是多少
好。到这儿基本上所有的植物栏的冷却值都知道了。
四、编写C#程序,实现植物栏无冷却
1 bool isCooling = false; //是否开启无冷却 2 int CoolingTimerId; //冷却时钟id 3 4 /// <summary> 5 /// 获取植物栏1冷却基址 6 /// </summary> 7 /// <returns></returns> 8 public int GetCoolingMemoryAddr() 9 { 10 int addr; //静态地址 11 int drift; //偏移1 12 int drift2; //偏移2 13 int drift3; 14 15 addr = EastDrive.DriverRead.ReadMemoryInteger(proId, 0x00755E0C); //获取出静态地址中的阳光地址值 16 drift = EastDrive.DriverRead.ReadMemoryInteger(proId, addr + EastDrive.Tools.BaseS_16To10("868")); //加上第一层偏移 17 drift2 = EastDrive.DriverRead.ReadMemoryInteger(proId, drift + EastDrive.Tools.BaseS_16To10("15C")); //第二层偏 18 drift3 = drift2 + EastDrive.Tools.BaseS_16To10("70"); //第三层偏移 拿到存值冷却值的地址 19 20 return drift3; 21 } 22 23 /// <summary> 24 /// 植物栏无冷却 25 /// </summary> 26 /// <param name="sender"></param> 27 /// <param name="e"></param> 28 private void check_cooling_CheckedChanged(object sender, EventArgs e) 29 { 30 isCooling = check_cooling.Checked; 31 32 if (!isCooling && CoolingTimerId != 0) //关闭 33 East.WinCore.Win32Api.CloseTimer(CoolingTimerId); 34 else 35 StartCooling(); //开启 36 } 37 38 /// <summary> 39 /// 开启无冷却 40 /// </summary> 41 public void StartCooling() 42 { 43 //创建时钟 锁定冷却值 44 CoolingTimerId = East.WinCore.Win32Api.SetTimer(() => 45 { 46 //总共6个植物栏地址 每次叠加50(十六进制的偏移) 对应十进制为80 47 EastDrive.DriverWrite.WriteMemoryInteger(proId, GetCoolingMemoryAddr(), 1); //写入1 无冷却。 48 EastDrive.DriverWrite.WriteMemoryInteger(proId, GetCoolingMemoryAddr() + 80, 1); 49 EastDrive.DriverWrite.WriteMemoryInteger(proId, GetCoolingMemoryAddr() + 80 * 2, 1); 50 EastDrive.DriverWrite.WriteMemoryInteger(proId, GetCoolingMemoryAddr() + 80 * 3, 1); 51 EastDrive.DriverWrite.WriteMemoryInteger(proId, GetCoolingMemoryAddr() + 80 * 4, 1); 52 EastDrive.DriverWrite.WriteMemoryInteger(proId, GetCoolingMemoryAddr() + 80 * 5, 1); 53 }, 100); 54 }
现在开启功能,我们就会发现,即使拿起植物,它也不会进入冷却状态。
下一章:实现豌豆射手秒杀僵尸的功能。