Вы когда-нибудь задумывались, сколько существует умной электроники? Куда ни глянь, везде натыкаешься на устройство, имеющее микроконтроллер со своей прошивкой.
Камера, микроволновка, фонарик.
Да даже на некоторых кабелях USB Type C есть прошивка! И все это, по идее, можно перепрограммировать, переделать, модифицировать.
Но как это сделать без документации и источников? Конечно, реверс-инжиниринг! Давайте рассмотрим этот самый обратный процесс очень подробно, от самой идеи до конечного результата, на небольшом, но интересном примере!
Идея
Шина PCI Express меня привлекала давно.Судите сами — высокие скорости, DMA-доступ к памяти компьютера, множество разных устройств и производителей, масса стандартов и реализаций.
Что, если мы возьмем какое-нибудь устройство PCI-E и изменим прошивку так, чтобы, работая параллельно, мы могли по своему желанию читать/записывать оперативную память компьютера?
Вы скажете - а ведь есть готовые решения, например, PCI-пиявка И Раскат грома .
Но PCI Leech не может работать как «обычное» устройство, а Thunderclap хоть и имитирует сетевую карту, но основан на громоздкой и дорогой плате разработки FPGA. По моей задумке устройство должно корректно определяться драйверами в любой системе и при этом быть недорогим.
Такое устройство можно использовать, например, в качестве аппаратного отладчика x86 — имея возможность чтения и записи оперативной памяти, гораздо проще разрабатывать драйверы для BIOS на коленке.
Выбор испытуемого
Я начал присматриваться к различным PCI-E устройствам несколько лет назад, но большинство устройств, которые мне попадались, были либо слишком простыми и имели жестко фиксированный функционал, либо очень мало возможностей со стороны прошивки:Контроллер USB 3.0 на чипе ASMedia Или они выглядели настолько сложными, что перспектива повернуть вспять такого монстра просто пугала:
Усовершенствованный сетевой контроллер Fujitsu Мне нужно было устройство, которое имеет:
- встроенный мощный микроконтроллер
- легко перепрограммируемое ПЗУ
- отладка интерфейсов (UART, JTAG)
- встроенная прошивка (не загружается драйвером)
И, как вы уже догадались из названия статьи, недавно я наткнулся на вот такой SATA-контроллер:
А именно меня привлекла предельная простота контроллера (только проц и ПЗУ) и радиатора на нем (а значит внутри мощный процессор!).
Быстрый поиск по названию чипа еще больше подогрел интерес к нему.
Найденная для него прошивка весила целых 500 КБ, имела признаки ARM-кода, не была сжата и имела достаточное количество текстовых отладочных строк:
Даже беглым взглядом на прошивку уже можно сказать, что исследовать ее не составит труда И к нему была некоторая документация, в которой многие пины не были подписаны, что давало шанс на наличие отладочных интерфейсов:
Какой подозрительный ряд неиспользованных булавок, не правда ли? Вскоре контроллер был куплен, и я присмотрелся к нему:
Без радиатора контроллер выглядит еще проще Контроллер действительно выглядел очень просто и многообещающе.
Но более детальное изучение даташитов показало, что выводы NC на самом деле являются NC, и отладки по нему ждать не стоит. Более продвинутый контроллер с поддержкой и SATA, и IDE, точно в том же корпусе, имел на этих выводах дополнительные сигналы:
Увы, скорее всего, эти выводы не являются тестовыми.
Но я нашел даташиты на другие очень похожие контроллеры, с явным упоминанием об отладке:
То, что производитель просит не подключать TST2-TST6, очень намекает на наличие JTAG, а прямое указание UART на TST0 и TST1 (в другом даташите) - это уже куш.
Поэтому было решено купить 88SE9215, как самый недорогой из имеющихся, и поиздеваться над ним:
Проверка работоспособности
И вот объект исследования у нас в руках, первое, что мы делаем – проверяем, что он работает. Это важный момент, здесь мы исключаем возможные будущие вопросы: «Я сломал или оно не работало?Э»Для этого мне пришлось купить райзер М2, так как единственный слот PCI Express на моем ПК занят видеокартой:
Разъем miniUSB 3.0 я увидел впервые вживую.
Твердый! В целом тест прошел успешно, я даже установил систему на HDD, подключенный к этому контроллеру, все подхватилось стандартными драйверами:
При запуске ПК мигает информация о состоянии контроллера, это PCI Option ROM и по идее из этого меню можно что-то настроить, но в настройки попасть не удалось:
Чтобы запечатлеть этот момент, мне пришлось записать видео
Анализ компонентов
Теперь нужно определить, что к чему подключено, где процессор, а где ПЗУ и какие компоненты за что отвечают. В нашем случае анализ предельно прост, особенно учитывая наличие даташитов:Да, нас не интересуют простые компоненты вроде транзисторов и конденсаторов.
Ну а соединения компонентов нам производитель нарисовал.
Примечание для исследователей Для быстрого осмотра плат я использую глупый, но часто эффективный подход — если микросхема квадратная и с множеством выводов, то это исполнительный элемент (процессор, ПЛИС, ЦСП), а если прямоугольная, то это память.
Некоторые производители дополнительно маркируют краской компоненты, содержащие внутри прошивку (очень полезно, когда ПЗУ находится в микроконтроллере и маркировка явно об этом говорит).
Что-то, что первым пришло из Google в качестве примера.
Точное назначение и тип компонентов мы можем узнать по маркировке и паспортам.
В нашем случае список компонентов совсем небольшой:
Маркировка | Цель | Параметры |
88SE9215-NAA2 | Центральный контроллер | SATA III x4/PCI-E 2.0 x1 |
25Q40H | ПЗУ с прошивкой | СПИ, 512 КБ |
Получение прошивки
Теперь мы убедились в работоспособности устройства, проанализировали из каких компонентов оно состоит, теперь нам следует его «бэкапить», максимально извлечь из него данные, чтобы в дальнейшем вернуть его в то же состояние.Прошивка может находиться как во внешнем ПЗУ, так и в самом контроллере; это также следует принять во внимание и тщательно изучить документацию.
Обычно прошивку можно получить тремя способами, это:
- обновления от производителя
- программатор из ПЗУ/контроллера
- через отладочные интерфейсы с устройства
Несмотря на то, что это .
exe файл, 7-zip его пережевал, и внутри оказались .
bin файлы самой прошивки:
Скачал все прошивки, которые смог найти в сети, в том числе и для подобных контроллеров, и это тоже дало результат - в одном из архивов нашел Readme с описанием чтения ПЗУ:
Но для этого нужно было подготовить загрузочную DOS-флешку, поэтому я просто считал ПЗУ программатором, благо тут есть типичная SPI Flash. Самый простой способ – с помощью клипсы.
Цепляемся за ПЗУ и пытаемся прочитать:
Самая простая клипса с Али, стоит меньше бакса
Эту коробку с надписью PF мы еще не раз увидим.
И в два клика ROM был идентифицирован и прочитан программатором:
Да, автор программатора очень любит писать «флэш» с мягким знаком
Часто контроллер мешает считыванию и приходится выпаивать микросхему или хотя бы подавать питание на устройство.
В данном случае нам повезло, но на всякий случай мы читаем его несколько раз и сравниваем содержимое, чтобы убедиться, что оно рассчитано правильно.
Анализ прошивки
В качестве объекта для анализа я взял скачанную с сайта прошивку (чтобы начать изучение еще до того, как купленный контроллер прибудет ко мне домой).Первым делом необходимо определить структуру образа прошивки.
Беглый взгляд на изображение сразу показывает, что большая часть изображения представляет собой пустое пространство, а полезная нагрузка начинается с некоторых адресов, кратных 0x1000. И по адресу 0x2000 мы видим довольно интересный набор данных:
Ну, нам даже структуру прошивки выписали! Итак, по описанию, на изображении мы имеем:
Предвзятость | Размер | Имя | Цель |
0x00000 | 0x000A0 | Автозагрузка | ?? |
0x0C000 | 0x00834 | Погрузчик | Погрузчик |
0x20000 | 0x07800 | БИОС | Дополнительное ПЗУ PCI-E |
0x30000 | 0x74558 | Прошивка | Прошивка контроллера |
В общем, столкнувшись с неизвестным образом, желательно запустить его через пешеходная дорожка , эта утилита сразу покажет известные форматы файловых систем и упакованные данные.
В данном конкретном случае он нашел только таблицы коэффициентов для CRC32:
Также полезно разбить прошивку на части и прогнать их cpu_rec чтобы знать, с какой архитектурой программного обеспечения мы имеем дело.
В начале статьи я предполагал, что контроллер должен иметь архитектуру ARM, а Дополнительное ПЗУ должно быть архитектуры x86, так как оно работает на хосте.
Давайте проверим это:
Теперь займемся обратным процессом.
Начнем с Loader — он на ARM-архитектуре и имеет небольшой размер.
Скорее всего контроллер оттуда начнет загружаться.
Попробуем загрузить его в дизассемблер:
И мы видим, что первые инструкции переходят на адреса 0xFFFF00**, а это значит, что либо контроллер при запуске сначала переходит в ПЗУ Маски по адресу 0xFFFF0000 (что сомнительно), либо по этому адресу загружается сам код загрузчика.
Перезагружаем код в дизассемблер по адресу 0xFFFF0000 и действительно, всё парсится корректно:
Функций здесь очень мало (целых четыре), и разобраться, что делает код, не составит труда:
- По адресу 0xF8064000 код обращается к содержимому ПЗУ.
- В ПЗУ производится поиск сигнатуры "MAGIIMGF"
- Блок данных с этой сигнатурой анализируется и разбрасывается по оперативной памяти.
- Основная система запускается с перехода на адрес 0.
И теперь мы можем разобрать Прошивку и правильно загрузить ее в дизассемблер! Как и ожидалось, всё отлично загружается и можно приступать к анализу основной системы:
Основная задача реверс-инжиниринга — назвать функции и понять, что происходит в коде.
Это поможет нам:
- часто называемые стандартные функции (malloc, memset, memcpy)
- текстовая отладочная информация из прошивки
- различные уникальные константы
Например, здесь имя файла намекает, что эта функция распределяет память:
И здесь явно инициализируется последовательный порт:
Кстати, немного проанализировав задачи инициализации системы, можно наткнуться на функцию, которая принимает указатель на другую функцию и какое-то имя.
Очень похоже на начало новой задачи! Итак, назовем это:
В процессе изучения кода задачи мы сталкиваемся с интересной функцией, которая часто получает красивые десятичные значения (100, 1000).
И это очень похоже на функцию задержки выполнения, спать :
Судя по цифрам, наш процессор работает на частоте 300 МГц – неплохо.
Также из этой функции мы получаем очень важную информацию — системный таймер расположен по адресу 0xD0020314. Попытки поиска этого адреса в Интернете привели к очередному успеху – PDF с подробным описанием еще один процессор Marvell:
И вот у нас уже есть некая документация, с помощью которой мы находим то, что искали изначально, а именно функцию сопоставления (сопоставления) адресного пространства ПК с адресами самого контроллера:
С помощью этой функции контроллер взаимодействует с ПК, к которому он подключен.
Достаточно задать нужный адрес в аппаратных регистрах транслятора, и чтение/запись в пределах заданного «окна» по адресу 0x40000000 автоматически приведет к чтению/записи физической памяти ПК! Теперь осталось узнать, как взаимодействовать с прошивкой и подавать команды извне, внедрить в прошивку собственный код, который попадет в оперативную память компьютера и.
готово?
Ищем интерфейсы отладки
Устали смотреть скриншоты ассемблерного кода? Вернёмся к аппаратному обеспечению! У нас есть набор тестовых пинов, но мы не знаем, где на них находятся отладочные интерфейсы (и есть ли они вообще).
Что вам нужно в первую очередь? Правильно, припаиваем к ним и подводим к гребенке:
Импровизированное рабочее место инженера Производителю совершенно плевать на глаза реверс-инженеров, они даже пятака не сделают!
Уф, мне придется купить микроскоп.
Паять такие мелочи сложно.
А потом подключаем устройство для поиска JTAG, отключаем питание и поехали!
Главный секрет статьи раскрыт! PF означает «Поиск контактов».
Иа, ничего не нашлось:
Ну, по крайней мере, мы выяснили, какие контакты In, а какие Out. Как и ожидалось, подумал я и вспомнил пин «TESTMODE» из даташита.
Наверное, его нужно использовать и тогда.
Что ж, припаиваем еще проводки, ставим подтяжку в TESTMODE:
И снова ничего не нашлось, однако картинка немного другая, почему-то всё стало Вводом:
Теперь по какой-то причине все выходы стали входными.
Ну что это, да ладно JTAG, хоть UART найду, подумал я.
Подключаем логический анализатор.
А это другая коробка, хотя внешне похожа И ни на одном пине мы не видим признаков UART…
А при поднятом TESTMODE тестовые выходы сходят с ума, и это точно не UART:
Ну я думаю это просто в прошивке отключено.
Вам нужно его включить! Вношу небольшие изменения и сталкиваюсь с тем, что через клипсу Теги: #информационная безопасность #Программирование микроконтроллеров #Компьютерное оборудование #SATA #обратное проектирование #Ассемблер #pci-e
-
Справочный Центр Google Chrome
19 Oct, 24 -
Geektimes.ru → Geektimes.com
19 Oct, 24 -
+250 Новых Вакансий
19 Oct, 24 -
Google Adsense – Заработок На Видеоклипах.
19 Oct, 24 -
Создание Собственного Летающего Робота
19 Oct, 24