-2

我试图编写一个程序作为概念证明,以便从我的 HDD 中删除 GPT 分区表。为了在打开磁盘后缩短它,我执行以下操作:

   //Removes the first partition table in the beginning of the disk
    ::lseek(fd, 0, SEEK_SET);
    ::write(fd, '\0', GPT_PARTITION_TABLE_SIZE);
    
    //Removes the backup partition in the end of the disk
    ::lseek(fd, -GPT_PARTITION_TABLE_SIZE, SEEK_END);
    ::write(fd, '\0', GPT_PARTITION_TABLE_SIZE);

尽管这似乎运作良好,但我从朋友那里得到消息说这种方式不正确,我应该使用本地缓冲区进行写入,并且我的代码尝试使用 NULL 作为指向 write() 的指针,这是不正确的方法。

我花了好几个小时来理解他的意思,但我仍然不确定我是否明白。有没有人尝试过类似的东西?

4

1 回答 1

4

在这行代码中:

::write(fd, '\0', GPT_PARTITION_TABLE_SIZE);

to 的第二个参数write是 a const void *。正在发生的事情是charNUL ( '\0') 值是一个常数0,因此等于NULL或转换为该nullptr值。然后该write调用尝试读取GPT_PARTITION_TABLE_SIZE从该地址开始的字节。在典型的系统上,NULL 的地址实际上是 0,通常 tehre 没有映射到那里的页面,它会导致异常。在操作系统内核或某些嵌入式系统中,可能在地址 0 处存在可读取的内存映射,这可能会写入映射到那里的任何内容。

与代码示例比较:

char buffer[GPT_PARTITION_TABLE_SIZE];
memset(buffer, '\0', sizeof(buffer));
write(fd, buffer, sizeof(buffer));
于 2017-12-12T21:50:39.360 回答