Как игровые тренеры изменяют адрес в памяти, это динамично?

Позволяет предполагают, что я - игра, и у меня есть глобальное int* это содержит мое здоровье. Игровое задание тренера состоит в том, чтобы изменить это значение ко что для достижения режима бога. Я искал учебные руководства на игровых тренерах, чтобы понять, как они работают, и общее представление состоит в том, чтобы использовать сканер памяти, чтобы попытаться найти адрес определенного значения. Затем измените этот адрес путем введения dll или что бы то ни было.

Но я сделал простую программу с глобальным int* и его адрес изменяется каждый раз, когда я запускаю приложение, таким образом, я не добираюсь, как игровые тренеры могут трудно кодировать эти адреса? Или мой пример неправильно?

Что я пропускаю?

12
задан AstroCB 30 August 2014 в 20:44
поделиться

4 ответа

Обычно это делается путем отслеживания цепочки указателей от статической переменной до адреса кучи, содержащего данную переменную. Например:

struct CharacterStats
{
    int health;
    // ...
}

class Character
{
public:
    CharacterStats* stats;

    // ...

    void hit(int damage)
    {
        stats->health -= damage;
        if (stats->health <= 0)
            die();
    }
}


class Game
{
public:
    Character* main_character;
    vector<Character*> enemies;
    // ...
}

Game* game;

void main()
{
    game = new Game();
    game->main_character = new Character();
    game->main_character->stats = new CharacterStats;

    // ...

}

В данном случае, если последовать совету mikek3332002 и установить точку останова внутри функции Character::hit() и отменить вычитание, это приведет к тому, что все персонажи, включая врагов, станут неуязвимыми. Решение состоит в том, чтобы найти адрес переменной "game" (которая должна находиться в сегменте данных или в стеке функции) и следовать по всем указателям, пока не будет найден адрес переменной здоровья.

Некоторые инструменты, например, Cheat Engine, имеют функциональные возможности для автоматизации этого процесса и пытаются найти цепочку указателей самостоятельно. Однако в более сложных случаях вам, вероятно, придется прибегнуть к обратному инжинирингу.

7
ответ дан 2 December 2019 в 22:04
поделиться

EDIT: неважно, похоже, это была просто удача, однако последние 3 цифры указателя, похоже, остаются неизменными. Возможно, это ASLR срабатывает и меняет адрес базового образа или что-то еще?

aaahhh моя ошибка, я использовал %d для printf, чтобы вывести адрес, а не %p. После использования %p адрес остался прежним

#include <stdio.h>

int *something = NULL;

int main()
{
    something = new int;
    *something = 5;

    fprintf(stdout, "Address of something: %p\nValue of something: %d\nPointer Address of something: %p", &something, *something, something);
    getchar();
    return 0;
}
1
ответ дан 2 December 2019 в 22:04
поделиться

Пример динамически выделяемой переменной

Значение, которое я хочу найти, - это количество жизней, чтобы мои жизни не уменьшились до 0 и игра не закончилась.

  1. Играйте в игру и ищите местоположение переменной lifes в данном экземпляре.
  2. Найдя ее, используйте дизассемблер/отладчик, чтобы проследить за изменениями в этом месте.
  3. Потеряйте жизнь.
  4. Отладчик должен был сообщить адрес, по которому произошло уменьшение.
  5. Замените эту инструкцию на no-ops

Получили этот паттерн из программы под названием tsearch


Несколько связанных сайтов, найденных при исследовании этой темы:

1
ответ дан 2 December 2019 в 22:04
поделиться

Такие вещи, как коды Gameshark, выяснялись путем дампа образа памяти приложения, затем выполнялось одно действие, а затем смотрели, что изменилось. Может измениться несколько вещей, но должны быть закономерности, которые нужно искать. Например, сброс памяти, выстрел, сброс памяти, снова выстрел, сброс памяти, перезагрузка. Затем поищите изменения и получите представление о том, где/как хранятся патроны. Со здоровьем все будет примерно так же, но будет меняться гораздо больше вещей (поскольку вы будете как минимум двигаться). Но проще всего будет делать это при минимизации "внешних эффектов", например, не пытайтесь делать дифф дамп памяти во время перестрелки, потому что много чего происходит, делайте дифф, стоя в лаве, или падая со здания, или что-то в этом роде.

1
ответ дан 2 December 2019 в 22:04
поделиться
Другие вопросы по тегам:

Похожие вопросы: