Какой заголовок нужно перефразировать?

Здравствуйте,

Какой заголовок нужно перефразировать?
Листинг одной игры

Пока на SE7ENе царят нескончаемые анонсы «сенсационных» обновлений редких утилит, о которых слышали лишь пара пользователей, я задался вопросом: «Почему бы не поделиться собственным решением?» Представляю вам мой свежий проект — универсальный загрузчик ROM-файлов SNES и продвинутый модуль поддержки процессора WD65816 для IDA Pro. Он создан для тех, кто пытался реверсить игры SNES и сталкивался с десятками препятствий.

В этой статье вы узнаете:

  • В чём слабые места штатного загрузчика и процессорного модуля SNES в IDA Pro
  • Почему анализ игр SNES в IDA Pro превращается в настоящую головоломку
  • Какие преимущества приносит мой плагин

Откуда взялось вдохновение

Я увлекся изучением внутреннего устройства старых игр как формой интеллектуальной медитации. Для Sega Mega Drive у меня давно работает плагин-отладчик ROM-файлов — smd_ida_tools2, и я участвовал в реверс-проектах для этой платформы. Super Nintendo у меня никогда не было, но после знакомства с игрой Clock Tower и впечатляющим портом Thunder Force 3 я решил расширить свои навыки и на SNES.

Почему реверс SNES в IDA Pro — это вызов

При первом знакомстве с неизученным форматом в IDA Pro вы получаете острые ощущения, а особенности архитектуры SNES лишь усугубляют ситуацию:

Сегментация памяти

SNES использует «банки» памяти с сегментными регистрами, задающими базовый адрес вида 0xNN0000. Некоторые инструкции учитывают этот регистр при расчёте адресации. После реверса DOS-игр в IDA Pro слово «селектор» заставляет меня нервничать.

Список сегментов для одной игры
Список сегментов для одной игры

Изменяющийся размер инструкций

В WD65816 длина некоторых инструкций зависит от флагов процессора (m и x). Например, при m=1 команда SBC #const занимает два байта, а при m=0 — три. Оригинальный модуль пытается отслеживать эти флаги, но делает это настолько неинтуитивно, что изменить их иногда можно лишь «методом научного тыка».

Режимы инструкций .A8, .A16, .I8, .I16
Режимы инструкций .A8, .A16, .I8, .I16 для последующих команд

Зеркалирование памяти

SNES поддерживает «зеркальные» диапазоны: одни и те же данные могут адресоваться по разным адресам. К примеру, WRAM по адресу $7F0000–$7F1FFF зеркалируется как $000000–$001FFF. IDA Pro не справляется с этим автоматически, поэтому ссылки могут дублироваться в разных сегментах.

Некорректный синтаксис

Штатный модуль WD65816 генерирует неверные дизассемблированные инструкции, неправильно рассчитывает переходы и начальные векторы прерываний. Всё это создаёт путаницу при анализе кода.

Непонятные инструкции на .80:80B6 и .80:80BA
Непонятные инструкции на .80:80B6 и .80:80BA

Штатный загрузчик ROM

Встроенный загрузчик создаёт десятки сегментов с собственными селекторами, по которым очень тяжело ориентироваться и связывать участки кода.

Множество селекторов
Бесконечные селекторы

Как я улучшил процесс

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

  1. Добавил явные метки типа «Uses Data Bank» и «Uses Direct Page» для мгновенного понимания области адресации. Постфиксы .B, .W, .L подсказывают размер операндов.

    Явные пометки области адресации
    Ясная визуализация адресуемого пространства
  2. Упростил правку ссылок: нажал O или Ctrl+O — и нужный вариант готов. Больше не нужно лезть в диалоги сегментных регистров.

    Было
    Было
    Стало
    Стало
  3. Можно отключать опкоды BRK, COP, WDM, которые редко встречаются в SNES-играх, чтобы избавиться от «шума» в дизассемблированном коде.

    Настройка опкодов
    Гибкая настройка опкодов
  4. Парсинг ROM основан на проверенном эмуляторе MESEN2, что гарантирует корректность обработки формата и опкодов.

  5. Сочетание клавиш Shift+X переключает режим инструкций, что помогает восстановить корректный дизассемблированный код при необходимости.

    Было
    Было
    Стало
    Стало
  6. Реализовал зеркалирование сегментов памяти — теперь ссылки ведут в один сегмент, несмотря на множественные отражения адресов.

    Просмотреть полный скриншот
    Полный скриншот работы с зеркалированием
    Полный снимок экрана (фрагмент)

Планы на будущее

  1. Присвоить понятные имена управляющим регистрам
  2. Интегрировать MESEN2 в качестве отладчика через gRPC
  3. Полностью разреверсить мои любимые проекты

Благодарю за внимание. Репозиторий проекта: https://github.com/lab313ru/snes_ida

 

Источник

Читайте также