Написать код MBR - PullRequest
       82

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

10 голосов
/ 20 февраля 2009

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

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

Любые предложения будут оценены

Крис

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

Ответы [ 11 ]

20 голосов
/ 20 февраля 2009

Существуют различные способы записи в загрузочный сектор диска, и есть общая ссылка, которую я использовал, когда экспериментировал с разработкой доморощенной ОС: 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 из = / dev / sda bs = 512 count = 1

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

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

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

9 голосов
/ 20 февраля 2009

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 для записи ваших данных в выбранный вами сектор на блочном устройстве по вашему выбору. - Просто, как пирог этой части.

5 голосов
/ 20 февраля 2009

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

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

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

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

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

4 голосов
/ 20 февраля 2009

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

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

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

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

2 голосов
/ 30 октября 2012

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

2 голосов
/ 10 июня 2011

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

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

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

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

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

2 голосов
/ 15 апреля 2010

Я думаю, что вам лучше всего использовать 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. Reboot.
  6. Выберите в меню TESTMBR.
  7. Посмотрите, как это происходит.

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

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

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

2 голосов
/ 20 февраля 2009

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

Изменение MBR Windows

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

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

1 голос
/ 15 апреля 2010

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

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

1 голос
/ 20 февраля 2009

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

...