植物大战僵尸外挂笔记

植物大战僵尸外挂笔记

0x00 CE初步

CE修改器(Cheat Engine)是一款内存修改编辑工具,CE修改器它允许你修改你的游戏,所以你将总是赢.它包括16进制编辑,反汇编程序,内存查找工具.CE修改器与同类修改工具相比,它具有强大的反汇编功能,且自身附带了修改器制作工具,可以用它直接生成修改器。

总之,CE可以帮助我们搜索看到的程序效果在内存中的表示,比如搜索一个数据存在哪块内存上,而写游戏外挂的本质就是修改游戏中的数据,来实现一些爽操作

0x01 找阳光

image-20220630105800050

从这里我们可以看到,目前的阳光值是50,所以直接在CE里面first scan

image-20220630105915395

这是在对植物大战僵尸所有的内存块进行搜索,寻找当前值为50的内存块,左边是搜索结果,目前来看有很多,其中黑色地址的是动态地址,绿色地址的是静态地址,区别在于每次打开游戏时,动态地址会变,而静态地址是不变的

这时我们为了找到究竟哪一个地址存放着阳光,对阳光进行一次改变,

image-20220630110211461

改变的时候有个 小技巧,尽量不要让阳光为0,因为一个程序里面为0的值很多,筛选效率比较低

image-20220630110318023

我们收集一个阳光,令阳光达到75,再次scan就直接找到了阳光的动态地址0x1BFF3550

但是找到动态地址还不够,这个地址每次打开游戏都不一样,不能用外挂程序直接操控,所以我们要去找静态地址

image-20220630110718825

右键点击这个地址,选择“Find out what writes to the address”,

image-20220630111032492

在下次收集到阳光时,CE会找到修改了这个值的汇编语句,从这条语句我们发现,eax+0x00005578这个位置的值加上了ecx的值,我们选中这条语句,点击“more information”

image-20220630111243260

发现ecx=0x19,也就是十进制的25,刚好是一个阳光的数量,那么被加的地址应该就是存储阳光的地址了,也就是刚刚我们看到的阳光的动态地址0x1BFF3550的来历,看一下eax的值是0x1BFEDFD8

但是这个值依然不是一个静态地址,我们要找到这个地址是怎么来的,于是继续搜索这个地址

image-20220630115525849

可以看到搜出来有很多地址,其中0x0019开头的都是堆栈的地址,找到下面的0x03EAB958

image-20220630120119461

右键点击这个地址,选择“Find out what accesses this address”,

image-20220630120214904

可以看到改变eax的值的语句

我们分别看一下两条改变eax的语句

image-20220630120544438

发现无论从ecx改还是从esi改,实际上都是用的0x03EAB0F0这个地址+0x868

于是继续搜索0x03EAB0F0

image-20220630120708455

终于看到了绿色的静态地址,随便选一个就行

image-20220630121011471

双击这个地址,设置一下指针,注意两个偏移值顺序不能换,因为实际上这是两层的指针

即静态地址是第一层指针p1,其中存的值为0x03EAB0F0

p1指向的地址是第二层指针的基址,所以+0x868得到了第二层指针p2

图中可以看到p2应该是的0x1BFEDFD8,这个指针再加0x5578得到了最终实际存储阳光的地址

这个时候找基址的部分就结束了,然后就需要进行自动化修改

0x02 自动化修改阳光

参考这篇博客https://blog.csdn.net/weixin_43752471/article/details/84445871?spm=1001.2101.3001.6650.2&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7Edefault-2-84445871-blog-117117813.pc_relevant_vip_default&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7Edefault-2-84445871-blog-117117813.pc_relevant_vip_default&utm_relevant_index=3学习了一下C++修改其他程序内存

然后把相关的参数改一下,大概就拿这篇代码直接用了,顺便还一块做了修改金币的功能,道理是一样的,只不过金币的存储是数量/10存储的,直接搜金币数搜不出来,要/10才能搜出来,最后获取的静态地址和阳光的一样就不用两个地址了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
#include <tchar.h>
#include <stdio.h>
#include <tchar.h>
#include <Windows.h>
#include<iostream>
using namespace std;
int gameaddress = 0x00731C50; //游戏基址;
HANDLE gameprocess; //句柄类型 获取
//2次偏移
int *get5point(int gameaddress,int p1,int p2)
{
int iBase, iP1, *iP2;
if (!ReadProcessMemory(gameprocess, (LPVOID)gameaddress, &iBase, 4, NULL))//初地址赋值
{
return NULL;
}
if (!ReadProcessMemory(gameprocess, (LPVOID)(iBase + p1), &iP1, 4, NULL))
{
return NULL;
}
iP2=(int *)(iP1+p2);
return iP2;
}
//修改阳光
void rwyg()
{
int *pwx=get5point(gameaddress,0x868,0x5578);
int wx = 0x2710;
cout<<"pwd="<<pwx<<endl;
WriteProcessMemory(gameprocess, pwx,&wx, 4, NULL);
}

void rwjb()
{
int *pwx=get5point(gameaddress,0x94c,0x54);
int wx = 0x186a0;
cout<<"pwd="<<pwx<<endl;
WriteProcessMemory(gameprocess, pwx,&wx, 4, NULL);
}

int _tmain(int argc, _TCHAR* argv[])
{
//获取游戏窗口所在进程的进程ID,也就是PID
HWND hWnd = FindWindow(NULL, TEXT("Plants vs. Zombies"));
if (NULL == hWnd)
{
printf("查找窗口失败\n");
return 0;
}

DWORD dwProcessId;
GetWindowThreadProcessId(hWnd, &dwProcessId);
printf("进程ID:%d\n", dwProcessId);

//获取进程句柄
gameprocess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessId);
if (NULL == gameprocess)
{
printf("打开进程失败\n");
return 0;
}
rwyg();
rwjb();
getchar();
return 0;
}
  • Copyright: Copyright is owned by the author. For commercial reprints, please contact the author for authorization. For non-commercial reprints, please indicate the source.
  • Copyrights © 2021-2024 Kery
  • Visitors: | Views:

请我喝杯咖啡吧~

支付宝
微信