Чтение памяти из .exe + смещение?

Я использую 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;
}

person Skamah One    schedule 31.07.2013    source источник
comment
Вам нужно найти базовый адрес game.dll, а затем добавить 1C50.   -  person Mats Petersson    schedule 31.07.2013


Ответы (1)


Базовое смещение обычно является началом модуля в памяти, вы можете получить его с помощью GetModuleHandle (возвращаемый адрес — это начало PE в памяти). Я говорю вообще, потому что некоторые соглашения определяют базу относительно начала раздела кода, который вам затем нужно прочитать из PE.

вы можете сделать что-то вроде следующего:

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

Вышеприведенное работает только в том случае, если вы работаете в адресном пространстве процесса, на который вы нацеливаетесь (через внедрение dll), чтобы сделать это через удаленный процесс (как показывает ваш пример), вам нужно перечислить модули обработки, чтобы получить действительный дескриптор для интересующий вас модуль.

В MSDN есть пример этого здесь, немного рефакторинг, вы можете создать функцию, которая проверяет имя и возвращает HMODULE, если оно совпадает, приведя это, вы получите базовый адрес модуля.

person Necrolis    schedule 31.07.2013
comment
Не работает, это просто дает мне какие-то странные цифры, а не правильные адреса: / Я отредактировал вопрос, у меня уже есть статический указатель .exe - person Skamah One; 31.07.2013
comment
@SkamahOne Вы проверили, является ли адрес, который сообщает CE, относительным к файлу или относительному разделу кода? а что за странные цифры? - person Necrolis; 31.07.2013
comment
Нет, как мне это проверить...? У меня есть указатель со значением "mygame.exe" + 1C50, который указывает на другой адрес, я пытаюсь получить другой адрес. И просто огромные целые числа, 17512325403 и т.д. - person Skamah One; 31.07.2013
comment
@SkamahOne, это огромное целое число - это адрес, ReadProcessMemory будет выполнять только один уровень косвенности, поэтому вам нужно будет использовать его несколько раз, чтобы следовать указателям. - person Necrolis; 31.07.2013
comment
@SkamahOne: только что понял, что вы работаете не в адресном пространстве процесса, поэтому GetModuleHandle завершится ошибкой, см. мое обновление - person Necrolis; 31.07.2013
comment
Это действительно должен быть принятый ответ. Я также использую CE, и он дает адрес относительно модуля. Я всегда использую GetModuleHandle() + offset, как предлагает Necrolis, но я делаю это из внедренной DLL (также как предлагает Necrolis). Этот ответ правильный; Skamah One работает не в том же адресном пространстве, к которому обращается и Necrolis. - person benbotto; 03.05.2016