【问题标题】:Write MBR Code编写 MBR 代码
【发布时间】:2010-10-08 18:37:19
【问题描述】:

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

我完全理解这需要用汇编语言编写,并且考虑到 MBR 中大约 446 字节的代码空间,我只是希望调用 MBR 之外的其他代码。我的问题是写入 MBR 的最佳方式是什么?如果我想更改磁盘 HDD_1 的 MBR ... 将 HDD_1 从属到另一台机器然后写入它,或者在当前机器中直接(在 Windows 之外)写入它会更好。基本上,我想我会插入一个呼叫,而不要理会 MBR 的其余部分。

任何建议将不胜感激

克里斯

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

【问题讨论】:

  • 我很清楚这会很困难。我的问题是将指令放入 MBR 的最佳方式是什么?不用说,Windows 不允许直接访问磁盘。您如何建议我将指令写入 MBR?

标签: assembly mbr


【解决方案1】:

有多种写入驱动器引导扇区的方法,我在尝试自制操作系统开发时使用了一个通用参考: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 ~/modified_bootloader.bin

  4. 覆盖引导加载程序

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

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

显然,您不希望在实时系统上调试这种方法。使用某种 x86 仿真器(如 bochs、qemu 或 VMWare Server)将为您省去很多麻烦。

然而,正如 Michael Burr 所说,这可能是个坏主意。修改 Windows 引导加载程序可能会让您几乎没有空间来编写自己的代码。

【讨论】:

  • 赞成 wiki.osdev 的链接...只是在那里呆了一个小时而不是编码!
  • 爱它!简单易行。
【解决方案2】:

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

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

一旦你在 ram 中加载了足够的内容来运行你的程序,就可以跳转到它了。

这就是操作系统真正“通过它自己的引导程序将自己拉起来”的方式

http://en.wikipedia.org/wiki/Master_boot_record

现在,您没有理由不能用 C 或 C++(或大多数其他语言)编写引导代码,除非使用汇编,您可以确切地知道将生成什么代码,并且很容易进行 BIOS 调用。

我建议你写一个 512 字节的磁盘驱动器到 ram copier,将你的程序从磁盘加载到 ram 中,然后跳转到程序的起始地址。然后,您可以用您想要的任何语言编写程序。请记住,当您的引导代码开始运行时,这 512 个字节是您唯一可以依靠的,就像在 ram 中一样。 (好吧,BIOS 在那里,您可以进行 BIOS 调用。BIOS 还会在 ram 中的某些位置放置一些系统信息……)自己将它们加载到 ram 中。

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

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

另外,Michael Burr 是对的,得到你想要完成的事情将是一场噩梦。

在回答您关于如何在硬盘驱动器上实际写入此内容的评论时,有几个“原始写入”程序可以复制到磁盘上的扇区。此外,您可以从 linux live cd 启动并使用 dd 将数据写入您选择的块设备上您选择的扇区。 -- 那部分简直太简单了。

【讨论】:

    【解决方案3】:

    基本上,我想我会插入一个呼叫,然后不理会 MBR 的其余部分

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

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

    • 防病毒程序经常将其标记为可疑代码,因为这是病毒用来控制机器的一种技术
    • 程序使用了将自己插入 MBR 并将附加代码和数据存储在磁盘的“保留”扇区中的技术(因为在 MBR 中确实没有什么可以做和存储的)。不幸的是,由于没有好的、标准的方法来实际保留这些扇区,这种技术(有时用于复制保护)可能会导致磁盘上的数据结构损坏(即,驱动器上的所有数据都消失了)。用户真的很讨厌这样。我相信 Quicken 曾经使用过一种保护方案,它做了类似的事情并面临相当大的反弹。

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

    【讨论】:

    • 事实上引导扇区病毒代码可能是一个很好的起点。无论如何,它是相当无害的,因为一旦 Windows 接管它就会杀死任何在实模式下运行的东西(实模式?调用任何低于 640K 限制的不受保护的东西),因此不会感染计算机。
    【解决方案4】:

    为什么不用说 Windows 不允许直接访问磁盘? CreateFile() 的 MSDN 页面是这样说的:

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

    Windows Server 2003 和 Windows XP/2000:直接访问磁盘或 到一卷不受此限制 方式。

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

    【讨论】:

      【解决方案5】:

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

      Modifying the MBR of Windows

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

      就实际从 Windows 执行这一切而言,我有点无能为力。到目前为止,我几乎所有的编程经验都是在 Unix 环境下进行的。

      【讨论】:

        【解决方案6】:

        我认为你最好的方法是使用 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 中断,它将任何集群加载到磁盘上。出于测试的目的,我只需要显示其内容,但如果您愿意,我可以仔细查看。

        希望能帮到你,抱歉回复太长了。

        【讨论】:

          【解决方案7】:

          如果您可以制作软盘、CD 或记忆棒来引导到 MS 命令提示符,并且具有匹配的 MS 调试版本,您可以如下读取和写入 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 将图像写入正确的扇区。

          【讨论】:

            【解决方案8】:

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

            【讨论】:

              【解决方案9】:

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

              【讨论】:

                【解决方案10】:

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

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

                【讨论】:

                  【解决方案11】:

                  Windows 有一个未记录的实用程序“调试”,它允许:1) 将硬盘的任何扇区(包括 mbr)加载到内存。 2)将该代码视为二进制或汇编。 3)在ram.4中组装一些代码)将该代码写入任何扇区(也写入mbr)。要启动此实用程序,请在命令提示符处键入调试,然后按 Enter。提示变为“-”。然后键入“帮助”。你会得到关于如何使用它的信息,

                  【讨论】:

                    猜你喜欢
                    • 1970-01-01
                    • 2016-09-15
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 2019-05-18
                    • 2012-07-02
                    • 2012-07-11
                    相关资源
                    最近更新 更多