Heroes III. The Restoration of Campaign

    О третьих героях, понятное дело, все знают. Недели времени, потерянного за hotseat-ом, вызубренные характеристики юнитов, тактика застройки, развития. Еженедельные посиделки с друзьями за героями c кофе и рогаликами. Здорово, в общем было. А вот на днях захотелось повторить и сыграть по сети. Уже ж разъехались все, hotseat не прокатит. Скачали дистрибутив клинка Армагеддона, настроили hamachi, да не заладилось что-то. Пинг большой почему-то, не завелось ничего. Ну, занятые все, разбираться некогда, да и неохота. Не пошла игра.

    А герои то установлены, желание играть есть. Решил кампанию пройти (к своему стыду, так ни разу не хватило терпения пройти ее в прошлом). Запустил, выбрал кампанию возрождения Эратии, нажал на эпизод «Жертвы войны». И я не знаю, интуиция, наверное, появляется какая-то за то время, пока программированием занимаешься. В общем, показали мне герои такую картинку:

    И, как часто у меня случается, игра закончилась, а началась более интересное и захватывающее занятие.

    Запускаю в отладчике, выбираю тот самый, проблемный пункт. На этом участке кода происходит исключение при доступе к памяти на строчке mov bl, [eax+ecx+1F879h].

    .text:004567A3                 mov     ecx, dword_68C818
    .text:004567A9                 test    ecx, ecx
    .text:004567AB                 jl      short loc_4567F2
    .text:004567AD                 mov     dl, [eax+edi+1F879h]
    .text:004567B4                 mov     bl, [eax+ecx+1F879h]


    Смотрю на значения регистров: EDI равен нолю, EAX указывает на правильный участок памяти, ECX просто огромный и указывает в никуда. Скорее всего, проблема в нем. Теперь нужно найти откуда в него заносится значение. Поднимаюсь чуть выше по коду, нахожу строку mov ecx, dword_68C818. Ага, значит регистр ECX заполняется из глобальной переменной. Открываю окно перекрестных ссылок, чтобы посмотреть, где в эту переменную пишут значение.


    Что интересно, значение в нее пишут в этой же функции. Вообще странное дело. Переменная глобальная, а используется только в одной функции. По-всему выходит, что она должна на стеке создаваться? Ну ладно, наверное я чего-то не понимаю. Смотрю кто же в нее пишет. А выглядит это примерно так:
    .text:00456736    mov     eax, [eax+1F468h] ; это аргумент
    .text:0045673F    push    eax
    .text:00456743    mov     ecx, [ecx+0A4h] ; здесь объект с "плохим" значением
    .text:00456749    mov     edx, [ecx] ; а это его таблица указателей на виртуальные функции
    .text:0045674B    call    dword ptr [edx+20h] ; здесь вызывают подпрограмму
    .text:00483A60    push    ebp 
    .text:00483A61    mov     ebp, esp
    .text:00483A63    mov     eax, [ecx+8]
    .text:00483A66    mov     ecx, [ebp+arg_0] ; этот аргумент равен -1
    .text:00483A69    mov     eax, [eax+ecx*8] ; здесь происходит что-то вроде result = arr[-1]. Очень подозрительное место
    .text:00483A6D    pop     ebp
    .text:00483A6E    retn    4
    .text:0045674E    mov     dword_68C818, eax ; здесь записуют в нашу глобальную переменную значение, которое подпрограмма вернула. Это та самая, "плохая", цифра, которая и обрушивает игру.


    Очень странно, что к массиву обращаются по отрицательному индексу. Можно предположить, что ошибка в аргументе. Текстовым поиском ищу обращение к переменной со смещением 1F468h


    Как видно, обращаются к ней ровно два раза. Первый раз в нее записывают константу при инициализации (видимо эта константа как раз мне и попадает). Второй случай придется изучить более детально. Перехожу по адресу, указанному в результатах поиска (функция большая поэтому скриншот приводить не буду), ставлю точку останова, выбираю сценарий. Ничего не происходит. Поднимаюсь выше, к началу функции. Функция вызывается довольно часто. По наличию множества ветвлений, можно предположить, что это обработка каких-то сообщений. Пробую нажать на все кнопки, которые имеются в окне сценария. Точка останова срабатывает во время выбора начального приза. Примерно вот так, как на картинке:

    Теперь можно сформулировать ошибку по-человечески. Существует виртуальная функция getStartupBonus, которая возвращает начальный бонус. В сценариях одного типа возвращается переменная, в сценариях другого — элемент массива, заданный каким-то внешним индексом. Подразумевается, что индекс не выходит за рамки массива. Но по каким-то причинам, перед загрузкой сценария, в индекс записывается неправильное значение. Происходит выход за пределы массива, приложение падает.
    Тут есть несколько вариантов решения. Можно, например изменить константу, которой инициализируется переменная на ноль. Но, правда, это может привести к совсем неожиданным последствиям. Мне кажется, что лучше всего будет дописать перед функцией, которая работает с массивом, несколько инструкций, которые будут проверять аргумент. И функция станет выглядеть так:
    .text:0048385A push ebp 
    .text:0048385B mov ebp, esp; ebp указывает на стек
    .text:0048385D mov eax, [ecx+8]; eax указывает на массив
    .text:00483860 mov ecx, [ebp+arg_0]; в аргументе содержится предполагаемый индекс массива
    .text:00483863 test ecx, ecx; проверяем, не является ли индекс отрицательным
    .text:00483865 jns short loc_483869; если не является, то переходим к cчитыванию элеменита массива
    .text:00483867 xor ecx, ecx; если индекс массива отрицательный, то приравниваем его к нолю
    .text:00483869 mov eax, [eax+ecx*8]; возвращаем элемент массива
    .text:0048386C pop ebp
    .text:0048386D retn 4

    Записываю изменения в исполняемый файл, перезапускаю игру, выбираю кампанию, работает.
    Share post

    Similar posts

    Comments 74

      +4
      Похвально!)
        +1
        Похвально — это мягко сказано! Я думал, что в наше время, когда уже даже контроллеры програмят на си, не осталось людей, которые способны так свободно разобраться в сгенерированном коде. Респект.
        +52
        Пользуясь случаем, хочу порекомендовать кастомный исполняемый файл для героев с оптимизацией под 2012 год (разрешение экрана, поддержка ОС).

        sites.google.com/site/heroes3hd/
          –9
          Этот коммент полезнее статьи!
            0
            С этим модом всё равно Герои вылетают через некоторое время.
              +2
              В последней версии это исправлено. Причина в несвежем mp3dec.asi.
              +2
              Без этой статьи не было бы и этого коммента. ТС респект.
              +2
              Тогда уж пользуясь случаем хочу посоветовать разработку российских модостроителей. Господа смогли нормально впилить десятый город в стиле «Классического аддона»

              forum.df2.ru/index.php?showtopic=27837
                +2
                Спасибо большое, здорово выглядит. Только ради этой ссылки стоило написать статью.
                  +3
                  Спасибо! Уже месяц как играю в купленную на GOG версию. Вылетает раз в час если я использую pulse для аудио, через alsa не вылетает (играю через wine). Вдруг кому полезно это знание…
                    0
                    «The Restoration of Erathia» есть под linux.

                    Только вот, модов похожих на heroes3hd не видел. Да и насчёт вылетов не понятно, пока лишь запустил и немного побегал по карте, и это всё на Fedora 17 x86_64, если интересно.
                    0
                    Прямо захотелось помочь этому проекту!
                    +2
                    Ай. Только успешно забыл про Героев, а тут пост о Героях. Нужно будет вечером установить.
                      +3
                      Отпуск оформили, родных предупредили, дочке/сыну напутствие во взрослую жизнь дали? а то ведь когда их всех увидите? )
                      • UFO just landed and posted this here
                      0
                      Ребята, как же вы все вовремя, я как раз на днях третьих Героев поставил.
                        +7
                        А я их и не удалял никогда ;-)
                          0
                          Живучий у вас комп.
                            0
                            Скорее, жесткий диск :-)
                        0
                        PS

                        Скачали дистрибутив клинка Армагеддона, настроили hamachi, да не заладилось что-то. Пинг большой почему-то, не завелось ничего.

                        Похожая ситуация. Ставил «Дыхание смерти», версию, которая нормально без бубнов установилась на новых ноутах.

                        А вот с сетевой игрой что-то не задалось. Первый раз юзаю хамачи, делал всё по данной инструкции.
                        IP-шники в игре на обоих ноутах сменились, но друг друга они видеть не хотят.
                          0
                          Пробовали напрямую по IP заходить в игру?
                            0
                            Ага. Не видит, зараза. Правда, я не закидывал DLL-ку в папку system32 еще, может, поможет.
                            Без нее работает у кого?
                          • UFO just landed and posted this here
                              0
                              Heroes of Might & Magic III
                              Heroes of Might & Magic III: Armageddon's Blade

                              Надо будет попробовать. Скажите, а вы сами пробовали?
                              • UFO just landed and posted this here
                                • UFO just landed and posted this here
                                0
                                Попробуйте Tunngle.
                                0
                                Ребята, я вас люблю! Вы напомнили о такой классной игре!
                                  +4
                                  Нет героев, кроме первых, и синие гидры охренительны.
                                    +5
                                    На вкус и цвет ) Я успел поиграть во всех Героев и во все части «Меч и магия».

                                    Мой выбор — третьи Герои и 6-8 части «Меч и магия».
                                      +1
                                      Всецело вас поддерживаю:)
                                        +1
                                        Меч и магия 8. До сих пор помню с каким упоением я собирал всех драконов в команду и смешивал микстуры
                                          +1
                                          А помните это:

                                          — тюрьма
                                          — яйцо
                                          — ?

                                          ))
                                            +2
                                            агааааа я вообещ был в шоке когда попросили что-то ввести O_o
                                              0
                                              Но как это было круто по сравнению с другими игрушками, а?

                                              Да блин, даже щас такой крутотенюшки в играх не встретишь.
                                                +1
                                                «Даже»?
                                                Скорее «ТЕПЕРЬ» не встретишь, раньше это было довольно популярно, теперь диалоги сводятся к выбору «хороший/плохой/дибил»…
                                                  0
                                                  Да я с сожалением. На самом деле, столько лет прошло, можно было использовать новые технологии игростроения вкупе со старыми идеями типа этой.

                                                  Ну и одно дело диалоги, которые, как вы верно заметили, сейчас слишком упрощены, а другое дело — именно самостоятельный ввод ответов. Не выбор хоть из 50 вариантов ответа, а вообще ввод с клавы своих вариантов.

                                                  Это очень круто. Очень впечатлило в первый раз при прохождении игры.
                                                    0
                                                    Может это и к лучшему, что убрали. Да, это добавляло атмосферности, но наши локализаторы иногда недетски жгли. В Wizardry 8, помнится, надо было вводить ответы на английском.
                                            0
                                            Нет, нет, ММ8 это какой-то тупой раш почти без сюжета. Вот 4-5, 6 и 7 — это да, это Вещи.
                                        –1
                                        HoMM 3.5 WOG
                                        0
                                        Это просто высший пилотаж! Всегда мечтаю применить свои знания, так скажем в быту. А то получается, что я сантехник, а кран дома ни разу не чинил. У вас получилось, поздравляю!
                                          +2
                                          Эрафия вместо Эратии. И раз уж все здесь такие фанаты героев почему бы не сыграть, но думаю у 95% выходные окажутся занятыми, а вечера уставшими от работы и до игры дело не дойдет.
                                            0
                                            overmind Как знать, расслабиться — поиграть после игры достаточно неплохая идея. :)
                                            0
                                            Ещё бы готовый инструмент для изменения экзешников от Героев :) Давно уже так и не пришлось снова поиграть в них из-за семёрки.
                                              +1
                                              А в чем проблема? У меня под семеркой HoMM-3 SoD отлично работает.
                                                +1
                                                У меня вылетало минут через 10 игры. Не знаю почему.
                                                  0
                                                  У вас русифицированная версия?
                                                    0
                                                    Да. Ставил лицензию «Возрождение Эрафии», результат тот же. Остальное не пробовал, кажется.
                                                      +1
                                                      В общем, с английской версией SoD все в порядке.
                                                      У подруги золотое издание (на русском) тоже работает.
                                                +1
                                                Странно, у меня под семеркой отлично играется. В полноэкранном режиме, в окне. А ollydbg — инструмент для изменения экзешников от всего :)
                                                0
                                                Кстати, а версия с GOG тоже страдает данным недугом?
                                                  0
                                                  Только английский HoMM, только хардкор!
                                                    0
                                                    м-м-м…
                                                    Золотое издание, лицензия, 7про64 — полёт нормальный как на ноуте с авто 4:3, так и на 24" — там растягивается на 16:9 и так же нормально играется.
                                                      +7
                                                      Как играют в Героев 3 на хабре) ни с чем не сравнится
                                                        +1
                                                        почти офтоп: а онлайн еще никто не сделал на уровне thesettlers?

                                                        P.S. А проходить вам еще видимо долго ))))
                                                          +1
                                                          Не сказал бы, что меня это огорчает )))
                                                          0
                                                          Так надо было ещё и драконов чёрных себе прописать!!!
                                                            +2
                                                            Это неспортивно
                                                            +3
                                                            миссия в IDA — предварительный сценарий для начала кампейна, ящитаю
                                                            • UFO just landed and posted this here
                                                                0
                                                                Очень странно, что до сих пор Ubisoft не выпустит ремейк третьих героев под современные ос и мобильные платформы. Думаю, что при умеренной стоимости спрос был бы неплохой!
                                                                  0
                                                                  А разви Убисофт имеет какое-то отношение к 3-им героям?
                                                                    0
                                                                    Ну изначальным издателем героев =<5 была вроде как 3DO, которая при развале в 2003-м распродала все свои бренды, в том числе и Ubisoft.
                                                                  • UFO just landed and posted this here
                                                                      0
                                                                      Всё-таки, для меня с друзьями 3 самые крутые, особенно с модом WOG.
                                                                      Кстати, разработчики WOG обращались к Ubisoft с просьбой предоставить им исходники 3х Героев, но получили отказ…
                                                                        +1
                                                                        По-моему шестые герои это римейк 5ых, которые в свою очередь с классическими героями имеют мало чего общего.
                                                                        • UFO just landed and posted this here
                                                                        +1
                                                                        этой игре не нужен ремейк
                                                                        0
                                                                        Да, мой способ не такой оригинальный, но покупаю игры на gog.com. Молодцы ребята. Оптимизируют старые игры под современные ОС. Проблем не было ни с одной.
                                                                          0
                                                                          10usd за Эрафию, Клинок и Дыхание. И еще 10 за Heroes Chronicles. Счастье :)
                                                                          –1
                                                                          Может ты мне пофиксишь вылеталкер? =) А то менять платформу ради игры сейчас не готов…

                                                                          Хотя там может слишком сложшно, всё ж таки GPU…
                                                                            +2
                                                                            Знать бы еще о чем ты говоришь =)
                                                                              0
                                                                              Да Сталкер у меня вылетает на одной локации и ничего не помогает. Я уже всё перепробовал, все советы какие нашёл.

                                                                              Но там, такое чувство, что вылетает рендер, а не логика игровая, хотя может и логика.

                                                                              Есть подозрение, что если я сменю платформу (AMD -> NVIDIA), то вопрос решится, но менять ради этого сейчас пока не с руки и не с ноги.
                                                                            0
                                                                            В Возрождении Ератии был ещё один неприятный баг. Как только в лесном замке вы развивались до продвинутых единорогов игра падала.

                                                                            Only users with full accounts can post comments. Log in, please.