Приветствую коммьюнити мододелов! Представляю вашему вниманию свою базу данных героев, содержащую скромное количество оригинальных сигнатур. Суть в том, чтобы восстановить остальные неизведанные сигнатуры игры, применяя знания STL C++, общие наблюдения о работе игры и, собственно, источник сигнатур - базу данных RoE Dreamcast.
К сожалению, IDA не имеет встроенного декомпилятора для SH-4(RISC-процессора Sega Dreamcast), поэтому приходится анализировать только ассемблерный листинг. Ghidra имеет декомпилятор SH-4, но он очень кривой.
Ссылки для скачивания:
SoD-База by Void_17:
https://drive.google.com/file/d/1MY28K8c...sp=sharing
RoE-Dreamcast-база:
https://drive.google.com/file/d/1rAWaKjz...sp=sharing
ТЕХНИЧЕСКИЕ ОСОБЕННОСТИ ОРИГИНАЛЬНОЙ ПК-ВЕРСИИ ГЕРОЕВ МЕЧА И МАГИИ 3:
Heroes Of Might and Magic III - пошаговая стратегия, написанная на языке C++ с применением Microsoft Visual Studio. Стандарт языка - новейший на тот момент C++98.
Игра написана с использованием классов и инструментов библиотеки STL.
Код игры можно разделить на две большие части:
Интерфейс и Игровая Логика.
Интерфейс - это все кнопки, картинки, звуки и все то, что делает из холодного машинного кода удобный для человека инструмент управления программой.
Игровая Логика - это правила игры и поведение ИИ - компьютерного игрока.
ИНТЕРФЕЙС
Интерфейс реализован в основном на классах с большим количеством наследования, а значит, виртуальных методов. Компилятор ввиду особенностей виртуальных функций генерирует массив указателей на переопределенные методы - Таблица Виртуальных Функций (VMT, vftable).
В интерфейс входят классы pcx-изображений, звуков, музыки и диалоговых окон, шрифтов и текстов, 16 и 24 битной графики, анимаций, заключенных в DEF-архивы.
ИГРОВАЯ ЛОГИКА
Игровая логика реализована на разных классах, зачастую без применения виртуальных методов. Этих классов больше и они описывают характеристики героя, массива армии, монстров, городов, менеджеров и т.д.
Как продолжить восстановление сигнатур и типов?
Я применяю примерно следующие тактики:
1. Захожу в область интересующего класса
2. Нахожу "пробелы" ввиде неизученных методов/функций
3. Смотрю где они применяются
4. Сравниваю функцию по внутреннему устройству с функцией в дримкаст базе по ассемблерному листингу. Зачастую, вызовы функций идут по порядку.
БУДЬТЕ ПРЕДЕЛЬНО ВНИМАТЕЛЬНЫ СО ВСТРОЕННЫМИ ФУНКЦИЯМИ!
5. Называю относительно базы Dreamcast. (Нажимаете на кнопку n и копируете функцию со всеми странными символами(это называется деманглер, позволяет в строке зашифровать сигнатуру функции
https://en.wikiversity.org/wiki/Visual_C...e_mangling )
Но это если очень поверхностно, мне честно говоря трудно описать абсолютно все в деталях, я уже как-то интутивно это все делаю.
Сложности:
>STL функции и контейнеры, их методы. Затрудняют изучение засчет загромождения встроенными(inline) функциями.
>Встроенные функции. Основная попаболь всех тех, кто изучает внутреннее устройство программ.
Совет: помечайте повторяющимся комментарием(кнопка ";") и цветом те функции, которые встроены в SoD, но не в RoE-Dreamcast. (я помечал некоторые голубым цветом и комментарием "inline function")
>Dreamcast база -- RoE. А моя база -- ПК-SoD. Но впринципе, это не особо страшно, так как новведения относительно легко заметить.
>Не все функции идут друг за другом так, как в Dreamcast-базе. Есть одна из тактик, при которой можно просто брать сигнатуры из Dreamcast-базы, но нужно быть предельно осторожным, т.к. это не всегда так и там, где, казалось бы, в Dreamcast-базе по порядку идут методы одного класса, в SoD прямо посреди этого "ряда" может быть кусок другого класса.
Остальное распишу потом. Отвечу на все вопросы и дам рекоммендации ИТТ. Надеюсь, что коммьюнити продолжит мое дело по приведению базы игры в порядок и систематизации всего, что известно об игре. Будем сотрудничать. Тред на другом форуме:
https://handbookhmm.ru/forum/viewtopic.php?f=56&t=968
Соглашения об именах:
1. Функции
Если вы не знаете, что метод точно принадлежит классу, но пока не до конца знаете, что это за сигнатура(или ее вообще нет в Dreamcast), следует переименовать функцию по следующему шаблону: имякласса_адрес
пример: combatManager_46A150
Если вы узнали, что эта сигнатура есть и функция с данной сигнатурой совпадает или почти полностью совпадает с функцией в Dreamcast-базе, скопируйте сигнатуру из Dreamcast-базы вместо имени этой функции. Если функция была добавлена в AB/SoD, отразите это перед именем метода.
Пример: combatManager::SOD_is_in_fear
2. Поля структур/классов:
Называть поля согласно CamelCase.
Пример: SoundFileName.
Неизвестные поля называть field_смещение или f_смещение
Неиспользуемые поля называть unused_смещение или u_смещение
3. Аргументы функций и локальные переменные:
Аргументы функций называть с заглавной буквы(искл.: this)
Локальные переменны со строчной. Желательно избегать snake_case.
4. Глобальные переменные
Приставка g — global, перед каждой глобальной переменной,
после нее p — pointer, если переменная является указателем или первая буква в названии типа, если НЕ указатель и НЕ целый класс/структура. Например глобальная int-переменная будет giVar