我想使用驱动器序列号+分区偏移量+分区大小来创建自己的卷ID,但是我需要知道如何在OS X上获取分区信息。我(成功地)尝试了以下操作:
int fd;
if ((fd = open("/dev/disk0s1", O_RDONLY|O_NONBLOCK)) >= 0) {
struct hd_geometry geom;
if (ioctl(fd, 0x0301, &geom) == 0){ //0x0301 is HDIO_GETGEO
printf("Index = %u\n", geom.start);
}
close(fd);
}
Run Code Online (Sandbox Code Playgroud)
但是,即使是成功的,这是因为作为一个有缺陷的解决此指出:hd_geometry.start是一个无符号长,“将不包含在大小的磁盘超过219千兆有意义的价值。” 此外,我相信它需要管理权限,这也是不好的。还有其他方法吗?
好吧,最后一点。由于您要读取原始磁盘,因此需要管理员权限。例如,您可能潜在地寻找写入私有密钥并以非特权用户身份读取它的块,那么我们将在哪里?
其次,/ dev / disk0s1只是一个分区,也是它的块设备版本。您需要读取磁盘的字符设备版本,该版本为/ dev / rdisk0。
第三,HDIO_GETGEO是一个Linux内核ioctl(尤其是考虑它的0x0301值),您不会因此而在Darwin上走得太远。看一下<sys/disk.h>相关的磁盘IOCTL。我认为DKIOCGETFEATURES / DKIOCGETPHYSICALBLOCKSIZE等应该可以助您一臂之力。
如果您对这些概念有疑问,我强烈建议您在可以破坏的虚拟机中进行此开发,因为您不希望意外使用会损坏磁盘的IOCTL。
因此,您正在Mac OS X / Darwin上工作;我们假设GUID分区表
LBA ==逻辑块寻址...; 1块= 512字节
LBA 0 - Master Boot Record (also contained old partition table)
LBA 1 - GUID Partition Table (standard for OS X)
LBA 2 - first 4 entries
LBA 3 - 33 - next 124 entries making for a total of 128 entries
LBA 34 - Partition 1
Run Code Online (Sandbox Code Playgroud)
您可以抓住第二个区块并开始跟踪信息
阅读http://en.wikipedia.org/wiki/GUID_Partition_Table
它的定义很明确。GUID对整数值使用小尾数字节顺序(请参阅Wikipedia页面底部的示例)
进行复制,以免损坏实际的磁盘:
dd if = / dev / rdisk0 of = fakedisk count = 33
这将创建前33个块或磁盘的副本。使用fakedisk测试您的程序。
如果您的磁盘使用MBR,请使用与GPT相同的概念
http://en.wikipedia.org/wiki/Master_Boot_Record
对各部门都有很好的描述。
dstrings fdisk dump显示fdisk使用上述方法。
dtruss fdisk -d / dev / rdisk0
SYSCALL(args) = return
open("/dev/dtracehelper\0", 0x2, 0x7FFF5CFDD5C0) = 3 0
__sysctl(0x7FFF5CFDD084, 0x2, 0x7FFF5CFDD070) = 0 0
bsdthread_register(0x7FFF8BCA41D4, 0x7FFF8BCA41C4, 0x2000) = 0 0
[[ .... content edited ... ]]
open("/dev/rdisk0\0", 0x0, 0x7FFF5CFDDD7A) = 3 0
fstat64(0x3, 0x7FFF5CFDDA10, 0x0) = 0 0
fstat64(0x3, 0x7FFF5CFDDAC8, 0x0) = 0 0
ioctl(0x3, 0x40086419, 0x7FFF5CFDDB60) = 0 0
ioctl(0x3, 0x40046418, 0x7FFF5CFDDB5C) = 0 0
close(0x3) = 0 0
open("/dev/rdisk0\0", 0x0, 0x0) = 3 0
fstat64(0x3, 0x7FFF5CFDDAD0, 0x0) = 0 0
open("/dev/rdisk0\0", 0x0, 0x0) = 4 0
fstat64(0x4, 0x7FFF5CFDDA80, 0x0) = 0 0
lseek(0x4, 0x0, 0x0) = 0 0
issetugid(0x102C22000, 0x3, 0x7FFF5CFDDC00) = 0 0
geteuid(0x102C22000, 0x3, 0x0) = 0 0
[[ tracing data suppressed ]]
read(0x4, "\0", 0x200) = 512 0
close(0x4) = 0 0
getrlimit(0x1008, 0x7FFF5CFDCFA8, 0x7FFF8BD0D470) = 0 0
fstat64(0x1, 0x7FFF5CFDCEF8, 0x7FFF5CFDCFBC) = 0 0
ioctl(0x1, 0x4004667A, 0x7FFF5CFDCF94) = 0 0
write_nocancel(0x1, "1,625142447,0xEE,-,1023,254,63,1023,254,63\n\0", 0x2B) = 43 0
write_nocancel(0x1, "0,0,0x00,-,0,0,0,0,0,0\n\0", 0x17) = 23 0
write_nocancel(0x1, "0,0,0x00,-,0,0,0,0,0,0\n\0", 0x17) = 23 0
write_nocancel(0x1, "0,0,0x00,-,0,0,0,0,0,0\n\0", 0x17) = 23 0
close(0x3) = 0 0
Run Code Online (Sandbox Code Playgroud)
我如何确定使用的是这些ioctl。
dtruss转储为:
ioctl(0x3,0x40086419,0x7FFF5CFDDB60)= 0 0 ioctl(0x3,0x40046418,0x7FFF5CFDDB5C)= 0 0
0x40086518对应于DKIOCGETBLOCKSIZE,这是通过回溯disk.h来收集的(注意_IOR在ioccom.h中扩展为_IOC),并且后8位对应于IOCTL常量定义中的第二个数字。
#define DKIOCGETBLOCKSIZE _IOR('d', 24, uint32_t)
在0x40086418中尾随的18(十六进制)== 24(十进制)
因此,现在我们注意到fdisk执行DKIOCGETBLOCKCOUNT和DKIOCGETBLOCKSIZE来获取物理范围,因为从技术上讲,您应该使用该结果来找出LBA偏移量(请参阅下面的解密ioctl)
这是fdisk的执行方式:
打开(“ / dev / rdisk0 \ 0”,0x0,0x0)= 4 0读取(0x4,“ \ 0”,0x200)= 512 0关闭(0x4)= 0 0
您可以按照以下步骤操作,确保将0x200替换为实际的块大小。
另外,如果您要使用上面的dd命令进行复制,请使用此处显示的块大小。
| 归档时间: |
|
| 查看次数: |
1030 次 |
| 最近记录: |