读取进程C ++的内存

时间:2018-01-11 13:58:36

标签: c++ memory process

我正在尝试读取地址的值,但我似乎无法做到这一点。我试图获取: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)

似乎没什么用。我可以得到一些帮助吗?

2 个答案:

答案 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),因为我认为您使用的是错误的位