Введение

Всем добра и здравия!

Цель статьи: показать подход к реверсу незнакомой архитектуры в условиях отсутствия привычных инструментов анализа.

Задача: модифицировать вывод информации на дисплей автомобильной приборной панели, построенной на базе 9S12HY64 от Freescale. Забегая вперед, банальной таблицы ASCII символов там нет.

Опыта работы с архитектурой HCS12 от Freescale у меня нет, как и инструментов, которые позволяют адекватно дизассемблировать прошивку. При этом разбор исполняемого кода не являлся самоцелью — требуется изменить лишь результат отображения информации на дисплее.

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

Интересующие нас индикаторы выглядят следующим образом.

Иллюстрация тестового режима приборной панели. Красным выделены сегменты с которыми будем работать. Цель: изменить A на P, M на D.
Иллюстрация тестового режима приборной панели. Красным выделены сегменты с которыми будем работать.
Цель: изменить A на P, M на D.

Анализ аппаратной части

При вскрытии приборной панели, был обнаружен МК 9S12HY64 от Freescale и модуль дисплея без опознавательных знаков. Внешнего драйвера у дисплея нет, подключен он 6-ти контактным разъемом, из чего делаем вывод, что драйвер встроенный и общаются они по какому-то стандартному протоколу.

Фото аппаратной части приборной панели. Красным выделена колодка подключения информационного дисплея.
Фото аппаратной части приборной панели. Красным выделена колодка подключения информационного дисплея.

Путем прозвонки цепей, находим контакты МК подключенные к разъему дисплея. Открываем референс мануал на МК и опознаем протокол общения - это I²C.

Скриншот MC9S12HY/HA-Family Reference Manual, Rev. 1.05
Скриншот MC9S12HY/HA-Family Reference Manual, Rev. 1.05

Сбор референсных данных с шины

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

Подключаем логический анализатор на шину между МК и дисплеем, и в первом приближении получаем следующую картину.

Скриншот программы Saleae Logic
Скриншот программы Saleae Logic

Далее снимаем данные с шины во всех интересующих нас режимах и делаем сводную таблицу.

Сводная таблица данных снятых с шины между МК и дисплеем для разных режимов отображения. Красным выделены байты, которые в теории, будут являться сигнатурами поиска по прошивке.
Сводная таблица данных снятых с шины между МК и дисплеем для разных режимов отображения. Красным выделены байты, которые в теории, будут являться сигнатурами поиска по прошивке.

Имея опорные данные идем в прошивку.

Анализ прошивки

Для анализа будем использовать Ghidra, которую АНБ любезно открыла для всех) Дизассемблировать HCS12 она не умеет, но имеет очень удобный и гибкий поиск.

Из сводной таблицы, первым делом, бросаются в глаза байты 0x5A, 0xC9, 0x9A, 0x8D(вторая строка в выделенном сегменте).

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

Скриншот Ghidra с результатами первичного поиска сигнатур
Скриншот Ghidra с результатами первичного поиска сигнатур

Переходим по первому адресу и детально рассматриваем:

Скриншот Ghidra с интересующей нас областью памяти
Скриншот Ghidra с интересующей нас областью памяти

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

Иллюстрация соответствия данных снятых с помощью логического анализатора и найденной области памяти. Отличая первого байта для режимов A1 и M1 рассматриваются ниже
Иллюстрация соответствия данных снятых с помощью логического анализатора и найденной области памяти. Отличая первого байта для режимов A1 и M1 рассматриваются ниже

Т.к. цель заменить отображение A на P, M на D, берем прошивку от более свежей приборки(аппаратно не совместимы, поэтому просто прошить не получится) и ищем сигнатуры P и D в ней.

Иллюстрация удобства поиска в Ghidra. Узнав паттерн, можно использовать его для поиска
Иллюстрация удобства поиска в Ghidra. Узнав паттерн, можно использовать его для поиска

Нашли интересующие адреса - идем смотреть.

Скриншот сигнатур в прошивке современной приборной панели
Скриншот сигнатур в прошивке современной приборной панели

Как видно из скриншота, для P нужно заменить только 01й байт посылки. Для D 01й и 02й.

Сравнение посылок для разных режимов
Сравнение посылок для разных режимов

Патчим прошивку

Патчить будем прямо в srec. Коротко о структуре srec-файла:

Скриншот из Википедии
Скриншот из Википедии

При изменении строки, нужно пересчитать КС строки. Быстрым поиском находим готовый скрип на Питоне(гитхаб автора), проверяем на исходной строке - считает корректно.

Находим в текстовом редакторе интересующие нас байты. Для изменения отображения D, нужно править 2 строки, соответственно и КС нужно пересчитать для двух строк.

Скриншот SREC-файла с отмеченными посылками
Скриншот SREC-файла с отмеченными посылками
Скриншот работы скрипта подсчета КС
Скриншот работы скрипта подсчета КС
Измененные КС
Измененные КС

Далее, прошиваем приборную панель и смотрим результат.

Фото результата(почти удовлетворительного) первичного патчинга
Фото результата(почти удовлетворительного) первичного патчинга

Убираем цифру

Так как режимы M и A в исходной логике сопровождаются отображением текущей передачи (1–5), а при замене на P и D эта цифра становится артефактом, требуется её подавить. Для этого в прошивке ищем сигнатуры, отвечающие за отображение цифр, и зануляем нужную цифру.

По всей видимости, цифра образуется так: 00й байт меняет первый ниббл, к 12му байту с базовым значением 0x80 прибавляется передаваемое значение. В сводной таблице это можно видеть.

Скриншот найденных сигнатур для отображения цифр
Скриншот найденных сигнатур для отображения цифр

Формат такой же, как с самим режимом: номер байта-данные, зануляем данные для отображения 4ки(1,2,3 понадобятся), пересчитываем КС и прошиваемся.

Результат

Результат, который хотели получить, полноценная автоматная индикация, на старой приборной панели.

Фото результата патчинга
Фото результата патчинга

Заключение

Иногда проще смотреть живые данные, с последующим "поиском" в прошивке, нежели анализировать код. В данном кейсе это позволило очень быстро изменить отображение приборной панели без полноценного анализа прошивки. Методика может быть полезна для широкого круга embedded‑систем.

Спасибо за прочтение, надеюсь, кому-нибудь будет полезно)