Реверс-Инжиниринг Esp8266 — Часть 2

Продолжаем изучение модуля ESP8266. На этот раз мы рассмотрим процесс скачивания прошивки на разборку.

Первая часть статьи Здесь .



Реверс-инжиниринг ESP8266 — Часть 2



Содержание

  1. Введение
  2. Архитектура ESP8266
    • Карта памяти (адресное пространство)
    • Формат прошивки
    • Процесс запуска
  3. Инструменты
  4. Скачать прошивку для исследования
  5. Ассемблер Xtensa
    • Регистры
    • Основные операторы
    • Функции
    • Условные переходы
  6. Заключение
  7. Ссылки


4. Скачать прошивку для исследования

Подготовив необходимые инструменты, мы подошли к самому интересному – скачиванию и разборке прошивки.



ЭЛЬФ
Начнём с самого простого - скачиваем файл app.out - прошивку в формате ELF, созданную с помощью SDK. Обычно файл app.out доступен при наличии исходного кода прошивки, который гораздо проще и логичнее изучить.

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

После компиляции и сборки в папке сборки у нас появится файл app.out, который представляет скомпилированный пользовательский код, данные, библиотеки и отладочную информацию.

В таком виде прошивку невозможно загрузить в модуль, поэтому после сборки ELF-файла SDK конвертирует app.out в один или два файла в папке прошивки — 0x00000.bin и 0x40000.bin, которые можно напрямую прошить.

Открыв app.out в HIEW и посмотрев таблицу сегментов (ввод, F8, F6) мы увидим следующую картину:

Реверс-инжиниринг ESP8266 — Часть 2

Столбец VirtAddr содержит адреса начала сегментов в адресном пространстве Xtensa. Обратите внимание, что три сегмента (.

data, .

rodata и .

bss) будут загружены в область оперативной памяти, сегмент .

text будет записан по адресу пользовательского исполняемого кода, а сегмент .

irom0.text будет записан в область ОЗУ.

Адрес кода библиотеки SDK. Остальные сегменты, имеющие стартовый адрес, равный нулю, содержат служебную информацию и не будут добавлены в прошивку, готовую к загрузке в модуль.

Забегая вперед, скажу, что сегмент .

irom0.text будет скопирован в исходном виде в файл 0x40000, а сегменты .

data, .

rodata, .

bss и .

text будут собраны в файл 0x00000.bin с учетом формат, о котором говорилось выше.

Чтобы загрузить app.out в IDA, вам необходимо сделать следующее: 1. Откройте IDA Pro 6.6 или выше.

2. Нажимаем «Перейти» — файлы пока открывать не будем.

3. Откройте пункт меню Файл – Файл сценария и выберите скрипт определения процессора xtensa.py. 4. Загрузите файл app.out, здесь нужно выбрать тип процессора и нажать «Установить»:

Реверс-инжиниринг ESP8266 — Часть 2

5. В следующих окнах с предупреждением о неизвестном типе машины и предложением скачать отладочную информацию нажмите «Да» 6. В результате мы получим готовый к исследованию файл:

Реверс-инжиниринг ESP8266 — Часть 2

Чего в нем не хватает? Недостаточно системного ПЗУ, содержащего основные функции модуля.

При необходимости вы можете скачать его вручную, что мы и сделаем в следующем разделе.



Прошивка модульной системы
Мы рассмотрели достаточно простую загрузку прошивки в IDA в виде ELF-файла.

Однако на практике часто приходится изучать уже готовые прошивки, извлеченные из флеш-модуля (путем прямого подключения к флэшу) или распространяемые в виде файлов 0x00000.bin и 0x40000.bin. Здесь требуется немного ручной работы.

Начнем с загрузки образа ПЗУ системы.

В первой части я дал связь в архив с файлом 40000000.bin - вот он.

Последовательность действий следующая: 1. Откройте IDA Pro 6.6 или выше.

2. Нажмите «Перейти».

3. Откройте пункт меню Файл – Файл сценария и выберите скрипт определения процессора xtensa.py. 4. Откройте файл 40000000.bin. 5. Выберите тип процессора Tensilica Xtensa [xtensa] и нажмите «Установить».

6. Далее необходимо указать организацию памяти для корректной загрузки бинарного файла.

Здесь мы создаем сегмент кода по адресу 0x40000000 и загружаем в него наш файл:

Реверс-инжиниринг ESP8266 — Часть 2

7. Образ ROM скачан, но его сложно прочитать из-за отсутствия названий функций.

Теперь загрузим скрипт 40000000.idc, который проделает дополнительную работу — определит имена функций и создаст дополнительные сегменты в адресном пространстве: Файл — Файл сценария — 40000000.idc. Вот результат:

Реверс-инжиниринг ESP8266 — Часть 2

На этом загрузку системного ПЗУ можно считать завершенной; можно приступать к его осмотру.

Скрипт определил названия функций системного ПЗУ, теперь можно разобраться, что делает та или иная функция, вызываемая из SDK. А вот, кстати, функция копирования кастомной прошивки с флешки в память SoC:

Реверс-инжиниринг ESP8266 — Часть 2

В SDK такой функции нет, поэтому я дал ей произвольное имя.

Но прошивка не является полной без загрузки пользовательской части - файлов 0x00000.bin и 0x40000.bin. Поэтому мы загрузим эти файлы в ПЗУ системы.



Кастомная прошивка
Мы загрузили системное ПЗУ модуля в IDA, и скрипт подготовил нам несколько сегментов для загрузки остальных частей.

Начнем с простого — загрузки кода библиотеки.

Как я уже говорил выше, файл прошивки 0x40000.bin представляет собой образ сегмента кода без какой-либо служебной информации и напрямую отображается в адресное пространство процессора по адресу 0x40240000. Чтобы загрузить его в IDA, сделайте следующее: 1. Убеждаемся, что у нас открыта база данных 40000000.bin и скрипт 40000000.idc создал дополнительные сегменты: RAM, ROM, IRAM, IROM 2. В меню выбрать Файл – Загрузить файл – Дополнительный бинарный файл, открыть файл прошивки 40000.bin. 3. В следующем окне выберите параметры загрузки.

Обратите внимание, что загрузка производится по смещению по пунктам, т.е.

вместо адреса мы указываем значение в 10h раз меньшее (последний ноль отбрасываем).

Вы можете снять флажок создания сегмента; мы уже создали его:

Реверс-инжиниринг ESP8266 — Часть 2

4. Файл скачивается.

После указания начала кода (в данном случае это 4024000Ch) получаем примерно следующую картинку:

Реверс-инжиниринг ESP8266 — Часть 2

В отличие от ELF-файла, здесь не будут определены имена функций и переменных, но с этим ничего не поделаешь.

Небольшое лирическое отступление Как проверить голый ассемблерный код? Как понять, что делает та или иная функция? Для многих известных SDK IDA имеет подписи FLIRT, определяющие имена стандартных функций.

В нашем случае это не поможет, так как IDA не знает этого SDK. Поэтому эту работу придется выполнять вручную.

В качестве примера приведем несколько способов в порядке возрастания сложности: 1. Найти сигнатуру изучаемой функции в дизассемблере ELF-файла, скомпилированного той же версией SDK. Есть вероятность, что вы его найдете, и у него будет имя (из отладочной информации).

Для этого я и рассмотрел возможность загрузки прошивки в ELF. 2. Известные константы — функция может ссылаться на текстовые строки или двоичные данные.

С опытом вы запоминаете многие из этих констант наизусть; если константа незнакома, мы гуглим ее.

Вот пример:

Реверс-инжиниринг ESP8266 — Часть 2

Мы видим две замечательные константы.

Первая ссылка, которую дает Google, — это описание алгоритма strlen, использующего эти константы:

Реверс-инжиниринг ESP8266 — Часть 2

Сравнив реализации алгоритма, можно с уверенностью сказать, что функция strlen находится по адресу 40100E70h. Или этот фрагмент кода сразу выдает функцию деления:

Реверс-инжиниринг ESP8266 — Часть 2

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

Иногда можно определить, что это «локальная» реализация знакомого алгоритма, а иногда нет. В любом случае навык понимания ассемблерного кода приходит с опытом, так что дерзайте! Теперь перейдем к загрузке файла 00000.bin. Мы помним, что это не просто изображение, а файл со структурой, описывающей данные и сегменты кода.

Вот как это может выглядеть в шестнадцатеричном формате:

Реверс-инжиниринг ESP8266 — Часть 2

Сначала идут 8 байт общего заголовка прошивки, определяющего количество сегментов и точку входа.

Затем идут сами сегменты, которые также имеют 8-байтовые заголовки с адресом и длиной.

Чтобы правильно загрузить их в IDA, я разрезал данные каждого сегмента (без заголовков) на отдельные файлы, назвав их по адресу загрузки:

Реверс-инжиниринг ESP8266 — Часть 2

Теперь осталось только загрузить их в IDA. Для каждого файла выполняем последовательность действий, аналогичную загрузке системного ПЗУ: 1. Файл – Загрузить файл – Дополнительный двоичный файл, выберите файл данных.

2. В параметрах загрузки указываем сегмент (по имени файла без последнего нуля), сегмент не создаём.

Всё, теперь прошивка у нас полностью загружена и готова к тестированию!

Реверс-инжиниринг ESP8266 — Часть 2

В этой части статьи мы рассмотрели процедуры загрузки различных типов прошивок ESP8266 для дизассемблирования в IDA Pro. В заключительной части мы рассмотрим особенности процессора Xtensa, отличия от архитектуры x86, набор регистров и команд. Теги: #ESP8266 #обратное проектирование #diy #iot #обратное проектирование

Вместе с данным постом часто просматривают: