前言
本人在网络上看到一些视频,学习写作而成。代码仅供学习参考,切勿作为商业用途。虽然没人会用我这么low的代码
主要思路
这种简单的修改器也就是对于内存的读写就可以了,而且PVZ(植物大战僵尸)这个单机游戏没做反外挂,内存基址始终不变。经个人几个电脑实验,只要是同一版本的PVZ其基址都相同。
可能会用到的工具
Visual studio :可自行找度娘安装教程
Cheat Engine:也可自己找度娘安装,若是觉得网上不安全有病毒,可以下载本人找到的资源:百度网盘–Cheat Engine 7.0,提取码:m0iz
植物大战僵尸:可自行网络下载,或者本人找到的资源:百度网盘 --PVZ中文年度版,提取码:32yh
基址获取
1.用CE(Cheat Engine) 去自己寻找,过程也非常有趣,推荐教程(非本人所写,读者也可自行百度)。
2.本人所用版本的基址:
请认准窗口名称:Plants vs. Zombies 1.2.0.1073 RELEASE
以下均为16进制
基址: 007794f8
阳光:+868+5578 (两次偏移)
金钱: +950+50 (两次偏移)
3.如果不是本人版本的PVZ,那么可以自行百度。
以下为本人找的基址大全的一篇博客:植物大战僵尸 基址大全
真实性与正确性,本人未曾一一验证。
PS:读者在c++中使用时请将16进制下的地址转换为10进制,如本人程序所写
// plantwg.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
#include "pch.h"
#include
#include
#include
#include
//主菜单
void MainMenu()
{
printf("-----歪瓜选项------\n");
printf(" 1.修改阳光\n");
printf(" 2.修改金币\n");
printf(" 3.退出\n");
printf("---created by wjl---\n");
}
//修改阳光
void ModifySun()
{
//根据窗口名字获取窗口句柄
HWND hgame = ::FindWindow(NULL, "Plants vs. Zombies 1.2.0.1073 RELEASE");
//得到线程或者进程id
DWORD ProcessId;
::GetWindowThreadProcessId(hgame, &ProcessId);
//根据id得到进程句柄
HANDLE hProcess = ::OpenProcess(PROCESS_ALL_ACCESS, false, ProcessId);
//内存基址
LPVOID pBase = (LPVOID)7836920;//十六进制7794F8转换为10进制
int sun = 0;
LPVOID rbuffer = (LPVOID)&sun;
//传出参数
DWORD byred;
::ReadProcessMemory(hProcess, pBase, rbuffer, 4, &byred);
pBase = (LPVOID)(sun + 2152);//十六进制868转换为10进制
::ReadProcessMemory(hProcess, pBase, rbuffer, 4, &byred);
pBase = (LPVOID)(sun + 21880);//十六进制5578转换为10进制
::ReadProcessMemory(hProcess, pBase, rbuffer, 4, &byred);
printf("当前阳光值:%d \n", sun);
int wsun = 0;
printf("请输入阳光的修改值\n");
scanf("%d", &wsun);
LPVOID wbuf = (LPVOID)&wsun;
DWORD by;
::WriteProcessMemory(hProcess,(LPVOID)pBase,wbuf,4,&by);
printf("修改阳光成功!\n");
}
//修改金币
void ModifyMoney()
{
//根据窗口名字获取窗口句柄
HWND hgame = ::FindWindow(NULL, "Plants vs. Zombies 1.2.0.1073 RELEASE");
//得到线程或者进程id
DWORD ProcessId;
::GetWindowThreadProcessId(hgame, &ProcessId);
//根据id得到进程句柄
HANDLE hProcess = ::OpenProcess(PROCESS_ALL_ACCESS, false, ProcessId);
//内存基址
LPVOID pBase = (LPVOID)7836920;//十六进制7794F8转换为10进制
int money = 0;
LPVOID rbuffer = (LPVOID)&money;
//传出参数
DWORD byred;
::ReadProcessMemory(hProcess, pBase, rbuffer, 4, &byred);
pBase = (LPVOID)(money + 2384);//十六进制868转换为10进制
::ReadProcessMemory(hProcess, pBase, rbuffer, 4, &byred);
pBase = (LPVOID)(money + 80);//十六进制5578转换为10进制
::ReadProcessMemory(hProcess, pBase, rbuffer, 4, &byred);
printf("当前金币值:%d \n", money);
int wmoney = 0;
printf("请输入金币的修改值\n");
scanf("%d", &wmoney);
LPVOID wbuf = (LPVOID)&wmoney;
DWORD by;
::WriteProcessMemory(hProcess, (LPVOID)pBase, wbuf, 4, &by);
printf("修改金币成功!\n");
}
int main()
{
//根据窗口名字获取窗口句柄
HWND hgame = ::FindWindow(NULL, "Plants vs. Zombies 1.2.0.1073 RELEASE");
//得到窗口的具体信息
RECT r;
::GetWindowRect(hgame, &r);
//printf("窗口信息:\n 左上角坐标:%d %d 右下角坐标: %d %d\n", r.left, r.top, r.right, r.bottom);
//获得鼠标点击的位置
POINT P;
::GetCursorPos(&P);
//printf("鼠标位置:%d %d\n", P.x, P.y);
if (NULL == hgame)
{
printf("请先运行游戏,后重新开启歪瓜!\n");
Sleep(3000);
return 0;
}
int op;
while (1)
{
MainMenu();
scanf("%d",&op);
switch (op)
{
case 1:
{
ModifySun();
break;
}
case 2:
{
ModifyMoney();
break;
}
default: break;
}
if (op != 1 && op != 2)
{
printf("感谢使用!\n");
break;
}
}
return 0;
}
欢迎指正和评论!