惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

G
GRAHAM CLULEY
T
Tenable Blog
Know Your Adversary
Know Your Adversary
C
CXSECURITY Database RSS Feed - CXSecurity.com
P
Privacy International News Feed
S
Security Affairs
NISL@THU
NISL@THU
O
OpenAI News
Attack and Defense Labs
Attack and Defense Labs
Application and Cybersecurity Blog
Application and Cybersecurity Blog
Hacker News: Ask HN
Hacker News: Ask HN
Webroot Blog
Webroot Blog
Schneier on Security
Schneier on Security
S
SegmentFault 最新的问题
S
Schneier on Security
G
Google Developers Blog
V
V2EX
C
Check Point Blog
U
Unit 42
Google DeepMind News
Google DeepMind News
T
Threatpost
阮一峰的网络日志
阮一峰的网络日志
T
The Exploit Database - CXSecurity.com
Recent Announcements
Recent Announcements
M
MIT News - Artificial intelligence
S
Secure Thoughts
博客园 - 司徒正美
Recorded Future
Recorded Future
P
Proofpoint News Feed
Spread Privacy
Spread Privacy
K
Kaspersky official blog
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
AI
AI
博客园 - 聂微东
N
News and Events Feed by Topic
SecWiki News
SecWiki News
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
V
Vulnerabilities – Threatpost
P
Palo Alto Networks Blog
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Engineering at Meta
Engineering at Meta
Recent Commits to openclaw:main
Recent Commits to openclaw:main
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
酷 壳 – CoolShell
酷 壳 – CoolShell
WordPress大学
WordPress大学
The Hacker News
The Hacker News
The Last Watchdog
The Last Watchdog
Project Zero
Project Zero
W
WeLiveSecurity
博客园 - Franky

Все публикации подряд на Хабре

Ловим музу за клавиатуру: как айтишнику стать автором Что умеет Midjourney в 2026? Мой немного грустный разбор этого шикарного инструмента Никто не любит писать тесты, но ИИ может исправить это IPv8 выглядит как мечта. Поэтому почти наверняка не взлетит Производители вернули в продажу материнки с DDR3. Что происходит? Управление агентом с телефона через Telegram теперь в KodaCode От координации к лидерству: как меняется роль руководителя разработки Я сделала родителям бизнес вместо пенсии: зарабатываем 70 тысяч, мама не даёт продать В три раза быстрее приемка товара и оптимизация трудозатрат на 73%: как «РСТ-Инвент» помог Gulliver Group ИИ-шечный мир победил? О влиянии искусственного интеллекта на игропром Кремль снижает давление на Телеграмм пока Европа строит интернет по паспорту Как CEO, CTO и CIO за 8 часов собрали ИИ-директора, который умеет держать позицию под давлением Как (не) потерять домен за выходные Вместо 8 разных VPS: как я организовал практику студентам на одном сервере Почему твой Open Source проект не замечают? R&D: искусство управления неопределенностью в разработке AI-дефляция: вакансий для разработчиков больше, а рост зарплат — худший за 15 лет Мы отдали управление роботами OpenClaw. Что из этого вышло Галактический ID: система идентификации для всех форм разумной жизни Шесть основ бизнес-анализа: начинаем с вопроса «Кто в игре?» Код-ревью, в котором дело не в коде Данные переехали. Команда — нет Системной подход к сдаче OSWE в 2025 Почему комната управления реактором покрашена в цвет морской пены 4 YAML-файла вместо PySpark: как аналитикам строить пайплайны без разработчиков LLM-агент для поиска свободных доменов: автоматизируем подбор Когда, зачем и как правильно начинать новую сессию в Claude Code? Как я заставил нейросеть писать макросы для FreeCAD Анатомия ИИ‑агента для подбора персонала. От тысячи резюме к топ‑10 за минуты Опыт разработчика как экономика внимания Автономность как точка невозврата: кто будет субъектом в цифровом будущем Обучение ИИ в «диких» условиях: как рутинные действия превращаются в датасеты Как измерить LLM для задач кибербеза: обзор открытых бенчмарков Где хранить код? Сравнение GitHub, GitLab и Bitbucket Математика объясняет, почему нормальное распределение встречается повсюду Почему ваш FinOps не работает: 12 тезисов от практиков Как подписать проектную документацию УКЭП с использованием бесплатных лицензий Pilot Адаптивное администрирование Sigla Vision Я грузил уран в бочки, а потом 20 лет строил ИТ в атомной отрасли Чем позвонить с Эвереста? История и обзор спутниковой связи. Часть 2 Как языковая модель помогает контролировать качество инструктажей по охране труда в металлургии Как не передать на desktop свой IP в РКН Анатомия SAP Privileges: как устроено управление правами в macOS MoneyDev: Сказка про три главных слова Обновлённый токенизатор видео K-VAE 2.0 от Сбера Как сделать диспетчеризацию дома на 1284 квартиры почти бесплатно Как мы разогнали железную дорогу Мы дали агентам рутину. Теперь надо решить — что делать с освободившимся временем Токсичный контент, промпт-хакинг и защита ИИ — всё о Guardrails для LLM Умный город начинается с точного взгляда: как «Фалькон Тех» меняет пространство к лучшему Навайбкодил приложение для анализа графов Почему Дюну так интересно читать? Упрощаем работу с рутиной или как стать Гендальфом Белым Деконструкция Go: CPU, RAM и что там происходит. Go Assembler база. Часть 1.1 Какие профессии исчезнут из-за ИИ, а какие появятся? И что с этим делать Как мы построили IT-отдел, где хочется расти: архитектурные встречи, прозрачные метрики и книжные подарки Rufler: Делаем из Claude Code автономный рой через один YAML-конфиг Sing-box и белый список приложений Как построить надёжный обмен сообщениями в микросервисах: лучшие практики для enterprise OpenAI строит MLM-пирамиду, а McKinsey и Accenture помогают ей в этом Дом, который не построил Фишер (Часть 2) «Сверхзвуковой математик» против «Вдумчивого логиста»: битва алгоритмов 3D-упаковки Мультимодальные модели – грубый и дорогой инструмент Разговоры ничего не стоят. Код тоже Проверки физических лиц: с кого начнет ФНС Топ-10 бесплатных нейросетей для создания видео в 2026 году Первые слои кода: как наши решения сегодня определяют архитектуру ИИ на десятилетия Разработка нового статического анализатора: PVS-Studio JavaScript Поиск уязвимостей ПО: базовый минимум или роскошный максимум Почему оценка персонала не работает как инструмент управления Как мы разработали ИИ-ассистента и сократили рутину продуктовой команды на 50% Как я ушел из найма, нажарил косточек и продал на маркетплейсах на 168 млн в год Когда 1С:ERP уже внедрена, а нормального производственного плана всё ещё нет Как я сделал Claude мультимодальным, подключив к нему Qwen Omni Как приглашение на вакансию мечты превращается в атаку Infrastructure as Code: философия и лучшие практики IaC Тестируем Yandex Code Assistant на задаче, в которой нужно хранить секреты nxs-universal-chart v3.0: новое поколение универсального Helm-чарта Callback Injection: Техника, которая отправила Microsoft Defender в глухой нокаут «Все идеи на стол»: митап как способ вывести проект из тупика Сегодня я узнал нечто новое о GPU благодаря багу в своей игре Как заставить LLM ̶ ̶г̶а̶л̶л̶ю̶ ̶ эволюционировать Карта событий как фундамент аналитики: практический кейс для E-commerce Что выбрать для AI: x86, ARM или RISC-V? Дайджест железа за март Роль соматических мутаций в развитии аутоиммунных заболеваний: путь к избирательной терапии Mythos от Anthropic — тревожный сигнал для всех, а не только для банков Guardrails для LLM на Java: как приручить промпт‑инъекции и токсичные ответы Green-VLA: как мы собрали VLA-модель для реального антропоморфного робота и не потеряли обобщение Финансовая гонка вооружений: почему умные люди добровольно в ней участвуют Эра ИИ-агентов наступила: выбираем лучшего цифрового сотрудника # Практический опыт внедрения WinCC Redundancy на производственном предприятии Сделал MVP за 3 дня, а потом неделю прикручивал оплату. Оно того стоило? Физика против Маска: почему Starship V3 может оказаться ещё одной катастрофой Нефть Венесуэлы: крупнейшие запасы в мире, но не крупнейшая нефтяная держава JPA 4. Переосмысление Hibernate Почему зеркальная фотокамера Nikon D5 десятилетней давности идеально подошла для миссии «Артемида-2» Проект «Уровень-Спутник» или как мы сделали платформу для гидрологов «Замедлиться, чтобы ускориться»: почему ИИ повышает цену ошибок в требованиях и архитектуре Как с нуля поднять трафик IT-компании на 1657% при бюджете 55 тыс. и выжить Pixel-perfect Downsampling — идеальная отрисовка 50 миллионов точек без потерь
Ножом и термофеном: реверс-инжиниринг USB-устройства
interpres (R · 2026-04-29 · via Все публикации подряд на Хабре

В 2024 году bjiru выложил видео о портативном устройстве ME2 — выпущенной примерно в 2008 игрушке, способной при помощи USB синхронизировать очки и драгоценности между устройством и онлайн-миром. Игра была крайне нишевой, поэтому никто не архивировал её ПО, драйверы и ресурсы; по крайней мере, до тех пор, пока bjiru не создал онлайн-клиент игры.

Я руководитель Miuchiz Reborn — созданного в 2015 году проекта по реверс-инжинирингу, эмуляции и поддержке доступности похожей игры, состоящей из онлайн-части и портативного устройства, соединяемых через USB. ME2 тоже была старой игрой подобного типа, поэтому моя группа Miuchiz рассказала мне о ней ещё в 2018 году; она считала (ошибочно), что они могут быть архитектурно схожи. Несмотря на то, что я уже несколько лет знал о существовании устройства, именно видео bjiru подтолкнуло меня начать его исследование.

Поначалу я занимался исключительно воссозданием сервера, необходимого для обеспечения функциональности копии компьютерной игры, принадлежащей bjiru, но со временем я обратил внимание и на портативное устройство. Разумеется, воссоздание онлайн-игры не было бы полным без механизма синхронизации очков с устройством. В конце концов, это общение между компьютером и устройством ME2 было основной «фишкой» игры. Я подумал, что мой предыдущий опыт работы с портативными устройствами Miuchiz поможет мне в анализе ритуала необходимого им общения... если мне удастся выполнить реверс-инжиниринг кода.

Моё любопытство требовало жертвоприношения в виде ME2. EBay требовал жертвоприношения в виде фиатных денег. Спустя какое-то время я получил эти два образца.

ME2 Devices

Это маленькие устройства с парой кнопок и гнездом mini-USB. В коробке был кабель, но отсутствовал диск с ПО и драйверами. При помощи USB-разъёма можно было бы синхронизировать очки между компьютером и устройством, но когда я начал анализ устройства Miuchiz, то получил полный доступ к его флэш-памяти благодаря реверс-инжинирингу работы его ПО для Windows. Для ME2 такого ПО нет, поэтому я не мог разобраться, как общаться с устройством, при помощи реверс-инжиниринга. Даже после проверки Wayback Machine и общения с bjiru мне не удалось найти сохранившихся копий ПО для коммуникации с устройствами. Кажется, оно называлось ME2 Desktop Buddy, но это приложение было отдельным от восстановленного bjiru клиента игры. При подключении ME2 отображается как съёмное устройство-накопитель, но содержимое просто перенаправляет онлайн для скачивания игры ME2, которая уже недоступна.

Дальнейший маршрут понятен: остался лишь один вариант — вскрытие оборудования.

Что внутри

ME2 PCB

Основная прошивка ME2 хранится на SST39VF3201 — флэш-чипе объёмом 2 мегаслова (4 мегабайта с 16-битными адресуемыми блоками). Главный микроконтроллер спрятан под твёрдой каплей эпоксидки. Это называется chip-on-board (CoB) и обычно используется для экономии, но из-за этого невозможно найти информацию об интегральной схеме. На чипе в обычном корпусе есть маркировка, как в случае с флэш-чипом. Так как микроконтроллеры в подобных устройствах часто содержат внутренний ROM, возможно, что в нём полностью или частично находится весь код USB, который я хочу подвергнуть реверс-инжинирингу. Наличие этого кода в ROM может обеспечить возможность восстановления превратившегося в кирпич устройства или, если так решит производитель, прошивки устройства после сборки. Этот ROM должен находиться в чипе, идентифицировать который я не в состоянии.

Извлечение данных с флэш-чипа — простой и подробно задокументированный процесс: выпаиваем чип, помещаем его в стандартный программатор флэш-памяти, например, производства XGecu, и с его помощью дампим содержимое. Если мне понадобится информация и из ROM микроконтроллера, то сделать это будет сложнее, но вполне возможно, ведь в подобном устройстве применение защиты маловероятно. В прошлом я добавлял в SPI-флэш Tamagotchi Pix код, копировавший загрузочный ROM в свободное пространство на флэш-чипе; затем я считывал этот ROM при помощи того же программатора, с помощью которого инъецировал код. Однако в том случае у микроконтроллера был настоящий корпус с напечатанной информацией о модели, поэтому я смог найти его даташит, позволивший узнать используемый набор команд и местоположение его ROM в пространстве памяти. Пока этой информации о загадочном chip-on-board ME2 у меня не было.

Извлечение

Несмотря на отсутствие определённости, единственное следующее очевидное действие заключается в выпаивании флэш-чипа. Кроме того, я приобрёл несколько сокетов для флэш-чипа в надежде, что мне удастся припаять один из них к печатной плате портативного устройства. Это позволило бы мне перепрограммировать ME2 и быстро выполнять итерации на случай, если бы мне понадобилось записывать код для создания дампа внутреннего ROM из микроконтроллера.

К сожалению, мне не удалось снять флэш-чип при помощи паяльника, не повредив при этом чип. Чтобы компенсировать нехватку моих навыков, спустя множество безуспешных попыток я приобрёл паяльную станцию (по сути, термофен, который, по заявлению продавца, должен обеспечивать температуры до 500 °C) и снял чип, расплавив припой горячим воздухом. Это позволило мне без проблем сдампить содержимое флэш-памяти, однако выяснилось, что пользоваться приобретёнными мной сокетами не удастся из-за нехватки опыта. Мне не только пришлось бы припаять все 48 крошечных контактов к печатной плате, но и сделать это достаточно быстро, чтобы не оплавить пластик сокетов. Для этого мне не хватало ни навыков, ни инструментов, поэтому если мне нужен был ROM, придётся воспользоваться другой стратегией.

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

Images in firmware dump

Определение набора команд

Я получил дамп прошивки с флэш-чипа, но прежде чем приступать к серьёзному реверс-инжинирингу, мне хотя бы нужно знать, на каком наборе команд работает устройство. На самом оборудовании не было никаких маркировок, поэтому пришлось гадать. Я попробовал анализировать код в Ghidra (опенсорсном дизассемблере, декомпиляторе и кошмаре, при помощи которого я зарабатываю на жизнь) почти со всеми типами имевшихся у него процессорных спецификаций. Может, это какой-то вариант ARM? Или потомок 6502? MIPS? Буквально что угодно, поддерживаемое Ghidra? Увы, ответом на все эти вопросы было чёткое «нет».

Я пробовал всё, но ничто не могло дизассемблировать этот код. Я знал, что это код, потому что даже нашёл нужные мне части кода!

USB code in hex editor

Код USB в шестнадцатеричном редакторе

Благодаря прошлому опыту работы с устройством Miuchiz я получил некоторые знания о работе съёмных USB-накопителей. Я определил, что этот блок кода почти наверняка копирует куда-то 'U', 'S', 'B', 'S' — сигнатуру именно того типа коммуникаций USB-накопителя, который я искал. Код USB, необходимый мне для реверс-инжиниринга взаимодействия с устройством, частично или полностью находился в этом дампе, но не зная, на каком наборе команд он написан, я не мог его дизассемблировать.

Теперь у меня уже была пара поломанных ME2. Это может показаться глупым, но, вероятно, под каплями эпоксидки может обнаружиться какая-то маркировка? Скорее всего, нет, но на этапе исследований полностью разобранное устройство будет более ценным, чем просто поломанное.

Итак, у меня есть термофен и нож. Как говорится, когда у тебя в руках термофен и нож, всё вокруг превращается... в гвозди? Вроде есть такая поговорка.

Chip-On-Board off board

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

Как я и сказал, иногда полностью раскуроченное устройство ценнее сломанного.

Microcontroller freed from its epoxy

Хм.

Ого!

Я понятия не имел, что можно таким образом извлечь CoB. Он просто выскочил без каких-либо проблем, а учитывая его температуру, я рад, что не в мою сторону. Он очень красивый; к тому же, он позволит нам двигаться дальше. Рассмотрим его повнимательнее через мой электронный микроскоп.

User manual claiming that a digital microscope is an electron microscope

По крайней мере, в руководстве утверждается, что он электронный. Вообще я проверил, он содержит как минимум один электрон.

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

Poor quality die shot

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

Siliconpr0n, теперь также называющийся Siliconprawn — это архив, в который множество людей загружали снимки кристаллов, хоть и обычно более высокого качества, чем мой. К сожалению, по имеющейся у меня информации выполнять поиск по сайту было невозможно, поэтому я начал работать мышкой...

Matching die shot

Мы нашли подозреваемого!

В четыре ночи, спустя множество часов, я наконец-то нашёл нечто похожее. Качество снимка лучше моего, но структуру ни с чем не спутаешь. Это GPL162002A (или B), повёрнутый на снимке Джона Макмастера на 180 градусов; микроконтроллер GeneralPlus, его даташит можно найти в Интернете, а внутри него используется набор команд μ'nSP.

Реверс-инжиниринг прошивки

Как оказалось, μ'nSP довольно широко используется в подобных старых игрушках. Надеюсь, меня можно простить за то, что я не смог вычислить набор команд, название которого содержит символы, даже не входящие в латиницу. Несмотря на популярность, он всё равно довольно нишевый, поэтому не поддерживается Ghidra изначально. К счастью, по нему уже есть сторонний проект, благодаря которому я смог начать дизассемблировать его в Ghidra, давать имена функциям и импортировать имена регистров из даташита.

Вот функция, которая, как я был уверен из шестнадцатеричного дампа, являлась кодом USB; она взаимодействует с регистрами USB в соответствии с даташитом микроконтроллера:

USB function decompilation

USB function decompilation

Как я говорил выше, мне уже был знаком принцип общения USB-накопителей, особенно учитывая эксперименты по портированию USB-библиотеки Miuchiz в macOS при помощи libusb. Съёмные USB-носители, по сути, туннелируют команды SCSI, которые подробно задокументированы онлайн. Вот, например, команды для запроса чтения с устройства или записи на него.

SCSI dispatch function decompilation

Однако я знал, что общие стандартные команды наподобие чтения или записи будут для меня бесполезны. С ними компьютер и так умеет работать при помощи встроенных драйверов съёмных накопителей. Он отправляет команды для взаимодействия с ними, как с обычными съёмными медиаустройствами. В этом случае команда чтения просто получит файловую систему с файлом справки, а команда записи не сделает ничего, потому что устройство не поддерживает запись. Они не предназначены для взаимодействия со всем флэш-чипом; по сути, это крошечный симулируемый CD-ROM, помогающий новичкам.

Впрочем, часть ID команд зарезервирована под действия, которые хотел реализовать производитель. Обработчики части зарезервированных ID грубым образом инъецируются перед выполнением поиска обычных ID.

Special commands decompilation

При помощи статического анализа я смог найти нужные функции (для чтения, программирования и стирания флэш-памяти) и дать им имена. Это нестандартные команды, реализованные для ME2 и, возможно, других устройств GeneralPlus; почти наверняка они использовались для ПО и драйверов, которые изначально поставлялись с устройством. Для активации любого из этих путей можно составить USB-сообщение. Read позволяет извлекать данные из флэш-памяти. Program позволяет «программировать» память. Erase позволяет сбросить все биты в области флэш-памяти на 1, которые при использовании в сочетании с командой может вызвать полную запись во флэш-память, поскольку «программирование» может менять значения битов только с 1 на 0. Каждая из этих интересующих меня специализированных команд использует зарезервированный ID 0xFF, за которым следуют ID подкоманд и необходимые операции параметры.

Конкретные структуры команд не особо важны для нашей статьи, зато полезной может быть методология. Для упрощения взаимодействия через USB я воспользовался libusb (точнее, rusb). Этот способ позволяет для общения с USB-устройством писать код пространства пользователя, а не создавать новый драйвер.

Когда из Интернета пропало ПО ME2 для Windows, умер предпоследний говорящий на его языке. Последним осталось устройство ME2. Поэкспериментировав и изучив почти всегда правильную декомпиляцию, я научился произносить слова на этом почти вымершем языке. И когда устройство ответило, я понял, что нахожусь на верном пути.

Я задавал ему вопрос: можно ли получить сектор твоей флэш-памяти? А как насчёт следующего сектора? Сможешь запрограммировать биты в этом секторе? Можешь показать свою флэш-память, чтобы я проверил, изменилась ли она? Осмелюсь попросить тебя стереть сектор... и, надеюсь, ты разберёшься, какой именно я прошу тебя уничтожить.

Шаг за шагом я писал код для структурирования, заполнения и передачи сообщений, которые должно было услышать ME2. Придя к взаимопониманию, я попросил его отправить мне пару дампов флэш-памяти, имея разное количество очков. Сравнив их, я смог разобраться, где очки хранятся в памяти, и наконец-то изменить их через компьютер!

Score on device that says 654321

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

Several devices with the Miuchiz Reborn emblem hacked into them

«Embadded» ROM и «Embadded»-баги

Похоже, когда я впервые попробовал читать/записывать флэш-память, я был немного опрометчивым, потому что не видел весь исполняемый код. Например, код делал часть вызовов ко внутреннему ROM микроконтроллера или к подпрограммам в ОЗУ, скопированным туда ROM. Частично мои гипотезы о других функциях были основаны на том, как подготавливались регистры DMA (direct memory access). Например, если регистры DMA настраивались для копирования из буфера USB, то, вероятно, эти данные использовались для программирования флэш-памяти, а не для чтения из неё.

SCSI erase function decompilation

SCSI erase function decompilation

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

Нужная область памяти чётко описана в даташите:

Memory layout from datasheet with "Embedded ROM" spelled "Embadded ROM"

Здесь есть 128 килослов встроенного ROM (embedded написано с опечаткой, embadded), к которому у меня пока нет доступа, поэтому я не могу понять систему целиком.

К счастью, эта функция команды чтения специальной флэш-памяти не выполняет проверку границ. Благодаря этому при помощи особым образом составленного сообщения, пытающегося выполнить чтение из очень высокого адреса флэш-памяти, можно вернуться к самому началу адресного пространства микроконтроллера. Так как это обеспечивает нам возможность произвольного чтения, на этот раз мне не нужно писать кода для дампинга, выполняемого внутри устройства! При помощи этого бага мы можем считать всю память, чем я и воспользовался для чтения Embadded ROM, который сохранил для дальнейшего реверс-инжиниринга.

Получив всю память, я смог найти буфер кадров устройства в ОЗУ, в котором находилось изображение, выводимое в текущий момент на экран устройства:

Framebuffer in RAM dump

Буфер кадров в дампе ОЗУ

Кроме того, мне удалось считать регистры ввода-вывода общего назначения (GPIO) из адресного пространства устройства, воспользовавшись информацией о них из даташита. Выполняя баг десятки раз в секунду, я мог, по сути, опрашивать нажатия кнопок и при желании превратить устройство в USB-контроллер: (видео)

GPIO dumping

В процессе тестирования я заменил странное изменение значения во флэш-памяти, которое вроде бы не должно было сохранять данные.

Diff showing 0xAA being written into flash

Значение 0x00AA (напомню, что размер слова системы равен 16 битам) записывалось во флэш-память по адресу, который я не указывал. Благодаря Embadded ROM мы можем наконец увидеть код, который это объясняет.

Disassembly showing the code that causes the OOB write

Дизассемблирование объясняет код, вызывающий запись OOB

Эти флэш-чипы получают команды, выполняя запись по конкретным смещениям. В отличие от ОЗУ, которое сразу передаёт записанные данные, флэш-чип лишь пытается интерпретировать операции записи как часть команды, поэтому одной операции записи в адресное пространство флэш-памяти недостаточно для изменения данных. Когда блок кода хочет запрограммировать флэш-память, он передаёт многоэтапную последовательность команд, которая начинается с записи 0xAA в 0x5555 и завершается записью нужных данных по нужному адресу.

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

Процессор: Эй, флэш-память! Я хочу начать программировать ещё одно слово!

Флэш: Поняла тебя! Программирую 0xAA в 0x5555!

Процессор: ...Чего?

Из-за рассинхронизованных тактов команд флэш-память путает первый такт следующей команды с последним тактом предыдущей команды, и 0xAA программируется в 0x5555. Эквивалентным адресом для типичных 8-битных байт будет 0xAAAA, что соответствует месту записи 0x00AA в мой дамп флэш-памяти.

Потенциально это можно использовать для произвольной записи, если нас устроит повреждение определённого слова в памяти, но устройства и так достаточно изучены, поэтому я не хочу рисковать и снова окирпичивать их. Возможно, поломанные устройства можно спасти, поскольку реверс-инжиниринг Embadded ROM также показал, что в нём содержится собственный обработчик USB и реализации чтения/программирования/стирания флэш-памяти. Однако мне удалось перевести ROM в это состояние (вместо запуска кода флэш-чипа) только раз, и больше этого сделать не получалось. Судя по декомпилированному ROM, он может использовать незадействованный порт GPIO, но уверенности у меня нет. Как бы то ни было, моя миссия уже выполнена.

Готовые продукты и выводы

Результатом этих шалостей стала утилита командной строки, которая может:

  • Читать флэш-память.

  • Записывать её.

  • Считывать очки.

  • Записывать очки.

  • Считывать драгоценности.

  • Записывать драгоценности.

  • Дампить память (при помощи эксплойта).

  • Следить за вводом с кнопок (при помощи эксплойта).

Всё это вместе с кодом сервера игры и другими исследованиями выложено в репозиторий ME2-Restoration. Так как подробности реализации описаны в нём и, скорее всего, не очень интересны обычному читателю, в статье я опустил технические детали, чтобы подробнее описать процессы и методики.

Ещё важнее здесь демонстрация того, что оригинальное ПО на стороне PC не обязательно для понимания или сохранения функциональности устройств. Даже если официальное ПО было утеряно, можно открыть «чёрный ящик» ME2 и воссоздать его протокол на основании оборудования и прошивки, превратив мёртвый интерфейс во что-то полезное. И это касается не только интерфейсов наподобие USB. В ещё одной моей статье можно прочитать, как я воссоздал давно мёртвый сервер лицензий, чтобы вернуть к жизни векторный редактор, заброшенный десяток лет назад.

В проекте по возрождению ME2 я впервые вскрыл корпус интегральной схемы, поэтому чтобы отдать этому моменту должное, я приобрёл более мощный микроскоп и выложил на siliconprawn GPL162002A/B фото наивысшего качества (показанное ниже изображение уменьшено):

High quality die shot