12.使用mfc实现游戏辅助的界面 在它的代码上进行修改
12.使用mfc实现游戏辅助的界面它的代码是频繁读写游戏的内存,这样不是很好,下面的代码是在它的基础上进行了封装,控制无敌的逻辑在我们申请的内存中实现(也就是在一个全局中实现)
实现无敌的代码:26F0019位置就是用来控制是否无敌的
修改后游戏中跳转的位置
修改后的代码:data进行了修改,在GaameCracker.h文件中新加int类型叫wuDiAdr变量(用来存放26F0019位置cmp后面的哪个地址)
int GaameCracker::OpenGame(DWORD pid)
{
hProcecss = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
if (hProcecss) {
LPVOID 在其它进程开辟的空间 = VirtualAllocEx(hProcecss, NULL, 0x1000, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
if (在其它进程开辟的空间) {
char data[]{ 0x81,0xFE, // cmp esi
0x00,0x00,0x00,0x00, // 角色的this
0x75, 0x02, // jne 跳两个字节
0x31,0xFF, // xor edi, edi
0x8B,0xD0, // mov eax, eax
0x29,0xFA, // sub edx, edi
0x39,0xCA,// cmp edx, ecx
0xE9,// jmp
0x00,0x00,0x00,0x00, // 返回地址
0x00,0x00,0x00,0x00, // 存储用来判断是否无敌的值
0x83,0x3D, // cmp
0x00,0x00,0x00,0x00, // 存储用来判断是否无敌值的内存地址
0x00,
0x75,0xDE,
0xEB,0xE6
};
int jmpReturnDiZhi = 0x41FD67 - ((int)在其它进程开辟的空间 + 0x10) - 0x5;
// 用来存放不确定的内存地址的值比如,角色的this值,返回地址
int* nCode = (int*)(data + 0x11);
nCode[0] = jmpReturnDiZhi;
nCode = (int*)(data + 0x2);
nCode[0] = 0x4CEF08;
wuDiAdr = (int)在其它进程开辟的空间 + 0x15;
nCode = (int*)(data + 0x1B);
// 存储用来判断是否无敌值的内存地址 赋值
nCode[0] = wuDiAdr;
// 把实现无敌的代码写入内存
WriteProcessMemory(hProcecss, 在其它进程开辟的空间, data, sizeof(data), NULL);
// 实现外挂逻辑代码中的返回我们修改了的游戏地址
jmpReturnDiZhi = ((int)在其它进程开辟的空间+0x19) - 0x41FD61 - 0x5;
nCode = (int*)(E9Code + 0x1);
nCode[0] = jmpReturnDiZhi;
// 跳转到实现无敌代码
DWORD dPro = 0;
VirtualProtectEx(hProcecss, (LPVOID)0x41FD61, 0x6, PAGE_EXECUTE_READWRITE, &dPro);
// ReadProcessMemory(hProcecss, (LPVOID)0x41FD61, oldE9, 0x6, NULL);
WriteProcessMemory(hProcecss, (LPVOID)0x41FD61, E9Code, sizeof(E9Code), NULL);
// 实现秒杀
VirtualProtectEx(hProcecss, (LPVOID)0x41FD86, 4, PAGE_EXECUTE_READWRITE, &dPro);
// WriteProcessMemory(hProcecss, (LPVOID)0x41FD86, miaoSha, 0x4, NULL);
ReadProcessMemory(hProcecss, (LPVOID)0x41FD86, lodMiaoSha, 0x4, NULL);
return OPEN_OK;
}
else {
return ALLOC_MEMOPRY; // 分配内存失败
}
}
return OPEN_PROCESS_FAILE; // 打开进程失败
}
无敌复选框的代码改为:
mCracker.setWuDi(B_WuDi);