Вопрос

Я прочитал некоторые данные из процесса (адрес:0x58F03C) с помощью функции WINAPI. ReadProcessMemory:

DWORD proc_id;
GetWindowThreadProcessId(hwnd, &proc_id);
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, proc_id);
int value=0;

while (1)
{
    ReadProcessMemory(hProcess, (LPVOID)0x58F03C, &value, sizeof(value), 0);
    cout << "val: " << value << endl;
}

Поскольку адрес меняется каждый раз, когда я перезапускаю процесс, мне интересно, есть ли способ всегда получать один и тот же адрес?Он должен быть, потому что я вижу много «программ-тренеров», которые способны на это.Как они получают правильное значение адреса для чтения/записи?

В настоящее время я получаю его путем сканирования значения с помощью CheatEngine и выполните следующее сканирование для определения измененного значения.

Спасибо.

Это было полезно?

Решение

Вы столкнулись с динамическим распределением памяти.В мире CheatEngine они называются «указатели».

Рассмотрим некоторые данные (например, uint32_t/DWORD) внутри памяти, которая была malloc'д.Если вы найдете адрес данных, нет никакой гарантии, что при следующем запуске процесса адрес будет тот же.Это связано с тем, что память, возвращаемая malloc может быть основано в другой точке памяти.

Хитрость, используемая для обхода динамического распределения памяти, заключается в том, чтобы найти адрес статической кучи, который может привести вас к адресу интересующего вас значения.Учебник CheatEngine покажет вам, как это делается.То же самое относится и к многоуровневым указателям.На более высоком уровне это соответствует динамически выделяемой памяти, которая содержит указатель на некоторую другую динамически выделяемую память и так далее.

Метод, используемый в CheatEngine для получения указателей, работает примерно так:

  • Установите аппаратную точку останова доступа по адресу интересующего вас значения данных.
  • Когда код обращается к нему, аппаратная точка останова покажет вам, как выглядит код.

Обычно код будет выглядеть примерно так:

mov eax, 0x1234ABCD 
dec dword ptr ds:[eax+0x85]

Это может соответствовать некоторому коду, который уменьшает ваше здоровье при ударе врагом.В данном случае 0x1234ABCD — это указатель, а 0x85 — смещение.В коде C это могло произойти:

struct some_struct* blah = malloc(...);
...
blah->HP--;

0x1234ABCD будет адресом blah.Значение HP находится где-то внутри блока, на который указывает blah.Смещение в блоке памяти равно 0x85.Тогда, если бы вы писали трейнер, вы бы прочитали DWORD (QWORD если 64-битный) по адресу 0x1234ABCD и добавьте к значению 0x85.Это даст вам адрес значения HP.

Другие советы

Это будет работать, если адрес находится в части исполняемости раздела данных, где проживает PrealLocated переменные (не подходит для кучи и стека) ...

Посмотрите на «Перечислять все модули для процесса» Пример на MSDN .

Это использует enumprocessmodules () Чтобы получить модульные ручки.Это являются базовыми адресами изображения.

Вы можете получить базовый адрес изображений для исполняемого и настроить свой адрес.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top