标签:僵尸 存储位置 uri 有一个 lse mem download hud code
??这是植物大战僵尸系列的第一个练习,目的是实现任意阳光修改功能。
??该功能的原理其实很简单,大致步骤就是:
1. 开始任意一局游戏;
2. 找到该局游戏的阳光值在内存中的地址;
3. 根据该地址,找到游戏阳光的基地址;
4. 编写一个手动修改该值的小程序。
系统:Windows 7 SP1 x64 ultimate
游戏:植物大战僵尸
工具:CheatEngine v6.7、VisualStudio 2017
??启动游戏,打开任意一局游戏。
可以看到此时游戏中的阳光值为50。
??CE加载游戏,使用精确搜索,定位阳光在内存中的位置。因为一般情况下第一次的搜索结果会很多,所以多次改变阳光值,并多次搜索,最终确定位置。
??试着修改该地址的值,确定该地址是否正确,如果不正确会影响后面的分析。
可以看出来阳光的变化,可以确定这就是阳光在内存中存储的位置了。
??确定阳光在内存中位置就可以实现该局中阳光值任意修改,但是只限于该局中,因为这个位置是动态变化的,每一句有不一样。那我们总不能每一次都用CE搜索一次吧,那样就太麻烦了。我们希望可以使用程序来替我们完成计算阳光位置的功能,但是我们无法确定阳光每次的位置。这时就需要看游戏本身如何确定这个位置了。
??对于游戏本身而言,在每局游戏前,都会根据一个基地址来计算出本局游戏的阳光存储位置,然后游戏对这个地址进行一系列写入与读取的操作,代表了游戏中阳关的修改和显示。而这之中的基地址就是我们需要找到的。基地址是不变的,所以我们可以利用基地址计算出每一局游戏阳光的存储位置。
??利用刚才确定的阳光地址,定位哪些位置对这个地址进行了访问操作。
可以看到 esi 和 edx 两个位置偏移 00005560 的位置被访问,esi 和 edx 就是阳光位置的指针,所以我们需要找到哪些地址存储了 esi 和 edx 的值,即0x0F3C4FC8。
搜索后发现有很多结果,这时需要一个一个排除,但是这里根据经验,与其他地址差别最大的可能性最大,而这里有两个差别很大,所以一个一个排除。经过分析和测试,确定是0x026630A0。查看哪些地址访问。
可以看到有一个指针,寄存器+00000768,而该寄存器的值都为0x026630A0,可以知道 0x026630A0 就是我们要找的第二级指针。
??搜索哪些位置存储第二级指针,和上次的方法一样排除。确定位置 0x006A9EC0。查看哪些地址访问。
发现竟然是固定地址,那么可以确定这就是阳光的基地址了。
??关于如何排除问题,我的方法就是查看哪些地址访问该地址,然后去收阳光或者种植物,看访问列表有没有什么动静,然后看看每个访问指令中。我们搜索的地址的值是否是我们之前确定的值。有些不明白,我现在也说不清楚,自已多意会吧。
??在确定基地址后,可以测试下正不正确。添加一个基地址指针,
然后新开一局游戏,修改基地址指针的值,看是否成功。
??确定了阳光的基地址后,就可以开始编写阳光修改器了。程序大致分为几步:
1. 获取游戏进程ID(我电脑上的进程名为Plants.vs.Zombies.exe)
2. 获取游戏进程内存权限
3. 计算阳光位置
4. 将目标值写入阳光位置
??参照这三步,即可完成阳光修改器的编写。下面是一些核心代码:
获取游戏进程ID和游戏进程权限。
//拍摄系统进程快照,获取游戏进程
hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hProcessSnap == INVALID_HANDLE_VALUE)
{
MessageBox(0, L"系统快照拍摄失败!", L"错误", MB_OK);
return false;
}
bRet = Process32First(hProcessSnap, &pe32);
while (bRet)
{
if (!wcscmp(pe32.szExeFile, L"Plants.vs.Zombies.exe"))
{
targetid = pe32.th32ProcessID;
break;
}
bRet = Process32Next(hProcessSnap, &pe32);
}
CloseHandle(hProcessSnap);
if (targetid == 0)
{
MessageBox(0, L"没有找到游戏进程", L"失败", MB_OK);
return false;
}
//打开游戏进程
hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, targetid);
if (hProcess == INVALID_HANDLE_VALUE)
{
MessageBox(0, L"打开游戏进程失败", L"错误", MB_OK);
return false;
}
计算当前阳光位置,修改阳光值。
//计算阳光地址
//读取第一层地址
if (!ReadProcessMemory(hProcess, (LPCVOID)dwBaseAddr, (LPVOID)&dwTempAddr, sizeof(DWORD), 0))
{
MessageBox(L"读取第一层地址失败", L"失败", MB_OK);
return;
}
//读取阳光地址
if (!ReadProcessMemory(hProcess, (LPCVOID)(dwTempAddr + 0x768), (LPVOID)&dwTempAddr, sizeof(DWORD), 0))
{
MessageBox(L"读取阳光地址失败", L"失败", MB_OK);
return;
}
//读取阳光
dwYangguangAddr = dwTempAddr + 0x5560;
if (!ReadProcessMemory(hProcess, (LPCVOID)dwYangguangAddr, (LPVOID)&dwYangValue, sizeof(DWORD), 0))
{
MessageBox(L"读取阳光失败", L"失败", MB_OK);
return;
}
//修改阳光值
if (!WriteProcessMemory(hProcess, (LPVOID)dwYangguangAddr, (LPCVOID)&m_nYangguang, sizeof(int), 0))
{
MessageBox(L"阳光修改失败", L"失败", MB_OK);
return;
}
MessageBox(L"阳光修改成功", L"成功", MB_OK);
启动修改器,输入期望阳光值。
返回游戏查看。
??到此,我们已经实现了我们的目的,任意修改阳光并编写了我们自己的阳光修改器。
CheatEngine:https://www.cheatengine.org/
VisualStudio:https://www.visualstudio.com/zh-hans/downloads/
标签:僵尸 存储位置 uri 有一个 lse mem download hud code
原文地址:https://www.cnblogs.com/Roachs/p/9365240.html