This page hosts a formal specification of VMWare Virtual Disk using Kaitai Struct. This specification can be automatically translated into a variety of programming languages to get a parsing library.
digraph {
rankdir=LR;
node [shape=plaintext];
subgraph cluster__vmware_vmdk {
label="VmwareVmdk";
graph[style=dotted];
vmware_vmdk__seq [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
<TR><TD BGCOLOR="#E0FFE0">pos</TD><TD BGCOLOR="#E0FFE0">size</TD><TD BGCOLOR="#E0FFE0">type</TD><TD BGCOLOR="#E0FFE0">id</TD></TR>
<TR><TD PORT="magic_pos">0</TD><TD PORT="magic_size">4</TD><TD></TD><TD PORT="magic_type">magic</TD></TR>
<TR><TD PORT="version_pos">4</TD><TD PORT="version_size">4</TD><TD>s4le</TD><TD PORT="version_type">version</TD></TR>
<TR><TD PORT="flags_pos">8</TD><TD PORT="flags_size">4</TD><TD>HeaderFlags</TD><TD PORT="flags_type">flags</TD></TR>
<TR><TD PORT="size_max_pos">12</TD><TD PORT="size_max_size">8</TD><TD>s8le</TD><TD PORT="size_max_type">size_max</TD></TR>
<TR><TD PORT="size_grain_pos">20</TD><TD PORT="size_grain_size">8</TD><TD>s8le</TD><TD PORT="size_grain_type">size_grain</TD></TR>
<TR><TD PORT="start_descriptor_pos">28</TD><TD PORT="start_descriptor_size">8</TD><TD>s8le</TD><TD PORT="start_descriptor_type">start_descriptor</TD></TR>
<TR><TD PORT="size_descriptor_pos">36</TD><TD PORT="size_descriptor_size">8</TD><TD>s8le</TD><TD PORT="size_descriptor_type">size_descriptor</TD></TR>
<TR><TD PORT="num_grain_table_entries_pos">44</TD><TD PORT="num_grain_table_entries_size">4</TD><TD>s4le</TD><TD PORT="num_grain_table_entries_type">num_grain_table_entries</TD></TR>
<TR><TD PORT="start_secondary_grain_pos">48</TD><TD PORT="start_secondary_grain_size">8</TD><TD>s8le</TD><TD PORT="start_secondary_grain_type">start_secondary_grain</TD></TR>
<TR><TD PORT="start_primary_grain_pos">56</TD><TD PORT="start_primary_grain_size">8</TD><TD>s8le</TD><TD PORT="start_primary_grain_type">start_primary_grain</TD></TR>
<TR><TD PORT="size_metadata_pos">64</TD><TD PORT="size_metadata_size">8</TD><TD>s8le</TD><TD PORT="size_metadata_type">size_metadata</TD></TR>
<TR><TD PORT="is_dirty_pos">72</TD><TD PORT="is_dirty_size">1</TD><TD>u1</TD><TD PORT="is_dirty_type">is_dirty</TD></TR>
<TR><TD PORT="stuff_pos">73</TD><TD PORT="stuff_size">4</TD><TD></TD><TD PORT="stuff_type">stuff</TD></TR>
<TR><TD PORT="compression_method_pos">77</TD><TD PORT="compression_method_size">2</TD><TD>u2le→CompressionMethods</TD><TD PORT="compression_method_type">compression_method</TD></TR>
</TABLE>>];
vmware_vmdk__inst__len_sector [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
<TR><TD BGCOLOR="#E0FFE0">id</TD><TD BGCOLOR="#E0FFE0">value</TD></TR>
<TR><TD>len_sector</TD><TD>512</TD></TR>
</TABLE>>];
vmware_vmdk__inst__descriptor [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
<TR><TD BGCOLOR="#E0FFE0">pos</TD><TD BGCOLOR="#E0FFE0">size</TD><TD BGCOLOR="#E0FFE0">type</TD><TD BGCOLOR="#E0FFE0">id</TD></TR>
<TR><TD PORT="descriptor_pos">(start_descriptor * _root.len_sector)</TD><TD PORT="descriptor_size">(size_descriptor * _root.len_sector)</TD><TD></TD><TD PORT="descriptor_type">descriptor</TD></TR>
</TABLE>>];
vmware_vmdk__inst__grain_primary [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
<TR><TD BGCOLOR="#E0FFE0">pos</TD><TD BGCOLOR="#E0FFE0">size</TD><TD BGCOLOR="#E0FFE0">type</TD><TD BGCOLOR="#E0FFE0">id</TD></TR>
<TR><TD PORT="grain_primary_pos">(start_primary_grain * _root.len_sector)</TD><TD PORT="grain_primary_size">(size_grain * _root.len_sector)</TD><TD></TD><TD PORT="grain_primary_type">grain_primary</TD></TR>
</TABLE>>];
vmware_vmdk__inst__grain_secondary [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
<TR><TD BGCOLOR="#E0FFE0">pos</TD><TD BGCOLOR="#E0FFE0">size</TD><TD BGCOLOR="#E0FFE0">type</TD><TD BGCOLOR="#E0FFE0">id</TD></TR>
<TR><TD PORT="grain_secondary_pos">(start_secondary_grain * _root.len_sector)</TD><TD PORT="grain_secondary_size">(size_grain * _root.len_sector)</TD><TD></TD><TD PORT="grain_secondary_type">grain_secondary</TD></TR>
</TABLE>>];
subgraph cluster__header_flags {
label="VmwareVmdk::HeaderFlags";
graph[style=dotted];
header_flags__seq [label=<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
<TR><TD BGCOLOR="#E0FFE0">pos</TD><TD BGCOLOR="#E0FFE0">size</TD><TD BGCOLOR="#E0FFE0">type</TD><TD BGCOLOR="#E0FFE0">id</TD></TR>
<TR><TD PORT="reserved1_pos">0</TD><TD PORT="reserved1_size">5b</TD><TD>b5</TD><TD PORT="reserved1_type">reserved1</TD></TR>
<TR><TD PORT="zeroed_grain_table_entry_pos">0:5</TD><TD PORT="zeroed_grain_table_entry_size">1b</TD><TD>BitsType1(BigBitEndian)</TD><TD PORT="zeroed_grain_table_entry_type">zeroed_grain_table_entry</TD></TR>
<TR><TD PORT="use_secondary_grain_dir_pos">0:6</TD><TD PORT="use_secondary_grain_dir_size">1b</TD><TD>BitsType1(BigBitEndian)</TD><TD PORT="use_secondary_grain_dir_type">use_secondary_grain_dir</TD></TR>
<TR><TD PORT="valid_new_line_detection_test_pos">0:7</TD><TD PORT="valid_new_line_detection_test_size">1b</TD><TD>BitsType1(BigBitEndian)</TD><TD PORT="valid_new_line_detection_test_type">valid_new_line_detection_test</TD></TR>
<TR><TD PORT="reserved2_pos">1</TD><TD PORT="reserved2_size">1</TD><TD>u1</TD><TD PORT="reserved2_type">reserved2</TD></TR>
<TR><TD PORT="reserved3_pos">2</TD><TD PORT="reserved3_size">6b</TD><TD>b6</TD><TD PORT="reserved3_type">reserved3</TD></TR>
<TR><TD PORT="has_metadata_pos">2:6</TD><TD PORT="has_metadata_size">1b</TD><TD>BitsType1(BigBitEndian)</TD><TD PORT="has_metadata_type">has_metadata</TD></TR>
<TR><TD PORT="has_compressed_grain_pos">2:7</TD><TD PORT="has_compressed_grain_size">1b</TD><TD>BitsType1(BigBitEndian)</TD><TD PORT="has_compressed_grain_type">has_compressed_grain</TD></TR>
<TR><TD PORT="reserved4_pos">3</TD><TD PORT="reserved4_size">1</TD><TD>u1</TD><TD PORT="reserved4_type">reserved4</TD></TR>
</TABLE>>];
}
}
vmware_vmdk__seq:flags_type -> header_flags__seq [style=bold];
vmware_vmdk__seq:start_descriptor_type -> vmware_vmdk__inst__descriptor:descriptor_pos [color="#404040"];
vmware_vmdk__inst__len_sector:len_sector_type -> vmware_vmdk__inst__descriptor:descriptor_pos [color="#404040"];
vmware_vmdk__seq:size_descriptor_type -> vmware_vmdk__inst__descriptor:descriptor_size [color="#404040"];
vmware_vmdk__inst__len_sector:len_sector_type -> vmware_vmdk__inst__descriptor:descriptor_size [color="#404040"];
vmware_vmdk__seq:start_primary_grain_type -> vmware_vmdk__inst__grain_primary:grain_primary_pos [color="#404040"];
vmware_vmdk__inst__len_sector:len_sector_type -> vmware_vmdk__inst__grain_primary:grain_primary_pos [color="#404040"];
vmware_vmdk__seq:size_grain_type -> vmware_vmdk__inst__grain_primary:grain_primary_size [color="#404040"];
vmware_vmdk__inst__len_sector:len_sector_type -> vmware_vmdk__inst__grain_primary:grain_primary_size [color="#404040"];
vmware_vmdk__seq:start_secondary_grain_type -> vmware_vmdk__inst__grain_secondary:grain_secondary_pos [color="#404040"];
vmware_vmdk__inst__len_sector:len_sector_type -> vmware_vmdk__inst__grain_secondary:grain_secondary_pos [color="#404040"];
vmware_vmdk__seq:size_grain_type -> vmware_vmdk__inst__grain_secondary:grain_secondary_size [color="#404040"];
vmware_vmdk__inst__len_sector:len_sector_type -> vmware_vmdk__inst__grain_secondary:grain_secondary_size [color="#404040"];
}