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

в 17:19, , рубрики: diy или сделай сам, UEFI, модификация, системное программирование, метки: ,

В этой статье я постараюсь рассказать о наиболее популярных и полезных модификациях 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 (0x01) в регистр 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

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js