Хакаем самую дешёвую консоль с Ozon

Хакаем самую дешёвую консоль с Ozon

Помните статью про самую дешёвую консоль с Ozon — Sup GameBox? Тогда я рассказал вам о том, что у этого чуда инженерной мысли находится «под капотом» и почему эта консоль не так проста, как кажется на первый взгляд.
После статьи я решил написать письмо производителю процессора этой консоли. И что самое интересно — мне ответили! Даже Спустя 40 лет после релиза оригинальной NES, тайваньская компания V.R.T продолжает развивать архитектуру оригинальной NES. Мне больше ничего не оставалось, кроме как включить фен, достать программатор и хакнуть этот девайс...

❯ Предисловие

В прошлой статье мы с вами разобрали Sup GameBox и выяснили его главную тайну: на самом деле это не эмулятор, как думают многие, а полноценный аппаратный клон оригинального Famicom. Инженеры из тайваньской компании V.R.T не только реализовали полную совместимость с японской консолью, но и заметно доработали её архитектуру, превратив NES во что-то типа микроконтроллера с продвинутыми мультимедийными возможностями.

Та самая капелька! 
Та самая капелька! 

Мы также с вами выяснили то, что чипсет устройства способен работать не только с оригинальными картриджами, но и недорогими SPI/NOR-флэшками, а при наличии программатора мы теоретически сможем заменить существующие и даже добавить новые игры к и без того обширному ромсету из 500 самых известных релизов!

Хакаем самую дешёвую консоль с Ozon

Однако в комментариях некоторые читатели задавали вполне логичные вопросы в духе мол «кто вообще будет производить новые чипы с аппаратными клонами NES, если какой-нибудь AllWinner F1C100s стоит буквально 2$ и при этом в разы мощнее оригинальной консоли? Наверняка это какие-то складские остатки, а компании уже давно не существует...». Всерьёз заинтересовавшись вопросом, я решил написать V.R.T письмо с восхищением, а также просьбой поделится информацией о чипсетах в Sup'ах:

London is capital of great Great Britain. Не судите мой рунглиш.
London is capital of great Great Britain. Не судите мой рунглиш.

И спустя неделю мне ответили! Я был в небольшом шоке и экстазе одновременно... Джек пояснил, что в GameBox'ах действительно используется чипсет VT38 или 39'ой серии, а также предложил использовать утилиту NesMaker с сайта компании для сборки собственного ромсета для консоли. Кроме того, Джек пояснил что реализация GameBox'а в виде девкита невозможна из-за пиратских игр, но вероятно компания прощупывает почву среди демосценеров и DIY'щиков — ведь сейчас, пожалуй, самые лучшие времена для любителей разрабатывать и собирать что-то своё!

Хакаем самую дешёвую консоль с Ozon

Но пока девкита 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 — на него фото плат получаются просто изумительные!

Микросхема EPROM с BIOS'ом для 286-ноутбука старше меня почти на 10 лет...
Микросхема EPROM с BIOS'ом для 286-ноутбука старше меня почти на 10 лет...

И вот наконец-то весь комплект для прошивки приехал... пришло время снова разобрать консоль и включить фен!

❯ Делаем дамп

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

Хакаем самую дешёвую консоль с Ozon

Обычно выводные микросхемы снимают паяльником с использованием сплава Розе или делают импровизированные SMD-щипцы для того, чтобы лишний раз не перегревать чип памяти. Однако я решил снять его феном в щадящем режиме, поскольку не хотел чистить пятачки от Розе после каждой переустановки микросхемы, да и при снятии TSOP феном риск сорвать пятачки кратно ниже!

Хакаем самую дешёвую консоль с Ozon

Далее мы отмываем плату и чип памяти от флюса, а затем вставляем его в колодку:

Хакаем самую дешёвую консоль с Ozon

И выставляем параметры нашего чипа в программе Xgpro. Затем нажимаем «Verify» для проверки ID контроллера, дабы убедиться что все линии флэшки надежно прижаты к колодке и затем как минимум 3-4 раза вычитываем дамп с переустановкой чипа и последующей верификацией образов дабы точно убедится что всё прочиталось корректно.

Хакаем самую дешёвую консоль с Ozon

И вот теперь начинается самое интересное: мы открываем дамп в HEX-редакторе и начинаем искать зацепки для того, чтобы примерно понять разметку памяти. Изначально я ожидал что в начале будет инициализация вектора прерываний, init-sequence для дисплея и код меню выбора игр, однако как оказалось — флэшка каким-то очень хитрым способом поделена на CHR ROM и PRG ROM, и при этом CHR ROM идёт первой!

Хакаем самую дешёвую консоль с Ozon

«Наверняка названия игр хранятся в виде обычного ASCII-текста» — подумал я, так что мы сможем найти меню по ключевым словам — Mario, Angry Birds, Contra... Но никакого результата поиск текста не дал. Тогда я начал искать паттерны из CHR ROM того же самого Марио — и всё равно я не смог ничего найти. Единственное что напоминало об играх - нечитабельные ошметки названия игр.

Хакаем самую дешёвую консоль с Ozon

Тогда я решил поизучать дампы Sup'ов других людей и наткнулся на пост darknesmonk с 4pda. Образ его консоли хоть и был практически идентичен моему, у него названия игр были корректными, а данные из PRG ROM и CHR ROM можно было найти по паттернам. И вот тут то я понял в чём заключается секрет!

Дело в том, что издавна существует очень простой аппаратный способ защиты кода от изучения и реверс-инжиниринга: перестановка битов на дата-линиях. Сама шина в процессоре остаётся точно такой-же, меняется лишь разводка на плате: там, где по логике должен быть бит (сигнальная линия) DQ8 — может оказаться бит DQ10, а там где DQ9 — DQ11 и наоборот. На последнем этапе подготовки прошивки запускается специальный скрипт, который переставляет биты так, чтобы они оказались на своём месте и по итогу для процессора всё остаётся прозрачным. Также поступили и разработчики Sup'а, перемешав биты DQ1 с DQ9 и DQ2 с DQ10.

Обратите внимание на странный порядок распиновки дата-линий.
Обратите внимание на странный порядок распиновки дата-линий.

На первый взгляд может показаться что инженеры пытаются что-то скрыть, однако на практике это скорее всего особенности трассировки платы: мы ведь не забыли, что она у нас однослойная? Иными словами, эти линии может быть проблематично подвести напрямую к процессору, а резисторы-нулевики ставить банально некуда, поэтому разработчикам пришлось выкручиваться вот таким костылем!

С виду трассировка у наших плат практически идентичная, особенно шина к флэшке, но почему у меня биты поменяны местами — мне так и непонятно. 
С виду трассировка у наших плат практически идентичная, особенно шина к флэшке, но почему у меня биты поменяны местами — мне так и непонятно. 

❯ Реверсим

Теперь когда мы разгадали секрет «защиты» ROM консоли, я решил написать небольшую утилиту, которая преобразовывает дамп в формат, удобный для реверса и обратно. Конечно можно просто порезать дороги до соответствующих линий, раскидать перемычки и покрыть маской, но это не совсем изящное решение :)

private static bool GetBit(byte b, int bit) { return ((b >> bit) & 0x01) == 1; } private static void SetBit(ref byte b, int bit, bool value) { b = (byte)(value ? b | (1 << bit) : b & ~(1 << bit)); } static void Main(string[] args) { const int firstBit = 1; const int secondBit = 2; if(args.Length < 1) { Console.WriteLine("Usage VTFasoler <ROM dump>"); return; } string fileName = args[0]; string ext = Path.GetExtension(fileName); FileStream input = File.OpenRead(args[0]); FileStream output = File.Create(Path.GetFileNameWithoutExtension(args[0]) + (ext == ".bin" ? ".fixed" : ".bin")); byte[] data = new byte[input.Length]; input.Read(data, 0, data.Length); /* VT chipsets use whole 16 data lines, which means we have D1 swapped with D9 and D2 swapped with D10 */ for(int i = 0; i < data.Length / 2; i++) { byte b1 = data[i * 2]; byte b2 = data[i * 2 + 1]; byte tmp = b1; SetBit(ref b1, firstBit, GetBit(b2, firstBit)); SetBit(ref b1, secondBit, GetBit(b2, secondBit)); SetBit(ref b2, firstBit, GetBit(tmp, firstBit)); SetBit(ref b2, secondBit, GetBit(tmp, secondBit)); data[i * 2] = b1; data[i * 2 + 1] = b2; } output.Write(data, 0, data.Length); output.Close(); input.Close(); }

После подготовки дампа, я начал искать текстовые строки с названиями игр в надежде выйти на таблицу их дескрипторов в многоигровке. Увы, текстовый пул здесь находится отдельно от описания самих игр. Тогда я решил сверится с официальный утилитой NesMaker от производителя чипсета, однако у него на выходе игры как раз имеют формат структуры без отдельного пула строк.

Хакаем самую дешёвую консоль с Ozon

Выйти на 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 байт).

Заголовок имеет размер в 16 байт.
Заголовок имеет размер в 16 байт.

Далее переходим на 17-й байт (при отсчете от единицы) и начиная от него выделяем столько же байт, сколько у вас получилось при умножении числа блоков PRG ROM на 16.384 - в моём случае 32768 байта и копируем их в буфер обмена.

Затем нам необходимо найти начало PRG ROM заменяемой игры: для этого выделяем 8 байт с отступом хотя-бы в 64-128 байт от начала секции (поскольку иниты в играх Nintendo очень похожи и можно случайно найти не ту игру) и записываем их значения в виде паттерна «78 D8 A9 10 8D 00 20 A2».

Если говорить простыми словами, то лучше выбирать паттерн начиная с адреса A0
Если говорить простыми словами, то лучше выбирать паттерн начиная с адреса A0

Далее ищем паттерн в нашем дампе и устанавливаем позицию курсора на начало секции PRG ROM, который в моём случае оказался по адресу 0x60000:

Хакаем самую дешёвую консоль с Ozon

И просто вставляем скопированные ранее данные секции с заменой существующих данных. Получается вот так:

Хакаем самую дешёвую консоль с Ozon

Тоже самое проделываем с CHR ROM, однако учтите что в начале этой секции у некоторых игр идёт стандартный шрифт. Поэтому паттерн лучше брать с смещения 64-128 байт от начала. Для проверки того, что вы нашли секцию от нужной игры, можно использовать замечательную программу YY-CHR, которая покажет её спрайты.

Хакаем самую дешёвую консоль с Ozon

Осталось заменить название игры в пуле строк, не выходя за пределы нуль-терминатора, иначе мы сломаем названия других игр!

❯ Оно реально работает?

Пришло время записать наш дамп обратно на флэшку и посмотреть что у нас получилось в итоге!

Хакаем самую дешёвую консоль с Ozon

Далее ставим флэшку на место, не забывая хорошо пропаять все её пины и отмываем флюс:

Хакаем самую дешёвую консоль с Ozon

Момент истины: если консоль просто висит с черным экраном без подсветки — значит контакт одной из сигнальных линий был нарушен и необходимо пропаять чип ещё раз. У моей флэшки почему-то был немного гнутый корпус, поэтому иногда приходилось пропаивать по 2-3 раза перед тем как консоль включалась и стабильно работала. Далее выбираем наш хак Mario и...

Вот это графика, почти что SEGA Mega Drive! Не то что в оригинале!
Вот это графика, почти что SEGA Mega Drive! Не то что в оригинале!

Всё работает идеально!

❯ Заключение

Ну что друзья, как я и обещал — контенту с моддингом Sup'а быть! Конечно всё прошло не так гладко, как хотелось бы, но... кто знает, вдруг V.R.T действительно сделает какую-нибудь NES-совместимую DIY консоль, на которую игры можно будет легко заливать с помощью CH341A. А там глядишь и демосцена подтянется!

На данный момент, Sup GameBox — самый доступный гаджет для написания хоумбрю под NES и тестирования его на реальном железе... И кто знает, вдруг на нём когда-нибудь окажется игра моей собственной разработки...

А если вам интересна тематика ремонта, моддинга и программирования для гаджетов прошлых лет — подписывайтесь на мой Telegram-канал ‭«Клуб фанатов балдежа‭», куда я выкладываю бэкстейджи статей, ссылки на новые статьи и видео, а также иногда выкладываю полезные посты и щитпостю. А ролики (не всегда дублирующие статьи) можно найти на моём YouTube канале.

Если вам понравилась статья...

И у вас появилось желание что-то мне задонатить (например прикольный гаджет) - пишите мне в телегу или в комментариях :) Без вашей помощи статьи бы не выходили! А ещё у меня есть Boosty.

Если V.R.T выпустит консоль по типу Sup GameBox, но при этом с возможностью лёгкой разработки и прошивки своих игр — купили бы её?
Да, 100% купил бы! Давно хотелось попробовать написать что-то под ретро-консоли, а эмуляторы — совсем не то!
1000% что купил бы! Портативный аппаратный фамиклон, да ещё и с встроенным «мод-картриджем» — вот это то, чего реально не хватало NES-сцене!
Я бы купил такую консоль для нецелевого применения… Сделал бы 6502-часы или 6502-поливалку :) 0
Купил бы, но только при условии адекватной цены. Скажем, до 3.500 рублей — нормальная сумма.
Не купил бы. Не интересно.
Что думаете о таком моддинге?
Балдеж. Теперь в России есть ещё один кастомизированный Sup!
monobogdan, я тебя не узнаю. Ты почему не припаял сверху ещё одну NOR'ку, параллельно выведя их CS на отдельный тумблер?!
@ КОНСОЛЬ — 400 РУБЛЕЙ @ ПРОГРАММАТОР — 3.500 РУБЛЕЙ @ КОЛОДКА — 1.500 РУБЛЕЙ @ УДОВОЛЬСТВИЕ ОТ ПРОЦЕССА — БЕСЦЕННО!
Такой уг-моддинг только для тех, кому заняться нефиг. Автора на завод!!!
Дико извеняюс пробегал кобанчиком увидел вашу Статью чё тут? АХАХХААХ 24 года мужику сидит нарисованных человечков патчит, я в твоих годах уже старший слесарь был)) Ладно до встречи Моддеры блин))
Как относитесь к формату статей с моддингом чего-то необычного… или наоборот чего-то очень обычного?
Мне нравится! Лонги живут!
Статья лонгосодержащая, идентичная натуральной. Ей не сравнится с настоящими лонгами из 2020!
Статья не лонг, а мусор и трешак, которому не место даже на DTF!!!
Ладно, щас спущусь в комментарии чтобы узнать обновления романа с операторшей СДЭК и Яндекс.

Подготовлено при поддержке @TimeWeb.Cloud

110
33
8
3
2
1
39 комментариев