Редактирование кода программы - Assembler

Узнай цену своей работы

Формулировка задачи:

Написал трейнер для игры, который делает бесконечные жизни и патроны путём перезаписывания в цикле соответствующих значений в памяти
int MAX_HEALTH = 100;
DWORD health_adr = 0x3A93A480; // адрес жизней, который нашёл через CheatEngine
WriteProcessMemory(hProc, (LPVOID) health_adr, &MAX_HEALTH , 4, NULL);
Всё отлично работает. Решил пойти дальше и узнал, что можно изменять сам код игры
Зачем изменять память, когда мы можем изменять сам код игры? Код, во время выполнения, тоже хранится в памяти, его тоже можно изменять, в т.ч. программно. Это гораздо удобнее - код не меняет адрес, мы можем заставить игру делать что угодно: например, значения не придётся "замораживать" таймерами. В общем, сами увидите, как это здорово 8)
Поставив брекпойнт на запись в адрес жизней (0x3A93A480) нашёл инструкцию, которая уменьшает количество жизней при получении урона

1012954E - 89 03 - mov [ebx],eax

originalcode:
mov [ebx],eax
mov ebx,eax
mov eax,[esp+14]
и вот когда заменяю первую строчку
mov [ebx],eax
на
mov [ebx],64
то при получении урона как и должно быть кол-во жизней принимает значение 100, но и количество патрон и гранат тоже принимает значение 100. Т.е. получается что одна инструкция

1012954E

отвечает за изменение и жизней, и патронов, и гранат. Для справки сейчас в трейнере по умолчанию заморозка отключена, по нажатию кнопки F6 переменная bool godMode принимает true, по нажатию F7 - bool unlimitedAmmo = true. И далее в бесконечном цикле while(1) выполняется перезапись:
// Rewrite data if FREEZE FLAG enabled
if(bGodMode)
{
    setPoints(MAX_HEALTH, MAX_ARMOUR);
}
if(bUnAmmo)
{
    updateAmmo();
}
Собственно вопрос можно ли как-нибудь сделать так, чтобы если захотел заморозить кол-во жизней, то кол-во патронов и гранат не будут замораживаться? Думаю может нужно проверять что приходит в

ebx

- жизни, патроны, гранаты и в зависимости от флагов bool godmode, bool unlimitedAmmo выполнять заморозку. Что-то например:
if (ebx == adr_ammo){
    if(unlimitedAmmo == true){
       nop
    }
    else {
       mov [ebx],eax
    }
}
else if (ebx == adr_health){
    if(godMode == true){
       nop
    }
    else {
       mov [ebx],eax
    }
}

Решение задачи: «Редактирование кода программы»

textual
Листинг программы
    while(true)
    {
 
        // Close Trainer IF GAME is NOT RUNNING
        if(!gameIsRun())
        {
            break;
        }
 
        // Continue IF GAME is not active
        if(!gameOnFocus())
        {
            Sleep(1000);
            continue;
        }
 
        // Continue IF PLAYER is DEAD
        iHealth = Game.getHealth();
        if(iHealth < 1 || iHealth > MAX_HEALTH)
        {
            Sleep(1000);
            Game.refresh();
            continue;
        }
 
        // Rewrite data if FREEZE FLAG enabled
        if(bGodMode)
        {
            Game.setPoints(MAX_HEALTH, MAX_ARMOUR);
        }
        if(bUnAmmo)
        {
            Game.updateAmmo();
        }
        Sleep(100);
    }

Объяснение кода листинга программы

  1. Происходит проверка, запущена ли игра. Если игра не запущена, то цикл прерывается.
  2. Происходит проверка, активна ли игра. Если игра не активна, то происходит задержка в 1 секунду и цикл продолжается.
  3. Происходит проверка, жив ли игрок. Если здоровье игрока меньше 1 или больше максимального значения здоровья, то происходит задержка в 1 секунду, обновляется здоровье игрока и цикл продолжается.
  4. Происходит проверка, включен ли режим бога. Если режим бога включен, то устанавливается максимальное здоровье и броня игрока.
  5. Происходит проверка, включен ли режим отсутствия боеприпасов. Если режим отсутствия боеприпасов включен, то обновляется количество боеприпасов игрока.
  6. Происходит задержка в 0,1 секунды и цикл продолжается.

Оцени полезность:

11   голосов , оценка 3.636 из 5