Хакаем самую дешёвую консоль с Ozon
Помните статью про самую дешёвую консоль с Ozon — Sup GameBox? Тогда я рассказал вам о том, что у этого чуда инженерной мысли находится «под капотом» и почему эта консоль не так проста, как кажется на первый взгляд.
После статьи я решил написать письмо производителю процессора этой консоли. И что самое интересно — мне ответили! Даже Спустя 40 лет после релиза оригинальной NES, тайваньская компания V.R.T продолжает развивать архитектуру оригинальной NES. Мне больше ничего не оставалось, кроме как включить фен, достать программатор и хакнуть этот девайс...
❯ Предисловие
В прошлой статье мы с вами разобрали Sup GameBox и выяснили его главную тайну: на самом деле это не эмулятор, как думают многие, а полноценный аппаратный клон оригинального Famicom. Инженеры из тайваньской компании V.R.T не только реализовали полную совместимость с японской консолью, но и заметно доработали её архитектуру, превратив NES во что-то типа микроконтроллера с продвинутыми мультимедийными возможностями.
Мы также с вами выяснили то, что чипсет устройства способен работать не только с оригинальными картриджами, но и недорогими SPI/NOR-флэшками, а при наличии программатора мы теоретически сможем заменить существующие и даже добавить новые игры к и без того обширному ромсету из 500 самых известных релизов!
Однако в комментариях некоторые читатели задавали вполне логичные вопросы в духе мол «кто вообще будет производить новые чипы с аппаратными клонами NES, если какой-нибудь AllWinner F1C100s стоит буквально 2$ и при этом в разы мощнее оригинальной консоли? Наверняка это какие-то складские остатки, а компании уже давно не существует...». Всерьёз заинтересовавшись вопросом, я решил написать V.R.T письмо с восхищением, а также просьбой поделится информацией о чипсетах в Sup'ах:
И спустя неделю мне ответили! Я был в небольшом шоке и экстазе одновременно... Джек пояснил, что в GameBox'ах действительно используется чипсет VT38 или 39'ой серии, а также предложил использовать утилиту NesMaker с сайта компании для сборки собственного ромсета для консоли. Кроме того, Джек пояснил что реализация GameBox'а в виде девкита невозможна из-за пиратских игр, но вероятно компания прощупывает почву среди демосценеров и DIY'щиков — ведь сейчас, пожалуй, самые лучшие времена для любителей разрабатывать и собирать что-то своё!
Но пока девкита VT38 ещё нет, нам остаётся лишь ковырять и моддить уже существующие консоли... и это не так уж и сложно как кажется на первый взгляд! В первую очередь, важно понимать что Sup'ы собираются буквально «из того что было», при этом чипы памяти зачастую используются Б/У. Насколько мне известно, существует как минимум три ревизии консоли:
- Первая использует NOR Flash в корпусе TSOP56 и имеет на борту 500 игр. Производитель флэш-памяти может быть любой, однако я чаще всего встречал чипы от Spansion. Объём флэши составляет 16МБ (но возможны отклонения в большую и меньшую сторону) и с этими чипами памяти связан определенный нюанс, о котором я расскажу чуточку позже.
- Вторая тоже использует NOR Flash, однако уже в корпусе TSOP48, который можно прошить обычной копеечной колодкой для NAND-флэшек. Такой тип памяти встречается как минимум в версии 400 in 1 и его объём составляет 8МБ, однако судя по большому количеству стертых страниц и 0xFF в дампе — используется далеко не вся память!
- Третья самая сложная — она использует специальные припаиваемые к плате адаптеры с BGA NOR-памятью. Эти адаптеры нужны неспроста: во первых многие дешевые фамиклоны используют однослойные платы, где развести пины под BGA может быть проблематичным, а во вторых BGA NOR-память ушла с рынка электроники лет так 15 назад, её в огромных количествах сдувают с устройств по типу спутниковых ресиверов и DVD-плееров и поэтому она стоит копейки на вторичке. Главная сложность заключается в сборке адаптера: @promolife смог такой собрать, но во время подготовки статьи мы с ним не общались.
Как вы уже могли понять, моя консоль относится к первой ревизии, что вносит определенные сложности. Дело в том, что для прошивки TSOP-56 флэшек необходимо покупать специальную колодку типа «A», которая стоит 1.500 рублей и более того — она подходит только для программатора XGecu T48! Один из моих зрителей компенсировал стоимость покупки программатора и колодки в полном объёме — за что ему огромнейшее спасибо!
Также спасибо читателю Alex за iPhone X — на него фото плат получаются просто изумительные!
И вот наконец-то весь комплект для прошивки приехал... пришло время снова разобрать консоль и включить фен!
❯ Делаем дамп
При детальном рассмотрении платы можно ещё раз убедится в том, что консоли собираются буквально из того что есть. Присмотревшись к чипу памяти я заметил трещину на корпусе, многочисленные царапины и потертости, а также пайку сомнительного качества: из-за них некоторые экземпляры не живут и недели. Интересно, где этот чип трудился в «прошлой жизни»?
Обычно выводные микросхемы снимают паяльником с использованием сплава Розе или делают импровизированные SMD-щипцы для того, чтобы лишний раз не перегревать чип памяти. Однако я решил снять его феном в щадящем режиме, поскольку не хотел чистить пятачки от Розе после каждой переустановки микросхемы, да и при снятии TSOP феном риск сорвать пятачки кратно ниже!
Далее мы отмываем плату и чип памяти от флюса, а затем вставляем его в колодку:
И выставляем параметры нашего чипа в программе Xgpro. Затем нажимаем «Verify» для проверки ID контроллера, дабы убедиться что все линии флэшки надежно прижаты к колодке и затем как минимум 3-4 раза вычитываем дамп с переустановкой чипа и последующей верификацией образов дабы точно убедится что всё прочиталось корректно.
И вот теперь начинается самое интересное: мы открываем дамп в HEX-редакторе и начинаем искать зацепки для того, чтобы примерно понять разметку памяти. Изначально я ожидал что в начале будет инициализация вектора прерываний, init-sequence для дисплея и код меню выбора игр, однако как оказалось — флэшка каким-то очень хитрым способом поделена на CHR ROM и PRG ROM, и при этом CHR ROM идёт первой!
«Наверняка названия игр хранятся в виде обычного ASCII-текста» — подумал я, так что мы сможем найти меню по ключевым словам — Mario, Angry Birds, Contra... Но никакого результата поиск текста не дал. Тогда я начал искать паттерны из CHR ROM того же самого Марио — и всё равно я не смог ничего найти. Единственное что напоминало об играх - нечитабельные ошметки названия игр.
Тогда я решил поизучать дампы Sup'ов других людей и наткнулся на пост darknesmonk с 4pda. Образ его консоли хоть и был практически идентичен моему, у него названия игр были корректными, а данные из PRG ROM и CHR ROM можно было найти по паттернам. И вот тут то я понял в чём заключается секрет!
Дело в том, что издавна существует очень простой аппаратный способ защиты кода от изучения и реверс-инжиниринга: перестановка битов на дата-линиях. Сама шина в процессоре остаётся точно такой-же, меняется лишь разводка на плате: там, где по логике должен быть бит (сигнальная линия) DQ8 — может оказаться бит DQ10, а там где DQ9 — DQ11 и наоборот. На последнем этапе подготовки прошивки запускается специальный скрипт, который переставляет биты так, чтобы они оказались на своём месте и по итогу для процессора всё остаётся прозрачным. Также поступили и разработчики Sup'а, перемешав биты DQ1 с DQ9 и DQ2 с DQ10.
На первый взгляд может показаться что инженеры пытаются что-то скрыть, однако на практике это скорее всего особенности трассировки платы: мы ведь не забыли, что она у нас однослойная? Иными словами, эти линии может быть проблематично подвести напрямую к процессору, а резисторы-нулевики ставить банально некуда, поэтому разработчикам пришлось выкручиваться вот таким костылем!
❯ Реверсим
Теперь когда мы разгадали секрет «защиты» ROM консоли, я решил написать небольшую утилиту, которая преобразовывает дамп в формат, удобный для реверса и обратно. Конечно можно просто порезать дороги до соответствующих линий, раскидать перемычки и покрыть маской, но это не совсем изящное решение :)
После подготовки дампа, я начал искать текстовые строки с названиями игр в надежде выйти на таблицу их дескрипторов в многоигровке. Увы, текстовый пул здесь находится отдельно от описания самих игр. Тогда я решил сверится с официальный утилитой NesMaker от производителя чипсета, однако у него на выходе игры как раз имеют формат структуры без отдельного пула строк.
Выйти на XRef'ы не получалось поскольку у меня нет опыта реверса программ для 6502 и я уже начал терять надежду... Однако я вспомнил что в основном, игры для NES имеют фиксированный формат с двумя секциями: PRG ROM (область памяти с кодом игры), а также CHR ROM (тут находится графика). Учитывая что в ромах .nes есть информация об используемом типе маппера и размерах секций PRG ROM/CHR ROM, мы можем подменять игры на нужные путем поиска секций существующих игр по паттернам и замены их на нужные! Однако такой способ подойдет только для игр с идентичными мапперами и размерами областей. Иными словами: мы можем заменить Dr. Mario с маппером типа 0 на хак Super Mario Bros или Battle City, но не сможем записать, например, Batman.
Сделать это просто: открываем нужную игру в HEX-редакторе, переходим на 5-й байт и смотрим размер PRG ROM, который указывается в блоках размерностью 16.384 байт. В следующем байте находится размер CHR ROM, который указывается в виде блоков по 8.192 байта. В Dr. Mario PRG имеет размерность 2 (32.768 байт), а CHR — 4 (тоже 32.768 байт).
Далее переходим на 17-й байт (при отсчете от единицы) и начиная от него выделяем столько же байт, сколько у вас получилось при умножении числа блоков PRG ROM на 16.384 - в моём случае 32768 байта и копируем их в буфер обмена.
Затем нам необходимо найти начало PRG ROM заменяемой игры: для этого выделяем 8 байт с отступом хотя-бы в 64-128 байт от начала секции (поскольку иниты в играх Nintendo очень похожи и можно случайно найти не ту игру) и записываем их значения в виде паттерна «78 D8 A9 10 8D 00 20 A2».
Далее ищем паттерн в нашем дампе и устанавливаем позицию курсора на начало секции PRG ROM, который в моём случае оказался по адресу 0x60000:
И просто вставляем скопированные ранее данные секции с заменой существующих данных. Получается вот так:
Тоже самое проделываем с CHR ROM, однако учтите что в начале этой секции у некоторых игр идёт стандартный шрифт. Поэтому паттерн лучше брать с смещения 64-128 байт от начала. Для проверки того, что вы нашли секцию от нужной игры, можно использовать замечательную программу YY-CHR, которая покажет её спрайты.
Осталось заменить название игры в пуле строк, не выходя за пределы нуль-терминатора, иначе мы сломаем названия других игр!
❯ Оно реально работает?
Пришло время записать наш дамп обратно на флэшку и посмотреть что у нас получилось в итоге!
Далее ставим флэшку на место, не забывая хорошо пропаять все её пины и отмываем флюс:
Момент истины: если консоль просто висит с черным экраном без подсветки — значит контакт одной из сигнальных линий был нарушен и необходимо пропаять чип ещё раз. У моей флэшки почему-то был немного гнутый корпус, поэтому иногда приходилось пропаивать по 2-3 раза перед тем как консоль включалась и стабильно работала. Далее выбираем наш хак Mario и...
Всё работает идеально!
❯ Заключение
Ну что друзья, как я и обещал — контенту с моддингом Sup'а быть! Конечно всё прошло не так гладко, как хотелось бы, но... кто знает, вдруг V.R.T действительно сделает какую-нибудь NES-совместимую DIY консоль, на которую игры можно будет легко заливать с помощью CH341A. А там глядишь и демосцена подтянется!
На данный момент, Sup GameBox — самый доступный гаджет для написания хоумбрю под NES и тестирования его на реальном железе... И кто знает, вдруг на нём когда-нибудь окажется игра моей собственной разработки...
А если вам интересна тематика ремонта, моддинга и программирования для гаджетов прошлых лет — подписывайтесь на мой Telegram-канал «Клуб фанатов балдежа», куда я выкладываю бэкстейджи статей, ссылки на новые статьи и видео, а также иногда выкладываю полезные посты и щитпостю. А ролики (не всегда дублирующие статьи) можно найти на моём YouTube канале.
Если вам понравилась статья...
Подготовлено при поддержке @TimeWeb.Cloud