Шаблон ReadProcessMemory с разыменованием - PullRequest
0 голосов
/ 10 июля 2020

Итак, у меня есть функция шаблона, использующая ReadProcessMemory для чтения моей игры из внешней программы для отладки.

Это функция:

template<typename T>
T read(DWORD addy)
{
    T buffer;
    ReadProcessMemory(targetProcess, (LPVOID)addy, &buffer, sizeof(T), NULL);
    assert(buffer != NULL);
    return buffer;
}

Теперь я хотел бы прочитать многоуровневый указатель с несколькими разыменованиями, такими как этот:

*(*(game.exe+0x12345)+0x50)+0x70

И моя цель - сделать это с помощью моей функции шаблона:

float data = read<float>(((game.exe+0x12345)+0x50)+0x70);

Без разыменований и даже если возможно без скобок.

Я думал об использовании пакета параметров для моего шаблона, но не уверен, что он оптимален в моем случае.

например:

template<typename T>
T retVal(T val){
   return *val;
} 


template<typename T, typename ...LvlsType>
T read(DWORD addy, LvlsType... levels){
    T buffer;
    ReadProcessMemory(targetProcess, (LPVOID)addy, &buffer, sizeof(T), NULL);
    assert(buffer != NULL);
    return retVal(...levels);
}

Будет ли это правильно в данном случае?

Иначе не могли бы вы дать какие-нибудь советы?

Заранее спасибо .

1 Ответ

2 голосов
/ 10 июля 2020

DWORD addy должно быть DWORD_PTR addy или даже void* addy.

А assert() бесполезен. Вместо этого вам нужно проверить возвращаемое значение ReadProcessMemory().

В любом случае вы не можете избежать чтения нескольких значений. В игре есть несколько указателей, вам нужно читать их индивидуально и следить за адресами, как и в игре. Таким образом, ваша попытка использовать read<float>(((game.exe+0x12345)+0x50)+0x70); не будет работать.

Вам нужно сначала прочитать значение указателя, расположенное по адресу game.exe+0x12345. Затем вам нужно добавить 0x50 к этому значению и прочитать значение указателя, расположенное по этому адресу. Затем добавьте 0x70 к этому значению и прочтите float, расположенный по этому адресу.

Вы можете попробовать что-то еще примерно так:

template<typename T>
T read(DWORD_PTR addy)
{
    T buffer;
    if (!ReadProcessMemory(targetProcess, (LPVOID)addy, &buffer, sizeof(T), NULL))
        throw ...;
    return buffer;
}

template<typename T, typename... OffsetTypes>
T read(DWORD_PTR addy, DWORD offset, OffsetTypes... offsets)
{
    DWORD ptr = read<DWORD>(addy);
    return read<T>(ptr + offset, offsets...);
}

...

DWORD_PTR baseAddr = ...; // base address of game.exe process
float data = read<float>(baseAddr+0x12345, 0x50, 0x70);

Использование DWORD ptr в Вариант c версия read() предполагает, что game.exe является 32-битным EXE. Если это 64-битный EXE, замените DWORD ptr на DWORD64 ptr и убедитесь, что ваш код скомпилирован для 64-битной версии, так что DWORD_PTR addy будет DWORD64 и сможет достичь всех возможных 64-битных адресов.

Живая демонстрация

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...