The last 512 bytes of a UDIF image are its trailer. A reader starts here: the trailer says where the data and the block tables are. Numbers are big-endian. Apple has not published this layout; it comes from independent documentation, and was checked against real images.
Layout
0Signaturekoly, then version, size and flags16 bytes16Forks where the data fork and the resource fork are40 bytes56Segments number, count and ID, for an image split over several files24 bytes80Data fork checksum a type, a size and up to 128 bytes136 bytes216XML the property list’s offset and length16 bytes232Reserved120 bytes352Master checksum a type, a size and up to 128 bytes136 bytes488Image variant and sector count12 bytes500Reserved12 bytes
Fields
| Offset | Size | Field | Meaning |
|---|---|---|---|
| 0 | 4 | Signature | The characters koly |
| 4 | 4 | Version | 4 |
| 8 | 4 | Header size | 512, the size of this trailer |
| 12 | 4 | Flags | Bit 0 means the image is flattened: its data and block tables are in the one file |
| 16 | 8 | Running data fork offset | Where this segment’s data starts in the data of a segmented image; 0 otherwise |
| 24 | 8 | Data fork offset | Where the runs of sectors start in this file, usually 0 |
| 32 | 8 | Data fork length | How many bytes the runs take |
| 40 | 8 | Resource fork offset | Where a classic resource fork starts, on images that have one |
| 48 | 8 | Resource fork length | Its length |
| 56 | 4 | Segment number | This file’s number in a segmented image, or 0 or 1 in a single-file image |
| 60 | 4 | Segment count | How many files the image is split over, or 0 or 1 |
| 64 | 16 | Segment ID | An ID shared by the segments of one image; zero when unused |
| 80 | 4 | Data fork checksum type | 0 for none; 2 for CRC-32 |
| 84 | 4 | Data fork checksum size | The checksum’s size in bits: 32 for CRC-32 |
| 88 | 128 | Data fork checksum | The checksum, in the first bytes of the field; unused bytes are zero |
| 216 | 8 | XML offset | Where the XML property list starts |
| 224 | 8 | XML length | Its length in bytes |
| 232 | 120 | Reserved | Zeros |
| 352 | 4 | Master checksum type | 0 for none; 2 for CRC-32 |
| 356 | 4 | Master checksum size | Its size in bits |
| 360 | 128 | Master checksum | The checksum itself, in the first bytes of the field; unused bytes are zero. In the images checked, it is a CRC-32 of the partitions’ CRC-32 checksums, each as four big-endian bytes, in the order the property list lists them |
| 488 | 4 | Image variant | 1 for a whole device, 2 for a partition image |
| 492 | 8 | Sector count | The size of the disk, in 512-byte sectors |
| 500 | 12 | Reserved | Zeros |
Reading it
Read the last 512 bytes of the file and check for koly. The property list
at the XML offset holds the block tables; an image with an XML length of zero and a
resource fork length that is not zero keeps them in the resource fork instead.
The data fork normally fills the file from byte 0 up to the property list. Images made by hdiutil can also store a checksum of the data fork; many leave it at type 0, with no checksum.