首先,我們打開游戲,輸入掃描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 }
最后,附上一張最后效果圖

如果有哪里做得不好,歡迎大家多多評論!!!!!!!!!!!!!!
