【发布时间】:2016-11-24 22:17:34
【问题描述】:
我想计算 VHD 中父定位器的结束偏移量。这是 VHD 标头的一部分:
Cookie: cxsparse
Data offset: 0xffffffffffffffff
Table offset: 0x2000
Header version: 0x00010000
Max table entries: 10240
Block size: 0x200000
Checksum: 4294956454
Parent Unique Id: 0x9678bf077e719640b55e40826ce5d178
Parent time stamp: 525527478
Reserved: 0
Parent Unicode name:
Parent locator 1:
- platform code: 0x57326b75
- platform_data_space: 4096
- platform_data_length: 86
- reserved: 0
- platform_data_offset: 0x1000
Parent locator 2:
- platform code: 0x57327275
- platform_data_space: 65536
- platform_data_length: 34
- reserved: 0
- platform_data_offset: 0xc000
来自Virtual Hard Disk Image Format Specification的一些定义:
"Table Offset:该字段存储文件中块分配表(BAT)的绝对字节偏移量。 平台数据空间:此字段存储存储父硬盘定位器所需的 512 字节扇区数。 平台数据偏移量:此字段以字节为单位存储绝对文件偏移量,其中存储了平台特定的文件定位器数据。 平台数据长度。该字段以字节为单位存储父硬盘定位器的实际长度。"
基于此,两个父定位器的结束偏移量应为: 数据偏移 + 512 * 数据空间:
0x1000 + 512 * 4096 = 0x201000
0xc000 + 512 * 65536 = 0x200c000
但如果只使用数据偏移+数据空间:
0x1000 + 4096 = 0x2000 //end of parent locator 1, begin of BAT
0xc000 + 65536 = 0x1c000
后一种计算更有意义:第一个父定位器的结尾是 BAT 的开头(参见上面的标题数据);并且由于第一个 BAT 条目是 0xe7(扇区偏移),这对应于文件偏移 0x1ce00(扇区偏移 * 512),如果第二个父定位器以 0x1c000 结束,则可以。
但是如果使用公式数据偏移量 + 512 * 数据空间,他最终会将其他数据写入父定位器。 (但是,在这个例子中不会有数据损坏,因为平台数据长度非常小)
所以这是规范中的错误,以及句子
“平台数据空间:该字段存储存储父硬盘定位器所需的512字节扇区数。”
应该是
“平台数据空间:该字段存储了存储父硬盘定位器所需的字节数。”?
【问题讨论】:
-
我的第一个猜测是显示 VHD 标头的任何内容都已经将平台数据长度乘以 512。您需要查看标头的实际二进制内容才能确定。
-
为了提取标题信息,我使用了自己的工具,但我没有乘任何东西。这是来自十六进制编辑器的原始数据:
57 32 6B 75 00 00 10 00 00 00 00 54 00 00 00 00 00 00 00 00 00 00 10 00 57 32 72 75 00 01 00 00。平台代码 0x57326b75 (W2ku) 之后是 0x1000 (4096),0x57327275 (W2ru) 之后是 0x10000 (65536)。 -
当然看起来它是字节数而不是扇区数。这可能是规范中的错误,或者可能是生成相关 VHD 的任何软件的错误;无论哪种方式,只要最初保留的空间总是足够的,它可能会被忽视。
-
是否有一个 MS 工具可以更改现有 VHD 的父硬盘定位器的内容?如果是这样,如果数据空间不足以容纳新数据,它应该拒绝这样做,因此也许您可以使用二进制编辑器将 VHD 的数据空间字段更改为 1 并查看工具是否将其解释为“有足够的空间容纳 512 字节的数据”或“足够的空间容纳 1 字节的数据”。 :-)