首先,我们打开游戏,输入扫描50,得到如下结果
种植一颗植物,然后输入 25 点击再次扫描,然后得到结果如下
修改这个结果的数值,游戏的结果同时改变,证明我们找到的结果正确
然后,我们在下方右击选项“是什么访问了这个地址”,然后双击第一个结果,弹出结果如下,这个时候我们几下 地址 0x2019B570和偏移地址5578
然后进行新的扫描,搜索地址0x2019B570,这个时候为我们选择和其他地址相差较大的地址,我们选择地址为003EBC20这个地址
然后同样是右击选项“是什么访问了这个地址”,然后我们双击第四个结果,mov eax,[ecx+00000868]
结果如下,
这个时候,我们记下地址0x003EB3B8和偏移地址868,然后再次搜索16位地址0x003EB3B8
得到结果如下,然后我们尝试007794F8是否是正确的基址
修改数值,发现游戏的数值同样一起修改了,证明我们找的基址没有错!
下面我们开始编程
注意!
这个游戏是在VC6++环境下编译运行的,如图所示
1 #include <stdio.h> 2 #include <Windows.h> 3 4 int main(){ 5 //植物大战僵尸的游戏的左上角的标题 6 LPCWSTR cs=L"Plants vs. Zombies 1.2.0.1073 RELEASE"; 7 //记录程序错误的变量 8 DWORD getLastError; 9 //获取游戏进程的句柄 10 HANDLE hProcess; 11 //进程ID 12 DWORD dwPID; 13 //阳光值和记录内存的变量 14 DWORD dwNum = 0, dwSize = 0; 15 16 //基址 17 DWORD SunShineBaseAddress; 18 //游戏基址的数值 19 DWORD SunShineBaseAddressValue; 20 //一级偏移 21 DWORD SunShineOffsetFirst; 22 //一级偏移值 23 DWORD SunShineOffsetFirstValue; 24 //二级偏移 25 DWORD SunShineOffsetSecond; 26 //记录游戏阳光的数值 27 DWORD SunShineNum; 28 //最后修改的阳光址 29 int modifySunshine; 30 31 //找到游戏的窗口 32 HWND hWinmine = FindWindowW(NULL, cs); 33 34 35 if(hWinmine==NULL){ 36 printf("no\n"); 37 } 38 else{ 39 printf("yes\n"); 40 } 41 dwPID = 0; 42 //获取进程标识 43 GetWindowThreadProcessId(hWinmine, &dwPID); 44 45 if (dwPID == 0){ 46 printf("获取PID失败\n"); 47 } 48 else{ 49 printf("%ld\n",dwPID); 50 } 51 //打开进程 52 hProcess = OpenProcess(PROCESS_ALL_ACCESS, 0, dwPID); 53 if (hProcess == NULL){ 54 printf("进程打开失败\n"); 55 getLastError = GetLastError(); 56 } 57 //这个是我们找到的基址 58 SunShineBaseAddress = 0x007794F8; 59 SunShineBaseAddressValue = 0; 60 if (0 == ReadProcessMemory(hProcess, (LPVOID)SunShineBaseAddress, &SunShineBaseAddressValue, sizeof(DWORD), &dwSize)) 61 { 62 printf("静态址获取失败\n"); 63 getLastError = GetLastError(); 64 //return -1; 65 } 66 67 //一级偏移 68 SunShineOffsetFirst = 0x868; 69 70 //一级偏移值 71 SunShineOffsetFirstValue = 0; 72 73 74 if (0 == ReadProcessMemory(hProcess, (LPVOID)(SunShineBaseAddressValue + SunShineOffsetFirst), &SunShineOffsetFirstValue, sizeof(DWORD), &dwSize)) 75 { 76 printf("一级偏移获取失败\n"); 77 getLastError = GetLastError(); 78 // return -1; 79 } 80 81 82 //二级偏移 83 SunShineOffsetSecond = 0x5578; 84 //最后值 85 SunShineNum=0; 86 if (0 == ReadProcessMemory(hProcess, (LPVOID)(SunShineOffsetFirstValue + SunShineOffsetSecond), &SunShineNum, sizeof(DWORD), &dwSize)) 87 { 88 printf("二级偏移获取失败\n"); 89 getLastError = GetLastError(); 90 // return -1; 91 } 92 93 94 printf("SunShineNum:%d\n", SunShineNum); 95 printf("输入你要修改后的值:"); 96 scanf("%d", &modifySunshine); 97 WriteProcessMemory(hProcess, (LPVOID)(SunShineOffsetFirstValue + SunShineOffsetSecond), &modifySunshine, sizeof(DWORD), &dwSize); 98 99 CloseHandle(hProcess); 100 101 system("pause"); 102 return 0; 103 }
最后,附上一张最后效果图
如果有哪里做得不好,欢迎大家多多评论!!!!!!!!!!!!!!