Розбираємося з помилкою завантаження через відсутньої цифрового підпису драйвера в x64 системі

У цій статті постараюся описати методику діагностики проблем з підписаними файлами драйверів в x64 бітової версії Windows систем, через які комп'ютер перестає завантажуватися і при завантаженні падає в BSOD. Але систему все-таки можна завантажити, відключивши перевірку цифрового підпису при завантаженні (F8 -> Disable Driver Signature Enforcement). Як приклад в цій статті я буду працювати з Windows Server 2008 R2 (яка, нагадаю, буває тільки в 64-розрядної редакції), але дана методика підійде так і для Windows 7 x64 і Vista x64.

Якщо повернутися до передісторії питання, то згадаємо, що Microsoft прийняла рішення про те, що в 64-бітних системах, починаючи з Windows Vista, Windows завантажує драйвера в режим ядра тільки в тому випадку, якщо драйвер має цифровий підпис. Якщо ж цифровий підпис драйвера відсутня, то при завантаженні системи трапляється критична помилка (залежить від типу драйвера, завантаження якого заблокована) і з'являється екран BSOD. Конкретна помилка і її код залежать від конкретного драйвера, який заблокований в процесі завантаження. Деякі помилок прямо на екрані BSOD можуть вказувати на файл непідписаного драйвера.

У моєму випадку після оновлення драйверів на сервері Windows 2008 r2 при звичайній завантаження машини з'явився синій екран смерті з текстом:

STOP: c000021a (fatal System Error)

The initial session process or system process terminated unexpectedly with a status of 0x00000000 (0xc000428 0x00100448). The system has been shut down

Спробуємо з'ясувати що це за помилка, який драйвер її викликає т визначимо по драйверу конкретний пристрій.

Для декодування помилки нам потрібен другий параметр (він виділений жирним) - 0xc000428.

Перетворимо hex код помилки в більш легку для читання форму. Для цього можна скористатися вбудованою в Windows утилітою SLUI.EXE або ж зіставити код цієї помилки у файлі ntstatus.h, знайти який можна в Windows SDK. Скористаємося першим способом, для чого в командному рядку виконаємо:

slui.exe 0x2a 0xC0000428

Як ви бачите на скріншоті, ми переконалися в тому, що BSOD викликана неможливістю перевірити цифровий підпис драйвера ( "Windows can not verify digital signature for this file")

Перезавантажуємо наш комп'ютер і при завантаженні тиснемо клавішу F8. У розширеному завантажувальному меню (Advanced Boot Options) відключаємо перевірку цифрового підпису, обравшиDisable Driver Signature Enforcement .

У тому випадку, якщо в такому режимі сервер завантажитися, ми точно впевнені в тому, що якийсь непідписаний модуль або драйвер не дозволяє системі нормально завантажитися.

Наступний крок - визначення файлу проблемного модуля або драйвера. Відкриємо консоль журнал подій (Event Viewer) і перейдемо в розділ Applications and Services Logs -> Microsoft -> Windows -> CodeIntegrity -> Operational.

Примітка: якщо при доступі до логам в цій гілці з'являється помилка "access denied ", створіть на диску c: каталог, надавши групі Everyone повний доступ. Потім змініть шлях до файлу ETL на новий каталог, і відключіть і заново дозволите логирование.

У моєму випадку, в журналі є подія EventID 3001 з текстом "Code Integrity determined an unsigned kernel module \ Device \ HarddiskVolume1 \ Windows \ System32 \ win32k.sys is loaded into the system. Check with the publisher to see if a signed version of the kernel module is available". Ось ми і знайшли проблемний драйвер!

Драйвер може бути як рідним драйвером Microsoft, так і драйвером стороннього розробника. Переконався, що даний драйвер дійсно не має цифрового підпису. Для цього нам знадобиться утиліта від Sysinternals під назвою SIGCHECK.EXE (взяти її можна тут http: //technet.microsoft.com /en-us /sysinternals /bb897441).

Перевірку наявності цифрового підпису виконаємо командою:

c: \ TOOLS> sigcheck.exe -i c: \ Windows \ System32 \ win32k.sys

Якщо підпис відсутній, то в поле Verified буде вказано Unsigned (в іншому випадку, відповідно Signed).

Перед нами є два варіанти вирішення проблеми неможливості нормальної загрукі системи з підписаним драйвером:

  1. Знайти підписану версію драйвера
  2. Відмовитися від використання даного драйвера (і пристрої)
  3. відключити перевірку цифрового підпису драйвера в Windows

Третій варіант може не підійти з тих чи інших причин. У перших двох випадках нам потрібно визначити до якого конкретного пристрою відноситься даний файл драйвера .sys.

Як же визначити пристрій, знаючи лише ім'я sys-файлу? Я використовую наступну методику (нехай нам потрібно визначити пристрій, драйвер якого має ім'я HpCISSs2.sys):

1) Відкриваємо редактор реєстру і пошуком по гілці HKEY_LOAL_MACHINE \ SYSTEM \ ControlSet001 шукаємо ключ із значенням HpCISSs2.sys

2) В моєму випадку він знайшовся в гілці HKEY_LOAL_MACHINE \ SYSTEM \ ControlSet001 \ services \ HpCISSs2

3) Розвертаємо вкладену гілку з назвою ENUM, нас цікавить значення ключа  0, в моєму випадку це PCI \ VEN_103C& DEV_3230& SUBSYS_3235103C & REV_01 \ 4 & 3b416f2c & 0 & 0018

4) Визначаємо, що виробник пристрою має ID 103C, а код пристрою 3230

5) Далі на сайті вказуємо в полях Vendor Search і Device Search знайдені нами коди.

6) Отримуємо що шукане нами пристрій контролер жорстких дисків HP Smart Array P400 Controller.

Нам залишилося лише знайти нову версію драйвера на сайті виробника устаткування (уважно дивіться для яких версій ОС підходить потрібний вам драйвер) і оновити драйвер на комп'ютері.