38,4
рейтинг
9 февраля 2014 в 21:19

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

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

Введение и еще один отказ от ответственности


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

Необходимые инструменты


Чтобы успешно модифицировать ваш образ UEFI BIOS, могут потребоваться следующие инструменты:
  1. Hex-редактор на ваш выбор.
  2. Редактор образов UEFI, в качестве которого я, по понятным причинам, буду использовать UEFITool, но вы также можете использовать PhoenixTool (универсальный и хорошо отлаженый, но не без ограничений) или MMTool (более или менее сносно работает только с образами AMI Aptio).
  3. Если для необходимой модификации не нашлось постоянного паттерна, могут потребоваться ассемблер и дизассемблер с поддержкой x86-64. Ассемблера вполне досточно онлайнового, а вот дизассемблер нужен нормальный, иначе поиски точки модификации могут сильно затянуться.
    К сожалению, бесплатная версия IDA Pro не поддерживает разбор 64-битных PE-файлов, поэтому для Windows я рекомендую использовать утилиту dumpbin, входящую в набор компиляторов Microsoft, а для MacOS X — либо objdump, либо пробную версию Hopper Disassembler.
  4. Если модификация может быть выполнена утилитой от производителя UEFI-платформы, пусть ей она и будет выполнена — это надежнее, чем вручную. К сожалению, «узок круг этих революционеров и страшно далеки они от народа», поэтому чаще всего подходящей утилиты от производителя не существует.


Модификации


Довольно предисловий, перейдем к сами модификациям. Здесь я опишу только те модификации, которые протестировал сам, поэтому список может быть обязательно будет неполным. Если вы пробовали какие-то другие моды — прошу поделиться результатами в коментариях. Формат описания будет таким: название модификации или класса модификаций, назначение и краткое описание необходимых шагов. Поехали.

CPU PM patch, MSR 0xE2 lock removal

Что: обход установки бита LOCK (0x0F) в регистр MSR_PMG_CST_CONFIG_CONTROL (0xE2) после прохождения POST
Зачем: открытый регистр 0xE2 необходим для работы подсистемы CPU Power Management в MacOS X, при закрытом происходит kernel panic. Если вы не планируете её уставновку или в вашем UEFI BIOSе присутсвует настройка «Unlock C-State MSR» — эта модификация вам не нужна.
Где искать: в UEFI-драйверах, относящихся к CPU PM. В старых БИОСах код установки лока находится в модуле CpuPei, в новых — в модуле PowerManagement (может также называться PowerManagement2.efi или PowerMgmtDxe.efi).
Способ модификации: В CpuPei код, который нужно модифицировать, выглядит примерно так:
81 FB D0 06 02 00  cmp         ebx,206D0h
75 0C              jne         FFFE426E
0D 00 80 00 18     or          eax,18008000h ; Бит 15 (LOCK) ставится здесь
EB 05              jmp         FFFE426E
0D 00 80 00 00     or          eax,8000h     ; Или здесь
6A FF              push        0FFFFFFFFh
6A F8              push        0FFFFFFF8h
6A 00              push        0
50                 push        eax
56                 push        esi
E8 DC 0F 00 00     call        FFFE5257      ; А внутри этой функции находится wrmsr
Достаточно заменить в этом месте 00800018 на 00000018 и 00800000 на 00000000, чтобы обойти установку лока.

В PowerManagement код выглядит иначе, чаще всего вот так:
80 FB 01           cmp         bl,1                    ; Если BL == 1
75 08              jne         0000000180002700        ; Перепрыгнуть две следующие команды
0F BA E8 0F        bts         eax,0Fh                 ; Установить бит 15 (LOCK)
89 44 24 30        mov         dword ptr [rsp+30h],eax ; Сохранить результат в переменную на стеке 
48 8B 54 24 30     mov         rdx,qword ptr [rsp+30h] ; Загрузить значение из этой переменной в RDX
B9 E2 00 00 00     mov         ecx,0E2h                ; А номер MSR в ECX
E8 79 0C 00 00     call        0000000180003388        ; И вызвать функцию с wrmsr внутри
Можно заменить JNE на JMP, BTS на BTR или просто «занопать» весь код установки лока. Проще всего сделать первое, т.е. поменять 75 08 на EB 08.

Если такого кода в вашем UEFI BIOS не нашлось, ищите в драйверах, относящихся к CPU Power Management, значение 0xE2, и проверяйте весь код на предмет установки 15-го бита. В последних версиях BIOSов для некоторых современных десктопных плат AMI перестали лочить этот регистр, поэтому такого кода в них уже не найти — считайте, что производитель сделал этот мод за вас.

AES NI unlock

Что: обход установки бита LOCK (0x02) в регистр MSR 0x13C
Зачем: включение аппаратного ускорения AES на системах с экспортными ограничениями
Где искать: в UEFI-драйверах, относящихся к CPU PM, чаще всего в PowerManagement
Способ модификации: мало чем отличается от PM patch'а (и уже был описан на хабре), поэтому останавливаться подробно на нем не буду.

Whitelist removal

Что: обход белого списка совместимого оборудования, который использую в своих UEFI BIOS'ах некоторые производители ноутбуков.
Зачем: идея производителя понятна — можно продать обладателям «несовместимого» оборудования еще и ребрендированное совместимое втридорога. Если вы сами хотите решать, что какое оборудование совместимо с вашим ноутбуком — эта модификация для вас.
Где искать: в UEFI-драйверах, относящихся к PCIe-устройствам. У HP это драйвер обычно называется BiosLockPcie, у Lenovo — LenovoWmaPolicyDxe.efi, но может называться и иначе.
Способ модификации: т.к. производители ноутбуков стараются менять код проверки Whitelist почаще, то описать какой-то постоянный способ довольно трудно.
Общая стратегия поиска такова:
  1. Вставить несовместимую карту в нотбук, дождаться сообщения о невозможности загрузки и запомнить его.
  2. Найти это сообщение в одном из FFS-файлов.
  3. Найти код, который ссылается на это сообщение.
  4. Исследовать этот код и попробовать изменить его так, чтобы проверка всегда заканчивалась успешно. Сделать это можно двумя способами: либо пропатчить переход, либо добавить свои Vendor ID и Device ID в белый список.

Подробности модификации на примере HP хорошо описаны здесь широко известным в кругах моддеров товарищем Donovan6000, а я опишу вариант модификации на примере Lenovo X121E.
Проверка осуществляется драйвером LenovoWmaPolicyDxe.efi, попасть необходимо вот сюда:
44 38 0D F0 0F 00 00   cmp         byte ptr [00001BF0h],r9b
75 18                  jne         0000000000000C1A
E8 35 FD FF FF         call        000000000000093C
48 85 C0               test        rax,rax
4C 8B C8               mov         r9,rax
0F 88 77 FF FF FF      js          0000000000000B8A
C6 05 D6 0F 00 00 01   mov         byte ptr [00001BF0h],1
49 8B C1               mov         rax,r9
E9 68 FF FF FF         jmp         0000000000000B8A
Все переходы к этому коду необходимо пропатчить на безусловные, а в самом коде необходимо «занопать» первую и вторую строки, после чего проверка всегда будет заканчиваться успешно.

BIOS lock removal

Что: снятие защиты от прошивки модифицированных образов UEFI встроенным программатором.
Зачем: при большом количестве экспериментов с UEFI доставать каждый раз программатор быстро надоедает, да и прошивка встроенным программатором происходит быстрее (засчет работы по протоколу QuadSPI вместо обыкновенного SPI в случае внешнего программматора).
Где искать: в драйверах чипсета, чаще всего в PchInitDxe (другой вариант мода — в BiosWriteProtect)
Способ модификации: вариант модификации PchInitDxe полностью описан здесь на английском, поэтому я приведу только идею. Необходимо найти запись бита BIOS Lock Enable (BLE) в регистр BIOS_CNTL чипсета и предотвратить её. Сделать это можно в нескольких местах, например, вот здесь:
48 8B 4C 24 40         mov         rcx,qword ptr [rsp+40h] ; Загрузить в RCX адрес структуры PchPlatformData
48 8B 41 50            mov         rax,qword ptr [rcx+50h] ; А в RAX - адрес дочерней структуры LockdownConfig
F6 00 10               test        byte ptr [rax],10h ; Проверить, установлен ли пятый бит (BiosLock) 
74 25                  je          0000000180001452 ; Если не установлен, перепрыгнуть весь код ниже
8A 50 01               mov         dl,byte ptr [rax+1]
B9 B2 00 00 00         mov         ecx,0B2h ; 
E8 A2 5A 00 00         call        0000000180006EDC
4C 8D 87 DC 00 00 00   lea         r8,[rdi+000000DCh] ; В RDI лежит базовый адрес регистров LPC чипсета, а 0xDC - смещение регистра BIOS_CNTL
33 C9                  xor         ecx,ecx
4C 8B CD               mov         r9,rbp
33 D2                  xor         edx,edx
4C 89 44 24 20         mov         qword ptr [rsp+20h],r8
E8 AA 76 00 00         call        0000000180008AFC ; Установить лок
Можно изменить JE на JMP, но иногда вместо короткого прыжка попадается длинный, у которого приходится дополнительно вычислять смещение, поэтому лучше изменить test на любую команду, устанавливающую флаг ZF, например на xor rax, rax (48 31 C0), а возможную разницу в размерах команд исправить добавлением NOP'ов.
Если в PchInitDxe нужного кода не нашлось, можно изменить драйвер BiosWriteProtect таким образом, чтобы обойти регистрацию находящегося в нем SMI-обработчика, который устанавливает бит BLE при попытке его сброса, после чего для разблокировки прошивки достаточно сбросить этот бит. У меня отлично работает вышеописанный способ, поэтому этот вариант я пока не пробовал и потому подробно описывать не буду.

Advanced settings unlock

Что: разблокировка доступа к скрытым настройкам BIOS Setup.
Зачем: среди эти настроек может попасться что-то интересное, но обычно их скрывают не просто так.
Где искать: для Phoenix и Insyde меню хранится в HII-файлах с именами вроде SetupMain, SetupAdvanced и т.п. Для AMI меню хранится в файле Setup, а настройки — в AMITSE. Более того, AMI предоставляет пороизводителям end-user продуктов свою программу AMIBCP, версии которой частенько утекают в публичный доступ. Работа с ней достаточно проста, поэтому описывать её я не вижу смысла — скачайте и попробуйте.
Способ модификации: для AMI — открываем образ в AMIBCP, меняем настройки по умолчанию, сохраняем, прошиваем, выполняем сброс настроек, готово. Для Insyde и Phoenix все немного сложнее. Если доступ на запись в NVRAM не запрещен, можно воспользоваться методом товарища Falseclock, описанным в этой его статье, а вот если доступа нет — придется модифицировать прошивку. Потребуется разобрать формат HII Form File либо вручную, либо предоставить это скрипту, описанному в вышеупомянутой статье, или утилите Universal IFR Extractor, которую необходимо натравить на извлеченные из образа UEFI файлы HII. После этого достаточно изменить в извлеченном файле HII Form условия SUPRESS_IF так, чтобы они никогда не выполнялись, и все меню станут доступны.

CPU Microcode, OptionROM, drivers and images update

Что: обновление микрокодов CPU, прошивок различных переферийных устройств, EFI-драйверов и отображаемых при загрузке и в BIOS Setup картинок.
Зачем: иногда обновление помогает исправить ошибки в работе системы, иногда добавляет поддержку важной фичи (работу TRIM для SSD в RAID0, к примеру), но чаще всего обновление производится потому, что наконец вышла новая версия.
Где искать: сильно зависит от производителя, EFI-драйверы можно найти просто по имени (SataDriver, например), микрокод можно найти по Model ID процессора, для которого он предназначен, OROMы — по VID/DID устройств, которые они обслуживают, картинки в формате JPEG можно найти по строке «JFIF», в GIF — по «GIF8» и т.п.
Способ модификации: прост как мычание — найти новую версию в свободном доступе, найти, где в образе лежит старая, и заменить одно на другое. Для AMI товарищем LS_29 был написан набор для автоматического обновления на основе утилиты MMTool, скачать можно из нашей темы на оверах. Об автоматизированных решениях для Phoenix или Insyde я пока не слышал.
Замена картинок может быть сделана либо утилитами вроде AMI ChangeLogo, либо вручную, но чаще всего не подготовленная специальным образом картинка вызывает зависание, т.к. декодеры форматов изображений бывают сильно ограничены. В общем, данные EXIF лучше удалить заранее.

Заключение


В этой статье я описал только те моды, которые успешно делал своими руками. Если у вас есть какие-то замечания и дополнения — буду рад вашим комментариям.
Еще раз смиренно попрошу администрацию Хабра и лично НЛО о создании хаба UEFI, ибо это очень широкая тема, а статьи по ней буквально некуда приткнуть.
Спасибо за внимание, желаю вам удачных модификаций.
Николай Шлей @CodeRush
карма
184,0
рейтинг 38,4
Firmware Engineer
Реклама помогает поддерживать и развивать наши сервисы

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

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

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

  • +3
    Олдскульный хардкор! Мне почему-то статья навеяла воспоминания о времени, когда я выставлял в компе частоту и питание проца перемычками. И еще когда в мотороле так же прошивки модифицировал в hex-редакторе и заливал их обратно — дико разовался когда появлялись возможности, о которых ничего и никогда не знал )))
    • 0
      Эх. а сейчас зашел в виндовое приложение от вендора материнки, развлёкся, ушел в ребут, профит.
      Скука, в общем.
      PS у самого Pentium Haswell + msi материнка, но память вместо 1600 работает на 1400, из-за этого видео набортное не очень работает быстро, мучаюсь :(
      • 0
        А разве прибавка 12% к скорости сильно заметной станет? В два раза, это я понимаю прибавка а 12% можно заметить разве что в тестах.
        • 0
          При поднятии параметров работы памяти с 1333 на 1400 (в биосе (мать ua.msi.com/product/mb/B85M-G43.html) в настройках нашел переключатель настроек) fps вырос, ненамного, но играть стало поприятнее. но мой p g3220 (http://ark.intel.com/products/77773/) вообще умеет только 1333 по спекам на сайте, хотя по тем же спекам гонится до 3,8G, но оверклокер из меня совсем никакой, поэтому мне бы хотя бы поднять работу памяти (http://hard.rozetka.com.ua/silicon_power_ddr3-1600_8gb_sp008gbltu160n02/p247437/) до 1600, если получится
          • 0
            В БИОСе можно частоту шины поднимать(одновременно с частотой процессора), это повлияет и на память но выше заявленных максимальных характеристик на матери не поднятся, увы. Ну и проблемы могут вылезти с PCI-шиной, устройства висящие на ней в т.ч. и интегрированные на материнку могут неправильно понять повышение частоты шины.
            • 0
              Ну вот я по этому и не лезу, т.к чайник.
              просто по тх процессора он (видимо low-end сегмент) он выше 1333 не понимает, но в биосе доступен профиль на 1333 и 1400, на 1600 профиля уже нет (ограничение чего? процессора, материнской платы..)
              Если бы кто помог, бы бы признателен (денег на внешнюю видеокарту пока не предвидится, да и не особо надо), а вот крутить виртуалки все таки позитивнее на 1600
  • 0
    Кратко, ёмко и познавательно :)
  • +1
    для Windows я рекомендую использовать утилиту dumpbin, входящую в набор компиляторов Microsoft, а для MacOS X — либо objdump, либо пробную версию Hopper Disassembler.

    Когда делал MSR мод на синкпаде для разблокировки AES-NI — писал python скрипт который используя либу pyew дизасмил все извлеченные из прошивки исполняемые модули и находил последовательности инструкций пишущие в регистр 13Ch по тупой сигнатуре.
  • –1
    UEFI слишком мудрен как для биоса. Со стандартным Фениксом проблем с загрузкой Линукса точно не было. Это те ощущения, будто впервые юзаешь Systemd
    • +7
      UEFI — это в целом благо, поскольку он делает коллективную разработку firmware намного более человечнее, проще и переносимее. Текущие конфликты с различными загрузчиками и ядрами (EMНИП, реально критичные проблемы там встречаются не часто) наверняка будут вылечены в скором времени в ходе естественного взросления технологии.
      • +1
        ну будем надеяться
    • +2
      «Стандартный Феникс» это платная проприетарщина и vendor locking, а UEFI это открытый и документированный стандарт с возможностью самостоятельного расширения.
  • +1
    Я таким образом изменял настройку HDA кодека Realtek. Если вкратце — сделали мы плату на x86 по референсу Intel, только повыкидывали кучу всего и контроллер аудио поставили от Realtek. Кто же знал, что verb table регистров прописывает не драйвер по старту, а BIOS. А Intel предоставляет референсный BIOS в бинарнике, а денег AMIшникам сами понимаете платить неохото было (Там примерно 30K$ за Aptio и за платформу). Ну что, расковырял, нашел место где эти регистры выставляются, поменял, вуаля…

    Сейчас правда есть исходники и всё гораздо проще.

    Спасибо за статью.
  • +2
    Пробуйте radare2 — он поддерживает и загрузку PE и TE, визуальный режим весьма удобен. Вот, например:
    дизассемблирование 16-битного биоса
    image

    и просто какой-то юзерспейсный код
    image
    • 0
      Спасибо большое за наводку, буду пользоваться. И за ваш вклад в flashrom тоже.
      • 0
        Если что — пишите, быстро поправим. Я тоже в radare2 ориентируюсь на дизассемблирование прошивок.
  • 0
    Разобрался с модом PchBiosWriteProtect.efi, который упоминал в статье. Пока еще не тестировал, но там нечему ломаться.

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