Spiiin's blog

Взлом NES игр без знания ассемблера

Ещё один рецепт взлома данных в играх на NES, на этот раз не требующий знания ассемблера.

Понадобится python для запуска скриптов и практически любой эмулятор, например, fceux.

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

Генерируется все возможные “испорченные” версии игры, в которых меняются небольшие участки данных.
https://gist.github.com/spiiin/7304994

Скрипт портит по 64 байта данных за раз, можно брать больше или меньше, в зависимости от потребностей.

Начало области коррапта данных - 0x10, сразу после заголовка ROM, оттуда начинаются банки с кодом игры. Конец области подбирается под конкретную игру, его можно посчитать, зная размер и маппер рома или посмотреть прямо из заголовке - он записан в 5-м байте. Умножаем кол-во банков на размер банка (16 килобайт) - получаем адрес конца области для коррапта.

Корраптить банки с видеопамятью не надо, что в них лежит, и так имеет строго определённый формат. На выходе получается несколько тысяч ромов, которые нужно проверить.

Скрипт проверки ромов.
https://gist.github.com/spiiin/7305188

Использует библиотеки pywin32 и Pil

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

Нужно максимально замедлить эмулятор и сохраниться в момент затемнения экрана.

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

Далее скрипт ненадолго засыпает, чтобы дать возможность отработать эмулятору, а потом снимает скриншот с загруженного уровня, убивает процесс эмулятора и запускает следующую версию игры. Совет для fceux - в конфиге отключить функцию бекапа сохранений (backupSavestates 0), чтобы эмулятор не создавал копию сейва для каждого из загруженных ромов, это немного ускорит обработку.

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

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

Вот пара примеров:
b2
gb

также иногда удаётся найти встроенные в игру секреты, например, для battle city:

tanks “tanks”
загуглив эту строчку, можно найти способ вызвать сообщение о несчастной любви программиста игры:
https://www.youtube.com/watch?v=qoZtgmi3Ej0

Дальше можно сделать ещё один скрипт, вариант первого, который будет менять один конкретный байт на экране, а потом написать ещё один, для вырезания этого блока из скриншотов и сохранения в отдельный файл.

Такие файлы поддерживаются блочным редактором CadEditor, в который можно загрузить экраны уровня игры, и отобразить их в том формате, в котором их показывает эмулятор (ну и передизайнить эти экраны на свой вкус).

https://gist.github.com/spiiin/7305425
добавил таким способом в CadEditor поддержку ещё шести игр:

  1. Chip ‘n Dale Rescue Rangers 2:
    cad_chip_and_dale_2
  2. New Ghostbusters 2:
    cad_new_ghostbusters_2
  3. Power Blade 2:
    cad_power_blade_2
  4. Flintstones - The Rescue of Dino & Hoppy:
    cad_flintstones
  5. Flintstones - The Surprise at Dinosaur Peak!:
    cad_flintstones_2
  6. Three Eyes Story (Mitsume ga Tooru):
    cad_editor_3eyes