Редактирование кода программы - Assembler
Формулировка задачи:
Написал трейнер для игры, который делает бесконечные жизни и патроны путём перезаписывания в цикле соответствующих значений в памяти
Всё отлично работает. Решил пойти дальше и узнал, что можно изменять сам код игры
Поставив брекпойнт на запись в адрес жизней (0x3A93A480) нашёл инструкцию, которая уменьшает количество жизней при получении урона
и вот когда заменяю первую строчку
на
то при получении урона как и должно быть кол-во жизней принимает значение 100, но и количество патрон и гранат тоже принимает значение 100. Т.е. получается что одна инструкция
Собственно вопрос можно ли как-нибудь сделать так, чтобы если захотел заморозить кол-во жизней, то кол-во патронов и гранат не будут замораживаться?
Думаю может нужно проверять что приходит в
int MAX_HEALTH = 100; DWORD health_adr = 0x3A93A480; // адрес жизней, который нашёл через CheatEngine WriteProcessMemory(hProc, (LPVOID) health_adr, &MAX_HEALTH , 4, NULL);
Зачем изменять память, когда мы можем изменять сам код игры? Код, во время выполнения, тоже хранится в памяти, его тоже можно изменять, в т.ч. программно. Это гораздо удобнее - код не меняет адрес, мы можем заставить игру делать что угодно: например, значения не придётся "замораживать" таймерами. В общем, сами увидите, как это здорово 8)
1012954E - 89 03 - mov [ebx],eax
originalcode: mov [ebx],eax mov ebx,eax mov eax,[esp+14]
mov [ebx],eax
mov [ebx],64
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 секунду и цикл продолжается.
- Происходит проверка, жив ли игрок. Если здоровье игрока меньше 1 или больше максимального значения здоровья, то происходит задержка в 1 секунду, обновляется здоровье игрока и цикл продолжается.
- Происходит проверка, включен ли режим бога. Если режим бога включен, то устанавливается максимальное здоровье и броня игрока.
- Происходит проверка, включен ли режим отсутствия боеприпасов. Если режим отсутствия боеприпасов включен, то обновляется количество боеприпасов игрока.
- Происходит задержка в 0,1 секунды и цикл продолжается.