Відключення перевірки цілісності bootmgr і winload | Блог по Windows

Найчастіше виникають потреби вивчення процесу завантаження операційної системи Windows на рівні вихідного коду. Ну а тут вже без внесення змін до коду просто не обійтися .. і в цьому самому місці нас чекає розчарування. Справа в тому, що якщо вносити зміни в код модулів bootmgr, winload.exe і файли драйверів, які беруть участь в процесі початкового завантаження, то процес запуску операційної системи починає “вилітати” з помилками, “валитися” в синій екран і режим відновлення. Логічно, адже ми зіткнулися з перевіркою цілісності bootmgr і winload, яка перешкоджає модифікації виконуваних образів, задіяних в ланцюжку запуску. Подібний механізм вперше з’явився в лінійці операційних систем Windows починаючи з версії Vista і тепер придбав перманентно-стійкий вид. Для самописних драйверів розробники залишили можливість завантаження в тестовому режимі (прапор TESTSIGNING), Проте залишаються умови, при яких внесення змін до коду компонентів закінчується відмовою в запуску ОС. Дослідникам архітектури Windows цей факт суттєво псує настрій, тому сьогодні ми розберемо кілька нестандартний метод відключення перевірки цілісності bootmgr і winload.

Для 32/64-бітових версій Windows Vista / 7/8 і далі є цілком офіційний спосіб відключення перевірки перевірки цілісності драйверів режиму завантаження, проте іноді доводиться працювати з тестовими (зміненими) версіями деяких завантажувальних файлів, в цьому випадку потрібно відключення взагалі всіх перевіряючих механізмів.

Для придушення перевірки цілісності ми будемо патчить код модулів таким чином, щоб алгоритми внутрішніх функцій перевірки хеш файлів завжди виконувалися по розгалуження типовий (нормальної) завантаження. В якості навчального матеріалу статті буде використана операційна система Windows 7 SP1 Professional RUS x86 в нормальному (legacy, PC / AT-MBR) режимі завантаження. Не дивлячись на те, що відключення перевірки цілісності в 32-бітної системи має менше сенсу ніж в x64-версії, наведене в даній статті рішення є універсальним, оскільки логіка роботи внутрішніх функцій перевірки цілісності аналогічна (навіть для режиму завантаження UEFI), за винятком, зрозуміло, вихідного коду.

Перед виконанням наведених нижче дій не забудьте зробити резервні копії файлів:

  • % SystemRoot% \ System32 \ Boot \ Winload.exe;
  • % SystemRoot% \ System32 \ Winload.exe;
  • Bootmgr (що знаходиться на прихованому системному розділі / розділі EFI);

Отже, нам буде потрібно:

  • інтерактивний дизассемблер
  • Шістнадцятковий редактор з можливістю пошуку / заміни шістнадцятирічних значень (ваш улюблений)
  • утиліта
  • утиліта
  • PE-редактор

Bootmgr

У процесі завантаження операційної системи Windows, після закінчення етапів MBR і PBR, управління передається на код менеджера завантаження Bootmgr. Що б сам менеджер завантаження в разі модифікації у нас не “брикався” різноманітними помилками контрольних сум, нам потрібно його пропатчити:

  • Для початку нам необхідно отримати файл bootmgr зі спеціального “прихованого” системного розділу. Метод описаний в цій статті, проте я приведу тут коротку послідовність дій: запускаємо оснащення Управління дисками, виділяємо (маркуємо) перший розділ диска (розмір ~ 100-300Мб), клацаємо правою кнопкою миші – вибираємо пункт меню Змінити букву диска або шлях до диску .. і призначаємо літеру.
  • В системі з’являється (стає доступний) новий диск. Відкриваємо, налаштовуємо уявлення провідника на показ прихованих файлів, папок і дисків, скасовуємо приховування захищених системних файлів.
  • У корені виявляємо стислий файл Bootmgr.
  • Розпаковуємо його за допомогою консольної утиліти bmzip (посилання вище):

    bmzip bootmgr bootmgr.exe

    У цільовому каталозі виявляємо новий щойно розпакований файл bootmgr.exe.

  • Дізассембліруем отриманий модуль bootmgr.exe за допомогою IDA. Обов’язково з працездатною можливістю з викачування символів з сервера Microsoft.
  • В інтерфейсі IDA, йдемо в Options – General – вкладка Disassembly, виставляємо значення параметра Number of opcode bytes в 8. Це потрібно для відображення в лістингу опкодов інструкцій.
  • В основному вікні дизасемблювати вихідного коду відкручуємо на початок лістингу, ставимо курсор в початок, потім тиснемо Alt+T і вводимо в рядок пошуку ImgpValidateImageHash (Можна без урахування регістру символів), тиснемо OK.
  • Для подальшого пошуку можна використовувати комбінацію Ctrl+T. Переміщаючись по вихідного коду знаходимо точку входу функції (не плутати з викликами функції call _ImgpValidateImageHash)
  • Знайшовши таким чином функцію, подорожуємо у кінець її коду і бачимо приблизно наступне:

    00421ED9 421900421ED900421ED97 00421EDB 00421EDC 00421EDD 00421EDE5 00421EE0 00421EE12 00421EE1 ImgpValidateImageHash
  • Функція ImgpValidateImageHash виконує перевірку контрольної суми (хеш) завантажувальних модулів. Для того, що б обійти різноманітні перевірки власної цілісності і завантажується в подальшому модуля Winload.exe, необхідно змусити функцію повертати нульове значення (згідно з угодою про виклики в регістрі eax) в будь-який випадок.
  • На даний момент в наведеному вихідному коді ми можемо спостерігати сигнатуру для пошуку і заміни:

    Саме в вашому випадку вона може бути іншою, оскільки все залежить від поточної ревізії файлу bootmgr;

  • Завантажуємо і запускаємо шістнадцятковий редактор. Відкриваємо в ньому наш файл bootmgr.exe.
  • Пошуком по шістнадцятиричним значенням знаходимо сигнатуру. Потрібно поміняти знайдений нами код так, що б в регістрі eax поверталося значення 0. В оригіналі ми бачимо команду mov eax, edi (опкоди 8B C7), Яка виконує привласнення eax = edi. Давайте замінимо її на xor eax, eax (опкоди 33 C0), Яка обнуляє регістр eax. Для цього в редакторі байти 8B C7 міняємо на 33 C0. Зберігаємо зміни, закриваємо редактор.
  • Тепер нам необхідно перетворити образ bootmgr.exe назад в стислий bootmgr. Для цього використовуємо утиліту BOOTMGR Recompiler v2 (посилання вище).
  • Розміщуємо вийшов стислий файл bootmgr в корінь прихованого розділу (який був у нас подмаплен в систему на початку). Атрибути на прихований міняти не треба!

Winload.exe

Але це ще не все, оскільки після того, як код менеджера завантаження Bootmgr знаходиться на завершальній стадії виконання, їм подгружается завантажувач наступної стадії – так званий завантажувач операційної систем під назвою Winload.exe. Даний модуль так само має звичку перевіряти цілісність ключових файлів, тому нам необхідно оновити та його код теж. Щоб не описувати кілька разів одне і те ж, домовимося, що кроки попереднього розділу актуальні і для поточного.

метод №1

  1. За вищеописаною методикою шукаємо функцію ImgpValidateImageHash.
  2. В кінці функції знаходимо приблизно такий ось фрагмент коду:
    00429812 4298120042981200429812 5800429816 00429817 00429818 004298195 0042981B 0042981C2 0042981C ImgpValidateImageHash
  3. У шістнадцятирічному редакторі знаходимо сигнатуру і міняємо (виділене) чотири байти 8B 44 24 18 на 33 C0 90 90, що буде еквівалентно серії команд:

метод №2

  1. За вищеописаною методикою шукаємо функцію OslInitializeCodeIntegrity.
  2. Дивимося точку входу функції:
    004045BE; =============== SUBROUTINE ================================== ===== 004045BE004045BE; Attributes: bp-based frame004045BE004045BE; __stdcall OslInitializeCodeIntegrity (x) 004045BE OslInitializeCodeIntegrity004045BE004045BE 10 dword004045BE dword004045BE 8 dword004045BE 2 004045BE 1 004045BE 0 dword004045BE004045BE 004045C0 004045C1 004045C3 004045C6 004045C7 004045C8                                  
  3. У шістнадцятирічному редакторі знаходимо сигнатуру і міняємо (виділене) перші три байта 8B FF 55 на B0 01 C3, що буде еквівалентно серії команд:

Модифікацію вимагають два файли Winload.exe, що знаходяться по шляхах:% SystemRoot% \ System32 \ і% SystemRoot% \ System32 \ Boot \. Тому після модифікації одного файлу не забудьте оновити і другий.

Коригування контрольної суми файлів

Є ще один тонкий момент. Візьміть в звичку, що якщо ви вносите winload.exe або ntoskrnl.exe, або будь-який драйвер початкового завантаження, то після всіх зроблених змін не забудьте перерахувати і поміняти контрольну суму (поле Checksum заголовка PE). Здійснюється це за допомогою утиліти LordPE або будь-якого аналогічного редактора PE-модулів. Причина проста: десь в коді Winload.exe є ще одна перевірка (яку я поки не зміг виявити), яка верифікує контрольну суму модуля, і при розбіжності йде на процес відновлення системи.

Ссылка на основную публикацию