利用C语言编写《植物大战僵尸》修改阳光值代码

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/wangqingchuan92/article/details/83036960

0x00前言

文章中的文字可能存在语法错误以及标点错误,请谅解;

如果在文章中发现代码错误或其它问题请告知,感谢!

0x01准备工具:

1.cheat engine:
https://www.cheatengine.org/

2.Visual Studio 2010

3.植物大战僵尸

0x02实现过程

1.思路

我们打开的每一个程序中,存储数据的内存地址都会发生改变,但是程序的基址和偏移不会变。所谓基址,可以简单理解为不会随程序运行的起始时间和环境改变的地址,即全局数据区的数据的地址。 所以,我们关闭游戏再启动,存放游戏关键值的变量的地址不变。

所以现在我们利用cheat engine工具找到游戏的基址和偏移,获取到之后,再利用C语言中ReadProcessMemory()和WriteProcessMemory()进行修改地址所指向的值就可以了。

2.找到阳光值基址

首先打开植物大战僵尸游戏:
1.开局
然后打开cheat engine,将植物大战僵尸附加到该应用上:
2将游戏附加到cheat engine

接下来看一下游戏左上角的太阳值,将太阳值写入value中,然后单击First Scan:
3查找太阳值
此时在cheat engine中左侧的内容区出现包含和刚才输入值相同的数据行,然后回到游戏,等待新的小太阳的出现,当捡到小太阳后,太阳值将发生改变,现在回到cheat engine中,观察内容区Value列,看该列数据是否出现变化的行(出现变化的行也会自动标红显示,方便查找):
找到小太阳值
上图中变化的行已经标记出来,为了确定该行和游戏中的太阳值相关,多在游戏中捡几个小太阳,看看标记的Value列是否跟着游戏改变,确定该地址和太阳值有关后,双击左键,将该行标记在最下对话框中,然后单击右键,选择“Find out what writes to this address”:
在这里插入图片描述

此时弹出一个对话框,对话框中没有内容,此时回到游戏中进行使用或收集太阳的操作,现在,对话框中出现数据操作的信息。注意,当你捡太阳值是“add……”信息,当你使用太阳值是“mov……”信息,双击以观察详细信息:

现在,在弹出对话框中观察红字部分:mov [edi + 00005560] ,esi,该指令意思是将esi的值传递给[edi + 00005600]所指的地址中,其中00005560为偏移量,为十六进制数值。通过查看edi的值得知,edi为1476A5B0(或者直接查看The value……probaply 1476A5B0那一行提示),这样,我们获得了上级地址0x1476A5B0和偏移00005560。然后在The value……probaply 1476A5B0那一行提示右键复制上级地址值。
在这里插入图片描述
关闭两个对话框,点击New Scan重新扫描,将上级地址粘贴到value中,勾选Hex,点击First Scan:
在这里插入图片描述
此时左侧列表出现很多值,仔细观察一会儿,会发现有些行数据一直变红变黑,表明数据值在变化,点击“Next Scan”将这些变化的值过滤掉(因为我们查找的value值一直没变是0x1476A5B0)。

回到游戏,继续捡太阳或者使用太阳值,然后选择左侧对话框中从第一行开始选择,右键选择“Find out what accessses this address”,直到在弹出的对话框中有类似mov……的指令为止。
在这里插入图片描述

在这里插入图片描述

同前,此时得到偏移0000768,上级地址为0x0283A1F8,将左侧对话框中的该行标记在最下对话框,关闭弹出的两个对话框,开始新一次Scan,复制0283A1F8到value中,勾选Hex,然后单击“First Scan”:
在这里插入图片描述

此时观察左侧对话框中有绿色的行,证明我们找到了一个绿色的静态地址(绿色显示的是基址),现在选择“Add Address Manually”,在弹出对话框中选择 “Pointer”:
在这里插入图片描述

在弹出的对话框中将基址输入的框中,然后单击两次“Add offset”(因为我们经过两次的寻址),依次填入偏移,一次偏移为0x0000768,一次为0x00005560(从最近一次的偏移开始填),填写完成后,查看Address中的数值是否为游戏中小太阳的值,如下图:
在这里插入图片描述
在这里插入图片描述

我们现在理清一次思路:

由基址0x006A9EC0里的值+0x768后是个地址,

该地址里的值+0x5560就是存储小太阳值的内存单元。

所以,现在我们找到了基址,然后在编写代码时将该基址加上0x768以及0x5560就是小太阳的内存单元。

3代码

#include <stdio.h>
#include <windows.h>

#define SUN_SHINE_BASE_ADDR 0x006A9EC0					//阳光基址
#define SUN_SHINE_OFFSET_FIRST 0x768					//一级偏移
#define SUN_SHINE_OFFSET_SECOND 0x5560					//二级偏移值

int main()
{
	int modifySunshine = 0;
	DWORD ErrorInfo = 0;
	DWORD Size = 0;
	DWORD SunShineNum=0;								    //最后值
	DWORD PID = 0;
	DWORD SunShineBaseAddress = SUN_SHINE_BASE_ADDR;		//阳光基址

	DWORD SunShineBaseAddressValue = 0;						//阳光基址值

	DWORD SunShineOffsetFirst = SUN_SHINE_OFFSET_FIRST;		//一级偏移

	DWORD SunShineOffsetFirstValue = 0; 					//一级偏移值

	DWORD SunShineOffsetSecond = SUN_SHINE_OFFSET_SECOND;	//二级偏移

	HANDLE Process = 0;

	HWND hWinmine = FindWindowW(NULL, L"植物大战僵尸中文版");	//找到窗口

	GetWindowThreadProcessId(hWinmine, &PID);				//获取进程标识

	if (0 == PID)
	{
		printf_s("获取PID失败\n");
		return -1;
	}

	Process = OpenProcess(PROCESS_ALL_ACCESS, 0, PID);
	if (NULL  == Process )
	{
		printf_s("进程打开失败\n");
		ErrorInfo = GetLastError();
		return -1;
	}

	if (0 == ReadProcessMemory(Process, (LPVOID)SunShineBaseAddress, &SunShineBaseAddressValue, sizeof(DWORD), &Size))
	{
		printf_s("获取基址失败\n");
		ErrorInfo = GetLastError();
		return -1;
	}

	if (0 == ReadProcessMemory(Process, (LPVOID)(SunShineBaseAddressValue + SunShineOffsetFirst), &SunShineOffsetFirstValue, sizeof(DWORD), &Size))
	{
		printf_s("获取一级偏移失败\n");
		ErrorInfo = GetLastError();
		return -1;
	}

	if (0 == ReadProcessMemory(Process, (LPVOID)(SunShineOffsetFirstValue + SunShineOffsetSecond), &SunShineNum, sizeof(DWORD), &Size))
	{
		printf_s("获取二级偏移失败\n");
		ErrorInfo = GetLastError();
		return -1;
	}

	printf_s("SunShineNum:%d\n", SunShineNum);
	printf_s("输入你要修改的值:");
	scanf_s("%d", &modifySunshine);

	WriteProcessMemory(Process, (LPVOID)(SunShineOffsetFirstValue + SunShineOffsetSecond), &modifySunshine, sizeof(DWORD), &Size);

	CloseHandle(Process);	//关闭句柄
	system("pause");
	return 0;
}

4运行结果

运行结果如下图,成功修改了小太阳的值:
在这里插入图片描述
因为获取的是静态基址,所以就算游戏关闭了,再开,也可以运行该代码进行修改。

另外,夜晚小太阳是25,白天小太阳是50,不要混淆以为都是50,这样防止在找小太阳值基址的过程中以为自己找错了。

以上。

参考文档:
https://blog.csdn.net/qq78442761/article/details/54670630
https://blog.csdn.net/xiaokangdream/article/details/79366176
https://www.cnblogs.com/gd-luojialin/p/7789569.html
https://blog.csdn.net/ChristmasYe/article/details/8757547
https://blog.csdn.net/xiaokangdream/article/details/79356831
https://blog.csdn.net/wangqingchuan92/article/details/82417454

猜你喜欢

转载自blog.csdn.net/wangqingchuan92/article/details/83036960