...

пятница, 18 апреля 2014 г.

[Из песочницы] Удаление Whitelist в bios ноутбуков на примере Lenovo X230

Недавно понадобилось поставить новую wifi карточку стандарта ac в свой ноутбук Lenovo x230, в котором есть whitelest для wlan карточек. Ниже опишу свои изыскания по отключению whitelist'а.





Для начала нам надо слить дамп нашего биоса, сделать это можно с помощью утилиты FPT

fpt -d bios.rom -BIOS

Далее нам понадобится утилита PhoenixTool 2.52. Запускаем её, выбираем наш bios.rom и ждём, пока она его распакует, далее в поле Manufacturer выбираем Lenovo и жмём кнопку Advanced, там ставим галочки «Allow user to modify other modules» и «No SLIC»



Нажимаем «Done» и «Go», когда откроется окошко



ничего не нажимаем и идём в папку DUMP, куда распакован наш биос. Далее нужно найти файл отвечающий за whitelist. Ищем просто по тексту ошибки (в кодировке UTF-16), которая выводится на экран при вставленном модуле не из вайтлиста «1802: Unauthorized network card is plugged in»



Находим файл 79E0EDD7-9D1D-4F41-AE1A-F896169E5216_2207.ROM — это модуль биоса для вайтлиста.

Далее грузим его в IDA, смотрим код и ищем нашу строку «1802: Unauthorized network card is plugged in»



К этой строке идёт обращение в процедуре Sub_A0C. Т.е. процедура Sub_A0C предположительно занимается выводом ошибки на экран, смотрим откуда она вызывается (кликаем по имени процедуры и нажимем клавишу X на клавиатуре)



Видим что это процедура Sub_B20. Идём в эту процедуру и нажимаем пробел для перехода к схематичному представления кода.



Видим что процедура Sub_A0C вызывается из блока кода на метке Loc_BDD. Далее можно проследить условные переходы к этой метке и т.д. Но я решил, чтобы лучше понять код работы этой процедуры, пройти код от начала процедуры.

Итак, первое условное ветвление проверяет регистр edx на ноль



test edx, edx
jz Loc_C6E




т.к. регистр edx выше в этой процедуре нигде не инициализируется, то понятно, что ему должно присваиваться значение перед вызовом процедуры Sub_B20. Это можно увидеть в коде

и

Что означает значение в регистре edx я не понял, поэтому пройдёмся по обоим веткам ветвления.

Пойдём для начала по правой веке, на Loc_C6E


В eax кладётся адрес данных qword_270, двойным щелчком по qword_270 переходим к просмотру этой записи, далее переходим на вкладку Hex View-A. Это и есть наш whitelist, он идёт с адреса 270h до 3FFh. С форматом тоже всё просто, каждая запись длинной в 16 байт (4 слова по 32bit) соответствует одному устройству: первое слово — какой-то флаг, принимающий значение 0, 1, 5 или 6, второе слово — это system id, третье — subsystem id, четвёртое — ещё один флаг, имеющий значение 0 или 1. Предполагаю что первый флаг определяет тип устройства: 0 — wifi карточка, 1 — модем, 5 — ?, 6 — конец списка.



Вернёмся к коду. Сравниваем eax с шестёркой, а шестёрка у нас — это конец вайтлиста, т.е. если вайтлист получается пустой, то идём сразу на Loc_BDD, которая у нас вызывает ошибку. Это условие нам не интересно, т.к. вайтлист у нас не пустой, и условие не выполнится. Далее кладём адрес qword_270 в регистр rdx, проверяем eax (первый флаг записи в вайтлисте) на ноль, если флаг отличный от нуля, переходим к ошибке. Это условие нас тоже не интересует. Это же условие является началом цикла обхода вайтлиста.

Дальше командами



movzx ecx, word ptr [r8+rdx+6]
movzx eax, word ptr [r8+rdx+4]
shl ecx, 10h
or ecx, eax




Помещаем system id из вайтлиста в регистр ecx. Регистр r8 здесь выступает в роли инкремента в цикле, изначально он равен нулю.

Далее сравниваем ecx (system id из вайтлиста) и значение в памяти по адресу в регистре rdi.

cmp [rdi], ecx



Несложно догадаться, что по адресу в регистре rdi у нас лежит идентификатор нашей вставленной wifi карточки, а в начале процедуры в регистр rdi мы кладём r8, т.е. процедуре Sub_B20 в качестве параметра использется регистр r8, где должен лежать адрес ячейки памяли с идентификатором нашей карточки.

Если идентификатор не совпал, то идём на Loc_CBA, там мы увеличиваем инкрементный регистр r8 на 10h (для этого в регистре r13w у нас заранее должна лежать еденица)

loc_CBA:
add r9w, r13w
movzx r8d, r9w
shl r8, 4




и проверяем, не в конце ли мы вайтлиста

mov eax, [r8+rdx]
cmp eax, 6
jz loc_BDD




Если в конце, то выходим из цикла и выдаём ошибку, если не в конце, то идём в начало цикла.

Понятно, что для обхода вайлиста, нам надо убрать условный переход при сравнении system id, т.е. заменить jnz short loc_CBA на jmp $+2.

Далее, если system id совпал, идёт аналогичный код для сравнения subsystem id

movzx ecx, word ptr [r8+rdx+0Ah]
movzx eax, word ptr [r8+rdx+8]
shl ecx, 10h
or ecx, eax
cmp [rdi+4], ecx
jz short loc_CD5




Если subsystem id не совпал, то перебираем по циклу идентификаторы дальше. Тут нам тоже необходимо поправить условные переход на безусловный jz short loc_CD5 на jmp short loc_CD5.

Дальше по коду уже нет переходов на ошибку, но есть интересный код, проверяющий второй флаг в записи вайтлиста, про который я писал ранее, он сравнивается с регистром r13d, и если совпадает, то выполняется некий дополнительный кусок кода. Что делает этот код понять трудно, по анализу вайтлиста можно заметить, что этот флаг стоит только у карточек фирмы Intel.

Так, с правой веткой разобрались, теперь пройдёмся по левой ветке.Там у нас код работы с вайтлистом начинается с метки Loc_C18. Аналогично проверяется, не пустой ли whitelist:



loc_C18:
mov eax, dword ptr cs:qword_270
xor r9w, r9w
cmp eax, 6
jz short loc_BDD




Далее сравнивается eax (первый флаг) и r13d (что за параметр лежит в r13d я так и не разобрался, в начале процедуры него кладётся значение по адресу [rbx+1]), далее в зависимости от выполнения этого условия, попадаем сразу на код проверки system id, либо выполняем интересное сравнение

cmp eax, 5
jnz short loc_C54




Проверяем первый флаг в записи вайтлиста на 5, если условие выполняется, то пропускаем эту запись вайтлиста (т.е. игнорируем wifi карточку) и идём далее по циклу проверки.

Чтобы понять что же это за такой интересный флаг, надо понимать, что передаётся в процедуру Sub_B20. Если помните, в правой ветке кода, если этот флаг был отличный от нуля, то выдавалась ошибка о неподдерживаемой карте. Т.е. чтобы карточка с флагом 5 загрузилась, должны выполниться следующие условия вызова процедуры Sub_B20: регистр edx должен быть отличным от нуля, а регистр r13d не должен быть равен пяти (cmp eax, r13d, а в eax у нас лежит наш флаг равный пяти). Можно лишь догадаться, что для запуска карточки с таким флагом, требуется ещё какое-то условие, кроме нахождения её в вайтлисте. Дальше выполнять анализ для меня было довольно сложно, поэтому, что же это за условие, узнать не удалось.

Далее по коду, мы аналогично правой ветке, проверяем в цикле system id



loc_C3B:
movzx ecx, word ptr [r8+rdx+6]
movzx eax, word ptr [r8+rdx+4]
shl ecx, 10h
or ecx, eax
cmp [rdi], ecx
jz loc_DF3




Здесь нам надо также заменить условный переход jz loc_DF3 на безусловный jmp loc_DF3.

Что интересно, далее в левой ветке нет проверки subsystem id, т.е. достаточно совпадения system id. Из вышеизложенного можно предположить, что правая ветка — проверка wifi карточек, а левая проверка модемов. А в регистре edx при вызове функции содержится тип устройства: 0 — wifi, 1 — модем. Но тут тоже непонятка, т.к. каточка 0087:8086 с флагом 5 — это wifi+wimax, а не модем, да и в edx может быть больше единицы, т.к. из edx вычитается r13d, а потом сравнивается с четвёркой:

sub edx, r13d
jz short loc_B4F
cmp edx, 4
jz short loc_B4F




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

Переводим команды в опкоды и делаем замены в hex редакторе, в итоге получаем такой патч:

C4E: 0F84->90E9 (jz to jmp)
CA3: 16->00 (jnz loc_CBA to jnz $+2)
CB8: 74->EB (jnz to jmp)




Сохраняем пропатченый файл 79E0EDD7-9D1D-4F41-AE1A-F896169E5216_2207.ROM и нажимеам в окне PhoenixTool кнопку Ok.

PhoenixTool соберёт новый биос с именем bios_SLIC.rom.

Осталось дело за малым, необходимо прошить новый биос. В свежих ноутбуках Lenovo, включая мой x230, изменённый bios нельзя прошить программно, поэтому шьём его программатором. Фото процесса прошивки через программатор к сожалению не делал. Биос находится в микросхеме MX25L3206E рядом с разъёмом ExpressCard. Эта микросхема представляет из себя обычный SPI EEPROM 25ой серии, простой программатор для которой стоит 300р.


На этом всё, наслаждаемся работой новой wifi карточки.


Использовались материалы с форума bios-mods.com

http://ift.tt/1pfSRKX

http://ift.tt/1f1CsQH


This entry passed through the Full-Text RSS service — if this is your content and you're reading it on someone else's site, please read the FAQ at http://ift.tt/jcXqJW.


Комментариев нет:

Отправить комментарий