【问题标题】:Methodology to read a virtual disk's MBR读取虚拟磁盘 MBR 的方法
【发布时间】:2013-01-16 01:09:40
【问题描述】:

我正在尝试构建我自己的 C 程序,它基本上就像 fdisk vdisk 'p' 命令一样工作。我只想能够读取磁盘的前 512 个字节,lseek 到分区的开头(0x1BE),然后读取分区类型、名称、大小等。我不确定如何实际读取这些值。我已经使用 read() linux 函数读取 512 个字节,但是当我尝试以任何方式显示/查看它们时,什么都没有显示。我做错了什么?

int main(int argc, char *argv[]) {
    int bytes_read;
    char mbr[512];
    int file;
    if(argc == 1) {
        // Print some help info
        printf ("Here is some help info: \n\n");
    } else if(argc < 3) {
        printf("File: %s\n\n", argv[1]);
        file = open(argv[1], O_RDONLY);
        lseek(bytes_read, 0, 0);
        //First get the MBR
        bytes_read = read(file, mbr, 512);
        printf("MBR=%s\n\nbytes_read=%d\n\n", mbr, bytes_read);
    } else {
        printf ("Incorrect usage: fdisk <disk>\n\n");
    }
}

【问题讨论】:

  • 嗯,您正在读取 18 个字节。如果它是块设备,您可能需要读取整个块 (512b)。
  • 我一开始就是这么做的。让我把代码改成我之前的样子
  • @YannRamin 所以我将代码更改为 512 个字节。即使我打印它,它仍然没有显示任何内容

标签: c linux disk-partitioning mbr


【解决方案1】:

不要尝试将printf 用于二进制数据。如果您的二进制数据以NUL (ASCII 0) 开头,那么 printf 将假定您有一个空字符串。您可以使用write() 写出任意数据(它需要一个缓冲区和长度),例如:

#include <unistd.h>

write(STDOUT_FILENO, mbr, 512)

...但即使这样也不一定显示任何有用的东西,因为您的终端可能会尝试解释输出中的控制字符。最好的办法是将输出通过管道传输到 xxdod 之类的东西,这两者都会生成其输入数据的十六进制转储。

例如,我本地驱动器的前 512 个字节都是NUL。在您的代码中使用write()(并删除该lseek)会在输出中产生512 个NUL 字节。尝试将磁盘以外的其他内容传递给您的代码,例如:

myexe /etc/passwd

标准 DOS MBR 的结构记录在 here,建议您可以从以下数据结构开始:

struct _partition {
        uint8_t         status;
        uint8_t         chs_start[3];
        uint8_t         part_type;
        uint8_t         chs_end[3];
        uint32_t        lba_start;
        uint32_t        sectors;
};

然后像这样填充它:

        fd = open(target, O_RDONLY);
        lseek(fd, 446, SEEK_SET);
        for (i=0; i<4; i++) {
                struct _partition p;

                bytes_read = read(fd, &p, sizeof(struct _partition));

                // assume this prints information to stdout or something.
                print_part(i, &p);
        }

【讨论】:

  • 我可以进行十六进制转储,但这仍然不能帮助我读取分区属性的实际值。我必须解析原始二进制数据吗?
  • ...当然!你期待什么?分区图是二进制结构;您需要准确了解结构的外观,创建必要的 C 数据结构,根据需要填充它们,并编写函数以生成人类可读的输出。
  • 感谢所有帮助。我了解这一切是如何工作的,唯一的事情就是想办法以纯文本而不是二进制形式打印它。有什么特殊的方法可以做到这一点吗?
  • 好吧,使用我建议的数据结构,您可以执行printf("Type: %d\n", part-&gt;part_type) 之类的操作,假设partstruct _partition *
【解决方案2】:

摆脱lseek。您的编译器现在应该会发出警告,因为您正在向它传递一个尚未初始化的参数 (bytes_read)。

完成后,您需要做一些事情来显示内容;现在,您没有任何东西可以使用您读取的数据。

【讨论】:

    猜你喜欢
    • 2013-11-20
    • 1970-01-01
    • 2018-02-23
    • 2018-03-08
    • 2014-07-05
    • 2011-02-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多