This document describes the file format of the loved/hated registry.dat file.
The registry file begins with a file header, followed by a tree. The tree consist of keys, each may containing one or more sub-keys. Each key may also contain entries. Both entries and keys have names. Entries also have values associated.
The registry file is in an optimized binary format. Consequently this document may be confusing on the first or second read. Byte-by-byte analysis of a sample file is provided. You are recommendated to print out the sample file analysis and consult it when you read this document.
The file header begins with with a 32-bit constant (0x76644441L) which identifies the file as a Registry.
The next two fields, major_version and minor_version signifies the file version. major_version is for incompatible changes and must be the same. minor_vesion is for backward-compatible changes.
The next field, next_avail, establishes where the next new node can be inserted. If a node has been deleted, this field points to that node. Otherwise this field points to one byte after the end of the file.
The last field, root_node, points to the location
of the root node (node /
).
Each node has an associated name. The node and its name
may or may not be stored together. In a clean
registry, name
is typically stored right before the node.
A node may follow two structures. If the node is a key, then its structure is as followed:
location | long |
name_location | long |
name_length | short |
type | short |
left | long |
subkey | long |
entry | long |
-- | long |
parent | long |
If the node is an entry, then its structure is:
location | long |
name_location | long |
name_length | short |
type | short |
left | long |
value_length | long |
value_location | long |
value_length | long |
parent | long |
A node begins with the field location. The value points to the offset of that field for verifictaion purpose.
The next field is name_location. The value points to where the node name is stored. Next is name_length which stores the length of the node name (including the null terminating charactor).
The next field, type, determines if the node is a key or an entry. The value is compared against an integer mask, which may be:
Users root key | 0x01 |
Common root key | 0x02 |
Current user root key | 0x03 |
Private root key | 0x04 |
UTF string entry | 0x0010 + 1 |
32-bit integer entry | 0x0010 + 2 |
byte entry entry | 0x0010 + 3 |
file entry | 0x0010 + 4 |
The next field is left which points to the next sibling node. The value is 0 if there is no next node at the same level.
The last field, parent, points to the location of the parent node. The value is 0 if there is no parent.
For a key node, subkey points to the location of the first sub-key, and entry points to the first entry of the key.
For an entry node, value_location points to the location of the entry value and the two duplicate value_length fields specify the byte-length of the value.
At the end of this document is portions of an actual registry file. The sample has the following structure:
(o)-+ / (o)-+ Users (o)-+ Common (o)-+ Profiles [] CurrentProfile: default [] AutoStartWithLast: 0 (o)-+ default (o)-+ Version Registry (o)-+ Private Arenas
offset | raw data | field | value |
---|---|---|---|
file header | |||
000 | 41 44 64 76 | magic number | 0x76644441L |
004 | 01 00 | version major | 1 |
006 | 02 00 | version minor | 2 |
008 | 2B 04 00 00 | next available node | 1067 |
012 | 82 00 00 00 | root node | 130 |
Reserved space | |||
016 | 00 | ||
: | 00 | ||
127 | 00 | ||
key / | |||
128 | 2F 00 | name | / |
130 | 82 00 00 00 | location | 130 |
134 | 80 00 00 00 | name location | 128 |
138 | 02 00 | name length | 2 |
140 | 01 00 | type | 0x01 (user key) |
142 | 00 00 00 00 | left | 0, no sibling key |
146 | A8 00 00 00 | subkey | 168, first sub-key is Users |
150 | 00 00 00 00 | entry | 0, no entry |
154 | 00 00 00 00 | --- | |
158 | 00 00 00 00 | parent | 0, no parent key |
key Users | |||
162 | 55 73 .. 00 | name | Users |
168 | A8 00 00 00 | location | 168 |
172 | A2 00 00 00 | name location | 162 |
176 | 06 00 | name length | 6 |
178 | 01 00 | type | 0x01 (user key) |
180 | CF 00 00 00 | left | 207, the next sibling key is Common |
184 | 00 00 00 00 | subkey | 0, there is no sub-key |
188 | 00 00 00 00 | entry | 0, no entry |
192 | 00 00 00 00 | --- | |
196 | 82 00 00 00 | parent | 130, the parent is / |
key Common | |||
200 | 43 6F .. 00 | name | Common |
207 | CF 00 00 00 | location | 207 |
211 | C8 00 00 00 | name location | 200 |
215 | 07 00 | name length | 7 |
217 | 01 00 | type | 0x01 (user key) |
219 | 00 01 00 00 | left | 256, the next sibling key is Version Registry(not shown) |
223 | 58 01 00 00 | subkey | 344, the next sub-key is Profiles |
227 | 00 00 00 00 | entry | 0, no entry |
231 | 00 00 00 00 | --- | |
235 | 82 00 00 00 | parent | 130, the parent is / |
key Profiles | |||
335 | 50 72 .. 00 | name | Profiles |
344 | 58 01 00 00 | location | 344 |
348 | 4F 01 00 00 | name location | 335 |
352 | 09 00 | name length | 9 |
354 | 01 00 | type | 0x01 (user key) |
356 | 00 00 00 00 | left | 0, no sibling key |
360 | 12 02 00 00 | subkey | 530, the first sub-key is default(not shown) |
276 | 0B 04 00 00 | entry | 1035, the first entry is CurrentProfile |
280 | 00 00 00 00 | --- | |
284 | CF 00 00 00 | parent | 207, the parent is Common |
key AutoStartWithLast | |||
468 | 41 75 .. 00 | name | AutoStartWithLast |
486 | 00 00 00 00 | value | false |
490 | EA 01 00 00 | location | 490 |
494 | D1 01 00 00 | name location | 468 |
498 | 12 00 | name length | 18 |
354 | 12 00 | type | 0x02 (32-bit integer) |
356 | B4 01 00 00 | left | 436, the next entry is HavePregInfo(not shown) |
360 | 04 00 00 00 | value_length | 4, the byte-length of value |
276 | E6 01 00 00 | value_location | 1027, the value is at offset 1027 |
280 | 04 00 00 00 | value_length | 4, the byte-length of value |
284 | 58 01 00 00 | parent | 344, the parent is Profile |
entry CurrentProfile | |||
1012 | 43 75 .. 00 | name | CurrentProfile |
1027 | 64 65 .. 00 | value | default |
1035 | 0B 04 00 00 | location | 1035 |
1039 | F4 03 00 00 | name location | 1012 |
1043 | 0F 00 | name length | 15, the length of name |
1045 | 11 00 | type | 0x11 (UTF string entry) |
1047 | EA 01 00 00 | left | 490, the next entry is AutoStartWithLast |
1051 | 08 00 00 00 | value_length | 8, the length of value |
1055 | 03 04 00 00 | value_location | 1027, the value is at offset 1027 |
1059 | 08 00 00 00 | value_length | 8, the length of value |
1063 | 58 01 00 00 | parent | 344, the parent is Profile |