1

ドライブ シリアル + パーティション オフセット + パーティション サイズを使用して独自のボリューム 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);
}

しかし、それが成功したとしても、次のように指摘されているように、問題のある解決策です。さらに、管理者権限が必要だと思いますが、これも悪いことです。これを行う他の方法はありますか?

4

2 に答える 2

5

では最後のポイントを先に。raw ディスクを読み取ろうとしているため、管理者権限が必要です。たとえば、秘密暗号鍵が書き込まれているブロックを探して、特権のないユーザーとして読み取ることができる可能性があります。

次に、/dev/disk0s1 は単なるパーティションであり、そのブロック デバイス バージョンでもあります。ディスクのキャラクター デバイス バージョンを読み取る必要があります。これは /dev/rdisk0 になります。

3 番目に、HDIO_GETGEO は Linux カーネルの ioctl です (特に 0x0301 の値を考慮してください)。<sys/disk.h>関連するディスク IOCTL を参照してください。DKIOCGETFEATURES / DKIOCGETPHYSICALBLOCKSIZE などでうまくいくはずです。

これらの概念に問題がある場合は、ディスクを台無しにする IOCTL を誤って使用したくないため、クロバーできる仮想マシンでこの開発を行うことを強くお勧めします。

補遺(おそらく答え)

GUID パーティション テーブル

つまり、あなたは 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

2番目のブロックをつかんで、情報の追跡を開始できます

http://en.wikipedia.org/wiki/GUID_Partition_Tableを読んでください。

それはかなり明確に定義されています。GUID は、整数値にリトル エンディアンのバイト順を使用します (ウィキペディア ページの下部にある例を参照してください)。

テストの提案

実際のディスクを台無しにしないように、コピーを作成します。

dd if=/dev/rdisk0 of=fakedisk count=33

これにより、最初の 33 ブロックまたはディスクのコピーが作成されます。プログラムをテストするには、fakedisk を使用します。

MBR

ディスクが MBR を使用している場合、GPT と同じ概念を使用します。

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

セクターの優れた説明があります。

dtruss fdisk -d /dev/rdisk0 dump を使用してヒントを取得する

dtrussing 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

ioctl の解読

使用されているのはこれらの ioctl であることがどのようにわかりましたか。

dtruss ダンプは次のとおりです。

ioctl(0x3, 0x40086419, 0x7FFF5CFDDB60) = 0 0 ioctl(0x3, 0x40046418, 0x7FFF5CFDDB5C) = 0 0

および 0x40086518 は DKIOCGETBLOCKSIZE に対応します。これは、disk.h をトレース バックすることによって収集され (_IOR は ioccom.h で _IOC に展開されることに注意してください)、最後の 8 ビットは IOCTL 定数定義の 2 番目の数値に対応します。

#define DKIOCGETBLOCKSIZE _IOR('d', 24, uint32_t)

0x40086418 の末尾の 18(16 進数) == 24(10 進数)

fdisk は物理エクステントを取得するために DKIOCGETBLOCKCOUNT と DKIOCGETBLOCKSIZE を実行することに注意してください。これは、技術的にはその RESULT を使用して LBA オフセットを計算する必要があるためです (以下の ioctl の解読を参照)。

fdisk の実際の読み取り

これが fdisk のやり方です:

open("/dev/rdisk0\0", 0x0, 0x0) = 4 0 read(0x4, "\0", 0x200) = 512 0 close(0x4) = 0 0

0x200 を実際のブロックサイズに置き換えてください。

また、上記の dd コマンドを使用してコピーを作成する場合は、ここに表示されるブロック サイズを使用します。

于 2013-05-20T19:03:59.787 に答える
0

DKIOCGETPHYSICALEXTENTioctlを試しましたか?dk_physical_extent_tこれは、64 ビットのオフセットと 64 ビットの長さを含む構造を埋めます。

于 2013-05-21T00:03:47.047 に答える