查基址这个东西就是找一个偏移嘛。
这次用的程序是1.0原版的植物大战僵尸。
找了个简单点的数据就是阳光,直接搜2次就能找到这个int变量。
然后查对于这个地址的内存访问。
找到的里面有个偏移,再对之前计算的那个进行查找,然后查看内存访问,最后结果如下:
阳光 = [[基地址+0x768] + 5560]
基地址0x6a9ec0
然后就是写代码修改阳光的问题了,主要就是先获取进程pid然后OpenProcess,然后对内存进行读写。
贴代码:
#include<stdio.h>
#include<Windows.h>
#include<TlHelp32.h>
#define NAME "mspaint.exx" //要修改的进程名
DWORD GetPid(char* szName){
HANDLE hprocessSnap = NULL;
PROCESSENTRY32 pe32 = {0};
hprocessSnap = CreateToolhelp32Snapshot(
TH32CS_SNAPPROCESS,
0);//捕捉所有进程的快照
if (hprocessSnap == INVALID_HANDLE_VALUE){
//快照失败
return 0;
}
//初始化pe32结构体
pe32.dwSize = sizeof(PROCESSENTRY32);
if (Process32First(hprocessSnap, &pe32)){
do{
if (!strcmp(szName, pe32.szExeFile)){
printf("Process Found, PID: %d
", (int)pe32.th32ProcessID);
return (int)pe32.th32ProcessID;
}
//遍历查找进程名
}while (Process32Next(hprocessSnap, &pe32));
}else{
CloseHandle(hprocessSnap);
}
return 0;
}
void main()
{
DWORD pid = GetPid("popcapgame1.exe"); // 获取进程pid
//获取进程句柄
HANDLE hProcess;
hProcess = OpenProcess(PROCESS_ALL_ACCESS,FALSE,pid);
printf("%x
", hProcess);
if (hProcess == NULL)
{
printf("fail to open process
");
CloseHandle(hProcess);
return;
}
//CloseHandle(hProcess);
// 获取模块地址
DWORD modaddr = NULL;
MODULEENTRY32 modentry;
HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, pid);
modentry.dwSize = sizeof(MODULEENTRY32); // 初始化一下
Module32First(hSnapshot, &modentry);
do{
if (!strcmp(modentry.szModule, "popcapgame1.exe")){
modaddr = (DWORD)(modentry.hModule);
printf("Module Found, addr: %x
", modaddr);
CloseHandle(hSnapshot);
break;
}
//遍历查找进程名
}while (Module32Next(hSnapshot, &modentry));
// 读阳光数据
/*
183fc4f8 + 5560
[[基地址+0x768] + 5560]
基地址0x6a9ec0
*/
DWORD pObj = modaddr; // 有的时候偏移要用,但是这次直接是固定基地址所以不用管
pObj = NULL;
printf("pobj: %x
", pObj);
int a = ReadProcessMemory(hProcess, (LPCVOID)(pObj+0x6a9ec0), &pObj, 4, 0);
printf("pobj: %x
", pObj);
ReadProcessMemory(hProcess, (LPCVOID)(pObj+0x768), &pObj, 4, 0);
printf("pobj: %x
", pObj);
DWORD pSun = pObj+0x5560;
int sun = 0;
int max_sun = 9999;
ReadProcessMemory(hProcess, (LPCVOID)(pSun), &sun, 4, 0);
printf("sun: %d
", sun);
while(1)
{
Sleep(1000);
ReadProcessMemory(hProcess, (LPCVOID)(pSun), &sun, 4, 0);
WriteProcessMemory(hProcess, (LPVOID)(pSun), &max_sun, 4, 0); // 阳光拉满
printf("sun: %d
", sun);
}
CloseHandle(hProcess);
return;
}
P.S.中间查模块的代码其实用不到,因为基址是写死的,不是相对于模块的偏移。