6

ReadProcessMemory()ゲームから「隠された」情報を読み取るためにWinAPI を使用しています。

Cheat Engine を使用して静的ポインターを見つけましたが、それらから読み取る方法がわかりません。Cheat Engine は、次のようなポインタを提供してくれます。"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: 核の値を読み取ろうとした方法は次のとおりですが、ゲームを再起動するたびに異なる乱数が得られます(場合によっては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 に答える