Открыть список
Как стать автором
Обновить

Реверс embedded: трассировка кода через SPI-flash

Блог компании НТЦ ВулканИнформационная безопасностьРеверс-инжинирингПрограммирование микроконтроллеровПроизводство и разработка электроники
Всего голосов 22: ↑22 и ↓0 +22
Просмотры3.6KКомментарии 16

Комментарии 16

Самые «укуренные способы дебага»:
Третье место(третье только потому, что это один из стандартных способов отладки):
Coreboot и его портирование. Когда я пытался добавить(в итоге не получилось — спалил) материнскую плату в этот проект у меня возникла проблема — исполнение не доходило даже до инициализации памяти, зависая где-то ещё на использовании кеша процессора в роли оперативки. При этом SIO полноценно не поднимался, что исключало вывод отладки в COM порт, с отладкой через USB тоже что-то не получилось(толи чипсет в неё не умел, толи у меня слишком мал радиус кривизны рук был). В итоге был применён speaker modem: отладочные сообщения кодировались в сигналы спикера, рядом с ним лежал микрофон, который подключался к другому ПК, на котором уже был запущен декодер этого самого speaker modem-а. Скорость была бесподобной — что-то около 150 бод, но на безрыбье…

Второе место: опять Coreboot, плата другая, но всё весело — в определённом режиме почему-то нормально не работают все прерывания, надо снять дампы того, как настроился чипсет, что выдаёт линуксовое ядро. Но тут возникает проблема — дальше initramfs никуда прогрузиться не получается (т.к. прерывания не работают, sata/usb при этом тоже не работает). Ну ладно, можно с тем минимумом, что нам это даёт получить нужную информацию, да и свой образ собрать. Возникает вопрос: а как это передать, сохранить на флешку/диск — не выходит, COM порт почему-то не работает, сетевая карта… ну тоже тамже. В итоге опытным путём выяснилось, что остался живым NVMe диск т.к. та модель работала через PME прерывания, чтож, cat cool_log.txt>/dev/nvme0n0p1. На IRC канале в тот момент у нас уже шли обсуждения вида «Так, а давайте сейчас в коде инициализации памяти не будем занулять воон тот кусок памяти, загрузимся в битый режим, сделаем вывод в /dev/kmem на этот кусок, потом в нормальном режиме прочитаем.»

Первое место: полностью переделываю прошивку платы, разработчик которой постарался сделать максимально непригодное решение для отладки — подцепиться некуда, UART/SPI/I2C и прочее — отсутствует, плюс от слова «паяльник» у всех инфаркт случается. Зато есть светодиод статуса… азбука Морзе, пришло твоё время!

светодиод прекрасно превращается в софтварный уарт ;)

Только если:
1) К нему можно подпаяться/подоткнуться щупом (тут был облом — паяльник ни-ни, шуп нужен был совсем миниатюрный.
2) Он подключен по нормальной схеме (тут был конденсатор зачем-то в параллель) — иначе прощай хоть что-то выше 2400.
=) снаружи подвешивается фотодиод или оптрон — оптрон заводится в уарт =)
конденсатор выкусывается и 115200, ну или хотя бы 19200 =)
по идее ничего паять не нужно =)
ps: сам раньше светодиоддебагингом занимался, пока не стал даже на 8 ножечных контроллерах любой вывод заводить в уарт… стало на порядок все проще
От кусачек там тоже инсульт бы случился у заказчика, а с ним там блин фронты такие, что морзянка на уровне только пришедшего школьника в ДОСААФ была.

Пожалуй самый ненормальный способ вывода данных из устройства в моей практике: несколько байт кода запускались в полностью неизвестном окружении, можно было либо вернуться в вызывающий код (который продолжит отвечать на команды), либо устроить fault, приводящий к перезагрузке устройства (на счастье очень быстрой) и видимому снаружи переподключению USB — ну чем не способ вывода одного бита? Автоматизируем (в цикле патчим шеллкод на «отправку» очередного бита, загружаем, проверяем переподключение/продолжение, всё по новой), запускаем, узнаём (из LR, это был ARM) из каких адресов нас вызывают. Дальше задаём «чтение» куска вызывающего кода и ложимся спать. Наутро смотрим в результат, узнаём адрес функции отправки по USB и через неё уже «лихо» читаем всё остальное.

офигеть, єто просто жесть какая-то)
Это было Bare Metal? Или линуксовое окружение?
Bare metal, BootROM. Ждать загрузки ОС после каждого перезагружающего шага было бы уже слишком.
А можно узнать как вы выполняли удаленный код? Это какая-то уязвимость была?
Интересно приходилось ли уважаемому автору находить способы подмены подписанного кода (подпись SHA256+RSA2048, ключ для зашифровки конечно же неизвестен), при том что подпись проверяется масочным кодом, а JTAG заблокирован аппаратно?
Есть ли какие-то трюки обхода такой защиты?
Под описанную схему попадают например почти все современные смартфоны (не считая «чайнафонов», в которых просто не тратят время на включение secure boot), никаких общих решений нет (иначе уже бы все их взломали и трубили об этом). Из общего: достать новый «пустой» процессор, слить из него тот mask ROM, изучать на предмет уязвимостей.
Из общего: достать новый «пустой» процессор, слить из него тот mask ROM, изучать на предмет уязвимостей.

будем считать, что изучение закончилось ничем.
меня бы интересовали нестандартные методы: «полуресеты» МК; использование особенностей кеширования памяти(ядро АРМ) для подмены содержимого в кеше, оставляя некешированные данные неизменными; какие-то комбинации на входе GPIO приводящие к нестандартному поведению МК; слепки DDR памяти и прочие хитропопости.
ключ для зашифровки конечно же неизвестен
Не всегда стоит быть таким категоричным. Например, LG выкладывала ключи для подписания прошивок для своих ТВ (они же подходили для подписания прошивок на тех же процессорах ТВ других фирм, таких как HiSense) у себя на сайте opensource.lge.com
Не всегда стоит быть таким категоричным.

не мы такие, жизнь такая :)
Ключ живет на сервере производителя вари и сервер не покидает
У меня был забавный проект — подводный робот для чистки бассейнов.
На борту был процессор и датчики. Питание подавалось с берега по кабелю. Процессор имел полноценный JTAG для отладки, беда только в том, что JTAG кабель был коротковат — 20 см, а мне нужно было 20 метров.
Вобщем, оказалось что JTAG можно сильно удлинить ценой снижения скорости. Я не помню сейчас точно на какой частоте клока я остановился — что-то около 300КГц.
Для передачи JTAG сигналов на 20 метров был использован LVDS интерфейс и обычный Ethernet CAT5 кабель. Кабель, естественно, не был предназначен для воды и его приходилось менять раз в месяц, но это небыло самой большой проблемой этого проекта.

Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

Информация

Дата основания
Местоположение
Россия
Сайт
ntc-vulkan.ru
Численность
101–200 человек
Дата регистрации

Блог на Хабре