然后按照惯例选择只狼的进程,搜索2323这个数据,可以发现出现了很多。
我去杀了一个小怪,把金币加到了2360。
再次搜索发现还有5个地址存在,直接修改会发现不会改变,有一种猜测是它用了一种类似于病毒中多进程相互守护一样的方法,会让数据保持一致,所以我们可以直接全部选中同事修改,会发现第三个没有修改成功,因为这个值不是背包中金币数量,而是战斗界面的数量,你可以自己试试。
金币顺利添加了两万,其它数据在本地的都是如此,可以自己尝试,但这种方法效率总是不高,我们可以使用代码的形式来把这个修改过程自动化。
这里多说一句,代码的方式是把数据的地址编码到代码中,如果游戏的更新导致这个地址改变话,代码里面也要同步修改,所以需要频繁更新的游戏其实修改器很多会失效。
二. 外挂程序编写先来了解几个Windows的API。
HWND FindWindow(LPCTSTR IpClassName,LPCTSTR IpWindowName); 通过类名或窗口名查找,返回窗口句柄 DWORD GetWindowThreadProcessId(HWND hWnd,LPDWORD lpdwProcessId); 得到窗口句柄后通过GetWindowThreadProcessId这个函数来获得窗口所属进程ID和线程ID HANDLE OpenProcess(DWORD dwDesiredAccess,BOOL bInheritHandle,DWORD dwProcessId) 打开一个已存在的进程对象,并返回进程的句柄 bool WriteProcessMemory(HANDLE hProcess,LPVOID lpBaseAddress,LPVOID lpBuffer,DWORD nSize,LPDWORD lpNumberOfBytesWritten ); 能写入某一进程的内存区域。入口区必须可以访问,否则操作将失败附上代码:
#include <windows.h> #include <stdio.h> int main() { HWND h = ::FindWindow(NULL, "植物大战僵尸中文版"); // 寻找并打开进程 DWORD processid; GetWindowThreadProcessId(h, &processid); HANDLE hprocess = 0; hprocess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, processid); if (hprocess == 0) { // 对应处理 printf("打开进程失败!\n"); return 1; } else { printf("打开进程成功!\n"); DWORD hp = 3000; // 要修改的游戏数据最大值 LPCVOID addr = (LPVOID)0x21BF10C8; // 通过CE找到的游戏数据地址 DWORD res = WriteProcessMemory(hprocess, (LPVOID)addr, &hp, 4, 0); // 写入内存修改游戏数据 return 0; } }这样一个代码,可以让我们随时调用,把阳光修改为2000,这个程序没有做图形化界面,因为太简单了,所以当做入门Demo吧。
我们修改了通过地址直接游戏的数据,那么能不能说做一个游戏助手,读出游戏的某些数据来辅助玩家呢? CE工具虽然可以搜索读取,但是效率太差,接下来介绍一个新的API,来读取固定地址的数据。
HWND ReadProcessMemory(HANDLE hProcess, LPCVOID lpBaseAddress, LPVOID lpBuffer, DWORD nSize, LPDWORD lpNumberOfBytesRead); 根据进程句柄读入该进程的某个内存空间lpBaseAddress的nSize字节,并写入缓冲区lpBuffer,多次计算基址和偏移即可尝试读取 :
附上代码实现:
#include <stdio.h> #include <windows.h> int main() { HWND h = ::FindWindow(NULL, "植物大战僵尸中文版"); // 寻找并打开进程 DWORD processid; GetWindowThreadProcessId(h, &processid); HANDLE processh = 0; processh = OpenProcess(PROCESS_ALL_ACCESS,FALSE,processid); if (processh == 0) { // 对应处理 printf("打开进程失败!\n"); return 1; } else { printf("打开进程成功!\n"); int sun; // 用于存放阳光数据 LPCVOID mbase = (LPCVOID)0x1E0CF020; LPVOID mbuffer = (LPVOID)&sun; ::ReadProcessMemory(processh, mbase, mbuffer, 4, 0); printf("您有阳光:%d\n", sun); return 0; } 三. 挂机自动外挂上述都是一些修改数据的外挂,此外还有一种是自动操作类的修改器,比如自动玩连连看(雾),自动下棋(雾),自动拼图(笑)。