38,4
рейтинг
7 февраля 2014 в 05:51

Разработка → Модификация UEFI BIOS, часть первая: знакомство с UEFITool tutorial

Прикрываясь полумифическими «безопасностью» и «защитой простого пользователя от буткитов» производители UEFI все сильнее закручивают гайки с каждым новым поколением своих продуктов. При этом поддержка предыдущих поколений быстро сходит на нет, и их пользователям ничего не остается, кроме как брать эту самую поддержку в свои руки. Конечно, при отсутствии исходного кода вносить какие-то изменения довольно сложно, но и без него можно сделать многое.
В своих предыдущих статьях об UEFI я планировал описать различные полезные модификации, которые помогают преодолеть некоторые заложенные производителями ограничения, но тогда до них руки не дошли, зато теперь — самое время.
В первой части этой статьи я опишу работу с написанным мной инструментом для модификации образов UEFI, а вторая будет посвящена самим модификациям.


Вступление, отказ от ответственности


Прошивка UEFI BIOS на современных платах, несмотря на наличие различных технологий вроде USB BIOS Flashback, Dual BIOS, Flash Recovery и т.п. — все равно лотерея. Прошивка же модифицированных образов — лотерея вдвойне.
Именно поэтому я прошу до начала любых экспериментов с прошивкой сделать при помощи аппаратного SPI-программатора полный дамп содержимого микросхемы, иначе восстановление после неудачной прошивки (а она рано или поздно случится) будет долгим, дорогим и болезненным.
SPI-программатор в данный момент может быть собран в домашних условиях из чего угодно, от пары резисторов и конденсаторов (SPIPGM) до Arduino или Raspberry Pi. Мой вариант дешевого и быстрого SPI-программатора описан здесь. Любителям вытравить пару-тройку плат советую обратить внимание на этот проект, а почитателям устройств «все-в-одном» — на этот.
Далее по тексту я полагаю, что у вас есть программатор, возможность восстановления после сбоя прошивки и готовность к экспериментам. Безумству храбрых, конечно, тоже можно петь песни, но не говорите потом, что я не предупреждал.
Традиционно, все, что вы тут сейчас прочитаете, написано в образовательных целях, автор не несет ответственности за возможную порчу вашего оборудования, недополученную прибыль, потерю времени и веры в человечество, вы пользуетесь предоставленным софтом на свой страх и риск и так далее.

UEFITool


Устав от ограничений существующих утилит для работы с образами UEFI (ну и пораженный синдромом NIH в самое сердце), я написал кроссплатформенную утилиту с открытым исходным кодом — UEFITool.
Это редактор образов UEFI, написан на C++\Qt, распространяется под лицензией BSD, готовые сборки выкладываются сюда.
Проект находится в активной разработке, поэтому код не блещет красотой и баги нет-нет, да попадаются. Если вдруг наткнетесь — буду рад репортам.
Для нормальной работы с утилитой стоит прочитать предыдущие статьи о структуре образа UEFI, иначе непонятно будет, что вообще происходит, но я постараюсь все же пояснить некоторые моменты. Будем считать, что это заготовка для будущей документации.
В качестве примеров в обеих частях статьи я буду использовать полные дампы с Zotac Z77-ITX WiFi (AMI Aptio4) и Dell Vostro 3360 (Phoenix SCT 2.3). К сожалению, у меня нет тестового стенда на платформе Insyde H2O, поэтому рассказать о ней мне нечего. Возможно, Falseclock знает о них немного больше.
С точки зрения UEFITool'а разницы между образами UEFI разных производителей практически нет, поэтому я остановлюсь на ней при описании патчей.
Итак, запускаем UEFITool, открываем образ (Ctrl+O) и видим примерно такое:

В левой части окна отображается структура открытого образа в виде дерева, справа — информация о выбранном элементе дерева, снизу — сообщения, указывающие на ошибки в формате файла, в данном случае — использование разработчиками Phoenix секций с типом 0xF0, назначение которых не описано в спецификации UEFI PI. Двойной щелчок по сообщению раскроет дерево так, чтобы был виден либо на сам элемент, который это сообщение вызвал, либо его родительский элемент. В это же окно выводятся результаты поиска, который можно вызвать нажатием Ctrl+F (оба варианта одной картинкой):

Здесь следует немного пояснить терминологию. Практически все структурные элементы в образе UEFI имеют заголовок, в котором хранятся служебные данные вроде GUID, атрибутов, контрольных сумм и т.п., и тело — в нем хранятся собственно данные. Текст же в заголовках не хранится, поэтому для него такой выбор не нужен.
На первом уровне дерева находятся Flash-регионы, в данном случае это Descriptor, ME и BIOS:

При выборе региона Descriptor можно узнать настройки доступа к регионам, в данном случае доступ полный, но такие настройки встречаются очень редко. Intel рекомендует производителям оборудования закрывать доступ к региону МЕ на чтение/запись и региону Descriptor на запись, именно поэтому на большинстве плат встроенными средствами полный дамп снять без «танцев с бубном» практически невозможно. При выборе региона ME можно узнать версию ME firmware, если же она не отображается — это не к добру и такой образ лучше не шить.
Перейдем еще на уровень ниже, к содержимому региона BIOS:

На этом уровне могут встречаться два типа элементов: тома и свободное место. Свободное в данном случае — не обязательно пустое, к примеру, в этом образе в самом начале Padding'а хранится прошивка EC.
Тома делятся на обыкновенные (формат файловой системы известен), загрузочные (формат ФС известен, содержат Security Core, изменять стоит с особой осторожностью) и неизвестные (либо неизвестен формат ФС, либо разбор еще не реализован). В нашем случае первый том после свободного пространства в начале — обычный, затем два неизвестных (на самом деле, в первом хранится NVRAM, а во втором — ключи и БД для SecureBoot, но программе я это пока еще не объяснил), последний том является загрузочным.
Откроем теперь обычный том, в данном случае в нем хранятся файлы, загружаемые в фазе DXE.

Такая структура (основной том внутри сжатой секции) используется довольно часто, она позволяет сэкономить приличное количество места в микросхеме. Есть еще вариант сжимать не весь том целиком, а каждый файл по отдельности — это несколько менее экономно в плане места, зато стартует такой UEFI BIOS быстрее, т.к. нет смысла распаковывать файлы, к которым не было обращений.
Теперь заглянем внутрь файла:

Все данные в нем хранятся внутри GUID-defined-секции (в заголовке таких секций обычно хранится ЭЦП или контрольная сумма, в данном случае — 4 байта, похожие на КС, которую, однако, никто не проверяет), и делятся на 4 секции: образ PE32 — собственно исполняемый файл в формате PE/COFF, секция зависимостей DXE — определяет порядок загрузки DXE-драйверов, секция UI — в ней хранится текст «SystemCapsuleRt.efi» в формате Unicode и неизвестная секция типа 0xF0 (скорее всего, её содержимое каким-то образом связано с вышеупомянутой КС).
Все это хорошо, конечно, но редактирования пока не видно. Не беда, вызываем для любого элемента контекстное меню, в котором видно, что с этим элементом можно сделать.

А сделать можно следующее:
  • сохранить элемент в файл либо целиком (Extract as is), либо только данные, без заголовков (Extract body)
  • пересобрать элемент (Rebuild), в этом случае при сохранении измененного образа для него (и всех его родительских элементов) будут пересчитаны размеры, контрольные суммы, исправлено выравнивание, т.е. структура образа будет приведена в соответствие со спецификацией UEFI PI
  • вставить элемент из файла, либо перед выбранным (Insert before), либо после (Insert after), либо внутрь него (Insert into, в данном случае внутрь PE32-секции ничего вставить не получится)
  • заменить элемент на другой элемент из файла, либо целиком (Replace as is), либо только его тело (Replace body)

Последнее действие является наиболее полезным, т.к. позволяет произвести модификацию какой-либо части UEFI, не затрагивая при этом структуры всего образа.

Пример использования


Рассмотрим в качестве примера полезную для пользователей MacOS X на ПК модификацию: обход установки бита LOCK (0x0F) в регистре MSR_PMG_CST_CONFIG_CONTROL (0xE2). Бит этот устанавливается DXE-драйвером PowerManagement, чтобы ОС не могла управлять множителем CPU путем записи в этот регистр. Для Windows и Linux это не большая проблема, а вот MacOS X не может стерпеть от UEFI такой наглости. Можно, конечно, пропатчить драйвер AICPM.kext (в 10.8) или ядро (в 10.9), но лучше пропатчить DXE-драйвер и не бояться, что очередное автоматическое обновление сломает загрузку. Патч этот нужен только системам на базе процессоров Intel SandyBridge, IvyBridge и Haswell и их *-E вариантов и делается так:
  1. Открываем свой дамп в UEFITool, очищаем Messages нажатием Ctrl+Backspace, чтобы не мешали
  2. Открываем поиск, выбираем Hex-pattern, Body only, ищем строку «75080FBAE80F»
  3. Делаем двойной щелчок на сообщении о том, что строка найдена, сохраняем тело указанного элемента в файл
  4. Исправляем в Hex-редакторе «75080FBAE80F» на «EB080FBAE80F» (JE становится JMP), сохраняем изменения
  5. Заменяем содержимое выбранного элемента на измененное, старый элемент будет помечен на удаление (Remove), новый — на замену (Replace), все родительские элементы до корня — на перестроение (Rebuild)

  6. Сохраняем измененный образ (Ctrl+S), если сохранение прошло успешно, будет выдан запрос на открытие только что сохраненного образа, если нет — сообщение об ошибке

Прошиваем полученный образ тем же SPI-программатором, которым он был сделан, и получаем отсутствие паники ядра при загрузке MacOS X.

Подробности, другие модификации, заключение


Если вам интересно, откуда взялся магический паттерн «75080FBAE80F» и на какие еще патчи стоит обратить внимание — читайте вторую часть этой статьи, которая будет опубликована немного позже. В ней я постараюсь подготовить побольше примеров в формате «что за модификация, зачем нужна, как сделать, кем и как была найдена», не углубляясь каждый раз в то, как именно вынуть подлежащий модификации элемент и как вставить его обратно.
Надеюсь, что статья не показалась слишком скучной и нудной. Если у вас есть вопросы и предложения — буду рад выслушать и ответить по мере сил. Баг-репортам буду рад еще больше. Спасибо заранее и удачных прошивок.

P.S. Уважаемая администрация и лично НЛО, сделайте для таких вот постов хаб UEFI, пожалуйста.
Николай Шлей @CodeRush
карма
184,0
рейтинг 38,4
Firmware Engineer
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Реклама

Самое читаемое Разработка

Комментарии (33)

  • +3
    Недавно тоже улучшал BIOS в своём ноутбуке -требовалось снять привязку к сетевой карте т.к. не работает под OS X. Метод похожий: поиск vendor id и dev id, правка JNZ на JMP и счастье наступает!
    Тул безусловно полезный, пригодиться скоро.
    • +1
      Можно еще исправить не переход (его иногда бывает непросто найти), а просто добавить свое устройство в список.
      Во второй части расскажу и про этот класс модов (whitelist removal) тоже.
      • +1
        В моём случае списка небыло, magic number и всё. Сейчас больше проблем доставляет заливка прошивки обратно т.к. похоже, что один из модулей проверяет контрольную сумму, а другой рапортует о невозможности заливки. Как модули общаются друг с другом — пока непонятно.
        • +1
          Программатор спасет отца русской демократии.
          На всякого рода презентациях производители UEFI любят рассказывать про то, как они защищают компоненты от модификации при помощи ЭЦП и поддерживают Chain-of-Trust, но по факту я не видел еще ни одного UEFI BIOS'а, в котором действительно бы проверялось что-то, кроме контрольных сумм, обычно все проверки выполняются на этапе прошивки. О способе прошивки модифицированного БИОСа можно еще здесь спросить, но я все равно рекомендую программатор — он в разы надежнее.
  • 0
    Так PhoenixTool все это раньше умел делать, то что описано в этой статье.
    • +4
      Он, все же, больше про SLIC, чем про модификации.
      Навскидку: Descriptor не разбирает, ошибки в структуре не видит и не исправляет, код закрытый, требует наличия .Net 3.
      Я не оспариваю первенства AndyP (а еще раньше apple_rom с его BIOS Patcher'ом), но не стал бы писать не самую простую программу, если бы аналогичная умела все, что мне нужно.
  • 0
    А нет ли в интернете уже готовой базы образов для разных моделей?
    • 0
      Готовой базы, насколько я знаю, нет, но найти дамп для какого-либо сравнительно популярного железа можно на форумах ремонтников (соответствующий раздел на notebook1.ru, например). Иногда дамп можно сделать из файла с обновлением, дописав в него необходимые данные, но эта возможность есть обычно только у обладателей десктопов.
  • –1
    > Модификация UEFI BIOS
    > Прикрываясь полумифическими «безопасностью» и «защитой простого пользователя от буткитов»

    Полумифической? Должно быть, вы уже написали софтверный vendor-agnostic UEFI инфектор для SecureBoot-enabled систем?))
    • +2
      Если бы и написал — все равно ответил бы, что нет. ;)
      Только вот это и не нужно, т.к. SecureBoot включен хорошо если на 2% имеющихся UEFI-систем, да и он не всегда помогает. При этом на одной половине UEFI-систем вообще нет никакой защиты, а на другой она снимается тривиально.
      А дальше все просто, бери flashrom, дампай@меняй@прошивай.
      • 0
        > SecureBoot включен хорошо если на 2% имеющихся UEFI-систем

        И что? Во-первых это довольно молодая технология, во вторых популярность какой-либо защиты (в отрыве от всего остального) мало что говорит о ее стойкости.

        > да и он не всегда помогает

        Это writeup по мотивам доклада на прошлом BH US который описывает атаку на кривую (в настоящий момент уже исправленную) реализацию SMM-кода в конкретных моделях машин (из pre-SecureBoot эпохи) конкретного вендора. К самому SecureBoot это имеет весьма косвенное отношение.

        > При этом на одной половине UEFI-систем вообще нет никакой защиты, а на другой она снимается тривиально.

        Это проблемы кривизны рук некоторых отдельно взятых hw вендоров.
        • +1
          Я описываю состояние безопасности существующих систем, а не тех, которые через 3 года встанут в строй. А его иначе как «полумифическим» назвать язык не поворачивается. И исправлена эта ситуация для владельцев UEFI-совместимых плат на чипсетах Intel 5, 6 и частично 7 серий уже не будет никогда.
          Безопасность системы определяется безопасностью самой слабой ее части. Что толку в SecureBoot, если AMI позволяет проишивать все, что угодно, несмотря на подписи, а на 95% современных десктопных плат UEFI основан на коде AMI? Да, это недоработка конкретного вендора, но кому становится легче от этого?
          Прошу меня простить, но о безопасность технологии SecureBoot я не говорил ничего. Я говорил о безопасности текущих реализаций UEFI, которая оставляет желать много лучшего, и будет оставлена в таком состоянии еще долго. Включайте SecureBoot и будьте спокойны, если вас это устраивает, в на 2 моих ПК из 3 его просто нет и уже никогда не появится.
          • 0
            > Да, это недоработка конкретного вендора, но кому становится легче от этого?

            Как минимум тем пользователям, которые разбираются в безопасности, для которых она востребована и которые готовы голосовать рублем против вендров-раздолбаев. Я считаю, что обсуждаемые защиты это по определению не продукт для широкой аудитории: не будет никто в реальной жизни с помощью персистентного UEFI бекдора ломать домашнюю машину Васи Пупкина.
            • 0
              Основная проблема в том, что выбора практически нет. Выбрасываем AMI — и для десктопа остаются только платы Intel. Выбрасываем Phoenix — из ноутбуков остаются только десяток моделей с Insyde H2O и машины Apple (на которых вообще никакой защиты нет и дамп замечательно снимается и пишется flashrom'ом). А после переезда ME в чипсет к безопасности всех систем на базе процессоров Intel люди, разбирающиеся в ней, не могут относиться без доли скептицизма. Сейчас еще AMD внедрит TrustZone, то про «безопасность» на системах x86 вообще можно забыть.
              • 0
                > Выбрасываем AMI

                Хотелось бы пруфы относительно того, что во всех машинах с AMI обновление firmware реализовано небезопасно (и про Phoenix тоже интересно). Комплексных системных исследований на эту тему я не видел, но вот новости об утечке ихних ключей проскакивали (следовательно, какакя-никакая цифровая подпись там есть, хотя если ее проверка реализована не в SMM то толку и правда мало).
                • 0
                  Практически на всех AMI, которые я встречал, регион BIOS либо не защищен вообще, либо защищен только установкой BIOS Lock, которую можно снять либо прошивкой через AFU в ключом /GAN, либо редактированием NVRAM. Цифровая подпись там хранится только в заголовке Aptio Capsule и в микросхему не попадает, а на некоторых платах (не будем показывать пальцем на Asrock) для обхода этой проверки можно просто удалить заголовок. В SMM там есть только обработчик установки бита BIOS Write Enabled, который ставит этот бит обратно, но и это можно отключить, сняв вышеупомянутый BIOS Lock редактирвоанием NVRAM.
                  Для Phoenix'ов имеются утекшие инженерные версии PFlash, которые прошивают что угодно даже на ноутбуках с последней версией платформы (SCT 2.3), где прошивка должна осуществляться описанным в вышеупомянутом докладе способом через оставление капсулы в памяти и софт-ресет, но по факту происходит обычным способом. Правда, на моем ноутбуке старая версия PFlash вызывает повреждение NVRAM, и после прошивки ноутбук перестает работать, но сам факт осуществления этой прошивки — на лицо.
                  Каких-то фундаментальных статей по безопасности UEFI я давно уже не видел, но скорее потому, что не слежу за темой, чем потому, что их нет. Вот тут можно посмотреть на практическую сторону «защиты» от прошивки модифицированных БИОСов, большая часть прозьб удовлетворяется вполне успешно.
              • 0
                > Сейчас еще AMD внедрит TrustZone, то про «безопасность» на системах x86 вообще можно забыть.

                Почему, кстати? Идея в целом адекватная: «давайте примем за аксиому что весь execution environment может являться скомпрометированным кроме специальных островков безопасности реализуемых средствами TrustZone/IntelSGX/whatever».
                • +2
                  Идея адекватная, но встает вопрос «кто будет контролировать контролеров?». Ничего не мешает производителю оборудования запускать в этой TrustZone любые закладки АНБ программы, а если технология будет скомпрометирована — исправить что-то можно будет только заменой оборудования.
                  • 0
                    Ему и сейчас ничего не мешает держать закладки в AMT, проблема доверия между пользователем и вендором — тема давняя.
                    • 0
                      Ну в свете последних событий, в плане публикации некоторых документов различных аппаратных бэкдоров онное множество. Поэтому тему безопасности и отсутствия бэкдоров со стороны вендора, можно даже не рассматривать. По умолчанию считая, что бэкдор в наличии — по принципу надеяться на лучшее, исходя из худшего.
                      Другое дело защита от иного вектора атаки, а верней группы…
                      • +1
                        Таки да, сoreboot с кусачками и паяльником врывается в тред как решение для настоящих параноиков: www.youtube.com/watch?v=2VvR-vsdMlQ (причем действительно грамотное и действенное решение для радикального снижения рисков со стороны untrusted firmware и отсечения целых классов векторов атак как чисто софтверных, так и evil maid подобных).
                        • 0
                          Спасибо, интересное видео, надо будет посмотреть от начала и до конца.
                    • 0
                      Вполне вероятно, что они там и есть. На сколько я знаю, пока нет вариантов полностью раскодировать/расшифровать прошивку Intel ME. Частично есть вариант извлечь некоторые модули, но они не дают полную картину о функционировании AMT.
      • +1
        И да, не смотря на все недостатки отдельных реализаций SecureBoot — другого механизма который решал бы те же самые задачи к сожалению нету :)
        • 0
          С этим не поспорить, альтернативы нетъ.
      • 0
        Ксати, про SecBoot.
        Вот я недавно купил msi мать на хасвел. поставил туда честную windows в режиме uefi.
        как теперь активировать SecBoot, что делать с сертификатами, как их создать.
        нет ли толкового мана на эту тему?
  • 0
    Подскажите, пожалуйста, инструменты поудобнее для перезаписи биоса, если на материнке нет SPI хэдера. И, если есть разница, он на Quad SPI.
    • +2
      В таком случае наиболее удобный инструмент — SOIC-клипса, только лучше купить не китайскую за 10 центов, а нормальную, производства Pomona или 3M. Также не стоит забывать, что программатору, подключенному клипсой к припаянному к плате чипу, придется еще и половину платы запитывать, поэтому нужно либо выпаивать чип (это надежнее), либо организовавать дополнительное стабильное питание, чтобы во время чтения\записи не было ошибок. То, то микросхема поддерживает Dual или QuadSPI — ничего страшного, обыкновенный SPI она от этого поддерживать не перестает, а если ваш программатор умеет QuadSPI — просто будет прошиваться 30 секунд вместо 2 минут.
  • 0
    Правильно ли я понимаю, что всё многообразие реализаций UEFI сводится к нескольким платформам UEFI от мастодонтов со времён BIOS? Вроде как это: Aptio 4 и 5 от AMI, SecureCore Tiano (SCT) нескольких версий от Phoenix, H2O от Insyde и собственные реализации от Intel и от Apple.
    А вообще, если возможно — то можно ещё одну промежуточную статью перечисляющую и сравнивающую эти реализации?
    • +1
      Правильно понимаете.
      Свои реализации есть также у поставщиков коммерческих систем виртуализации, (к примеру, у VmWare) и у Microsoft (используется на их смартфонах с WP8).
      Сравнивать реализации довольно непросто, т.к. для обычного пользователя отличия будут несущественные (иначе выглядит BIOS Setup), а для продвинутого их будет слишком много. Но я обещаю подумать в этом направлении.
      • 0
        Очень интересно.
  • +1
    Я понимаю что давнешняя статья, но мне очень помогла в борьбе с UEFI.
    Автору — спасибо!
    • 0
      Всегда пожалуйста.

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