Как декомпилировать bin прошивку
Приложение для разборки прошивки типа .APP
AppImageMaker.rar ( 6.57 КБ )
Требования:
— Windows 7 и выше;
— установка пакета .NET 4.0.
Для запуска используется командная строка вида:
AppImageMaker [key] [sourceFile] [destPath], где
sourceFile — полный путь и название файла прошивки. Например, d:\app\SR_APP_Update.app
destPath — полный путь к папке назначения, в которую будет произведена распаковка прошивки, например, f:\qwerty
key — ключ для получения дополнительной информации. Он может быть следующим:
/h, /?, —help — выводит справочную информацию о приложении.
Если никакой ключ не введен, то производится распаковка файла прошивки. Для этого должны быть введены имя с полным путем к файлу и путь к папке назначения. При отсутствии эта папка создается сама, а при наличии в нее перезаписываются имеющиеся там файлы.
Например, если команду ввести следующим образом:
AppImageMaker d:\app\SR_APP_Update.app f:\qwerty
то файл SR_APP_Update.app из папки d:\app будет распакован в папку f:\qwerty.
Если не введен путь к конечной папке (папке назначения), то она создается в той же папке, где находится приложение AppImageMaker, с именем «update» по-умолчанию. Например, строка вида:
AppImageMaker d:\app\SR_APP_Update.app
распакует указанный файл в папку с именем update, созданную рядом с приложением AppImageMaker.
Если не указать также путь и имя файла прошивки, то по-умолчанию для прошивки будет использоваться имя «Update.app». Например, если ввести строку вида:
AppImageMaker
то приложение будет искать файл с именем «Update.app» в папке рядом с ним. При наличии такого файла он будет распакован в тут же созданную папку «update».
Для особо любознательных есть еще один ключ «/crc». По нему в папку назначения параллельно с распакованными файлами прошивки будут записываться контрольные суммы этих файлов, найденные в прошивке в заголовках этих файлов, с расширением «.crc».
Приложение для разборки прошивок вида BIN, DZ, KDZ — LGwinTools_v1.03.7z ( 93.78 КБ )
- ОС Windows 7;
- пакет .NET 4.0.
- — распаковывает образы типа BIN1-BIN3, TOT, DZ1-DZ3, KDZ2.
- — собирает кусочные файлы в один;
- — мультиязычный интерфейс.
Приложение для разборки прошивок вида QSB-файл и INB-файл
Требования:
— Windows 7 и выше;
— установка пакета .NET 4.0.
LenovoWinTools_v1.02.7z ( 40.91 КБ )
- Windows 7 и выше;
- установка пакета .NET 4.0.
- /if:in_name (-if:) — имя файла прошивки для разборки, обязательный параметр;
- /ip:in_path (-ip:) — имя папки с файлами прошивки для сборки, обязательный параметр;
- /op:out_path (-op:) — папка выгрузки файлов при разборке или прошивки при сборке, обязательный параметр;
- /di:pack (-di:) — режим работы. При pack — сборка прошивки, при отсутствии ключа разборка (по-умолчанию).
- /h (-h, —help) — вызов справки.
У средства появились последователи, которые выпускают «модифицированные» под свои нужды варианты: And_pda
Примечание. Так как тема посвящена средствам, работающим исключительно под Windows, все посты, рекламирующие обработку Linux-средствами, будут безжалостно удаляться как несоответствующие основной теме и мешающие работе. Это не означает что я противник Linux, но для него существует море других тем.
В теме нет куратора. По вопросам наполнения шапки обращайтесь к модераторам раздела через кнопку под сообщениями, на которые необходимо добавить ссылки.
Сообщение отредактировал derak1129 — 17.09.20, 09:35
Полезная вещь — обратная связь! Причем не только в технике.
После общения с некоторыми пользователями средства RKwinTools я решил выложить инструкцию по прописыванию пути к папке в переменных среды Windows.
Инструкция по добавлению пути в переменные среды Windows
ВНИМАНИЕ. Внесенные изменения начнут действовать без перезагрузки компьютера при следующем вызове командной строки или запуске файлового менеджера.
Итак,
Операционная система Windows XP x86.
На рабочем столе выбираем ярлык «Мой компьютер», кликнув на нем правой кнопкой мыши, вызываем контекстное меню и выбираем в нем команду «Свойства». Откроется окно «Свойства системы».
Выбираем вкладку «Дополнительно».
Внизу слева нажимаем кнопку «Переменные среды». Откроется окно «Переменные среды».
В области «Системные переменные» находим переменную «Path» и, выделив ее, нажимаем на кнопку «Изменить».
В поле «Значение переменной:» в конце дописываем путь к необходимой папке, отделяя его от существующего значения «точкой с запятой». Например, «;D:\Cygwin».
Нажимаем «ОК» для записи пути и последовательно закрываем все открытые окна.
Операционная система Windows 7 x86.
Вариант 1.
По пути «Пуск»->»Компьютер», нажимаем правую кнопку мыши для выбора контекстного меню и выполняем команду «Свойства».
В открывшемся окне «Просмотр основных сведений о Вашем компьютере» выбираем слева пункт меню «Дополнительные параметры системы».
В открывшемся окне»Свойства системы» справа внизу нажимаем кнопку «Переменные среды».
В окне»Переменные среды» в области «Системные переменные» нужно найти и выделить переменную «Path», а затем нажать кнопку «Изменить. «.
В появившемся окне «Изменение системной переменной», в поле «Значение переменной» ДОПИСЫВАЕМ В КОНЕЦ путь к только что установленной папке Cygwin, например такой: «;Е:\Cygwin», ОБЯЗАТЕЛЬНО отделив его от существующего значения «точкой с запятой», и нажимаем кнопку «ОК» для сохранения значения.
Последовательно закрываем все остальные открытые окна, тоже нажимая кнопку «ОК», кроме окна просмотра основных сведений, которое закрывается «крестиком».
Вариант 2.
В любом свободном месте рабочего стола нажимаем правую кнопку мыши для вызова контекстного меню и выбираем команду «Персонализация». В открывшемся окне слева выбираем пункт меню «Панель управления — домашняя страница».
Откроется окно «Панель управления» для проведения настроек параметров Вашего компьютера.
В нем необходимо выбрать настройку «Система» и Вы попадете в окно просмотра основных свойств о Вашем компьютере, т.е. «Окно сведений о системе».
Дальнейшие действия описаны в пункте «Вариант 1».
Сообщение отредактировал vin2809 — 24.01.14, 18:37
Тема открыта нужная.
А может Ваша утилита, разбирать BOOT.img от других андроидов?
У меня Amlogic, процессор Amlogic AML8726-MХ. Попробовал найти, что -то подобное и не нашел.
Что нужно поправить, что-бы распаковать BOOT.img под Amlogic?
Файл img прилагается.
P.S. Каждому ПО требуются средства отладки.
В моем случае тишина (не ошибки, не вывода в лог), — а в ответ тишина.
Просьба подумайте над этим вопросом.
Сообщение отредактировал saunin_victor — 07.05.13, 08:18
Для начала я посмотрю устройство образа, а потом посмотрим, что нужно и можно сделать.
В ныне существующем готовом виде отвечу — НЕТ. не сможет.
А вообще — ничего невозможного нет.
Реверс-инжиниринг прошивки устройства на примере мигающего «носорога». Часть 1
26 апреля 2018 года компания ИНФОРИОН провела конференцию для студентов МГТУ им. Баумана SMARTRHINO-2018. Специально для конференции было подготовлено небольшое устройство на базе микроконтроллера STM32F042.
Этот носорожек стал подопытным главным героем мастер-класса по реверсу прошивки. К сожалению, за время, отведенное на мастер-класс, не представлялось возможным провести полное исследование прошивки, поэтому мы решили восполнить это подробным разбором в формате статьи. Надеемся, информация будет полезна не только участникам конференции, но также всем начинающим кодокопателям.
Первая часть статьи составлена по мотивам проведённого мастер-класса и рассчитана на начинающих — уделяется внимание базовым подходам к реверсу прошивок и особенностям работы с дизассемблером IDA.
Вторая часть немного сложнее, в ней уделяется внимание особенностям работы устройств на базе операционных систем реального времени.
Осторожно, под катом мигающий носорог и его прошивка!
Легенда
Участникам семинара была предложена следующая легенда.
Вам досталось устройство и небольшая инструкция к нему.
Прибор осветительный «Носорог»
Инструкция по эксплуатации
Прибор осветительный «Носорог» предназначен для освещения помещений небольшой площади. Прибор совмещает в себе стильный компактный дизайн, яркие светодиоды с низким потреблением тока и USB-интерфейс для подключения питания.
Устройство оснащено Bluetooth-модулем для удаленного управления. Предоставляются широкие возможности для контроля освещенности, позволяющие задавать оттенок и насыщенность для каждого светодиода в отдельности.
Управление устройством осуществляется через специальное программное обеспечение «Синезубик».
Упомянутого программного обеспечения для управления устройством у вас нет и необходимо написать его с нуля. Помимо этого необходимо удостовериться в безопасности использования данного устройства.
То есть всё, что есть у исследователя — устройство, которое можно включить. Если есть устройство, то можно попытаться получить его прошивку, вычитав её из flash-накопителя микроконтроллера. Этот этап был пропущен для упрощения и ускорения мастер-класса — участники получили готовый образ прошивки в виде бинарного файла rhino_fw42k6.bin (как если бы они получили прошивку, например, из обновлений).
Заинтересованный читатель также может скачать прошивку для самостоятельного исследования.
Мастер-класс проходил в интерактивном режиме – с возможностью спрашивать, предлагать свои пути решения. Для участников было доступно 4 рабочих «Носорога».
Внешний осмотр
Кратко: на этом этапе производится внешний осмотр устройства с целью поиска маркировок, доступных разъемов.
В начале семинара был сделан акцент на то, чтобы сначала внешне изучить устройство, потом уже приступать к реверсу прошивки.
/>
В первую очередь, интересует микроконтроллер, потом периферийные устройства и разъёмы.
Внешний осмотр устройства позволил установить следующее:
-
Микроконтроллер STM32F042 – тут сразу стоит обратиться к документации на микроконтроллер (если такая есть), откуда можно узнать архитектуру, разрядность микроконтроллера и много чего полезного (для нашего случая – 32 разрядный микроконтроллер на архитектуре ARM);
Также было обнаружено, что появились доступные Bluetooth-устройства c именами RHINOCEROS-220x, при подключении к которым в системе создаётся виртуальный COM-порт. Оказалось удобным подключаться к устройству по Bluetooth со смартфона и взаимодействовать через мобильное приложение «Serial Bluetooth Terminal» или аналогичное.
Было установлено, что при отправке в COM-порт произвольного текста устройство возвращает ответ Unknown command .
Начальное исследование прошивки
Кратко: на этом этапе выполняется предварительный анализ прошивки. Просмотр строк. Загрузка прошивки в IDA Pro.
Перед разбором кода прошивки имеет смысл проверить, не упакован ли код. Тут могут быть разные подходы, в простом случае достаточно воспользоваться утилитой strings, чтобы получить строки бинарного файла (приводятся в сокращении):
Строк нашлось много – можно сделать предположение, что прошивка не сжата и не зашифрована. Уже на этом этапе можно обратить внимание на некоторые примечательные строки, например, форматные строки, строки с описанием ошибок и указанием операционной системы (а вы их увидели?). Наличие осмысленных строк, по большому счёту, можно считать половиной успешного реверса.
Что ж, попробуем загрузить прошивку в самый популярный дизассемблер. Будем использовать IDA версии 6.9 для 32-битного кода (так как микроконтроллер 32-разрядный).
При открытии файла прошивки IDA не может автоматически определить архитектуру и точку входа – необходимо ей помочь.
На этом этапе необходимо снова обратиться к документации на микроконтроллер STM32F042x4 STM32F042x6 и посмотреть раздел 5 «Memory mapping»:

В качестве Processor Type выбираем ARM Little endian, ставим галку Manual load, нажимаем OK:

В окне «Do you want to change the processor type» нажимаем Yes, после этого IDA предлагает нам создать сегменты ОЗУ (RAM) и ПЗУ (ROM), ставим галку ROM.
Теперь мы должны указать адрес начала ROM. На схеме нужно смотреть секцию Flash – это адреса 0x08000000 – 0x08008000. Также укажем, что именно в этот же адрес мы хотим загрузить файл прошивки: Loading address = 0x08000000.

В окне «ARM and Thumb mode switching instructions» нажимаем OK.
Далее IDA говорит, что ничего не знает о произвольных двоичных файлах и точку входа – функцию main — вы должны определить самостоятельно. Нажимаем OK.
Загрузка произведена. Можно изучать прошивку.
Откроем окно строк (Shift + F12). Можно обратить внимание на то, что не все строки совпадают с результатами из утилиты strings – IDA распознала не всё, к сожалению. Немного погодя мы ей поможем…
Примечание для начинающих
- Любая программа/прошивка представляет собой набор двоичных данных. IDA Pro может по-разному интерпретировать эти данные исходного файла (представлять данные в виде команд или данных в том или ином формате). При этом тут нет кнопки «Назад» (Ctrl+Z), чтобы отменить выбранное отображение — нужно знать, как переключаться между разными режимами отображения. (Шпаргалка по горячим клавишам IDA Pro)
- Реверс-инженер из кажущегося хаоса двоичных данных восстанавливает логику, структуру и читаемость.
- Строки – важная информация при реверсе! Так как, по сути, среди всего набора двоичных данных являются наиболее просто и быстро воспринимаются человеком. Строки позволяют делать выводы о назначении функций, переменных и блоков кода.
- Именуй просмотренные функции! По умолчанию, IDA даёт функциям имена по их стартовым адресам. При анализе держать в голове эти адреса весьма сложно, гораздо проще пользоваться осмысленными именами. Для того, чтобы поименовать функцию достаточно хотя бы её беглого анализа – это уже будет важным подспорьем для дальнейшего анализа.
- Именуй распознанные переменные! Для того чтобы эффективнее проводить анализ блоков кода и функций, имеет смысл именовать переменные, которые распознала IDA, в соответствии с их назначением (всё, как в лучших практиках программирования).
- Оставляй комментарии, чтобы не забыть важное. По аналогии с программированием, комментарии при реверсе позволяют дополнительно пояснять логику работы программы или отдельных её участков.
- По возможности создавай структуры! IDA в своём арсенале имеет средство работы со структурами, имеет смысл освоить это средство и применять его при необходимости. При наличии структур исследуемый код станет еще проще для восприятия.
Анализ строк
Кратко: Анализ строк может помочь составить примерный план исследования двоичного файла.
Лишь только на основании строк уже можно получить много информации:
- Операционная система – FreeRTOS;
- Наличие форматных строк – скорее всего используются printf-подобные функции, можно будет установить назначение регистров/переменных;
- Названия задач (тасков) – можно предположить назначение этих самых тасков и связанных с ними функций;
- Использование AT-команд – предположительно так строится взаимодействие микроконтроллера и Bluetooth-модуля.
Идентификация стандартных функций
Кратко: на данном этапе необходимо удостовериться, что строки действительно распознались, после чего предстоит идентифицировать некоторые стандартные функции языка C.
После загрузки прошивки и автоматического анализа IDA распознала тела функций (не всех, кстати), но среди имён функций нет ни одного «нормального» (только автоматические имена от IDA), что может быть небольшой сложностью в сравнении с реверсом ELF- или PE-файла.

Таким образом, в ходе исследования нужно определить назначение не только специфических функций конкретной прошивки, но и идентифицировать стандартные C-функции. Может возникнуть разумный вопрос — где гарантия, что такие функции есть в прошивке и что они стандартные? Здесь стоит сказать, что обычно при создании программного обеспечения (в том числе прошивок), в 9 случаях из 10 не заморачиваются созданием своей уникальной libc-библиотеки, а пользуются тем, что уже написано и проверено временем. Именно поэтому в 90% случаев можно выдвигать предположение о наличии стандартных С-функций.
Поскольку Hex-Rays Decompiler умеет превращать ARM-ассемблер в С-код, воспользуемся этой приятной возможностью. Стоит обратить внимание, что наличие декомпилированного листинга не отменяет необходимости понимать ассемблер, тем более, декомпил существует далеко не для всех платформ.
Откроем окно строк в IDA (Shift+F12).

Выберем строку sendMsg error %s, откроем ссылки на эту строку (клавиша X – Xrefs — Cross References) — IDA распознала ссылки на строку, это хорошо:

Однако среди строк, выделенных зелёным в дизассемблере, есть просто байты, выделенные красным. При этом некоторые строки явно распознаны не полностью. Так, например, если установить курсор на адрес 0x080074E6 и нажать клавишу A (потом согласиться с предложением «Directly convert to string?»), то получится строка «No device connected». Таким же образом можно пройтись по всем строко-подобным данным и превратить их в строки (или, например, написать Python-скрипт, который пробежится по указанному диапазону адресов и создаст строки).
Следующее препятствие, которое может возникнуть – нераспознанные ссылки на строки (даже если строка распозналась). Попробуйте пройтись по строкам, нажимая клавишу X. Так, например, в моем случае не найдена ссылка на строку «recvMsg error». Ссылка на объект может быть не найдена по двум очевидным причинам:
- нет кода, который ссылается на текущий объект;
- IDA не распознала ссылку.

Получили одно вхождение:

Перейдём к нему (адрес 0x0800506С ):

Превратим DWORD-число в offset, нажатием клавиши O. Появилась ссылка на строку:

Установим курсор чуть выше — внутри функции sub_8005070 (диапазон 0x08005070-0x08005092 ). Переключимся к декомпилированному листингу нажатием Tab:

Обратим внимание на функцию sub_8006690. Если вернуться к строке «sendMsg error %s», то можно увидеть, что она также передается в функцию sub_8006690. Именно строки с символами форматирования могут привести к предположению о том, что функция sub_8006690 – это стандартный printf. Пусть сейчас на уровне предположения это будет printf (даже если наше предположение окажется неверным, то оно всё равно позволит нам продвинуться в исследовании).
Поставим курсор на имя sub_8006690, нажмём клавишу N, введём новое имя x_printf. Префикс «x_» добавим для удобства (от слова «eXecutable») – так можно будет отличить переименованные нами функции от функций, имена которым дала IDA автоматически.
Можно считать выполненной подготовительную часть, теперь перейдём к анализу таска, отвечающего за обработку Bluetooth-соединения. Выйти на него можно опять же через строки. Во многих окнах IDA можно выполнять поиск по Ctrl+F. Так, можно сразу выбрать строки со словом «bluetooth»:

Bluetooth-таск
Кратко: идентифицировать и проанализировать функцию обработки команд, передающихся по Bluetooth. Необходимо будет создать дополнительный сегмент памяти в IDA.
Строка «Bluetooth task\r\n» не имеет кросс-ссылок — воспользуемся снова двоичным поиском, получим адрес, где она используется – 0x080058A0 , перейдём туда и увидим список частично распознанных ссылок:

Создадим из них полноценные ссылки (проклацав клавишу O, или написав Python-скрипт для IDA).
Возможно, не везде создадутся ссылки (адреса, выделенные зелёным):

Перейдя по ссылкам, выделенным зеленым, увидим, что там не созданы строки. Исправляем — помогаем Иде.
Вернёмся к строке «Bluetooth task\r\n». Теперь в коде по адресу 0x08005556 появилась ссылка на эту строку:

Здесь же видим, что эта строка передается аргументом в уже просмотренную нами функцию x_printf. Не забудем также дать говорящее название текущей функции «sub_8005554», например, «x_bluetooth_task».
Переключимся в декомпил и просмотрим функцию полностью. Обратим внимание на строку 132, где в функцию x_printf передаётся некое число. Если изменить отображение числа с десятичной системы счисления на шестнадцатеричную (клавиша H), то увидим число 0x8007651 , которое очень похоже на адрес.

Уже знакомая ситуация – IDA не распознала ссылку. Помогаем ей, правда, для этого нужно переключиться из декомпила в дизассемблер (клавиша Tab): делаем offset, переходим по нему, создаём строку. Переходим обратно в декомпил, нажимаем F5 (обновить).
Радуемся улучшению кода:

Снова обратим внимание на строку 132. Явно, помимо форматной строки в x_printf должен передаваться еще список аргументов переменной длины (va_list), IDA этого не распознала… Ну вы поняли, да? Поможем ей.
Установим курсор на имя функции x_printf, нажмём Y – откроется окно изменения прототипа объекта. Впишем правильный прототип функции printf:
IDA отобразит аргументы для форматной строки:

Пришло время установить назначение (имена) переменных (снова строки нам помогают):
- x_printf(«recv %s state %d\r\n», v0, v25); — x_printf(«recv %s state %d\r\n», recv_data, state);
- x_printf(«cmd: %s\r\n», v24); — x_printf(«cmd: %s\r\n», cmd);
- x_printf(«addr=%x, size=%x\r\n», v14, v15); — x_printf(«addr=%x, size=%x\r\n», addr, size);
Например, обратим внимание на участок кода:

Переменная v3 сравнивается с числом 3, потом фигурирует сообщение о неправильной длине заголовка. Логично переименовать:
- переменную v3 в header_len;
- функцию sub_80006C8 в x_strlen (можно зайти в эту функцию и проверить наше предположение).

Функция sub_80006B4 используется несколько раз. Внутри она выглядит так:

Теперь обратим внимание на переменные v20000624, v20000344, v20000348 . IDA выделила их красным цветом. Всё потому, что они ссылаются на адреса, которые отсутствуют в текущей базе дизассемблера. Если снова обратиться к документации на микроконтроллер, то можно увидеть, что диапазон адресов 0x20000000-0x20001800 относится к RAM.
Если переменная ссылается на несуществующую область памяти, для нее будут недоступны xref’ы – исследование будет вызывать дискомфорт… Для удобства и производительности имеет смысл создать дополнительный сегмент памяти. Открываем окно сегментов (Shift + F7), добавляем RAM-сегмент:

Обновляем декомпил. Обращаем внимание на переменную unk_20000344:

Очень похоже, что это некий auth_flag (флаг авторизации). Так и запишем, то есть назовем эту переменную. В моем случае кросс-ссылок не нашлось – используем двоичный поиск и создаём ссылки.
Проверка на устройстве
Кратко: проверим отдельные предположения на работающем устройстве
Статический анализ – классная штука, но еще лучше, если есть возможность исследовать код в динамике. Тут тоже простор для творчества, но если не усложнять, то самое простое – подключиться к устройству по Bluetooth, отправить какую-то команду и посмотреть на результат.
Так, например, при отправке строки «ZZZ» устройство ответит строкой ERROR: Wrong header length\r\n , при отправке «MEOW» (эта строка есть в исследуемом коде, передаётся в функцию strcmp) увидим mur-mur (>._.<)\r\n , а при отправке «ZZZZ» — ERROR: Unk cmd . Таким образом, функцию sub_8005234 можно переименовать в x_bluetooth_send.
Составлю список команд, которые возможно поддерживаются устройством, и сразу проверю их. Вот что получилось:
- “ECH1” – возвращает «ОК», включает эхо-режим – команда дублируется отправителю;
- “ECH0” – выключает эхо-режим;
- “MEOW” – возвращает «mur-mur (>._.<)\r\n » — то ли пасхалка, то ли отладочная команда;
- “LED “ — выключает один из ярких светодиодов;
- “UART” – возвращает «ОК»;
- “BLE “ — однократно мигает красным светодиодом;
- “READ” – возвращает «ERROR: Not auth!»
- “WRIT” – возвращает «ERROR: Not auth!»
- “AUTP” – возвращает «ERROR: auth error!»
- “SETP” – возвращает «ERROR: Not auth!»
- “VIP “ — возвращает «Wrong won’t give up!»
- команда состоит минимум из 4 символов;
- есть довольно странные команды, как-то связанные с авторизацией (зачем авторизация на осветительном приборе?).
Улучшение кода. Создание структуры
Кратко: при возможности имеет смысл создавать структуры данных — большое подспорье для анализа.
Идём дальше. Задача минимум для нас – научиться управлять светодиодами.
Эксперимент показал, что с большими светодиодами связана команда «LED » — по крайней мере, она позволила выключить один из четырех больших светодиодов. Посмотрим, что находится в этой ветке:

Здесь можно было бы переименовать переменные, смущают только конструкции вроде
В большинстве случаев переменная v6 является указателем на структуру. Для удобства также создадим эту структуру. Контекстное меню для переменной v6 – выбираем пункт «Create new struct type».
IDA предлагает следующее определение для структуры:

Здесь доверимся автоматике относительно типов полей структуры, но установим читабельные имена, основываясь на данных из форматной строки:
После создания структуры код стал ещё приятнее:

Переменная v6 по ходу дела была переименована в led. Дополнительные переменные v7 и v8 для удобства также были переименованы. Пусть Вас не смущает появление дополнительных переменных – компилятору виднее.
По сведениям из форматной строки можно сделать вывод, что цвет задаётся в формате HSV (Hue, Saturation, Value). Для перевода цвета из RGB можно воспользоваться таблицей.
Про переменную v4 пока сложно что-то сказать наверняка, кроме того, что она является структурой и создается в функции sub_8005298:


Можно предположить, что переменная v4 представляет собой аргументы команды, пришедшие по Bluetooth. Давайте так и назовём:
- v4 — bt_args
- sub_8005298 — x_get_bt_args
При манипулировании именами и типами данных в декомпиле могут пропадать или появляться аргументы функций. В этом случае нужно для таких функций явно указывать их прототип (клавиша Y на заголовке функции). Из-за того, что в ARM’е первые 4 аргумента передаются через регистры, IDA при декомпиле может эти аргументы «терять», в этом случае… спешим на помощь ИДЕ. Если по декомпилу непонятно, какие аргументы передаются в функцию, идём в дизассемблерный листинг и смотрим на регистры R0-R3 – не заносятся ли в них какие-то значения перед обращением к интересуемой функции. Если заносятся, то в 90% случаев – это аргументы функции, и нужно прописать эти аргументы в прототипе.
Команда “LED ”
Кратко: исследование LED-команды, продолжаем переименовывать функции и переменные.
Сделаем еще несколько переименований для удобства восприятия:
- sub_8003B6E – x_create_struct
- sub_800532C – x_get_value_1
- sub_8005338 – x_get_value_2

Переименуем sub_800530C в x_get_value_3. А теперь сравним функции x_get_value_1 и x_get_value_2:

В них используется одна и та же функция x_get_value_3, но с отличающимся вторым аргументом (2 и 4). При этом x_get_value_1 возвращает 1-байтовое число, а x_get_value_2 – 2-байтовое.
Анализируем работу с x_get_value_3:
- работа ведётся со строкой bt_args (или структурой, содержащей строку);
- когда на вход подается число 2, на выходе – число размером 1 байт;
- когда на вход подается число 4, на выходе – число размером 2 байта.
- x_get_value_1 — x_get_byte;
- x_get_value_2 — x_get_word;
- x_get_value_3 — x_unhexlify.
Используется. Функция sub_8005344 выглядит так:

Можно переименовать её в x_get_dword.
Заинтересованный читатель может погрузиться в статический анализ функции x_unhexlify и структуры bt_args — наверняка это будет увлекательно.
На данный момент мы можем сформировать команду для управления светодиодами:

Остаётся вопрос – нужны ли разделители между отдельными полями?
Пользуясь преимуществом наличия устройства, я проверю 2 варианта:
- пробелы в качестве разделителей;
- без разделителей.
- Индекс светодиода (idx) = 0x00;
- Оттенок (hue) = 0x00;
- Насыщенность (saturation) = 0xFF;
- Значение (value) = 0xFF.
Команда без пробелов: «LED 000000FFFF» (пробел после символов «LED» нужен по формату команды) – светодиод зажегся красным цветом.
Таким образом, можно сделать вывод, что параметры команды должны передаваться без пробелов. И здесь же можно выстроить предположение (которое могут подтвердить те товарищи, кто провёл полный статический анализ функции x_unhexlify), что функция x_unhexlify служит для потокового вычитывания информации с указанием размера из некого базового буфера.
- Включить первый светодиод зелёным: «LED 010078FF80»
- Включить второй светодиод синим: «LED 0200F0FFFF»
- Включить третий светодиод фиолетовым: «LED 03012СFF80»

Обратите внимание на адреса 0x08004FF0, 0x08005D40 . Хотела спрятаться! Помогаем Иде – создаём ссылки.
Посмотрим теперь, куда ведут ссылки off_8004FF0 и off_8005D40 :
- функция sub_8004D84 – явно стартовая функция прошивки, так как внутри используется строка «\r\nHardware init done… Starting FreeRTOS\r\n» — переименуем эту функцию в x_main;
- функция sub_8005A08 – в самом начале использует строку «LED task\r\n» — переименуем эту функцию в x_leds_task.
- ближе к концу функции main;
- после получения данных по Bluetooth в x_bluetooth_task;
- в начале цикла функции x_leds_task.
- dword_20000624 — leds_queue;
- sub_8003BD0 — x_queue_recv;
- sub_8003B7C — x_queue_send.


- sub_800501C — x_sendMsg;
- sub_8005044 — x_recvMsg.
На этом мы немного прервёмся, выпьем чай с шоколадкой и продолжим во второй части статьи.
Как декомпилировать bin прошивку

Рисунок 1: Исходные тексты приложений, используемых роутером

Рисунок 2: Общая архитектура системы (загрузка и среда выполнения)
- Аппаратная часть: процессор, флеш-память, RAM и другие компоненты, физически соединенные друг с другом.
- Ядро операционной системы Linux: умеет управлять аппаратной частью. За основу разработчики взяли исходный код ядра, написали драйвера для конкретного устройства и скомпилировались все вместе в единое ядро. Этот компонент управляет памятью, читает и пишет в аппаратные регистры и т. д. В более сложных системах «модули ядра» позволяют отделить драйвера в файловой системе, которые при необходимости подгружаются динамически. В большинстве встроенных систем не требуется подобный уровень гибкости и разработчики встраивают все драйвера внутрь ядра.
- libc (“библиотека С”): Данная библиотека выполняет роль общей обертки для системных вызовов, включая очень популярные функции наподобие printf, malloc или system. Разработчики могут использовать системные вызовы напрямую, но в большинстве случаев намного удобнее пользоваться библиотекой libc. Вместо популярной библиотеки glibc (GNU C library), на нашем устройстве используется версия, оптимизированная для встроенных устройств: uClibc.
- Пользовательские приложения: исполняемые бинарные файлы в папке /bin/ и разделяемые объекты в директории /lib/ (библиотеки, содержащие функции, используемые различными бинарными файлами) включают в себя большую часть высокоуровневой логики. Разделяемые объекты используются для экономии дискового пространства, когда наиболее часто используемые функции хранятся в одном месте.

Рисунок 3: Логи, снятые с UART-порта

Рисунок 4: Строки из лога содержатся в различных компонентах системы
-
: наиболее популярный дизассемблер/отладчик. Богатый набор функций, мультиплатформенность, мощное сообщество, документация, плагины и так далее. Единственный недостаток – цена. Единичная лицензия на версию PRО, которая необходима для дизассемблирования бинарных файлов, заточенных под архитектуру MIPS, стоит свыше 1000 долларов. : дизассемблер с открытым исходным кодом с необычайно продвинутым интерфейсом и комадной строкой. Вокруг Radare2 также сформировалось сильное сообщество исследователей разных мастей. С другой стороны, продвинутость – синоним сложности, что требует серьезных временных затрат на изучение. : дизассемблер с закрытым исходным кодом, но по приемлемой цене (100 долларов за одну лицензию). В целом, находится где-то по середине между IDA и Radare. Эта утилита является относительно новой (выпущена в 2016), но с каждым днем набирает все большую популярность. Поддерживает некоторые архитектуры. К сожалению, MIPS пока не входит в этот список (но поддержка должна появиться вскоре). Кроме того, отсутствуют некоторые функции, которые мне были нужны для исследования бинарных файлов. Лично я планируют вернуться к изучению этого дизассемблера чуть позже.

Рисунок 5: Наглядное отображение кода в дизассемблере
$ file bin/busybox
bin/busybox: ELF 32-bit LSB executable, MIPS, MIPS-II version 1 (SYSV), dynamically linked (uses shared libs), corrupted section header size

Рисунок 6: Выдержка из документации на роутер
-
. : очень простые комбинации базовых инструкций, используемых с целью облегчения разработки/реверс-инжиниринга. : в MIPS отсутствует различия между регистрами, и для процессора не столь важны имена. Альтернативные имена используются для улучшения читаемости кода. В регистрах $a0 — $a3 хранятся аргументы функций. $t0 — $t9 – временные регистры.
/Tech/Reversing/Huawei-HG533_TalkTalk/router_filesystem
$ grep -i -r «restore default success» .
Binary file ./bin/cli matches
Binary file ./bin/equipcmd matches
Binary file ./lib/libcfmapi.so matches

Рисунок 7: Анализ файла /bin/equipcmd в IDA

Рисунок 8: Стандартный WiFi пароль
- На каждом устройстве предварительно настроены разные учетные записи.
- Эти учетные записи могут быть установлены производителем или сгенерированы на устройстве. Из предыдущих частей мы уже знаем, что и SSID и пароль хранятся в зарезервированной области флеш-памяти рядом друг с другом.
- Если эта информация установлена на фабрике, роутеру остается считать эти данные из нужной области памяти.
- Если эта информация генерируется на устройстве и затем сохраняется в памяти, значит, должен существовать алгоритм, который на базе одинаковых входных параметров будет всегда генерировать одинаковые результаты. Если входные параметры – общедоступны (например, MAC адрес), и мы сможем восстановить этот алгоритм, тогда впоследствии мы сможем сгенерировать стандартные пароли для любого роутера, использующего этот алгоритм.
$ grep -r ‘TALKTALK-‘ .
Binary file ./bin/cms matches
Binary file ./bin/nmbd matches
Binary file ./bin/smbd matches

Рисунок 9: Участок функции ATP_WLAN_INIT
- Ищется MAC адрес устройстве, на котором запускается функция:
- mac = BSP_NET_GetBaseMacAddress()
- snprintf(SSID, «TALKTALK-%02x%02x%02x», mac[3], mac[4], mac[5])
- ATP_DBSetPara(SavedRegister3, 0xE8801E09, SSID)

Рисунок 10: Инструкции, выполняемые после формирования и сохранения SSID
Рисунок 11: Пример выполнения команды ping через веб-интерфейс
Рисунок 12: Процедура формирования команды ping
Рисунок 13: Перечень ссылок на функцию system()
Рисунок 14: Попытка инжектировать команды через веб-интерфейс
Рисунок 15: Участок внутри функции main()
Рисунок 16: Пример эксплуатации уязвимости на базе переполнения буфера

Рисунок 18: Результаты декомпиляции в виде высокоуровневого языка
Рисунок 19: Пример описания и объявление функции ATP_DBSetPara внутри исходного кода- При линейная развертке происходит побайтовое чтение. Все, что похоже на функцию, показывается пользователю. Этот метод требует серьезной проработки алгоритма, чтобы снизить количество ошибок.
- При рекурсивном спуске мы ищем все функции, вызываемые из функции main(). Затем находим функции, вызываемые в найденных функциях и далее продолжаем рекурсивное отображение пока не найдем все функции. Этот метод очень надежный, но не отображает функции, на которые нет стандартной/прямой ссылки.

-
Микроконтроллер STM32F042 – тут сразу стоит обратиться к документации на микроконтроллер (если такая есть), откуда можно узнать архитектуру, разрядность микроконтроллера и много чего полезного (для нашего случая – 32 разрядный микроконтроллер на архитектуре ARM);



- Любая программа/прошивка представляет собой набор двоичных данных. IDA Pro может по-разному интерпретировать эти данные исходного файла (представлять данные в виде команд или данных в том или ином формате). При этом тут нет кнопки «Назад» (Ctrl+Z), чтобы отменить выбранное отображение — нужно знать, как переключаться между разными режимами отображения. (Шпаргалка по горячим клавишам IDA Pro)
- Реверс-инженер из кажущегося хаоса двоичных данных восстанавливает логику, структуру и читаемость.
- Строки – важная информация при реверсе! Так как, по сути, среди всего набора двоичных данных являются наиболее просто и быстро воспринимаются человеком. Строки позволяют делать выводы о назначении функций, переменных и блоков кода.
- Именуй просмотренные функции! По умолчанию, IDA даёт функциям имена по их стартовым адресам. При анализе держать в голове эти адреса весьма сложно, гораздо проще пользоваться осмысленными именами. Для того, чтобы поименовать функцию достаточно хотя бы её беглого анализа – это уже будет важным подспорьем для дальнейшего анализа.
- Именуй распознанные переменные! Для того чтобы эффективнее проводить анализ блоков кода и функций, имеет смысл именовать переменные, которые распознала IDA, в соответствии с их назначением (всё, как в лучших практиках программирования).
- Оставляй комментарии, чтобы не забыть важное. По аналогии с программированием, комментарии при реверсе позволяют дополнительно пояснять логику работы программы или отдельных её участков.
- По возможности создавай структуры! IDA в своём арсенале имеет средство работы со структурами, имеет смысл освоить это средство и применять его при необходимости. При наличии структур исследуемый код станет еще проще для восприятия.
- Операционная система – FreeRTOS;
- Наличие форматных строк – скорее всего используются printf-подобные функции, можно будет установить назначение регистров/переменных;
- Названия задач (тасков) – можно предположить назначение этих самых тасков и связанных с ними функций;
- Использование AT-команд – предположительно так строится взаимодействие микроконтроллера и Bluetooth-модуля.



- нет кода, который ссылается на текущий объект;
- IDA не распознала ссылку.






Bluetooth-таск






- x_printf(«recv %s state %d\r\n», v0, v25); — x_printf(«recv %s state %d\r\n», recv_data, state);
- x_printf(«cmd: %s\r\n», v24); — x_printf(«cmd: %s\r\n», cmd);
- x_printf(«addr=%x, size=%x\r\n», v14, v15); — x_printf(«addr=%x, size=%x\r\n», addr, size);

- переменную v3 в header_len;
- функцию sub_80006C8 в x_strlen (можно зайти в эту функцию и проверить наше предположение).




- “ECH1” – возвращает «ОК», включает эхо-режим – команда дублируется отправителю;
- “ECH0” – выключает эхо-режим;
- “MEOW” – возвращает «mur-mur (>._.<)\r\n » — то ли пасхалка, то ли отладочная команда;
- “LED “ — выключает один из ярких светодиодов;
- “UART” – возвращает «ОК»;
- “BLE “ — однократно мигает красным светодиодом;
- “READ” – возвращает «ERROR: Not auth!»
- “WRIT” – возвращает «ERROR: Not auth!»
- “AUTP” – возвращает «ERROR: auth error!»
- “SETP” – возвращает «ERROR: Not auth!»
- “VIP “ — возвращает «Wrong won’t give up!»
- команда состоит минимум из 4 символов;
- есть довольно странные команды, как-то связанные с авторизацией (зачем авторизация на осветительном приборе?).





- v4 — bt_args
- sub_8005298 — x_get_bt_args

- sub_8003B6E – x_create_struct
- sub_800532C – x_get_value_1
- sub_8005338 – x_get_value_2



- работа ведётся со строкой bt_args (или структурой, содержащей строку);
- когда на вход подается число 2, на выходе – число размером 1 байт;
- когда на вход подается число 4, на выходе – число размером 2 байта.
- x_get_value_1 — x_get_byte;
- x_get_value_2 — x_get_word;
- x_get_value_3 — x_unhexlify.


- пробелы в качестве разделителей;
- без разделителей.
- Индекс светодиода (idx) = 0x00;
- Оттенок (hue) = 0x00;
- Насыщенность (saturation) = 0xFF;
- Значение (value) = 0xFF.
- Включить первый светодиод зелёным: «LED 010078FF80»
- Включить второй светодиод синим: «LED 0200F0FFFF»
- Включить третий светодиод фиолетовым: «LED 03012СFF80»

- функция sub_8004D84 – явно стартовая функция прошивки, так как внутри используется строка «\r\nHardware init done… Starting FreeRTOS\r\n» — переименуем эту функцию в x_main;
- функция sub_8005A08 – в самом начале использует строку «LED task\r\n» — переименуем эту функцию в x_leds_task.
- ближе к концу функции main;
- после получения данных по Bluetooth в x_bluetooth_task;
- в начале цикла функции x_leds_task.
- dword_20000624 — leds_queue;
- sub_8003BD0 — x_queue_recv;
- sub_8003B7C — x_queue_send.


- sub_800501C — x_sendMsg;
- sub_8005044 — x_recvMsg.
HexRays – декомпилятор нового поколения: превращаем любой бинарник в C-код
У истоков HexRays
.text:0100318F push ebp
.text:01003190 mov ebp, esp
.text:01003192 push ecx
.text:01003193 push ecx
.text:01003194 lea eax, [ebp+hKey]
.text:01003197 push esi
.text:01003198 xor esi, esi
.text:0100319A push eax ; phkResult
.text:0100319B push 20019h ; samDesired
.text:010031A0 push esi ; ulOptions
.text:010031A1 push offset SubKey ; lpSubKey
.text:010031A6 push 80000000h ; hKey
.text:010031AB call ds:RegOpenKeyExA
.text:010031B1 test eax, eax
.text:010031B3 jnz short loc_10031E7
.text:010031B5 lea eax, [ebp+cbData]
.text:010031B8 mov [ebp+cbData], 104h
.text:010031BF push eax ; lpcbData
.text:010031C0 push [ebp+lpData] ; lpData
.text:010031C3 push esi ; lpType
.text:010031C4 push esi ; lpReserved
.text:010031C5 push offset ValueName ; lpValueName
.text:010031CA push [ebp+hKey] ; hKey
.text:010031CD call ds:RegQueryValueExA
.text:010031D3 test eax, eax
.text:010031D5 jnz short loc_10031DA
.text:010031D7 push 1
.text:010031D9 pop esi
.text:010031DA
.text:010031DA loc_10031DA: ; CODE XREF: sub_100318F+46?j
.text:010031DA push [ebp+hKey] ; hKey
.text:010031DD call ds:RegCloseKey
.text:010031E3 mov eax, esi
.text:010031E5 jmp short loc_10031E9
.text:010031E7
.text:010031E7 loc_10031E7: ; CODE XREF: sub_100318F+24?j
.text:010031E7 xor eax, eax
.text:010031E9
.text:010031E9 loc_10031E9: ; CODE XREF: sub_100318F+56?j
.text:010031E9 pop esi
.text:010031EA leave
.text:010031EB retn 4.text:01002306 loc_1002306: ; CODE XREF: sub_1002239+C4?j
.text:01002306 mov eax, dword_1008028
.text:0100230B push ebx
.text:0100230C push edi
.text:0100230D mov dword_1008BCC, eax
.text:01002312 push dword_10087D0
.text:01002318 call sub_10059A3
.text:0100231D test eax, eax
.text:0100231F jz short loc_1002328
Полную версию статьи
читай в февральском номере Хакера! Демонстрационную версию IDA ты найдешь на нашем диске. К сожалению, мы не можем выложить HexRays по правовым соображениям. На нашем диске будет видеоролик, демонстрирующий возможности HexRays.