前面两节课,我们对植物免冷却的过程进行了详细的分析,这节课,我们就编写程序来实现免冷却。
我们基于之前修改阳光的代码进行修改,给它增加免冷却的功能(有人问我为什么不用VC和MFC来写界面程序,我觉得没必要,用控制台写代码少,更能突出我们的主体代码)。首先,我们定义一个用来实现免冷却功能的函数:DisableCoolDown。我们采用第一种办法,即修改跳转条件来实现免冷却,第二种办法你们可以自己去实现。我们怎么用代码去修改它的跳转指令呢?修改它这个地址上的机器码就可以了。原来,指令是jle时,它对应的机器码是:7E 14,而我们所需要的跳转指令是ja,改成ja后它对应的机器码应该为:77 14。这样,我们只要往这个地址写入相应值就可以了。代码如下:
//免CD void DisableCoolDown() { int num = 0x1477; int ret = WriteProcessMemory(h_process, (LPVOID)0x00487296, &num, 2, NULL); if (ret) { cout << "免冷却成功!" << endl; } else { cout << "免冷却失败!" << endl; } }
我们看到,num这个变量的值是0x1477,为什么不是0x7714呢?这是因为,我们处理器是小端模式的。(如果不理解大端模式和小端模式的区别的话你也可以分两次写入,第一次写入77,第二次写入14(记得地址要加一))。我们将代码进行编译测试,成功免冷却!
程序的所有代码如下:
#include<iostream> #include<windows.h> using namespace std; HWND hwnd_Game; DWORD ProcessID; HANDLE h_process; int Base; int Offset[10]; void GetGameInfo() { hwnd_Game = FindWindow(NULL, L"植物大战僵尸中文版"); GetWindowThreadProcessId(hwnd_Game, &ProcessID); h_process = OpenProcess(PROCESS_ALL_ACCESS, false, ProcessID); Base = 0x006a9ec0; Offset[0] = 0x768; Offset[1] = 0x5560; } //通过基址加偏移得到动态地址 int GetDymThroughBase(int Base, int Offset[], int len) { int Dym_temp; ReadProcessMemory(h_process, (LPVOID)Base, &Dym_temp, 4, NULL); for (int i = 0; i < len; i++) { if (i == len - 1) Dym_temp += Offset[i]; else ReadProcessMemory(h_process, (LPVOID)(Dym_temp + Offset[i]), &Dym_temp, 4, NULL); } return Dym_temp; } //修改阳光 void ChangeSunshine(int num) { int DymnamicAddress = GetDymThroughBase(Base, Offset, 2); int ret = WriteProcessMemory(h_process, (LPVOID)DymnamicAddress, &num, 4, NULL); if (ret == 0) { cout << "修改失败!" << endl; } else { cout << "修改成功!" << endl; } } //免CD void DisableCoolDown() { int num = 0x1477; int ret = WriteProcessMemory(h_process, (LPVOID)0x00487296, &num, 2, NULL); if (ret) { cout << "免冷却成功!" << endl; } else { cout << "免冷却失败!" << endl; } } int main() { int n_sunshine_change; int n_choice; cout << "欢迎使用植物大战僵尸外挂,请选择你要实现的功能(0.修改阳光,1.植物免冷却)"; cin >> n_choice; GetGameInfo(); if (n_choice == 0) { cout << "请输入你要修改的阳光值:"; cin >> n_sunshine_change; ChangeSunshine(n_sunshine_change); } else if (n_choice == 1) { DisableCoolDown(); } return 0;