写MBR代码

时间:2009-02-20 05:08:22

标签: assembly mbr

我是一名电气工程师,他最近发现需要修改MBR中的代码。基本上我需要能够在HDD之前执行代码,操作系统启动并接管。

我完全理解这需要在汇编中编写,并且考虑到MBR中446个字节左右的代码空间我只希望调用MBR之外的其他代码。我的问题是什么是写入MBR的最佳方式?如果我想改变MBR,那就说磁盘HDD_1 ...是不是将HDD_1从另一台机器中引入然后写入它,或者直接在当前机器上(在窗口外)写入它。基本上我想我会插入一个电话并留下MBR的其余部分。

任何建议都将不胜感激

克里斯

我很清楚这会很困难。我的问题是将指令放入MBR的最佳方法是什么?不言而喻,Windows不允许直接访问磁盘。您如何建议我在MBR中写入指令?是否可以启动* nix的live CD并从那里写入MBR?

11 个答案:

答案 0 :(得分:20)

有多种方法可以写入驱动器的引导扇区,并且在我试验自制程序OS开发时,我使用了一般的参考:http://wiki.osdev.org/

我个人只是在linux下启动并使用dd:

  1. 先备份

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

  2. 反汇编引导加载程序

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

  3. 进行修改并重新组装

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

  4. 覆盖引导加载程序

    dd if =〜/ modified_bootloader.bin of = / dev / sda bs = 512 count = 1

  5. 这假设你的'sda'是正确的块设备。请注意,第4步不只是将文件复制到/ dev / sda(它可以,但如果输出二进制数> 512字节,则可能会覆盖第一个扇区)

    显然,您不打算在实时系统上调试此方法。使用某种x86模拟器(如bochs,qemu或VMWare Server)可以省去很多麻烦。

    然而正如Michael Burr所说,这可能是一个坏主意。修改Windows引导程序,可能会为您自己的代码留下很少或没有空间。

答案 1 :(得分:9)

BIOS通过读取每个引导设备的第一个扇区(512字节)并检查一组特定的签名字节,从硬盘驱动器(或软盘驱动器)引导计算机。如果找到这些字节,则将512字节扇区复制到ram(在特定位置),然后BIOS跳转以运行它。

除了签名字节之外,扇区中的446个字节可供您用作引导程序,但引导程序必须完全适合该扇区!由于446字节不是很大,你必须进行BIOS调用才能将其他扇区从硬盘驱动器(或软盘驱动器或其他任何东西)复制到ram中以运行它们。

一旦你装满了ram来运行你的程序,跳转到它就可以了。

这就是操作系统从字面上“通过它自己的引导”拉自己的方式

请参阅http://en.wikipedia.org/wiki/Master_boot_record

现在,没有理由你不能用C或C ++(或大多数其他东西)编写启动代码,除了使用汇编,你确切知道将生成什么代码并且很容易进行BIOS调用。

我建议你给ram复印机写一个512字节的磁盘驱动器,将你的程序从磁盘加载到ram,然后跳转到程序的起始地址。然后,您可以使用您想要的任何语言编写程序。请记住,当您的启动代码开始运行时,这些512字节是您可以依赖的唯一内容。 (好吧,BIOS就在那里你可以拨打BIOS电话.BIOS也会在ram的某些地方放置一些系统信息......)如果你想调用你所写的任何超出该部门的功能,你必须自己把它们装进公羊。

此外,测试代码的最简单方法可能是将其放在软盘上并启动它。

要回答原始问题,您可以在某处保留旧MBR的备份副本,并且您的新MBR可以将您的函数加载到ram中,运行它,然后加载原始MBR并运行它,允许Windows继续启动。

此外,迈克尔伯尔是对的,得到你想做的事情将是一场噩梦。

在回答您关于如何在硬盘上实际写入此内容的评论时,有几个“原始写入”程序可以复制到磁盘上的扇区。此外,您可以启动Linux live cd并使用dd将数据写入您选择的块设备上您选择的扇区。 - 简单就像馅饼一样。

答案 2 :(得分:5)

  

基本上我想我会插入一个电话并留下MBR的其余部分

此子程序调用将调用什么?此时内存中唯一的代码是MBR或ROM中的任何代码。

在你花太多时间之前,请仔细考虑一下你是否真的需要这个或那个没有更好的选择。写入MBR的第三方代码(除了OS加载器放入的MBR之外)通常不被用户接受,因为:

  • 防病毒程序经常将其标记为可疑代码,因为它是病毒用于控制机器的技术
  • 程序使用了将自身插入MBR并将附加代码和数据存储在光盘的“保留”扇区中的技术(因为实际上没有多少人可以在MBR中存储和存储)。遗憾的是,由于没有好的,标准的方法来实际保留这些扇区,这种技术(有时用于复制保护)会导致磁盘上数据结构的损坏(即,驱动器上的所有数据都会再次出现)。用户真的很讨厌这个。我相信Quicken在某一时刻采用了类似的保护方案并面临着相当大的反弹。

因此,如果您决定继续这条道路,请谨慎行事并为头痛做好准备。

答案 3 :(得分:4)

为什么不说Windows不允许直接访问磁盘? CreateFile()的MSDN页面说明了这一点:

  

直接访问磁盘或访问   数量有限。更多   信息,请参阅“文件更改   系统和存储堆栈   限制直接磁盘访问和直接   Windows Vista和中的卷访问权限   Windows Server 2008中的“帮助和帮助”   支持知识库   http://support.microsoft.com/kb/942448

     

Windows Server 2003和Windows XP / 2000:直接访问磁盘或   卷的数量不限于此   方式。

KB942448解释了这些限制,它们似乎允许具有足够权限的进程写入MBR或分区引导扇区。

答案 4 :(得分:2)

我发现了一个类似的问题可能会有所帮助:

Modifying the MBR of Windows

但是,您可能想详细说明您打算做什么。正如我自己发现的,引导程序代码可能非常繁琐。另外,如果可能的话,我肯定会用软盘测试一下。

至于从Windows实际执行此操作,我有点无能为力。到目前为止,我的所有编程经验都是在Unix环境下进行的。

答案 5 :(得分:2)

我认为最好的方法是使用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编译:{{1​​}}更正错误
  4. 将新创建的MBR复制到驱动器:nasm boot.asm -o boot.bin -f bin
  5. 重新启动。
  6. 在菜单中选择TESTMBR。
  7. 看看它是怎么回事。
  8. 当然,您可以直接在驱动器的MBR上执行此操作,而不是像我在此处所做的那样使用分区的MBR,但对于我自己的情况,它更实用。

    关于实际代码跳出MBR,您需要使用INT 13,42中断,它会加载磁盘上的任何群集。出于测试目的,我只需要显示其内容,但如果你愿意,我可以仔细看看。

    希望能有所帮助,对不起,长期回复。

答案 6 :(得分:2)

如果您可以制作将启动到MS命令提示符的软盘,CD或记忆棒,并且具有匹配的MS debug版本,则可以如下读取和写入MBR。运行win95或win98的机器应该能够为您创建启动软盘。只需将调试从windows \ command目录复制到软盘即可。

内部调试: 使用r命令更改寄存器值。 将ax设置为0201以进行读取,或将0301设置为写入。 将es:bx设置为您要使用的内存(缓冲区)的起始地址。 0000:7C00可能有效,因为这通常是您的下一个扇区在引导过程中读取的区域。 将cx设置为0001以读取/写入512字节的一个扇区。 将dx设置为0080以获得第一个物理硬盘驱动器。

使用“a”命令汇编一行代码: INT 13h

使用“p”命令继续。根据您选择的AX,将读取或写入数据。

您可以读取内存,“n”命名文件,“w”写入文件,然后在其他程序中编辑mbr的副本。完成后,使用debug的“n”和“L”命名并加载已编辑的MBR文件,并使用ax = 0301h调用int 13h将图像写入正确的扇区。

答案 7 :(得分:2)

您确定需要编写MBR吗?我是一个带分区的磁盘,你也可以修改分区的VBR(Volume Boot Record)。这可能更容易/更安全,因为您不需要触摸MBR,您的机器仍然可以启动到其他分区(和操作系统),即使您完全破坏了测试分区。

答案 8 :(得分:1)

您可以查看GRUB。我不是MBR代码的专家,自从我运行* nix操作系统以来已经有很长一段时间了,但我记得引导加载程序分阶段工作并在操作系统启动之前从磁盘加载了各个阶段。您可以编写自己的阶段来完成操作系统加载之前所需的工作,然后启动操作系统。我不确定这个选项有多实用,特别是因为代码似乎正在重写,因为根据文档,“遗留”版本是不可维护的。

答案 9 :(得分:1)

在Windows(XP)中完全可以编辑MBR。为了使用HxD十六进制编辑器,你可以在MBR上复制粘贴一个hex文件,甚至在你的活动系统驱动器上(谨慎使用!))http://mh-nexus.de/en/hxd/

作为起点,a将获得源可用的MBR,例如Grub。 (所以让grub对Windows进行转换)有了这个,你就有了一个很好的起点来对你的MBR进行更改。编辑MBR应该不会太难,因为这个小软件非常基础。但是需要一些16位(DOS)的汇编技能。另一种方法是让grub运行一些额外的有效负载而不是根本不改变MBR,但我100%确定这是否可行;请参考Grub手册。

答案 10 :(得分:0)

Windows有一个未记录的实用程序" debug"这允许:1)将hdd的任何扇区(包括mbr)加载到ram。 2)将代码视为二进制或汇编。 3)在ram中组装一些代码.4)将该代码写入任何扇区(也为mbr)。要启动此实用程序,请在命令promt中键入debug,然后按Enter键。提示更改为" - "然后键入" help"。你得到了如何使用它的信息,