Перейти к содержанию

Открываем карту Герои Меча и Магии II (убираем «Туман войны»)


Рекомендуемые сообщения

Конечно проще было бы записать видео, но во-первых – не умею, во-вторых у меня не такой тембр голоса как у Kenga, Codera и Bromvola (этим ребятам можно легко летсплеить прохождения игр), ну и в-третьих я косноязычен.
Хотя может быть всё это – дело наживное (дело опыта).
Прошу сильно не закидывать шапками – это моя первая попытка – написать полноценную статью. А описывать, то что делал, довольно трудным занятием оказалось.
 
Начинал взлом именно с этой игрушки, в то время пользовался Артмани, в этой теме выложена таблица для Артмани. Нашёл практически всё.
Совет для начинающих: 

1. Ломайте старые игрушки – они проще.


2. Ломайте игрушки, в которые играли и знаете нюансы игры, знание которых очень помогает при взломе.

Из ненайденного в то время был «Туман войны», хотя сейчас вспоминаю и не понимаю, почему я не смог найти (скорее всего связано с тем, что Разработчики сгладили (округлили) контуры видимой области карты. С одной стороны и хорошо, что не нашёл тогда, а то зная свой характер, я бы попытался вручную вбить все адреса карты в таблицу.
 
Ну что же… начнём:
 
1.     Поиск адресов:
Из того, что мне встречалось при подобных поисках (например «Карта-загадка» в тех же Героях) Нужно искать тип байт. Значения возможные
-1, 0, 1 и FF (255).
Для верности будем искать «Неизвестное».
Для ускорения поиска будем использовать, предусмотренный Разработчиками  «отладочный режим», с помощью него будем открывать всю карту сразу. Как запустить его:
Разработчики не порадовали нас разнообразием чит-кодов, однако и этого вполне достаточно:

• 8675309 - полностью открывает карту
• 32167 - дает текущему герою 5 черных драконов, если для них есть место
• 911 - немедленный выигрыш
• 1313 - немедленный проигрыш
Коды просто набираются с клавиатуры, причем они работают и в мультиплейере. Правда, начиная с версии 1.3 противники читера получают предупреждение. Также слово Cheater появится и в таблице High Scores рядом с именем игрока. Столь небольшое количество кодов объясняется тем, что в версии для Win 95/98 разработчиками был предусмотрен "отладочный режим" игры. Для его включения необходимо запустить игру через Start - Run, с ярлычка (или из командной строки DOS), и указать путь к исполняемому файлу игры с ключом /NWC т.е. (...\Heroes2w /NWC). После того, как вы начнете игру, перейдите в оконный режим, нажав F4. В заголовке окна увидите опциюDebug. Пользуйтесь, но только для отладки - при использовании этого режима слово Cheater также появится в таблице High Scores рядом с вашим именем. Особенно осторожно пользуйтесь чит-кодами при прохождении кампаний. В некоторых случаях вы можете получить запись "Читер" в конечном результате, хотя вроде-бы и карта закрыта, и загружались правильно и т.п. Будьте бдительны!

Запустим Героев, выберем пока самую маленькую карту и чтобы вражеских героев (героев-ботов) было хотя бы два.
Ищем «неизвестное». Открываем с помощью «отладочного режима» карту – отсев «изменилось». Загружаем снова эту же игру, но не сейв игры (отличительная особенность Героев, что при загрузке игры адреса не меняются, при загрузке сейва могут не поменяться, но могут и измениться) – отсев «изменилось».
На открытой карте пройдём героем, что-нить подберём – отсев «не изменилось».
 
Метод отсева: изменилось/изменилось/не изменилось
Значения в конце отсева в основном при загрузке равны 0, а при открытии карты – 1.
 
Нахождение адресов произошло довольно быстро – мы получили очень большое к-во адресов идущих друг за другом и отличающихся в основном на 1.  
 
Теперь давайте опять загрузим игру.
Возьмём любой из адресов и правой кнопкой «Посмотреть регион памяти». Посмотрим на то, что мы нашли.
 
Нашли мы довольно большую область памяти, в которой  значения в основном 0, где-то встречаются участки 80, если прокрутить увидим не-большую область с 1 и нечётными числами (типа 81), ещё выше (или ниже) – обнаружим 2 и 82, а если было два героя – то и 4 и 84.
 
Объясню: мы нашли карту игры, где 0 – невидимая область никем,
Если 80 – объект на карте (типа монстр, часовня, сундук, куст, замок, гора, ну и т.д.)
Если число нечётное – это видимая область нашим игроком,
Если 2 и 82 – область, видимая только 2 Ботом, 4 и 84 – 4 Ботом.
Ну а если допустим 3 и 83 – то, думаю уже догадались, что 2 Бот  находится, где то рядом с Вашим героем и в области пересечения обзоров цифры будут 3 и 83.
 
Прокрутим регион памяти в низ и сразу чётко видна последняя ячейка
Карты, т.е. это 0 после которого идёт много разных цифр, давайте проверим запишем туда  01 (прямо в регионе памяти) , перейдём в игру, спустимся в правый нижний край карты и действительно ячейка открылась.
 
Теперь давайте на всякий случай (чтобы не потерять результаты работы) сделаем некоторые шаги.  Добавим этот адрес в таблицу, вернём ему значение 0. поставим «Бряк на запись» и с помощью «отладочного режима» откроем карту, мы получим вот такую инструкцию: 


Перейдём в «Отладчик», выделим там эту инструкцию, и создадим скрипт, в котором не будем изменять оригинальные инструкции:


и сохраним скрипт в таблице.   Это временный скрипт и нужен он лишь для того, чтобы если что мы могли восстановить адреса. Пора уже сохранить на всякий случай и таблицу, а то как у нас часто делают соседи, вырубят в коридоре наш рубильник по ошибке и всё – работа потеряна.
 
2.     Поиск указателей:
Так как игрушка простая, решил воспользоваться «автоматическим поиском указателей». Поиск указателей занял меньше минуты (эх знал бы я раньше СЕ, а то я помню в Артмани, на поиск указателей я потратил двое суток). Перепишем наш адрес с указателем и назовём его допустим так: «Последняя ячейка  (для МАЛЕНЬКОЙ карты)». И опять сохраним таблицу. И того у нас есть первый адрес: [["Heroes2.exe"+001265DC]+ 50f].
3.     Нахождение 1 ячейки карты. Я думаю это будет
[["Heroes2.exe"+001265DC]+ 0]. Запишем адрес в таблицу, назовём
его  «Первая ячейка карты» и проверим:
поставим значение 1, перейдём в игру  и поднимемся в левый верхний угол карты – да ячейка открыта. Сохраним таблицу.
4.     Проверка указателей:
Выключим игру, снова включим, загрузим карту, поставим в оба адреса
1 и проверим в игре (открыты ли ячейки). Открыты – поинтеры рабочие.
5.     Расчёт размера карты и количества байт:
Ну размеры карты можно было бы узнать и в интернете, но зачем, если у нас уже есть цифры 50f-0+1=510 . Или в десятичной 1296, возьмём
квадратный корень – получим 36. Итого имеем Mалькую карту 36х36 и количество байт 1296.
6.     Размер Средней карты, количество байт и «Последняя ячейка  (для СРЕДНЕЙ карты».
Загрузим новую игру, выбрав Среднюю карту Первая ячейка совпадает (проверка описана ранее), а вот «Последняя ячейка  (для МАЛЕНЬКОЙ карты)» находится где-то посередине, спускаемся по региону памяти снова вниз и видим последнюю ячейку, добавляем адрес в таблицу, переписываем его с предыдущим поинтером (надеюсь смещение рассчитать сумеете) и называем его «Последняя ячейка  (для СРЕДНЕЙ карты)». Рассчитываем размер карты и кол-во байт аналогично 5. пункту, получаем 1440 /5184/72. Итого имеем Среднюю карту 72х72 и количество байт 5184.
7.     Аналогично для Большой карты: 108х108 и 11664 (2D90).
8.     Аналогично для Очень Большой карты: 144х144 и 20736 (5100).
9.     Получение инструкции для скрипта:
Загрузим снова Маленькую карту с несколькими Ботами (нужны будут для фильтра свой/чужой). Через известные уже нам адреса перейдём в регион памяти и поднимемся до значений с 1 и 81 выберем где-нибудь очень близко адрес со значением 0 и добавим его в таблицу (поинтеры ставить не нужно – это временный адрес). Поставим «Бряк на запись»
и в игре походим  нашим героем, чтобы сработал бряк, получим вот такую инструкцию:


выделим её и сделаем как и в предыдущем случае инъекцию без изменения оригинальных инструкций:


А теперь ВНИМАНИЕ, это информация не только для новичков, с таким я сталкиваюсь впервые. Опишу на этом этапе, хотя я обнаружил это не сразу:
Если активировать этот скрипт, который в игре вроде бы ничего не меняет, то игра вылетит.
Долго не мог понять в чём дело, хотя очень подозрительно выглядит вот этот прыжок, который попал в код вместе с нашей инструкцией : jmp Heroes2.exe+5B897
 
Как оказалось, если прокрутить в Отладчике чуть-чуть повыше нашей инструкции, то появятся стрелочки на этот прыжок из двух мест, т.е на этот прыжок ещё есть какие-то прыжки, а так как при активации кода этой инструкции jmp Heroes2.exe+5B897 уже не было в коде игры – игра вылетала.
 
Ну ничего страшного (жаль только затраченного  времени на поиск ошибки), захватим инструкцию над нашей и сделаем уже из неё инъекцию.


10.     Поиск нужных фильтров описывать не буду чаще всего я пользуюсь вторым способом из этого моего сообщения.
      11.     Итак первый скрипт: «Открываем маленькую карту», частично в нём  использован код Xipho из этой темы, ну и некоторые вещи нашёл читая про Ассемблер в интернете:


Более подробные комментарии будут в конечном скрипте.
Проверим скрипт – работает отлично.
Но это только для Маленькой карты.
12.Добавление в скрипт и других карт, конечно можно было бы просто
Добавить переменную, вывести её в таблицу и пусть пользователь вручную забивает нужное количество байт. Это тоже хороший вариант.
Но вспомню хорошую пословицу: «Нет худа, без добра»:
Когда я искал ошибку, из-за чего вылетала игра в предыдущем скрипте в кометах в Отладчике я заметил кое-что знакомое (Кстати о кометах – помню при просмотре какого-то видео урока Kenga, услышал, как он не лестно отозвался о них, мол не понимаю для чего они нужны. У меня о кометах сложилось абсолютно противоположное мнение, очень часто пользуюсь этой информацией (например для отладки своего кода)).
Так что это было за знакомое – в трёх инструкциях немного выше нашей значение равнялось (как раз размеру карты 36).
Так что добавив одну из этих инструкций (при проверке она работала только с одним адресом) в наш код мы получаем конечный скрипт.
     13.Добавление Аобскана, описывать не буду, почему в конце, чтобы в скрипте всегда находилось минимальное кол-во характеристик, которые нужно проверять при ошибках.
Итак скрипт: «Нам сверху видно всё»:


Скрипт проверен на всех размерах карт, в обычной игре и кампании по несколько раз.    

таблицу выложил здесь.
На видео показана работа скрипта "Нам сверху видно всё", который убирает "Туман войны".
Видео специально снято для Gamehacklab.ru
Gamehacklab.ru и YouTube - хорошего просмотра.

Heroes2.exe+5B857:mov [ecx+eax],dljmp Heroes2.exe+5B7D5    
[ENABLE]alloc(newMem, 2048)label(returnHere)newMem:mov [ecx+eax],dljmp Heroes2.exe+5B7D5jmp returnHereHeroes2.exe+5B857:jmp newMemdb 90 90 90returnHere:[DISABLE]Heroes2.exe+5B857:mov [ecx+eax],dljmp Heroes2.exe+5B7D5dealloc(newMem) 
Heroes2.exe+5B930:mov [edx+ecx],aljmp Heroes2.exe+5B897 
[ENABLE]alloc(newMem, 2048)label(returnHere)newMem:mov [edx+ecx],aljmp Heroes2.exe+5B897jmp returnHereHeroes2.exe+5B930:jmp newMemdb 90 90 90returnHere:[DISABLE]Heroes2.exe+5B930:mov [edx+ecx],aljmp Heroes2.exe+5B897dealloc(newMem) 
Heroes2.exe+5B92D:add edx,[ebp-10]mov [edx+ecx],al 
[ENABLE]alloc(newMem, 2048)label(returnHere)label(Cikl)label(Flag)registersymbol(Flag)newMem:add edx,[ebp-10]mov [edx+ecx],alcmp byte ptr [Flag],1jne returnHerecmp ebx,00000260jne returnHerecmp ebp,000cfa30jne returnHerepush esi // сохраняем регистрыpush ecx // перед использованиемmov ecx,510lea esi,[["Heroes2.exe"+001265DC]+0] // загружаем первую ячейку картыCikl:cmp byte ptr [esi],0jne @Fadd byte ptr [esi],1 // делаем видимой ячейку карты@@:test byte ptr [esi],1jne @Fadd byte ptr [esi],1 // делаем видимой ячейку карты@@:dec ecx // Уменьшаем счетчик циклаinc esi // увеличиваем адрес-источникcmp ecx,0 // Достигли ли конца цикла?je @F // Если да, выходим из циклаjmp Cikl // Если нет - прыгаем на метку Cikl, то есть, переходим к следующей итерации цикла@@: // Безымянная метка для указания местоположения выхода из циклаpop ecxpop esimov byte ptr [Flag],0jmp returnHereFlag:db 1Heroes2.exe+5B92D:jmp newMemnopreturnHere:[DISABLE]Heroes2.exe+5B92D:add edx,[ebp-10]mov [edx+ecx],alunregistersymbol(Flag)dealloc(newMem) 
[ENABLE]aobscan(Adres, 8bxxxxxxxxxx0fafxxxx8axxxx0axxxx8bxxxxxxxxxx0fafxxxx8bxxxxxxxxxx03xxxx88xxxxe9)aobscan(Adres1, 03xxxx88xxxxe9xxxxxxxxe9xxxxxxxxxx8b)alloc(newMem, 512)alloc(newMem1, 512)label(returnHere)label(returnHere1)label(Cikl)label(Small_Map)label(Average_Map)label(Big_Map)label(Very_Large_Map)label(K_voBt)registersymbol(K_voBt)label(Flag)registersymbol(Flag)registersymbol(Adres)registersymbol(Adres1)newMem:mov edx,[Heroes2.exe+F8B98]cmp edx,24 // Карта размером 36х36 Маленькаяje Small_Mapcmp edx,48 // Карта размером 72х72 Средняяje Average_Mapcmp edx,6c // Карта размером 108х108 Большаяje Big_Mapcmp edx,90 // Карта размером 144х144 Очень большаяje Very_Large_Mapjmp returnHereSmall_Map:mov dword ptr [K_voBt],510 // 1296 байтjmp returnHereAverage_Map:mov dword ptr [K_voBt],1440 // 5184 байтjmp returnHereBig_Map:mov dword ptr [K_voBt],2d90 // 11664 байтjmp returnHereVery_Large_Map:mov dword ptr [K_voBt],5100 // 20736 байтjmp returnHerenewMem1:add edx,[ebp-10]mov [edx+ecx],alcmp byte ptr [Flag],1 // условие - чтобы сработало только один раз.jne returnHere1cmp ebx,00000260 // условие - только работаем с адресами ячеек картыjne returnHere1cmp ebp,000cfa30 // условие свой/чужойjne returnHere1push esi // сохраняем регистрыpush ecx // перед использованиемmov ecx,[K_voBt] // загружаем какое количество (байт) ячеек на картеlea esi,[["Heroes2.exe"+001265DC]+0] // загружаем первую ячейку картыCikl:cmp byte ptr [esi],0 // условие только нулевые значения на картеjne @Fadd byte ptr [esi],1 // делаем видимой ячейку карты@@:test byte ptr [esi],1// условие только чётные значения на картеjne @Fadd byte ptr [esi],1 // делаем видимой ячейку карты@@:dec ecx // Уменьшаем счетчик циклаinc esi // увеличиваем адрес-источникcmp ecx,0 // Достигли ли конца цикла?je @F // Если да, выходим из циклаjmp Cikl // Если нет - прыгаем на метку Cikl, то есть, переходим к следующей итерации цикла@@: // Безымянная метка для указания местоположения выхода из циклаpop ecxpop esimov byte ptr [Flag],0jmp returnHere1K_voBt:dd 0Flag:db 1Adres:jmp newMemnopreturnHere:Adres1:jmp newMem1nopreturnHere1:[DISABLE]Adres:  // Heroes2.exe+5B90D:mov edx,[Heroes2.exe+F8B98]Adres1: // Heroes2.exe+5B92D:add edx,[ebp-10]mov [edx+ecx],alunregistersymbol(K_voBt)unregistersymbol(Flag)unregistersymbol(Adres)unregistersymbol(Adres1)dealloc(newMem)dealloc(newMem1) 
  • Плюс 5
Ссылка на комментарий
Поделиться на другие сайты

×
×
  • Создать...

Важная информация

Находясь на нашем сайте, Вы автоматически соглашаетесь соблюдать наши Условия использования.