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 -> SMSS -> Winlogon, часть каковой мы и будем рассматривать в данной статье. Начиная с 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.

21 комментарий:

  1. Илья

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

  2. Ростислав

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

    • einaare

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

  3. Дикий

    Ну, да.... Было купил нетбук б.у. на котором был такой "скрытый" раздел на диске "зарезервировано системой" 100 МБ - из чего понял, что стояла видимо Win 7 (с завода изготовителя нетбука).
    Перераспределил винчестер на два раздела, и так, что места не осталось для ещё одного, хоть и маленького раздела.
    То бишь, эти два раздела забрали под себя всё дисковое пространство.
    Потом на диск D поставил Win XP, а на диск С - Win 8. Никакого "зарезервированного системой" раздела естественно не появилось и все системные (загрузочные) файлы Win 8 легли в диск С.
    ----
    Интересная у Вас инфа... хотелось бы продолжения в том же русле... И к примеру, интересует вопрос: непосредственно перед выключением, когда уже отключается даже ведение журнала - какой то процесс в последние тройку секунд всё время переписывает файл BCD. Забрал себе права, остальным только чтение и выполнение. В свойствах файла ставлю галочку Только чтение. Перезагружаюсь.... Проверяю файл BCD: галочка Только чтение снята и изменено время Изменения файла - оно и равно примерно за тройку секунд (может побольше, десяток...два секунд - точно не мог измерить) до выключения (рестарта БИОС - если перезагрузка).
    Как вычислить какой процесс, перед перезагрузкой (выключением) меняет файл BCD ? И при этом игнорирует выставленные на файл Права.
    ---
    С веткой реестра: HKEY_LOCAL_MACHINE\BCD00000000 - аналогичный полтергейст. Там даже круче - обратно меняется Владелец ветки, а меня из групп допуска и вовсе выкидывают.
    Опять забираю себе Права - перезагружаюсь - меня в этой ветке уже нет (хотя я единственный Админ на этом буке). Система это всё игнорирует - Владельца, Права допуска.... возвращает всё обратно. Но ведь это тоже какой то системный процесс делает. Вопрос: какой ? В полтергейсты не верю :)

    • shofixti

      да, ситуация нетипичная.. кто может отслеживать активность непосредственно перед выключением? может стоит начать с этого: http://datadump.ru/boot-shutdown-issues-with-xbootmgr-xperf/
      команда: xbootmgr -trace shutdown -traceflags BASE+CSWITCH+DRIVERS+POWER+FILE_IO_INIT -numruns 1 –stackwalk Profile+CSwitch -resultpath C:\TEMP -noprepreboot

      • Дикий

        Ну, да... Это похоже, что помогло бы найти, что за процесс такой крутой, который игнорируя Права доступа к файлу (ветке реестра) переписывает BCD... Однако мой уровень подготовки в таких делах пониже, чем того хотелось бы, хоть и стараюсь его наращивать...
        Там по ссылке картинки есть... среди них картинка Services и по правой вертикали стопы процессов - насчитал 41 процесс. Какие из них могут менять файл BCD ? Или подозреваемый - всего один процесс ?

        • shofixti

          полученный отчет открываете через Windows Performance Analyzer, там в левом фрейме будет раздео storage.. при двойном щелчку на который в правом открывается дисковая активности. в правом фрейме на заголовке таблицы жмем правую кнопку мыши - выбираем path name.. начинает показывать целевой файл. но тем не менее, я не нашел там BCD. Он же не на диске C:, видимо обращение к скрытому разделу без литеры происходит по имени объекта как-то. Но эта активность в явном виде не видна.

          • Дикий

            BCD на диске С однако... Не сторонник делить винт на лишние разделы... Поэтому до установки Win 8.1, винт и разделил на 2 раздела, используя всё дисковое пространство. Соответственно Win 8 некуда было при установке девать свою загрузку (bootmgr и прочее), кроме как в диск С:\
            - - -
            А у Вас найдётся более "простое и элегантное решение" ?
            К примеру, как запретить системе постоянно перезаписывать BCD (если уж не подменять его на DBC) ?
            Кто то ведь это делает... Как то бы найти кто конкретно и малость его рихтануть.

        • shofixti

          ага, похоже обращение к скрытому разделу идет через $Mft .. в качестве процесса виден System, в контексте которого скрывается функционал ядра, имхо + драйвера.

  4. Дикий

    Собственно ближайшая цель раскопок:
    запретить системе менять файл BCD (либо ветку реестра HKEY_LOCAL_MACHINE\BCD00000000 - не могу понять, что из них меняется, а что лишь следствие этого изменения), что бы при перезагрузке ЭВМ (либо вкл/выкл) настроенное меню под Windows 7 не менялось (периодически) на восьмёрошное с целью предоставить мне выбор других действий - мне это не требуется. А потребуется - F8 нажму...
    Идея такая: по вышеизложенной статье автора - распаковать bootmgr > найти в нём путь \boot\BCD > поменять местами две буквы в имени файла (к примеру на: DCB) - такая хитрость спасёт от проверки файла по контрольной сумме на его оригинальность - и упаковать обратно bootmgr.
    Далее создать копию (к примеру на диск D) ориганального BCD, переименовать его в DCB и положить его по пути C:\boot\
    Что получится (теоретически): этот хитрый крутой процесс и далее будет перезаписывать файл BCD однако в холостую - файл уже не будет являться данными загрузки. Эти данные будут считываться с файла DCB, который менять будет уже некому... Цель будет достигнута.
    ---
    Вообще говоря далёк от мысли, что это МС беспокоится о безопасности пользователей в плане усложнения внедрения зловредов в ОС Windows вообще и в загрузчик в частности. Имею подозрение, что усложнение до такой степени (упаковка и далее постоянная распаковка bootmgr - как это следует из статьи автора) это не что иное, как первый этаж многоэтажной защиты от взлома ОС Windows.

    • shofixti

      имхо, Вы выбрали не самое простое решение. для того, что бы отключить взаимодействие (частично) с BCD, придется пропатчить ядро, поскольку именно в контексте процесса System (PID:4) работают функции из bootmgr/Winload/ntoskrnl по работе с файлом BCD. а переименование приведет к непредсказуемым последствиям, скорее всего по отказу в загрузке/завершении.. Надо искать более простое и элегантное решение.

      • Дикий

        Ваша мысль понятна, однако теоретически - чисто по логике не вижу никаких последствий (типо отказа в загрузке/завершении либо других), ибо ,при подмене на DBC, все , кроме bootmgr, кто как либо обращаются штатно к BCD - так и будут к нему обращаться на предмет его изменения или чтения с него данных, однако процесс загрузки будет идти уже в обход BCD, с использованием неменяющегося DBC.

        • Дикий

          Вроде как в заблуждение вводится словом "подмена BCD" - речь идёт о параллельном использовании обоих файлов, но DBC только для bootmgr, а штатный BCD - для всех остальных процессов. То бишь обоим файлам лежать рядом, в одной директории.

          • Дикий

            Плохо, что тут свою опечатку не отредактировать... Выше говорю об имени DCB (в опечатке DBC, хотя это и не принципиально, какие две буквы в итоге поменять местами).

            • einaare

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

            • einaare

              только вот распаковку и запаковку рекомендую производить при помощи BOOTMGR Recompiler v2.

              • Дикий

                Из Win XP - bootmgr_Recompiler_v2 не запустился...
                Распаковал указанной прогой из Win 8.1 x64. Получился с неё файл bootmgr_mod.
                Открыл этот файл HEX-редактором HEX Workshop Version 2.54 x32.
                Цепь boot\BCD прога не нашла (и только BCD - тоже).
                - - -
                Так же и при открытии в WinHex 10.47
                - - -
                Каким HEX-Editor_ом открыть, который увидит эту цепь ?

                • shofixti

                  открывайте его в Hex Editor Neo, например.. необходим редактор с поддержкой Unicode (UTF), поскольку строки все в нем.

  5. Дикий

    Из экспериментов ранее: забрал Права себе, остальным Чтение (что бы система видела, что оригинальный файл имеется, но не могла его выполнить) файлам:
    C:\Windows\System32\bcdedit.exe - Редактор данных конфигурации загрузки
    C:\Windows\System32\BCDboot.exe - Используется для создания или восстановления среды загрузки,
    расположенной в активном системном разделе
    C:\Windows\System32\bootcfg.exe - Перечисление или изменение параметров загрузки.
    C:\Windows\System32\bootsect.exe - Средство управления загрузочным сектором
    C:\Windows\bfsvc.exe - Утилита обслуживания файла загрузки
    -----
    Не найден в моей версии Windows 8.1 файл:
    bootrec.exe - Служит для исправления ошибок, связанных с повреждением загрузчика и,
    как следствие, невозможностью запуска операционных систем Windows 7
    -----
    Результат отрицательный - система всё равно файл BCD переписывает при каждой перезагрузке.
    При этом изменённые мной Права на эти файлы сохраняются (кроме BCD - атрибут только чтение система молча снимает и периодически изменяет сам файл. Дата и время файла изменяются постоянно, при каждой перезагрузке или вкл/выкл).

  6. Дикий

    NEO на Win 8 почему то не встал - установка прерывается в самом почти начале, без каких либо сообщений...
    Поставил HxD HEX Editor. Символьный поиск BCD - не найдено. Вбил тогда в поиск последовательность hex: 42 43 44
    - не найдено.
    Вариантов тогда вижу два:
    1) в Win 8.1 bootmgr если и использует BCD - то не напрямую, а через какого то посредника.
    2) искомая цепь к файлу C:\boot\BCD в bootmgr присутствует, но зашифрована (к примеру через политерное присвоение некоей переменной, по самому примитивному если, типо: Menu=ctr$42+ctr$43+ctr$44).
    - - -
    Ветка вроде не особо предназначена для общения... Буду рад с желающими продолжить эту тему через ВКонтакте (https://vk.com/id112809732) или как то ещё, где можно пообщаться.

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

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

Помощь сайту