Написать код MBR

Я инженер-электрик, который недавно обнаружил необходимость изменить код в MBR. По сути, мне нужна возможность выполнять код на жестком диске до того, как ОС запустится и вступит во владение.

Я полностью понимаю, что это нужно будет записать на ассемблере и с учетом примерно 446 байтов или около того пространства кода в MBR, я просто ожидаю вызова другого кода за пределами MBR. У меня вопрос, как лучше записать в MBR? Если я хочу изменить MBR, скажем, диска HDD_1... Лучше ли подключить HDD_1 к другой машине и затем записать на нее, либо записать на нее напрямую (вне окон) в текущей машине. Я полагаю, что вставлю вызов и оставлю остальную часть MBR в покое.

Мы ценим любые предложения

Крис

Я хорошо знаю, что это будет сложно. Мой вопрос: как лучше всего поместить инструкцию в MBR? Само собой разумеется, что Windows не разрешает прямой доступ к диску. Как бы вы посоветовали мне написать инструкции в MBR? Может быть, загрузка живого CD с *nix и запись в MBR оттуда?

11 ответов

Существуют различные способы записи в загрузочный сектор диска, и есть общая ссылка, которую я использовал, когда экспериментировал с разработкой доморощенной ОС: http://wiki.osdev.org/

Я лично просто загружаюсь под Linux и использую dd:

  1. Резервное копирование сначала

    dd if=/dev/sda of=~/windows_bootloader.bin bs=512 count=1

  2. Разбирать загрузчик

    ndisasm -b16 -o7C00h ~/windows_bootloader.bin > ~/windows_bootloader.asm

  3. Сделайте ваши модификации и соберите

    nasm ~/windows_bootloader.asm -f bin ~/ified_bootloader.bin

  4. Перезаписать загрузчик

    dd if=~/ updated_bootloader.bin of=/dev/sda bs=512 count=1

Это предполагает, что 'sda' является правильным блочным устройством. И обратите внимание, что шаг 4 не просто копирует файл в / dev / sda (что возможно, но тогда вы можете перезаписать больше, чем просто первый сектор, если выходной двоичный файл> 512 байт)

Очевидно, вы не захотите отлаживать этот подход в реальной системе. Это избавит вас от головной боли при использовании эмулятора x86, такого как bochs, qemu или VMWare Server.

Однако, как заявил Майкл Берр, это, вероятно, будет плохой идеей. Модификация загрузчика Windows, вероятно, оставит вам мало или совсем не оставит места для вашего собственного кода.

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

Кроме подписанных байтов, 446 байтов в секторе доступны для использования в качестве загрузочной программы, но загрузочная программа должна полностью соответствовать этому сектору! Поскольку 446 байт не очень велики, вам придется делать вызовы BIOS, чтобы скопировать другие сектора с жесткого диска (или дисковода гибких дисков, или чего-то еще) в оперативную память, чтобы запустить их.

Как только вы загрузите достаточно памяти для запуска вашей программы, переходите к ней, и все готово.

Таким образом, операционная система буквально "подтягивается к собственной загрузке"

Смотрите http://en.wikipedia.org/wiki/Master_boot_record

Теперь нет никаких причин, по которым вы не могли бы написать загрузочный код на C или C++ (или почти во всем остальном), за исключением того, что с помощью ассемблера вы точно знаете, какой код будет сгенерирован, и в BIOS легко выполнять вызовы.

Я бы посоветовал вам записать 512-байтовый диск в ram-копир, который загружает вашу программу с диска в ram, а затем переходит на начальный адрес вашей программы. Затем вы можете написать свою программу на любом языке, который вы хотите. Имейте в виду, что когда ваш загрузочный код начинает работать, эти 512 байтов - единственное, на что вы можете рассчитывать, как в оперативной памяти. (Ну, BIOS там, вы можете делать вызовы BIOS. BIOS также поместит некоторую системную информацию в определенные места в оперативной памяти...) Если вы хотите вызывать любые написанные вами функции, которые находятся за пределами этого сектора, вы должны загрузить их в оперативную память самостоятельно.

Кроме того, самый простой способ проверить ваш код, вероятно, будет поместить его на дискету и загрузиться с него.

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

Кроме того, Майкл Барр прав, получение того, что вы хотите сделать, станет кошмаром.

В ответ на ваш комментарий о том, как на самом деле записать это на жесткий диск, есть несколько программ "сырой записи", которые можно копировать в сектор на диске. Кроме того, вы можете просто загрузиться с live linux Linux и использовать dd для записи ваших данных в выбранный вами сектор на блочном устройстве по вашему выбору. - Просто, как пирог этой части.

В основном я полагаю, что я вставлю вызов и оставлю остальную часть MBR в покое

Что будет вызываться этим вызовом подпрограммы? Единственный код в памяти на тот момент - это то, что находится в MBR или ROM.

Пожалуйста, подумайте о том, действительно ли вам это нужно или нет лучшей альтернативы, прежде чем тратить на это слишком много времени. Сторонний код, записанный в MBR (кроме MBR, который вставляет загрузчик ОС), часто плохо воспринимается пользователями, потому что:

  • антивирусные программы часто отмечают его как подозрительный код, потому что это техника, которую вирусы использовали для получения контроля над машинами
  • программы использовали технику вставки себя в MBR и хранения дополнительного кода и данных в "зарезервированных" секторах диска (потому что на самом деле мало что можно сделать и сохранить в MBR). К сожалению, поскольку не существует хорошего стандартного способа зарезервировать эти сектора, этот метод (иногда используемый для защиты от копирования) может привести к повреждению структур данных на диске (т. Е. Все данные на диске прощаются). Пользователи действительно ненавидят это. Я полагаю, что в какой-то момент Quicken использовал схему защиты, которая сделала нечто подобное и столкнулась с довольно большой обратной реакцией.

Поэтому, если вы решили продолжить этот путь, пожалуйста, действуйте осторожно и будьте готовы к головным болям.

Почему само собой разумеется, что Windows не разрешает прямой доступ к диску? Страница MSDN для CreateFile() говорит это:

Прямой доступ к диску или тому ограничен. Дополнительные сведения см. В разделе "Изменения в файловой системе и в стеке хранения для ограничения прямого доступа к диску и прямого доступа к томам в Windows Vista и Windows Server 2008" в базе знаний справки и поддержки по адресу http://support.microsoft.com/kb/942448.

Windows Server 2003 и Windows XP/2000: прямой доступ к диску или тому не ограничен таким образом.

В KB942448 разъясняются ограничения, и они, по-видимому, позволяют процессу с достаточными привилегиями выполнять запись в MBR или загрузочный сектор раздела.

Если вы можете создать дискету, компакт-диск или карту памяти, которая будет загружаться из командной строки MS и иметь соответствующую версию отладки MS, вы можете читать и записывать в MBR, как показано ниже. Машина под управлением win95 или win98 должна иметь возможность создать загрузочную дискету для вас. Просто скопируйте debug из каталога windows\command на дискету.

inside debug: используйте команду r для изменения значений регистра. установите ax для 0201 для чтения или 0301 для записи. установите es:bx на начальный адрес памяти (буфера), которую вы хотите использовать. 0000:7C00 может работать, так как это обычно область, в которую читается следующий сектор в процессе загрузки. установите cx на 0001 для чтения / записи одного сектора из 512 байтов. установите dx на 0080 для первого физического жесткого диска.

используйте команду "a" для сборки одной строки кода: INT 13h

используйте команду "p", чтобы продолжить. Данные будут прочитаны или записаны в зависимости от вашего выбора AX.

Вы можете прочитать в память, "n", чтобы назвать файл, "w", чтобы записать файл, а затем отредактировать копию mbr в какой-нибудь другой программе. После завершения используйте отладочные "n" и "L", чтобы присвоить имя и загрузить отредактированный файл MBR, и вызвать int 13h, используя ax= 0301h, чтобы записать изображение в правильный сектор.

Вы уверены, что вам нужно написать MBR? На диске с разделами вы также можете изменить VBR (Volume Boot Record) раздела. Это может быть проще / безопаснее, поскольку вам не нужно прикасаться к MBR, и ваша машина все равно сможет загружаться с других разделов (и ОС), даже если вы полностью уничтожите свой тестовый раздел.

Я думаю, что ваш лучший способ с Linux, он имеет nasm для компиляции, dd для копирования кластера (что также означает MBR) и даже меню загрузчика (lilo например) если вы не хотите связываться с вашими реальными разделами.

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

LILO boot menu:
    -> WindowsXP
    -> linux

Я хотел сделать что-то отдельно для MBR, не влияя на фактическую установку, поэтому я создал новый (маленький) раздел и добавил его в список LILO (здесь опущены подробности), который дал следующее:

LILO boot menu:
    -> WindowsXP
    -> linux
    -> TESTMBR

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

Чтобы реально изменить эту MBR, я сделал это:

  1. Резервное копирование фактической MBR, например dd if=/dev/sda3 of=/home/you/mbr−backup count=1
  2. Редактировать код в файле: boot.asm
  3. Компилировать с помощью NASM: nasm boot.asm -o boot.bin -f bin исправление ошибок
  4. Скопируйте только что созданную MBR на диск: dd if=boot.bin of=/dev/sda3
  5. Перезагружать.
  6. Выберите TESTMBR в меню.
  7. Посмотрите, как это происходит

Конечно, вы можете сделать это прямо в MBR диска вместо MBR раздела, как я делал здесь, но для моего случая это было более практично.

Что касается фактического скачка кода из MBR, вам нужно использовать прерывание INT 13,42, которое загружает любой кластер на диске. Для целей моего теста мне просто нужно было показать его содержимое, но я могу приглядеться, если хотите.

Надеюсь, что это может помочь, извините за длинный ответ.

Я нашел похожий вопрос, который может помочь:

Модификация MBR Windows

Тем не менее, вы можете уточнить, что вы планируете делать. Как я выяснил, сам код загрузчика может быть довольно утомительным для работы. Кроме того, я бы, конечно, проверил это на дискете, если это возможно.

Что касается того, чтобы делать все это из Windows, я немного не в курсе. Почти весь мой опыт программирования до этого момента был в среде Unix.

Вы можете посмотреть в GRUB. Я ни в коем случае не являюсь экспертом в коде MBR, и я давно работал с операционной системой * nix, но я помню, что загрузчик работал поэтапно и загружал этапы с диска до запуска ОС. Вы можете написать свой собственный этап, чтобы выполнить работу, которую вы должны выполнить до загрузки ОС, а затем загрузить ОС. Я не уверен, насколько практичен этот вариант, особенно потому, что код, кажется, находится в середине переписывания, потому что "устаревшая" версия была недостижимой в соответствии с документацией.

Редактирование MBR вполне возможно из Windows(XP). Для этого используется шестнадцатеричный редактор HxD, вы можете легко скопировать и вставить шестнадцатеричный файл поверх MBR даже на активный системный диск (используйте с осторожностью!:)) http://mh-nexus.de/en/hxd/

В качестве отправной точки a получит MBR, источник которого доступен, например, Grub. (Так что позвольте grub выполнить загрузку в Windows). Таким образом, у вас есть хорошая отправная точка для внесения изменений в MBR. Редактирование MBR не должно быть слишком сложным, так как этот маленький кусочек программного обеспечения довольно прост. Тем не менее, необходимы некоторые 16-битные (DOS) навыки ассемблера. Другой способ - позволить grub запустить какую-то дополнительную нагрузку и вообще не менять MBR, но я уверен на 100%, возможно ли это; пожалуйста, обратитесь к руководствам Grub.

В Windows имеется недокументированная утилита "debug", которая позволяет:1) загружать любой сектор (включая mbr) жесткого диска в ram. 2) рассматривать этот код как двоичный файл или сборку. 3) Соберите некоторый код в ram.4) запишите этот код в любой сектор (также в mbr). Чтобы запустить эту утилиту, введите debug в командной строке, нажмите Enter. Подсказка изменится на "-" . Затем введите "помощь". вы получаете информацию о том, как его использовать,

Другие вопросы по тегам