我正在尝试读取地址的值,但我似乎无法做到这一点。我试图获取: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)
似乎没什么用。我可以得到一些帮助吗?
答案 0 :(得分:1)
您必须先获取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()来获取读/写权限,因为它通常不需要数据部分,但是如果你搞乱代码部分,则需要使用它。
答案 1 :(得分:0)
DWORD Address = 0xA9C0DC;
long long Address = 0xA9C0DC;
我只是将其更改为很长一段时间。 如果此方法不起作用,则地址有问题。
也可能是您使用了错误的位(我不太了解bit,32、64、84),因为我认为您使用的是错误的位