Сегодня мы поговорим о реверс-инжиниринге, но не о реверсе софта, а о реверсинге железа. Как следует из термина, реверс-инжиниринг (обратная разработка) - это процесс разборки спроектированного продукта или устройства на его элементарные инженерные компоненты. Мотивация для такого действия может быть различной: от конкурентного анализа и выявления нарушений патентных прав до восстановления дизайна проекта, исходный код которого утерян. Тем не менее, все они включают в себя необходимость или желание понять, как был создан продукт или устройство. Слово “как” здесь используется в самом широком смысле, включая вопросы о том, “что было использовано для его создания”, “где находится каждый элемент”, “когда происходят определенные события” и т.д.
Реверс-инжиниринг в мире электроники может принимать самые разные формы: от программного обеспечения до аппаратного обеспечения, от "черного ящика" до интрузивного использования. Реверс-инжиниринг аппаратного обеспечения может быть таким же простым, как разборка изделия для идентификации внутренних компонентов и схем платы, или таким же сложным, как извлечение полупроводниковых схем и тестирование на месте.
Говоря о реверсинге электроники можно к приведенному выше списку мотивов добавить также необходимость исследования готового устройства с целью производства аналогичного (очень актуальная тема в последние два года), а также реверсинг устройств для решения различных вопросов информационной безопасности. В частности, нам может потребоваться отреверсить подозрительное шпионское устройство, найденное в офисе. Конечно, устройства, подложенные специалистами из серьезных организаций вряд ли позволят себя, так просто, не то что отреверсить, а просто извлечь, так как они просто самоуничтожатся. Но если нам все-таки удалось разобрать такое устройство, нам будет очень интересно попытаться узнать, что оно делает. А для этого нам необходимо прочитать прошивку с имеющихся микросхем.
Конечно, на многих устройствах есть порты на плате для подключения по серийному порту и выполнения отладки. Однако, мы будем рассматривать ситуацию, когда считать прошивку можно только с микроконтроллера или микросхемы напрямую. На помощь отладочных портов на плате рассчитывать не приходится.
Знакомимся с паяльным феном
Для того, чтобы прочитать прошивку с микросхемы нам, очевидно, необходимо физически к ней подключиться. В зависимости от форм-фактора можно попробовать подцепиться к микросхеме непосредственно на выключенной плате при помощи специальных щипцов с контактами.
Такие щипцы подключаются к микросхеме и к программатору, с помощью которого можно считать прошивку. Однако, на практике у меня так и не получилось с помощью подобного девайса прочитать прошивку.
И в таком случае остается только самый хардкорный вариант – выпаивание микросхемы из платы. Конечно, это вариант требует некоторой подготовки. Опять-таки, в зависимости от форм-фактора микросхемы можно попытаться ее выпаять с помощью обычного паяльника. Однако, подогреть несколько ножек не так просто, поэтому лучше прибегнуть к помощи специального девайса под названием паяльный фен. Аккуратно придерживая микросхему пинцетом, подогреваем ее струей горячего воздуха, при этом стараясь не сильно задевать другие детали, до тех пор, пока не удастся отделить микросхему от платы.
Полученной детали даем немного остыть и помещаем в программатор, например в вот такой MiniPro:
Немного офтопа:
Как-то мне нужно было залить прошивку OpenWRT на дешевый роутер, но из-за неправильного выбора прошивки я что называется “окирпичил” железку. Из всех способов лечения, предлагаемых в Интернете, ничего не помогло. В частности, попытки подключения к плате по отладочному порту завершилась неудачей. Для того, чтобы все-таки попробовать оживить устройство нужно было выпаять модуль внешней энергонезависимой памяти (EEPROM) и перепрошить его. Для решения этих задач мне и пригодился паяльный фен и программатор. В итоге я перепрошил модуль памяти и устройство ожило под новой прошивкой. Так что не стоит считать процесс выпаивания микросхемы с платы сверхсложной задачей.
Итак, мы добыли трофей, что делать дальше?
Методы защиты
Конечно, существуют различные методы защиты прошивок от считывания и для рассматриваемых нами далее микроконтроллеров ATMega имеются специальные защитные (FUSE) биты.
Фьюзы в микроконтроллерах семейства AVR представляют собой специальные биты конфигурации (переключатели), изменяя которые (то есть устанавливая в них 0 или 1) мы можем изменять некоторые режимы работы микроконтроллера или использовать какие-либо его специальные возможности, которые недоступны в его конфигурации "по умолчанию".
Не будем подробно погружаться в эту тематику, так как на эту тему есть масса других публикаций. Будем считать что авторы устройства не озаботились защитой микроконтроллера от считывания прошивки. Например, использовали среду Arduino IDE с настройками по умолчанию, загрузчик bootloader, также с настройками по умолчанию.
В таком случае мы можем с помощью MiniPro или другого программатора считать прошивку с нашей выпаянной микросхемы, точнее микроконтроллера, в случае с Arduino.
Но на выходе мы получим просто HEX-файл. Преобразовать код обратно в язык высокого уровня у нас не получится. Здесь можно провести аналогию с EXE файлами, которые также в общем случае (не рассматриваем .NET и аналогичное) нельзя обратно превратить в высокоуровневый код.
Реверсим прошивку
Для того, чтобы превратить набор кода в нечто человеко-понятное (ну если Ассемблер можно считать человеко-понятным языком) нам потребуется… правильно, дизассемблер IDA Pro. Бесплатная IDA Free здесь нам не поможет, так что попробуйте где-нибудь “купить” версию Pro.
В интерфейсе IDA выбираем Binary file и далее в списке нужное семейство процессоров или микроконтроллеров.
Получаем что-то подобное:
Далее для правильной организации представления кода указываем создание ROM Section, начиная с нулевого адреса:
На следующем шаге IDA предлагает нам выбрать точную модель нашего “камня”:
В итоге мы получим нечто похожее на представленное на следующем рисунке:
Далее мы видим набор ассемблерных инструкций, сгруппированных в процедуры. Даже не слишком искушенному в реверсинге читателю видно, что инструкции ассемблера и регистры здесь немного другие и отличаются от уже знакомых нам инструкций Intel.
Мы не будем погружаться в дебри Ассемблера Atmel, так как на эту тему тоже есть много довольно интересных публикаций. И кроме того, возможно вам придется иметь дело с PIC, STM или Миландром и у этих МК будет совсем другой набор ассемблерных инструкций.
Заключение
В этой статье мы поговорили о том, как можно считать прошивку с микроконтроллера и как затем можно преобразовать ее в ассемблерный код. Конечно, эта задача не всегда решается столь просто, однако базовые моменты мы рассмотрели.
Больше практических кейсов вы можете узнать на наших курсах по информационной безопасности. Подробнее в каталоге.
Комментарии (13)
datacompboy
26.04.2024 13:44+14Ладно, материал можно пометить "детско дошкольный" по сложности, я еще могу понять.
Но, Господи, за что такие шакалы?!
Kill_Voice
26.04.2024 13:44+2Как нарисовать сову, вначале нарисовать куржочки, а потом нарисовать «остатки совы»
GennPen
26.04.2024 13:44+3Однако, на практике у меня так и не получилось с помощью подобного девайса прочитать прошивку.
Может быть, потому что такая "прищепка" предназначена для считывания с Flash/EEPROM памяти, а не с контроллера? И даже с запаянной Flash/EEPROM она может не считать данные, в зависимости от примененной схемотехники.
Для того, чтобы все-таки попробовать оживить устройство нужно было выпаять модуль внешней энергонезависимой памяти (EEPROM) и перепрошить его.
В EEPROM не хранится прошивка, особенно таких объемов как OpenWRT.
Ramzez
26.04.2024 13:44+1Я писал под AVR и STM на Си средние проекты, пока работал разработчиком встраиваемых систем. Но уже давно не работаю.
Однажды я очень хотел сделать чиптюнинг для ЭБУ своего старого опеля 78 года.
Считал прошивку, получил ассемблерный код... Я думал, ну возможно там хоть что то понятно будет. Но я не понял ничего)) не знал даже откуда начать копать. Там просто миллиарды процедур по несколько команд, Все обезличено. Как это все связать воедино - не понимал. Так и бросил.
Хотел найти таблицу, по которой пересчитывается датчик массового расхода воздуха, что бы он работал с современным.
Что нужно начать читать, что бы понять, как это сделать? Может преобразовать как то ассемблер в Си ?)) Если кто то подскажет, буду рад )) А то гештальт не закрытnafikovr
26.04.2024 13:44+1я больше скажу. даже имея си код таких девайсов как ЭБУ не всегда получается понять что они имели в виду и почему это работает...
0xdead926e
26.04.2024 13:44ghidra, если она может в архитектуру проца из того ЭБУ. если нет- проще дизассемблировать всю прошивку целиком и погрепать по доступу к конкретным ногам/периферии/адресам и доползти оттуда до нужной таблицы. ну или поэмулировать-потрассировать. иногда бывает быстрее. особенно если прошивка действительно большая, а не 64 килобайта.
Ramzez
26.04.2024 13:44я пытался плясать от периферии, но видимо не слишком усердно. а ассемблер меня просто вогнал в уныние. нашел где ноги дергаются, но через пару переходов из процедуры в процедуру уже перестаешь понимать, что тут вообще происходит. скорее всего еще знаний жестко не хватило.
спасибо за гидру, я почитаю про нее!
только что в голову пришло. возможно здесь есть нужный человек? может быть кто то за вознаграждение готов для меня раскопать эту таблицу? напишите пожалуйста)
dec123
26.04.2024 13:44следующие статьи будут про протоколы подключения к MCU? про глитч надеюсь тоже будет материал?
unreal_undead2
26.04.2024 13:44+1но не о реверсе софта, а о реверсинге железа
Прошивка это всё таки софт. Ревёрс железа - это скорее отревёрсить набор команд незнакомого процессора/микроконтроллера.
divanus
Вы серьёзно? )