C# 植物大战僵尸逆向之---找阳光基址 (编写植物大战僵尸辅助 一)

C# 植物大战僵尸逆向之---找阳光基址 (编写植物大战僵尸外挂辅助一)

 

本章说明:

  用到的工具:CE 7.3、VS2015  (本章节暂时只用到这两个, 下一章需要用到OD反汇编工具)。

  利用CE找出植物大战僵尸阳光值的基址,并修改阳光值

 

下一章实现:

  下一章讲解:道具栏1-6冷却基址+偏移(实现无冷却)、 豌豆射手秒杀僵尸的功能 ...

 

 

本章节功能演示:

 

一、(编写程序)创建C#一个winfrom程序,制作辅助了。

 

 

 1         public Form1()
 2         {
 3             InitializeComponent();
 4         }
 5 
 6         bool isLockSunshine = false; //是否开启无限阳光
 7         int SunshineTimerId; //阳光时钟id
 8 
 9         int proId; //游戏进程id
10 
11         /// <summary>
12         /// 窗体加载
13         /// </summary>
14         /// <param name="sender"></param>
15         /// <param name="e"></param>
16         private void Form1_Load(object sender, EventArgs e)
17         {
18             proId = EastDrive.DriverRead.GetProcessId("PlantsVsZombies");
19 
20             if (proId == 0)
21             {
22                 MessageBox.Show("检测到游戏未启动,请先进入游戏在打开本程序");
23                 System.Environment.Exit(0);
24             }
25             else
26             {
27                 this.Text = "游戏进程ID:" + proId;
28             }
29 
30             MessageBox.Show(GetSunshineMemoryAddr() + "");
31         }
32 
33         /// <summary>
34         /// 无限阳光
35         /// </summary>
36         /// <param name="sender"></param>
37         /// <param name="e"></param>
38         private void check_sunshine_CheckedChanged(object sender, EventArgs e)
39         {
40             isLockSunshine = check_sunshine.Checked;
41 
42             if (!isLockSunshine && SunshineTimerId != 0)  //关闭
43                 East.WinCore.Win32Api.CloseTimer(SunshineTimerId);
44             else
45                 lockingSunshine();  //开启
46         }
47 
48         /// <summary>
49         /// 获取阳光的基址   也可以在获取到值后,直接写死。 游戏不更新是不变的。
50         /// </summary>
51         /// <returns></returns>
52         public int GetSunshineMemoryAddr()
53         {
54             int addr; //静态地址
55             int drift; //偏移1
56             int drift2; //偏移2
57 
58             addr = EastDrive.DriverRead.ReadMemoryInteger(proId, 0x00755E0C); //获取出静态地址中的阳光地址值
59             drift = EastDrive.DriverRead.ReadMemoryInteger(proId, addr + EastDrive.Tools.BaseS_16To10("868"));  //加上第一层偏移
60             drift2 = drift + EastDrive.Tools.BaseS_16To10("5578"); //第二层偏移加上后,就获取到基址了
61 
62             return drift2;
63         }
64 
65         /// <summary>
66         /// 锁定阳光值
67         /// </summary>
68         public void lockingSunshine()
69         {
70             //创建时钟 锁定阳光
71             SunshineTimerId = East.WinCore.Win32Api.SetTimer(() =>
72               {
73                   EastDrive.DriverWrite.WriteMemoryInteger(proId, GetSunshineMemoryAddr(), 9999);
74               }, 100);
75         }

 

Ps:East.dll  和 EastDriver.dll  是我封装的一个类库,用于内存读写操作的。 (也是C#)编写。   至于内存读写,我后面在记录怎么操作的。

 

 

 

二、正式开始 (找基址)打开CE附加植物大战僵尸进程,点打开

  

 

 

二、开始一局游戏,CE 数据类型4字节搜索阳光的值 

  阳光值是10进制的 ,不需要勾选16进制选项

  

 

 

  随便种下一棵植物,或者捡一个阳光后,点击首次再次扫描。找出变化的值

现在还搜出几个,无法确定的话,就继续往复。 收集一点阳光,在看CE的当前值,来确定是哪个内存地址。

 

 

 

 

 现在就已经找到阳光的内存地址了,但这个地址是动态的,每次启动游戏,内存地址都不一样,我们需要找到他的静态地址+对应的偏移,来获取到他每次的固定地址。(基址)

 

 看出这条指令在给eax寄存器放数据   选中点更多信息

 右键复制出这块汇编代码

 

 

 

 搜索后 多点几次再次扫描,因为程序 阳光的地址都是从同一个入口进来获取阳光值的。多点几次再次扫描可以清理掉一些会变化的值,那肯定就不是。 最后扫出来还有40条左右,已经不能在扫了。

看了列表后,这两条是最像的,一般情况来说 很多重复规则的地址存的都不是,我们优先查看这种特别的地址。 把这两条脱下来看看。

 

 

 

 接着看上面那条。

 

这一条应该就是对的了,我们要从列表中找出是哪一条呢,我们回看到上面第一层偏移的地址.,分析如下

 

mov eax,[edi+00005578]   从edi寄存器的地址+5578偏移取值放到eax寄存器。  所以我们要找edi的来源,

从上图看到 : 

mov edi,[esi+00000868]  esi寄存器+868偏移取值放到edi寄存器。

那么,我们现在就继续跟着往上找esi的来源,步骤跟上面一样,点击 更多信息。

 

 我们搜索这个地址。

 

 

 

现在就已经追出来了,绿色的地址就是静态地址,每次启动游戏都不会变的。接下来我们要确定哪一个才能用。  把这四项拖下来

 

 

 

我们看到  这个静态地址的这一栏在给esi赋值,那么我们就找到了esi的来源。   现在我们已经知道静态地址和偏移了,我们就不用在追下去了。现在开始手动录入指针。

 

 

点击确定, 我们开始修改游戏中阳光的值

 

 

 

 修改就已经成功了,  C#编写程序见上面 一、

 

 

 

 

posted @ 2022-05-04 16:13  阿东呢  阅读(1206)  评论(2编辑  收藏  举报