Bootmgr - менеджер загрузки Windows 7

Метки:  , , , , , , , , , ,

Bootmgr (Boot manager, Windows Boot Manager) - это очередной этап развития загрузчиков (менеджеров загрузки) для операционных систем MS Windows. Bootmgr Windows 7 представляет собой дальнейшее эволюционирование хорошо известного нам по предыдущим версиям Windows загрузчика NTLDR, который был переписан с учетом потребности поддержки интерфейса EFI (Extensible Firmware Interface, Расширенный интерфейс прошивки), осуществляющего взаимодействие между кодом операционной системой и микрокодом, управляющим оборудованием. Тем не менее, загрузчик сохранил совместимость и со старой, традиционной схемой загрузки ОС, использующей последовательность BIOS -> MBR -> PBR (VBR) -> BOOTMGR -> winload.exe -> NTOSKRNL.EXE -> HAL.DLL, часть каковой мы и будем рассматривать в данной статье. Начиная с Windows Vista загрузчик операционной системы получил название bootmgr (bootmgfw.efi/bootmgr.efi для механизма загрузки EFI) и представляет собой гибридный исполняемый файл, располагающийся на скрытом системном разделе, и предназначающийся для подготовки среды загрузки ядра, обеспечения простого интерфейса взаимодействия с пользователем на начальном этапе, и загрузки непосредственно кода ядра операционной системы.

Начиная с версии Windows 7, даже при использовании классического способа разметки/загрузки (BIOS->MBR) появился специализированный скрытый раздел под названием System Reserved (Зарезервировано системой).

Тут самое время задаться вопросом, зачем разработчикам вводить отдельный раздел для классической схемы загрузки (BIOS/MBR)? Ведь раньше то ничего подобного не создавалось, все прекрасно загружалось без всяких там скрытых разделов, все файлы цепочки загрузки находились на основном системном разделе, куда же проще? А ответ, как мне кажется, достаточно прост. Выше мы уже упомянули, что схема загрузки была переделана Microsoft с учетом потребностей новой технологии UEFI, в которой для этих целей активно используется специальный раздел ESP. Так что же, для UEFI использовать один алгоритм загрузки, а для классической BIOS/MBR оставлять традиционный? Подобное решение влечет за собой огромное количество проблем и необходимость обновления двух веток кода, не проще ли привести все "к одному знаменателю", и традиционную и UEFI-загрузки реализовать в рамках единого алгоритма, и для традиционной схемы создав специальный раздел? Собственно что и было сделано.
Поэтому, раздел System Reserved в традиционной схеме загрузки (BIOS/MBR) предназначается для:

  • приведения иерархий разметки диска/файловой системы (используемых при традиционной (legacy) загрузке) в соответствие с аналогичной структурой стандарта UEFI: размещение на разделе (в классифицированном дереве директорий) файлов операционной системы, фигурирующих в начальном этапе загрузки ОС (Bootmgr/BCD);
  • дополнительной защиты загрузочных файлов операционной системы от (не)преднамеренных деструктивных действий приложений/пользователя;
  • хранения загрузочных файлов BitLocker Drive Encryption в случае, если используется шифрование разделов;

Раздел этот создается автоматически на этапе установки операционной системы и имеет типовой размер порядка 100Mb (хотя может быть уменьшен до 30Mb без потери функционала).
Но вернемся к нашему загрузчику Bootmgr. По внутренней структуре файла, которую мы подробнее рассмотрим далее, bootmgr представляет из себя некий гибрид из блока кода на языке ассемблера, и встроенного образа PE-формата (написанного на языке C) с ресурсами и дополнительными секциями, содержащими наборы рабочих данных.

Где находится bootmgr Windows 7

В ОС Windows 7 bootmgr имеет довольно ощутимый размер для файла загрузки (в тестовой системе = 383786 байт), поскольку, как мы сможем увидеть позже, по большей части написан на языке высокого уровня, в отличии от кода MBR и PBR, которые реализованы на низкоуровневом языке Ассемблера и имеют более скромные размеры. Располагается bootmgr в корневом каталоге основного активного скрытого раздела размером в 100 мегабайт. Данный раздел размещается в начале диска, предваряю остальные разделы. Партиции этой не присваивается логического имени (буквы диска), поэтому в самой операционной системе она невидима для стандартных пользовательских средств. Как вы можете догадаться, таким вот незатейливым способом данная партиция защищена от деструктивных действий пользователя, могущих повлечь за собой повреждение критически важной загрузочной информации.
Для того, чтобы найти файл bootmgr в системе, необходимо сначала научиться взаимодействовать со скрытым разделом. Для этого открываем апплет Управление компьютером, щелкнув правой кнопкой мыши на иконке "Компьютер" и выбрав пункт "Управление", либо можно запустить (Win+R) из командной строки diskmgmt.msc. Текущий пользователь должен иметь права администратора. В ответ на это действие откроется окно следующего вида:

Скрытый раздел содержащий bootmgr windows 7

Для того, чтобы увидеть содержимое скрытого раздела, нам необходимо назначить ему логический номер (букву). На рисунке (схематично) я обозначил последовательность действий, которые нам необходимо предпринять. После выбора пункта "Изменить букву диска или путь к диску" у нас появится следующее окно выбора:

Назначение буквы диска разделу, содержащему bootmgr windows 7

После нажатия кнопки ОК логическое имя будет присвоено разделу и он станет доступен в проводнике. Содержимое его, которое нам как раз и необходимо, наконец-то можно увидеть. Но это еще не все, дело в том, что некоторые файлы и директории раздела имеют атрибут "скрытый", поэтому нам нужно включить отображение скрытых и системных файлов. Это можно сделать в свойствах папки (Параметры папок и поиска - Вид). А теперь, давайте взглянем на искомый нами файл bootmgr, который можно увидеть прямо в корне партиции:

Структура скрытого раздела, содержащего bootmgr windows 7

На рисунке бывает порой сложно, а чаще и вовсе не получается наглядно отобразить всю структуру раздела, поэтому приведу его в виде текстового списка. Итак, содержимое скрытого раздела "Зарезервировано системой" выглядит следующим образом:

По комментарию напротив (справа от) каждого файла в окне представления вы можете увидеть краткое описание функционального назначения.
Хотелось бы сделать некое лирическое отступление и поговорить о файлах, имеющих расширение .mui. Если вы были достаточно внимательны, то обратили внимание, что одноименные файлы с расширением .mui имеют значительно меньший размер в сравнении со своими оригиналами. Это объясняется тем, что .mui-файл - это файл ресурсов, который содержит элементы локализации интерфейса основной программы для определенного языка. Проще говоря - это перевод интерфейса программы. Технология впервые была использована в ОС Windows Vista и предназначалась для связывания ресурсов, описанных в языковом файле (текст меню, диалоговых окон, строк помощи и прочее.) с независимым от языка основным исполняемым файлом.
Но, вернемся к основной линии повествования. Управление код bootmgr Windows 7 получает сразу после своей загрузки кодом загрузочного сектора раздела PBR.

Структура файла bootmgr Windows 7

По анализу кода загрузочного сектора раздела (PBR) в предыдущих статьях нам удалось определить, что первый файл, который загружается и выполняется после кода PBR, это bootmgr, находящийся в корне скрытого системного раздела. Интересно было бы посмотреть на структуру этого файла.

Дабы в следствии экспериментов не вывести систему из работоспособного состояния, стоит сделать резервную копию файла bootmgr в какой-нибудь временной директории, к примеру %TEMP%.

С чего мы начнем изучение? Первое, что приходит на ум, это визуально осмотреть структуру файла с помощью любого доступного под рукой шестнадцатеричного редактора. Что мы и сделаем сейчас, в моем случае я воспользовался встроенным в файловый менеджер FAR Commander редактором, переключив его в режим шестнадцатеричного представления.

Структура файла bootmgr Windows 7

При беглом осмотре структуры, удалось обнаружить некоторые особенности.

  • 16-битный загрузчик. Начиная со смещения 00000000 предположительно идет код, напоминающий по виду код реального режима (aka ассемблер). Вероятно, у bootmgr есть участок кода, который исполняется в реальном 16-битном режиме процессора сразу после прыжка из кода PBR (поскольку код PBR не переводит процессор ни в какой другой режим). Я думаю, что код этот производит некие подготовительные действия. Предположительно (!) в файле он размещается до адреса 00003DDF.
  • PE-образ неопределенного назначения. Далее, по смещению 00005BF0 удалось обнаружить некое подобие стандартного заголовка PE-образа, который начинается с сигнатуры MZ (4D 5A). Насколько я понял, этот образ располагается вплоть до адреса 00007BF0, то есть имеет размер 8192 байта (2000h). Этот образ содержит PE-заголовок, но при этом имеет не все типовые секции (такие как секции кода, данных, ресурсов). Многие из этих секций заполнены нулями, поэтому я могу сделать предположение, что он вообще не исполняется.
  • Запакованный bootmgr.exe. Затем, удалось найти еще один PE-образ по смещению 00007BF0, который так же начинается со стандартной сигнатуры MZ и размещается вплоть до самого конца файла bootmgr Windows 7.
Portable Executable — (PE, дословно: переносимый исполняемый) — формат исполняемых файлов, используемый во всех версиях операционной системы Microsoft Windows

По сути, на основе тех данных, которые нам только что удалось получить при беглом, поверхностном анализе данных, файл bootmgr имеет три составных части:

  1. некий 16-битный код-загрузчик;
  2. пустой PE-образ: назначение неизвестно;
  3. еще один PE-образ: предположительно 32-битный запакованный файл bootmgr.exe;

На этом предварительный анализ заканчивается. Теперь нам предстоит более предметно подойти к вопросу и попробовать "в лоб" дизассемблировать bootmgr Windows 7 с целью понять, действительно ли код, располагающийся в начале файла, простой участок кода реального режима?

16-битный загрузчик (16-bit stub)

В самом начале исходного кода я обнаружил (традиционный) блок настройки сегментных регистров. Базу сегмента я не корректировал пока (уверен, что при переходе от PBR они имеют другие значения), поскольку не разобрался, с какого адреса стартует этот участок кода.

Затем, далее по кодовому ветвлению, идет сброс контроллера диска.

Далее следует включение линии A20.

Потом код инициирует переход в защищенный режим.

А вот после этого начинается довольно большой участок кода, который активно манипулирует блоками данных и выполняет над ними различные арифметико-логические операции. Пока я пытаюсь разобраться в хитросплетениях кодов, поскольку знания мои не позволяют столь легко оперировать ассемблером, сколь бы хотелось. Очень похоже на код распаковки 32-битного образа bootmgr.exe. Затем идут процедуры подготовки окружения для запуска 32-битного образа. Образ распаковывается и размещается по адресу 0x400000, то есть мы видим уже классическую схему загрузки исполняемого файла Windows.

Заголовок размером 16 байт

Используется 16-битным блоком кода реального режима для определения параметров распаковки файла bootmgr.exe.

PE-образ размером 8192 байта неизвестного предназначения

Содержит структуру PE-заголовка. Заглушку для вывода ошибки при запуске в реальном режиме. Часть секций присутствует. Большинство секций заполнены нулями.

32-битный PE-образ bootmgr.exe

Как мы уже упоминали выше, последним найденным блоком данных был файл bootmgr.exe, правда основная проблема заключается в том, что он запакован (сжат). Поэтому, непосредственно перед изучением логики его работы, нам необходимо извлечь (и распаковать) этот файл из загрузчика bootmgr. Для выполнения извлечения и распаковки на просторах бескрайней Сети я нашел утилиту под названием bmzip, которую можно найти на странице автора тут. В моём случае распакованный файл bootmgr.exe занимал 523648 байт. А вот теперь то уже этот самый распакованный файл bootmgr.exe мы и попытаемся "подсунуть" дизассемблеру IDA.

Блок-схема алгоритма bootmgr windows 7

Выполнение кода bootmgr.exe начинается с основной процедуры модуля, которая носит название BmMain.
Процедура BmMain вызывает процедуру BlInitializeLibrary, которая, предназначена для инициализации критических структур данных, таких как внутренние переменные, различные физические устройства компьютера. Эта процедура вызывает следующие подпрограммы:

  • BlpArchInitialize -- инициализация таблиц дескрипторов GDT, IDT и прч.
  • BlpFwInitialize -- firmware
  • BlpTpmInitialize -- инициализация TPM
  • BlpIoInitialize --- инициализация файловых систем
  • BlpPltInitialize -- инициализация шины PCI
  • BlBdInitialize -- инициализация отладчика ядра
  • BlDisplayInitialize -- инициализация консоли
  • BlpResourceInitialize -- инициализация внутренней секции ресурсов .rsrc
  • BlNetInitialize -- Инициализация сети.

На этапе окончания подготовки рабочей среды вызывается процедура BmpInitializeBootStatusDatalog: она записывает состояние загрузки в файл bootstat.dat.
Исполняется BmpLogBootResolutions.
Исполняется BlResourceFindXml, которая отвечает за поиск и распаковку файла bootmgr.xsl из ресурсной секции .rsrc. Заданный файл содержит параметры меню загрузки.
Исполняется BlXmiInitialize: ожидает выбора пользователя (ввод с клавиатуры), либо инициализирует загрузку загрузочной записи, если она единственная.
Исполняется BlImgQueryCodeIntegrityBootOptions: Проверяет корректность записей загрузки и загружаемых образов.
Исполняется BmFwVerifySelfIntegrity: проверяет собственную целостность. Для отключения проверки целостности модулей используется функция ImgpValidateImageHash.
Исполняется BinResumeFromHibernate: проверяет статус гибернации, если находит, то вызывает winresume.exe.
Исполняется BlUtlRegisterProgressRoutine
Исполняется BlUtlRegisterMulticastRoutine

Функция BlXmiWrite тут вряд ли уместно приводить в составе основной логики функционирования bootmgr (поэтому я его и затенил на рисунке), поскольку это исключительно функция поддержки, которая парсит XML данные и выводит их на консоль.

Исполняется BlGetBootOptionBoolean: загружает опции приложений из файла BCD.
Исполняется BlGetBootOptionGuidList
Исполняется BmpGetSelectedBootEntry
Исполняется BmCloseDataStore
После определения записи загрузки вызывается процедура BmpLaunchBootEntry, которая и загружает образ, ассоциированный с записью.
В основной ветке кода, на завершающей стадии работы, bootmgr.exe проводит загрузку, проверку целостности и передачу управления на модуль следующей стадии загрузки операционной системы - winload.exe.

4 комментария:

  1. Илья

    В Windows Vista не было скрытого раздела. Он появился в Windows 7 и создан для защиты загрузочных файлов от пользователя.

  2. Ростислав

    После установки удалил раздел 100 Мб - Windows перестает загружаться. Восстановил с помощью Acronis - заработало. Разметил винчестер так, что место отсутствует, и переустановил Windows. Файл BootMGR оказался в корне системного раздела. Теперь всегда так делаю. Кстати, в Windows 10 уже 350 Мб

    • einaare

      что, серьезно? то есть скрытый раздел не создается а система при установке размещает bootmgr уже на существующем единственном системном разделе, на который впоследствии переписывается и директория \Windows?

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *