我正在尝试读取地址的值,但我似乎无法做到。 我试图得到:client.dll + 0xA9C0DC + 0x00FC。 我只是想从游戏中读取玩家的健康状况。 这是我的代码:
#include <iostream> #include <Windows.h> #include <string> DWORD pid; DWORD Address = 0xA9C0DC; int cHealth; int main() { HWND hWnd = FindWindowA(0, ("Counter-Strike: Global Offensive")); GetWindowThreadProcessId(hWnd, &pid); HANDLE pHandle = OpenProcess(PROCESS_VM_READ, FALSE, pid); while(true) { ReadProcessMemory(pHandle, (LPVOID)(Address + 0x00FC), &cHealth, sizeof(cHealth), 0); std::cout << cHealth <<std::endl; Sleep(200); } return 0; }而不是(Address + 0x00FC)我试过DWORD Address = 0xA9C0DC + 0x00FC; 要么
DWORD Address1 = 0xA9C0DC; DWORD offset = 0x00FC; DWORD Address = Address1 + offset; //or DWORD Address = (DWORD)(Address1 + offset)似乎没有任何工作。 我可以得到一些帮助吗?
I am trying to read a value of an address but i can't really seem to do it. I'm trying to get : client.dll + 0xA9C0DC + 0x00FC . I'm just trying to read the health of the player from a game. This is my code :
#include <iostream> #include <Windows.h> #include <string> DWORD pid; DWORD Address = 0xA9C0DC; int cHealth; int main() { HWND hWnd = FindWindowA(0, ("Counter-Strike: Global Offensive")); GetWindowThreadProcessId(hWnd, &pid); HANDLE pHandle = OpenProcess(PROCESS_VM_READ, FALSE, pid); while(true) { ReadProcessMemory(pHandle, (LPVOID)(Address + 0x00FC), &cHealth, sizeof(cHealth), 0); std::cout << cHealth <<std::endl; Sleep(200); } return 0; }Instead of (Address + 0x00FC) i've tried DWORD Address = 0xA9C0DC + 0x00FC; or
DWORD Address1 = 0xA9C0DC; DWORD offset = 0x00FC; DWORD Address = Address1 + offset; //or DWORD Address = (DWORD)(Address1 + offset)Nothing seems to work. Can i get some help ?
最满意答案
您必须首先获取client.dll模块的基址。 为此,您可以使用ToolHelp32Snapshot()遍历模块列表,找到匹配的模块并读取modBaseAddr成员变量。
以下是一个示例代码:
uintptr_t GetModuleBaseAddress(DWORD dwProcID, char* szModuleName) { uintptr_t ModuleBaseAddress = 0; HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32, dwProcID); if (hSnapshot != INVALID_HANDLE_VALUE) { MODULEENTRY32 ModuleEntry32; ModuleEntry32.dwSize = sizeof(MODULEENTRY32); if (Module32First(hSnapshot, &ModuleEntry32)) { do { if (strcmp(ModuleEntry32.szModule, szModuleName) == 0) { ModuleBaseAddress = (uintptr_t)ModuleEntry32.modBaseAddr; break; } } while (Module32Next(hSnapshot, &ModuleEntry32)); } CloseHandle(hSnapshot); } return ModuleBaseAddress; }然后做:
//get base address uintptr_t clientdllbaseaddr = GetModuleBaseAddress(dwProcId, "client.dll"); //add relative offset to get to pointer uintptr_t playerPtr = clientdllbaseaddr + 0xA9C0DC; //dereference the pointer using RPM, this gives you the dynamic address of the player object uintptr_t playerObjectAddr; ReadProcessMemory(pHandle, (LPVOID)playerPtr, &playerObjectAddr, sizeof(playerObjectAddr), NULL; //add health offset uintptr_t healthAddress = playerObjectAddr + 0xFC; //Overwrite the value int newValue = 1337; WriteProcessMemory(pHandle, (LPVOID)healthAddress, &newvalue, sizeof(newValue), NULL;请注意我正在使用uintptr_t,这是一个架构不可知的typedef,它将在x86中编译时解析为32位变量,在x64中解析为64位值,因此您需要在游戏使用的任何体系结构中编译您的项目。 现在开始执行此操作很有帮助,因此您在将来转移到x64游戏时不必更改所有代码。
另外请注意,我不使用VirtualProtectEx()来读取/写入权限,因为它通常不需要数据部分,但是如果您混淆了代码部分,则需要使用它。
You must first get the base address of the client.dll module. To do this you can walk the module list using ToolHelp32Snapshot(), find the matching module and read the modBaseAddr member variable.
Here is a sample code to do so:
uintptr_t GetModuleBaseAddress(DWORD dwProcID, char* szModuleName) { uintptr_t ModuleBaseAddress = 0; HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32, dwProcID); if (hSnapshot != INVALID_HANDLE_VALUE) { MODULEENTRY32 ModuleEntry32; ModuleEntry32.dwSize = sizeof(MODULEENTRY32); if (Module32First(hSnapshot, &ModuleEntry32)) { do { if (strcmp(ModuleEntry32.szModule, szModuleName) == 0) { ModuleBaseAddress = (uintptr_t)ModuleEntry32.modBaseAddr; break; } } while (Module32Next(hSnapshot, &ModuleEntry32)); } CloseHandle(hSnapshot); } return ModuleBaseAddress; }Then do:
//get base address uintptr_t clientdllbaseaddr = GetModuleBaseAddress(dwProcId, "client.dll"); //add relative offset to get to pointer uintptr_t playerPtr = clientdllbaseaddr + 0xA9C0DC; //dereference the pointer using RPM, this gives you the dynamic address of the player object uintptr_t playerObjectAddr; ReadProcessMemory(pHandle, (LPVOID)playerPtr, &playerObjectAddr, sizeof(playerObjectAddr), NULL; //add health offset uintptr_t healthAddress = playerObjectAddr + 0xFC; //Overwrite the value int newValue = 1337; WriteProcessMemory(pHandle, (LPVOID)healthAddress, &newvalue, sizeof(newValue), NULL;Please note I'm using uintptr_t which is a architecture agnostic typedef, it will resolve to a 32 bit variable when compiled in x86 and a 64 bit value in x64, so you will want to compile your project in whatever architecture the game uses. It is helpful to start doing this now so you don't have to change all your code when you move to x64 games in the future.
Also note I do not use VirtualProtectEx() to take read/write permissions because it's typically not necessary for data sections, but if you mess with code sections you will need to use it.
更多推荐
发布评论