读取进程C ++的内存 [英] Read Memory of Process C++

查看:176
本文介绍了读取进程C ++的内存的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试读取地址的值,但是我似乎并没有真正做到这一点.我正在尝试获取:client.dll + 0xA9C0DC + 0x00FC.我只是想从游戏中读取玩家的健康状况. 这是我的代码:

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;
}

我尝试了DWORD Address = 0xA9C0DC + 0x00FC;而不是(Address + 0x00FC)

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成员变量.

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;
}

然后做:

//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游戏时就不必更改所有代码.

Please note I'm using uintptr_t which is an 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.

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

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.

这篇关于读取进程C ++的内存的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆