Как открыть bootmgr для редактирования

Изучаем Bootmgr. Часть 1 — инструментарий и основные принципы отладки начальных этапов загрузки ОС Windows

Возможно некоторые читатели помнят мою самую первую статью на ресурсе, посвященную загрузке Windows с VHD-образа. Возможно я бы и не вернулся к этой теме, если бы не нашлись люди, попытавшиеся повторить данную технологию на своих домашних машинах. Естественно, с реализацией этого решения возникли проблемы, касающиеся в основном тех ошибок, которые выплевывает bootmgr в тех случаях, когда ему что либо не нравится. Попытки интерпретации ошибок загрузки вроде 0xc03a0003 путем гугления к особо ценным результатам не приводят, а документация Microsoft на этот счет хранит многозначительное молчание. Возникла идея изучить процесс обработки VHD-образов, получив информацию из первых рук, то есть от самого загрузчика.

Если обратится к уже имеющейся в сети информации, то существует замечательный блог «Записки эникейщика о Windows» на страницах которого (раз, два и три) размещены, на мой взгляд, самые ценные сведения, по вопросам устройства bootmgr. Автор подробно рассмотрел процесс загрузки, включая исследования кода MBR и PBR, остановившись на структуре bootmbr, кратко описав происходящие при его работе процессы.

Мы же пойдем дальше — опишем инструментарий, который можно использовать для изучения устройства загрузчика и попытаемся разобраться с некоторыми, интересующими нас алгоритмами. Если такое предложение показалось кому-то интересным, милости прошу под кат

1. Достаем код Bootmgr из системы

Загрузчик Bootmgr появился в операционных системах семейства Windows начиная с Windows Vista. Причиной его разработки послужило то, что старый добрый ntldr, использовавшийся в линейке NT не мог загружать систему, на компьютерах с материнскими платами оснащенными UEFI, в те времена (2005 год) мало распространенными среди широкого круга рядовых пользователей.

По умолчанию, при штатной установке, этот загрузчик помещается в отдельный раздел, расположенный в начале HDD, с размером, достаточным для размещения самого bootmgr а так же файлов его конфигурации. Данный раздел не монтируется в обычном режиме работы системы и буква диска ему не присваивается. В системах с MBR создания этого раздела можно избежать, устанавливая Windows на предварительно размеченный и отформатированный HDD. В этом случае загрузчик помещается в тот же раздел, что и файлы ОС. Системы с EFI + GPT изначально требуют наличия такого раздела, имеющего тип 0xef и отформатированного в FAT.

Таким образом, первая наша задача — добыть bootmgr. Желательно взять его из системы, которая будет выступать в роли подопытной. Для этого установим ОС Windows на виртуальную машину. Это может быть и VirtualBox, и VMware, и QEMU — всё зависит от того, каким инструментарием виртуализации вы располагаете. Я преимущественно работаю в ОС Linux, буду в основном ориентироваться на инструменты применяемые там, хотя уделю внимание и Windows.

Итак, предположим у нас есть виртуальная машина (ВМ) с установленной на ней Windows 7 (x86). Разметка диска выполнена на основе MBR, система установлена в один раздел. Допустим это QEMU, диск на котором установлена подопытная имеет формат raw. то есть обыкновенный двоичный образ. Монтируем этот образ

На смонтированном разделе мы увидим следующее содержимое

Для нас представляет интерес файл bootmgr. Однако, прежде нам нужен не совсем он, а 32-разрядный образ загрузчика bootmgr.exe, который находится в bootmgr в упакованном виде. Для его распаковки необходимо использовать утилиту bmzip, которая написана в общем-то для Windows (с наскока собрать её под Linux не вышло), поэтому распаковку выполним на виртуальной машине. Бинарную сборку этой утилиты, которая бы работала нормально оказалось довольно трудно найти, несмотря что тут дана ссылка на неё. В итоге, пакет был найден на каком-то из сайтов, посвященных кастомизации bootmgr. Для работы bmzip оказалась необходима библиотека MSCompression.dll. Готовый к работе пакет теперь можно скачать тут.

Создадим на диске ВМ папку utils и скопируем туда bmzip.exe вместе с MSCompression.dll. Отмонтируем образ и запустим ВМ. Запустим командную строку от имени администратора. Чтобы случайно не попортить загрузчик сделаем его копию

Файл загрузчика является скрытым и системным, поэтому снимем с него эти атрибуты

В итоге получаем распакованный образ bootmgr.exe

Как открыть bootmgr для редактирования

Выключаем ВМ и снова монтируем её диск в линуксе. Создадим какую-нибудь папку, где будем потрошить загрузчик дизассемблером и скопируем туда распакованный образ

2. Дизассеблируем bootmgr.exe

Теперь скормим полученный «экзешник» дизассемблеру. Например IDA Pro. Запустим «иду» и откроем в ней добытый файл.

Как открыть bootmgr для редактирования

IDA верно идентифицирует файл как 32-разрядный исполняемый файл формата PE. Жмем ОК. Теперь, если в IDA Pro установлен плагин для работы с pdb-файлами, по ходу дизасеммблирования нам предложат загрузить отладочные символы, и не откуда нибудь, а сайта Microsoft.

Как открыть bootmgr для редактирования

Соглашаемся и получаем такую картину

Как открыть bootmgr для редактирования

Ага, слева мы видим прототипы функций, содержащихся в исследуемом файле, благодаря тому что согласились загрузить отладочные символы. Это очень сильно облегчит нам последующую работу. А пока определим точку входа в код загрузчика, и нетрудно догадаться что это будет функция BmMain(). Однако, не принимая это на веру жмем Ctrl + E

Как открыть bootmgr для редактирования

убеждаясь что наша догадка верна — BmMain() является точкой входа, расположенной по адресу 0x401000. Жмем ОК и перемещаемся на начало кода

Как открыть bootmgr для редактирования

Видим мы заголовок функции BmMain() с внушительным списком локальных переменных, и чуть ниже и сам код функции

Как открыть bootmgr для редактирования

Разобраться в мешанине ассемблерного кода довольно трудно, да и не зачем этого делать. Прежде всего определимся с тем, какие функции загрузчика мы хотим изучить. Я что-то там говорил о VHD? Ну так поищем среди кода что-нибудь, касающееся виртуальных дисков. Щелкаем правой кнопкой по списку функций слева и в вывалившемся контекстном меню выбираем «Quick filter» (или перейдя в окно с прототипами жмем Ctrl + F). В строке поиска набираем «vhd» и…

Как открыть bootmgr для редактирования

да, таковые функции имеются в количестве 33 штук. Среди них VhdOpen() очевидно будет отвечать за открытие виртуального диска, а вот например VhdiVerifyVhdFooter() как пить дать отвечает за проверку футера VHD-диска на корректность. То есть мы примерно представляем себе, куда будем ставить точки останова в отладчике. Кстати, поговорить об отладке самое время

3. Отладка Bootmgr на связке QEMU + IDA Pro

ВМ запускается и сразу же становится на паузу, ожидая подключения отладчика

Важно! Ни в коем разе не используйте ключ -enable-kvm применяющий аппаратную виртуализацию. При её использовании отладка в QEMU не работает.

Теперь на панели инструментов в IDA выбираем отладчик «Remote GDB debugger»

Как открыть bootmgr для редактирования

Ответив «Да» на несколько заданных нам вопросов получим окошко

Как открыть bootmgr для редактирования

где вобьем параметры соединения с ВМ: localhost на порту 1234. Жмем ОК. Нам сообщат, что некоторый процесс уже запущен и ожидает подключения отладчика — не хотим ли мы присоединится к нему? Конечно же ходим!

Как открыть bootmgr для редактирования

Поэтому отвечаем «Да» и.

Как открыть bootmgr для редактирования

мы встаем на паузу где-то в начала bios виртуальной машины. Великолепно, но теперь мы должны добраться до того места, где начинает выполнятся bootmgr. Ставим точку останова на функции BmMain(). Нажимаем на панели инструментов список точек останова, жмем Insert на клавиатуре и указываем на каком адресе мы хотим прервать выполнение кода и перейти в отладку

Как открыть bootmgr для редактирования

Как открыть bootmgr для редактирования

Теперь мы можем проходить код по шагам, смотреть значения регистров и стека, отслеживать стек вызовов и так далее. В какой-то степени отладчик, встроенный в IDA удобен и интуитивно понятен.

Возможно меня спросят — а можно ли использовать GDB? Можно, запускаем ВМ в режиме отладки, запускаем gdb в консоли

Подключаемся к удаленной сессии ВМ

Включаем отображение дизассемблированных инструкций

Если вас не устраивает синтаксис AT&T переключаемся на интел

Ставим точку останова на BmMain() и запускаем исполнение

Пожалуйста, мы видим почти тоже самое, что видели в IDA, располагая при этом всей мощью GDB. Почти, потому что тут мы не сумеем использовать отладочные символы от Microsoft, ибо GDB их не понимает. Но возможности GDB не в пример более широки, чем возможности IDA именно в плане процесса отладки и его автоматизации.

Однако, существует ещё одна возможность отладки, мимо которой пройти нельзя

3. Отладка на связке WinDbg + VirtualBox

Те, кто занимается разработкой драйверов для ОС Windows безусловно знакомы с этим замечательным отладчиком. Замечателен он тем, что имеет возможности сравнимые с возможностями линуксового GDB. Единственным его недостатком является жуткий способ настройки его интерфейса. Но мы опустим эти моменты, а обратимся к возможностям данного отладчика для решаемой нами задачи.

Итак, пускай на у нас имеется ВМ на основе VirtualBox. Создадим для этой ВМ COM-порт со следующими параметрами

Как открыть bootmgr для редактирования

Это виртуальный COM-порт, пробрасываемый в именованый канал. Для отладки через последовательный порт виртуальную машину следует настроить соответствующим образом. Загружаем её и запускаем консоль с административными правами. С ней вводим команды настройки загрузчика для отладки

Эта команда включит возможность отладки загрузчика. Далее настроим порт для отладки

Указываем, что мы используем COM1 со скоростью 115200 бод. Отлично, выключаем ВМ и запускаем отладчик.

Отладчик WinDbg можно скачать официально с сайта Microsoft вместе с комплектом для разработки драйверов. Однако у этой сборки отладчика есть проблема — глюк с отображением значений регистров. Поэтому я использую сборку, которая качается с того же сайта редмодовцев, на которую ведет ссылка из твитера некоего Доминика Вонга. В этой сборке данный баг отсутствует. Запускаем WinDbg следующей командой

Теперь запустим ВМ. Практически сразу она встанет на паузу, а в окне отладчика мы увидим следующую картину

Как открыть bootmgr для редактирования

Ага, отладчик подключился к ВМ и встал на точке, любезно предоставленной нам майкрософтом. Ну что же, теперь нам доступны все возможности отладки с использованием windbg.

Однако мы останавливаемся не в самом начале кода загрузчика, а чуть дальше. Как показывает пошаговая отладка мы находимся как раз за функцией BlInitializeLibrary() которая обеспечивает начальную инициализацию оборудования

Как открыть bootmgr для редактирования

и, при отладке при помощи IDA мы сюда просто не попадаем. Таким образом, при отладке с WinDbg от нас ускользает часть действий bootmgr сразу после его запуска. В этом заключается недостаток использования стандартных средств отладки, предоставленных Microsoft. Однако, недоступный код мы всегда сможем исследовать отдельно с помощью IDA.

Теперь, в качестве примера, посмотрим на то, как bootmgr работает с образами VHD фиксированного размера.

4. Отлаживаем загрузку с VHD

Всё ниже следующее рассматривается на отладчике WinDbg, подключенном к ВМ на VirtualBox, но в равной степени справедливо и для других методов отладки, с учетом их особенностей. ВМ, используемая в данном примере содержит две системы: одна установлена на HDD, другая на VHD образ. Поставим точку останова на функции VhdOpen()

и нажмем F5. Отладчик встанет на указанной функции

Как открыть bootmgr для редактирования

Причем, внимание — мы ещё вообще не заходили в меню загрузки и не выбирали загрузку из VHD. А это означает, что проверка VHD происходит задолго до появления меню. Такое же поведение мы и наблюдаем, например если подсунем bootmgr пустой VHD. Меню загрузки нам вообще не покажут, а покажут ошибку с кодом 0xc000000F.

Проходим чуть дальше, нажимая F10 или вводя в комадной строке p и дойдем до вызова VhdiAllocateVhdData() — очевидно это создание в памяти некоторых структур для работы с образом

Как открыть bootmgr для редактирования

Чуть ниже расположен вызов VhdiVerifyAndInitializeVhd() — очевидно проверка корректности образа. Это показалось мне интересным и я пошел внутрь (F11)

Как открыть bootmgr для редактирования

Ниже, после некоторых подготовительных операций загрузчик читает последние 512 байт образа, в которых содержится так называемый «футер» образа, вызывая функцию VhdiReadVhdInformation(). Не надо ходить к гадалке, чтобы понять — функция возвратит указатель на структуру, содержащую данные футера. Как мне удалось выяснить, этот указатель, после вызова VhdiReadVhdInformation() оказывается в регистре ecx. Его значение равно 0x110098. Посмотрим на память по тому адресу

Команда читает память по указанному адресу, выводя её в окно отладчика в виде последовательности байт

Ага, мы видим знакомое слово — conectix. Это поле предваряет футер VHD образа, носит название cookie и хранит память о том, что Microsoft купила технологию VHD у фирмы Conectix, которая разработала данный формат виртуальных дисков для старых компьютеров Macintosh, Это несомненно футер VHD, мы можем видеть тут сигнатуру операционной системы в которой он был создан (Wi2k) а так же последовательность win указывает на то, что VHD создан средствами Windows. Да, все так и было. Пройдя чуть дальше мы натыкаемся на вызов VhdiVerifyVhdFooter() проверяющий формат футера. В качестве параметра он получает указатель на вышеописанную структуру, почему-то через регистр esi (. )

Как открыть bootmgr для редактирования

Этот участок кода интересовал меня больше всего, поэтому где-то с помощью IDA Pro, где-то руками, я преобразовал его в псевдокод на C

Футер VHD можно представить в виде следующей структуры (в комментариях указаны смещения от её начала).

Пользуясь этими данными можно сделать вывод о том, какие поля футера проверяет bootmgr и какие ошибки он выбрасывает. При корректном VHD образе данная функция возвращает ноль, в иных случаях расклад таков

Полученная мной информация решила спор возникший с коллегой по форуму, на котором обсуждалась методика загрузки Windows с VHD. Я его проиграл, считая что образы, созданные VirtualBox не будут грузится с помощью bootmgr. VirtualBox, создавая такие образы пишет все поля в соответствии со спецификацией Microsoft, кроме поля creator_application, куда записано win в оригинальном образе и vbox в случае с виртуалбоксом. Но это поле не проверяется bootmgr-ом, так что диски работают, а у меня они не работали по совсем другой причине, которая является предметом совсем другой истории.

Заключение

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

Источник

Редактирование меню загрузчика Windows

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

Сегодня займемся непосредственно редактированием конфигураций вариантов загрузки Windows. Речь пойдет о современном диспетчере загрузки Bootmgr, который впервые появился в Windows Vista, а точнее, о сопутствующем ему редакторе системного хранилища BCD (Boot Configuration Data) — bcdedit.exe и его командах.

Надо сказать, что редактировать меню загрузки операционных систем приходится не так уж и часто. Такая необходимость может возникнуть, когда на одном компьютере нужно установить несколько операционных систем, или в случае аварийной ситуации.

В контексте материалов, опубликованных на блоге, примеры редактирования данных конфигурации загрузки встречались уже несколько раз. Например, в статье, в которой описывалась загрузка операционной системы Windows 7 с другим (модифицированным) ядром. Или при обсуждении загрузки операционной системы с виртуального диска.

Возможности графического интерфейса Windows по редактированию меню загрузчика

До того, как мы начнем разбирать основные команды консольного редактора bcdedit, посмотрим какие графические утилиты предоставляет Windows для редактирования меню загрузчика и убедимся, что они предельно ограничены.

Если открыть элемент “Система” в “Панель управления” или, что то же самое, «Свойства» в контекстном меню (по правой кнопке мыши) «Компьютер» и дальше “Дополнительно” –> “Загрузка и восстановление” –> “Параметры”, откроется окно “Загрузка и восстановление” >

Как открыть bootmgr для редактирования

Единственное, что можно сделать в этом окне, это выбрать из выпадающего списка операционных систем, если их несколько, систему, загружаемую по умолчанию, и изменить время отображения списка в процессе загрузки.

Вторым вариантом редактирования BCD с использованием GUI (Graphical user interface) является оснастка «Конфигурация системы». Для ее запуска нужно в окне «Выполнить», или в командной строке, набрать и запустить msconfig >>

Как открыть bootmgr для редактирования

Дополнительно к тем немногочисленным возможностям, которые предоставляет апплет «Система» из «Панель управления», на вкладке «Загрузка» в «Конфигурация системы» можно еще удалить любой неактивный вариант загрузки. Это уже кое-что, но явно недостаточно для полноценного редактирования BCD.

Поэтому, придется о GUI забыть и обратиться к консольным командам редактора bcdedit.

Консольное редактирование меню диспетчера загрузки Windows

Сложного ничего нет. Главное понимать, что и зачем делаешь. Редактор bcdedit.exe, который находится в папке …\Windows\System32, нужно запускать с правами администратора — клик правой кнопкой мыши на «Командная строка» –> «Запуск от имени администратора».

Без параметров bcdedit выведет всю информацию о вариантах загрузки, записанную в хранилище BCD >

Как открыть bootmgr для редактирования

Комментировать все строки, которые мы видим на представленном фрагменте экрана, особого практического смысла нет. Кроме того, часть из них понятна и без объяснений. Выделим те, которые могут в первую очередь пригодиться на практике.

идентификатор — заключенный в фигурные скобки <> (скобки в командах писать обязательно) 36-символьный, 32-значный, номер записи, в которой прописаны параметры загрузки операционной системы. Для системы, загруженной в данный момент, номер заменяется на . Система, загружаемая по умолчанию, обозначается как .

Для того, чтобы не набирать на клавиатуре такой длинный идентификатор, очень удобно воспользоваться текстовой копией выдачи bcdedit. Для этого нужно кликнуть правой кнопкой мыши в любом месте окна командной строки, в появившемся контекстном меню выбрать «Выделить все» и нажать на клавиатуре «Enter». Аналогичного, но выборочного, результата можно добиться, выбрав в контекстном меню «Пометить» и выделив далее нужные строки. Далее запускаем текстовый редактор «Блокнот» и вставляем в новый файл содержимое буфера обмена.

device — раздел, на котором расположены файлы загрузчика операционной системы. Соответственно, для секции «Диспетчер загрузки Windows» это активный системный раздел, для секции «Загрузка Windows» — загрузочный раздел конкретной операционной системы;

description – название операционной системы, отображаемое в списке во время загрузки;

path — путь к загрузчику ОС;

displayorder, timeout – соответственно, порядок отображения вариантов в меню загрузки и время в секундах показа самого списка до начала загрузки дефолтной ОС.

Для того, чтобы изменить значение любого параметра, нужно запустить bcdedit с соответствующими ключами. Например, изменяем название операционной системы в меню:
bcdedit /set description «Новое название системы» где – идентификатор записи для данной ОС (вот тут очень пригодится подстановка из сохраненного текстового файла);

bcdedit /displayorder … указываем порядок отображения вариантов загрузки в меню.

Возможны действия с одной записью:
bcdedit /displayorder / addlast |addfirst |remove| – добавить запись в конец | начало списка | удалить (только из меню);

bcdedit /timeout XX – время отображения меню в секундах;

bcdedit /default — указываем систему, которая будет загружаться по умолчанию.

Наиболее вероятные варианты применения команд редактора bcdedit

Первое, что имеет смысл сделать до начала любых операций с BCD, это создать копию содержимого системного хранилища конфигурации загрузки:
bcdedit /export «C:\Backup\bcd-backup» где C:\Backup\ – произвольно выбранная для хранения папка, а bcd-backup – произвольное имя файла копии хранилища.

bcdedit /import «C:\Backup\bcd-backup» – противоположная команда. Восстанавливает содержимое хранилища конфигурации загрузки из его копии.

Создать новую загрузочную запись можно различными командами. Если тип новой системы аналогичен уже существующей, то имеет смысл воспользоваться командой копирования:
bcdedit /copy /d «Название новой системы»

Если в качестве «образца» выступает текущая операционная система, то команда будет выглядеть так:
bcdedit /copy /d «Название новой системы» Эта команда сразу добавит новую запись в загрузочное меню.

Если новая загрузочная запись создается «с нуля», то нужно использовать:
bcdedit /create /d «Название новой системы» /application osloader где/application задает тип приложения.

Для создания загрузочной записи NTLDR для загрузчика ОС прежних версий, например, Windows XP:

bcdedit /create /d «Microsoft Windows XP»

Дополнительно нужно указать на каком разделе диска находится загрузчик системы:
bcdedit /set device partition=X: где Х: — буква диска раздела, на котором находятся файлы загрузчика, и путь к нему:
bcdedit /set path \ntldr

Запись можно добавить в конец списка ОС в меню:
bcdedit /displayorder /addlast

Создание записи для системы, загружаемой с виртуального диска (VHD):

bcdedit /copy /d «Система на VHD» — создаем новую запись на основе текущей;

Запускаем bcdedit без параметров и копируем новый .
bcdedit /set device vhd=[X:]\DIR\filename.vhd — указываем полный путь к виртуальному диску, на котором лежат файлы загрузчика (системный раздел). Буква диска указывается в [];
bcdedit /set osdevice vhd= [X:]\DIR\filename.vhd — указываем местоположение виртуального диска с основными файлами операционной системы (загрузочный раздел);
bcdedit /displayorder /addlast — добавляем новую запись о системе в конец списка.

В статье, посвященной установке Windows 8.1 на виртуальный диск, представлен альтернативный способ создания соответствующей загрузочной записи в BCD.

В заключении рассмотрим команды удаления:

bcdedit /delete – удаление записи из хранилища;

bcdedit /deletevalue – команда удаляет элемент данных из записи в хранилище данных конфигурации загрузки, где — параметр, который следует удалить из указанной записи.

Естественно, все команды в короткой статье рассмотреть невозможно, поэтому в случае затруднения используйте встроенную справку:
bcdedit /?

Источник

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

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