6

我正在使用 WinAPIReadProcessMemory()从游戏中读取一些“隐藏”信息。

我使用作弊引擎找出静态指针,但我不知道如何读取它们。作弊引擎给了我一个指向这样的东西的指针:"mygame.exe"+1C50

我真的是 WinAPI 的新手,如何转换"mygame.exe"+1C50为可以读取的地址ReadProcessMemory()

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

这是我的作弊引擎地址的完整代码和图片:

#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: 这是我尝试读取我的 nuke 值的方法,但它给了我随机数,每次我重新启动游戏时都不同(有时是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;
}
4

1 回答 1

8

基本偏移量一般是模块在内存中的开始,你可以用这个来获取GetModuleHandle(这个返回的地址是内存中PE的开始)。我之所以这么说,是因为某些约定定义了相对于代码部分开头的基础,然后您需要从 PE 中读取该基础。

您可以执行以下操作:

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

仅当您在目标进程的地址空间中运行(通过 dll 注入)时,上述内容才有效,要通过远程进程执行此操作(如您的示例所示),您需要枚举进程模块以获得有效句柄您感兴趣的模块。

MSDN这里有一个例子,稍微重构一下,你可以创建一个函数来检查名称并返回HMODULE它是否匹配,转换它会给你模块基地址。

于 2013-07-31T08:52:21.190 回答