从“.exe”+偏移读取内存?

时间:2013-07-31 07:53:37

标签: c++ winapi pointers memory offset

我正在使用WinAPI的ReadProcessMemory()来阅读游戏中的一些“隐藏”信息。

我使用Cheat Engine找出静态指针,但我不知道如何从中读取。 Cheat Engine给了我一个指向这样的指针:"mygame.exe"+1C50

我是WinAPI的新用户,如何将"mygame.exe"+1C50转换为我可以使用ReadProcessMemory()阅读的地址?

编辑:我尝试简化问题,但我想我应该首先给出完整的代码。 所以我在这里使用静态地址和多级指针,但我仍然坚持获取基地址或w / e。

以下是完整代码和a picture of my cheat engine address

#include <iostream>
#include <windows.h>
#include <tlhelp32.h>

using namespace std;

HANDLE GetProcessHandle(const char *procName);

int main()
{
    const char *procName = "prism3d.exe";
    HANDLE hProc = GetProcessHandle(procName);
    if (hProc) {

     /* This works if I use the dynamic address (f.e. 0x02C2C4DC),
        but it changes every time I restart the game.
        I need to use the static address (prism3d.exe+A1C) to get
        the dynamic address for my "nuke".
      */
        float nuke;
        ReadProcessMemory(hProc, (void*)0x02C2C4DC, &nuke, 4, 0);
        cout << nuke;

    }
    CloseHandle(hProc);
    return 0;
}

HANDLE GetProcessHandle(const char *procName)
{
    HANDLE hProc = NULL;
    PROCESSENTRY32 pe32;
    pe32.dwSize = sizeof(PROCESSENTRY32);
    HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    if (Process32First(hSnapshot, &pe32)) {
        do {
            if (!strcmp(pe32.szExeFile, procName)) {
                hProc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pe32.th32ProcessID);
                break;
            }
        } while (Process32Next(hSnapshot, &pe32));
    }
    CloseHandle(hSnapshot);
    return hProc;
}

编辑2: 这是我尝试阅读核武器的价值的方法,但是它给了我随机数,每次重新开始游戏都有所不同(有时它是0,有时是324324324等等......):

if (hProc) [

    DWORD baseAddr = (DWORD)GetModuleHandle(procName) + 0xA1C50; // also tried this with GetModuleHandle(NULL)
    DWORD mainAddr;
    ReadProcessMemory(hProc, (void*)(baseAddr + 0x111C), &mainAddr, 4, 0);

    // Nuke
    float nuke;
    DWORD nukeAddr;
    ReadProcessMemory(hProc, (void*)(mainAddr + 0x48), &nukeAddr, 4, 0);
    ReadProcessMemory(hProc, (void*)nukeAddr, &nuke, 4, 0);
    cout << nuke;
}

1 个答案:

答案 0 :(得分:7)

基本偏移通常是内存中模块的开始,你可以用GetModuleHandle得到它(返回的地址是内存中PE的开始)。我通常会说,因为某些约定定义了相对于代码部分开头的基础,然后您需要从PE中读取。

您可以执行以下操作:

UINT_PTR addr = (UINT_PTR)GetModuleHandle("game.dll") + 0x1C50;
ReadProcessMemory(hProc,(void*)addr,pBuffer,nSize,&BytesRead);

以上只有在您所定位的进程的地址空间中运行时(通过dll注入),才能通过远程进程(如您的示例所示)执行此操作,您需要枚举处理模块以获取对您感兴趣的模块的有效句柄。

MSDN有一个here的例子,稍微重构一下,你可以创建一个检查名称的函数,如果它匹配则返回HMODULE,这会给你模块库地址。