读取进程C++的内存

Read Memory of Process C++

本文关键字:内存 C++ 取进程 读取      更新时间:2023-10-16

我正在尝试读取地址的值,但我似乎真的做不到。我正在尝试获取:客户端.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)

似乎什么都不起作用。我可以得到一些帮助吗?

必须首先获取客户端.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);

请注意,我使用的是与架构无关的 typedef uintptr_t:当用 x86 编译时,它将解析为 32 位变量,在 x64 中解析为 64 位值,因此您需要在游戏使用的任何架构中编译您的项目。现在开始执行此操作很有帮助,这样您将来迁移到 x64 游戏时就不必更改所有代码。

另请注意,我不使用 VirtualProtectEx() 来获取读/写权限,因为数据部分通常不需要它,但如果您弄乱了代码部分,则需要使用它。

DWORD Address = 0xA9C0DC;
long long Address = 0xA9C0DC;

我只是把它改成很长的长。如果这个剂量不起作用,那么地址就存在一些问题。

也可能是你使用了错误的位(我对位了解不多,32、64、84(,因为我认为你可能使用了错误的位