我想拆解我的可启动x86磁盘的MBR(前512字节).我已经将MBR复制到了一个文件中
dd if=/dev/my-device of=mbr bs=512 count=1
Run Code Online (Sandbox Code Playgroud)
对可以反汇编文件的Linux实用程序的任何建议mbr
?
我知道,在启动时,BIOS会在内存0x7c00上加载预定义设备驱动器的第一个扇区(512字节),然后跳转到该地址.
因此,从0x7c00到0x7dff的内存被占用.RAM中是否有其他部分被占用?
如果我正在编程操作系统,我可以使用除了0x7c00到ox7dff之外的所有RAM用于我自己的目的吗?或者,是否还有其他部分在启动时填充了"宝贵"信息,我不能覆盖?
我知道在给定的时刻,我可以覆盖内存中加载的MBR(链式加载),我的问题集中在......操作系统可用的内存部分是什么?
对不起,我的英语不好.谢谢你的回答!!
我是一名电气工程师,他最近发现需要修改MBR中的代码.基本上我需要能够在HDD之前执行代码,操作系统启动并接管.
我完全理解这需要在汇编中编写,并且考虑到MBR中的446个字节左右的代码空间我只希望调用MBR之外的其他代码.我的问题是什么是写入MBR的最佳方式?如果我想改变MBR,那就说磁盘HDD_1 ...将HDD_1引入另一台机器然后写入它,或者在当前机器中直接(在窗口外)写入它是否更好.基本上我想我会插入一个电话并留下MBR的其余部分.
任何建议,将不胜感激
克里斯
我很清楚这将是困难的.我的问题是将指令放入MBR的最佳方法是什么?不言而喻,Windows不允许直接访问磁盘.您如何建议我在MBR中写入指令?是否可以启动*nix的live CD并从那里写入MBR?
我需要找到一种方法来以编程方式确定Windows用于引导的磁盘驱动器.换句话说,我需要一种来自Windows的方法来确定BIOS用于启动整个系统的驱动器.
Windows是否公开了一个界面来发现这个?随着Windows API的大小,我希望那里埋藏着一些可以解决问题的东西.
特里
ps只是读取硬盘的第一个扇区并不是在陶醉任何东西.在我的开发盒上我有两个硬盘,当我查看任一硬盘上前几个扇区的内容时,我有一个标准的锅炉板MBR.
编辑以澄清一些事情.我想识别设备的方式是使用字符串来识别物理磁盘驱动器(而不是逻辑磁盘驱动器).物理磁盘驱动器的格式为"\\.\ PHYSICALDRIVEx",其中x是数字.另一方面,逻辑驱动器由形式为"\\.\ x"的字符串标识,其中x是驱动器号.
编辑以讨论抛出的一些想法.知道Windows用来启动哪个逻辑卷对我没有帮助.这就是原因.假设C:正在使用镜像RAID设置.现在,这意味着我们至少有两个物理驱动器.现在,我获得了从逻辑驱动器到物理驱动器的映射,我发现该卷使用了两个物理驱动器.Windows使用哪一个启动?当然,这假设用于引导的Windows物理驱动器与包含MBR的物理驱动器相同.
我有一个解决方案,使用空间数据来表示地图上的一组点.我需要使用表示簇的范围的坐标来找到可以包含所述点簇的最小边界矩形.
是否存在能够计算此算法的简单算法,或者C#中是否存在任何内置功能来实现此目的.我知道NetTopologySuite,但我不确定如何/如果我可以使用它来实现相同的目标.我有一个坐标列表,所以我需要将这个字符串列表传递给它并获得MBR.
我需要修改Windows的MBR,我真的很想从Windows中做到这一点.
这是我的问题.我知道我可以通过调用CreateFile来获取物理设备的句柄.MBR会不会出现在\\.\ PHYSICALDRIVE0?另外,我还在学习Windows API直接从磁盘读取.readabsolutesectors和writeabsolutesectdors是我需要用来读/写包含MBR的磁盘扇区的两个函数吗?
根据我自己学到的东西进行编辑.MBR并不总是在\\.\ PHYSICALDRIVE0上.此外,您可以通过使用包含MBR的驱动器的设备名称调用CreateFile来写入引导扇区(至少作为XP上的管理员).此外,您只需调用WriteFile并传递通过调用CreateFile创建的设备句柄即可写入此驱动器.
编辑以解决Joel Coehoorn.我需要编辑MBR,因为我正在开发一个项目,需要在BIOS中POST后修改硬件寄存器,但是在允许Windows启动之前.我们的计划是通过修改引导加载程序以在Windows启动之前执行我们的代码来进行这些更改.
编辑Cd-MaN.谢谢(你的)信息.但是,你的答案中没有任何内容,我不知道,你的答案也没有解决我的问题.特别是注册表绝对不会出于多种原因而做我们需要的事情.最重要的原因是Windows是将与我们的产品一起运行的多个软件层中的最高层.这些更改甚至需要在较低级别运行之前发生,因此注册表将无法工作.
PS为Cd-MaN.据我了解,您提供的信息不太正确.对于Vista,我认为如果写入的扇区是引导扇区,则可以写入卷.请参见http://support.microsoft.com/kb/942448
我试图了解vmware bios在加载之前如何找到MBR.
在物理硬盘中很容易 - MBR位于第一个扇区.
但是......在VM中会发生什么?
我创建了2个VM - 在第一个vmdk(安装了基于linux的系统)上,我发现MBR偏移量为0x2A0000.
在第二个vmdk文件(安装了Windows XP)中,我发现MBR不止一次 - 但我发现的所有偏移量都不能除以512(扇区大小),这有点奇怪(就我而言)知道,MBR应该从一个扇区的开头开始+扇区大小是512字节,在vmdk中=> MBR的起始偏移必须除以512.如果我错了,请纠正我.
所以他们可能是备份的副本我想..不用说xp .vmdk中的@偏移0x2A0000没什么好玩的.
那么.. vmware的BIOS如何找到MBR?这个可配置参数位于何处?如何计算?
附加信息:
- 两个VMDK都是1个文件硬盘文件(并且可以增长到40GB).
他们所服务的系统只使用它们(XP使用xp.vmdk,linux使用linux.vmdk,没有额外的VMDK).
- @Windows VM我在\.\ PhysicalDrive0上使用WinHex来获取MBR.it看起来没问题(签名等等).
- @Linux VM我使用命令"dd if =/dev/sda of = mbr.bin bs = 512 count = 1",然后查看十六进制字节以获得MBR.我看着它看起来很好(GRUB,最后签名等).
从VM获取MBR之后,我在每个相应的.vmdk文件中搜索了主机pc中的MBR(使用十六进制编辑器),并且偏移量如上所述.
任何帮助,将不胜感激.谢谢!
在修改程序集中编写bootsector代码之后,我想知道我是否可以在C中执行相同操作.到目前为止,空函数中的代码生成如下:
在C:
void _start() {
halt:
goto halt;
}
Run Code Online (Sandbox Code Playgroud)
随后的asm(由GCC生成):
7c00: 55 push %bp
7c01: 89 e5 mov %sp,%bp
7c03: eb fe jmp 0x7c03
Run Code Online (Sandbox Code Playgroud)
但是,是否可以指定对于此(入口)函数,我不希望初始化基本和堆栈指针?BIOS将控制权直接传输到0x7c00,因此设置堆栈指针的前两条指令是冗余的.
我已经尝试添加__attribute__ ((always_inline, noreturn, regparm(0)))
到函数声明,但似乎没有做任何事情.
我的引导加载程序由两个 512 字节的阶段组成。阶段 1 由 bios 加载到 MBR 区域。stage1 然后继续从驱动器加载 stage2 并跳转到它。
我用十六进制编辑器确认最终二进制“program.bin”的大小正好是 1024 字节长,并且包含两个“签名”(每个阶段的最后两个字节,0xAA55 用于 stage1(MBR 签名)和 0xCC77 用于 stage2)。
预期产出是:
1 // stage1 started
0000 or 0080 // drive# in hex
CC77 // stage2 "signature" in hex
2 // stage2 started
Run Code Online (Sandbox Code Playgroud)
这在 QEMU 中工作正常,但在 virtualbox 和硬件上失败。在我看来,stage2 加载无声无息地失败(错误分支没有被调用),我希望解决这个问题两周,但没有成功。
stage1.asm:
global _start
extern _stage2
extern _stage2data
BITS 16
_start:
; init registers
xor ax, ax
mov es, ax
mov gs, ax
mov ss, ax …
Run Code Online (Sandbox Code Playgroud) 想知道显式汇编指令实际构成X86架构上的主引导记录.感谢您的任何见解.
其他架构受到欢迎,但主要是针对X86.