Introduction | ||||||||||||||||||||||||||||||||||||||||||||||||||
itl File Format | ||||||||||||||||||||||||||||||||||||||||||||||||||
Envelope Header | ||||||||||||||||||||||||||||||||||||||||||||||||||
Crypt Size | ||||||||||||||||||||||||||||||||||||||||||||||||||
Encrypted AND zlib Compressed Payload | ||||||||||||||||||||||||||||||||||||||||||||||||||
Inner Library Sections | ||||||||||||||||||||||||||||||||||||||||||||||||||
| ||||||||||||||||||||||||||||||||||||||||||||||||||
Want To Help? | ||||||||||||||||||||||||||||||||||||||||||||||||||
Corrupt Library? | ||||||||||||||||||||||||||||||||||||||||||||||||||
Acknowledgements |
Apple iTunes has long been able to automatically generate an XML version of the iTunes library every time it changes, and I built Playlister around this feature. However, iTunes has been discontinued on macOS in favor of Apple Music.
At the end of 2019, I started working on figuring out the binary format of the Apple Music library files, but in doing so, I started with existing work on the iTunes library format so that I would be able to compare and contrast the differences.
None of the other projects have the offsets laid down in a way that I find useful, so I decided to write this page as a companion to the Apple Music library page that I worked on for a few years.
The first four bytes of the file are hdfm. One thing to immediately note is that the itl format's outer envelope is arranged with big endian integer storage (Apple's G4 line and older processors used this encoding). A near copy of this section, internal to the encrypted and compressed portion of this file is mfdh, (hdfm, backward) in which the repeated numeric values are in little endian format. All of the internal sections I've seen have little endian format storage (Intel and AMD x86 processors store numbers this way natively).
I suspect that iTunes itl files that were created and maintained on Apple computers that were made before Apple's switch to Intel processors (Apple G4 and older), were probably entirely stored in big endian byte order. Evidence suggests that on any big endian formatted section, the section header name will be backwards, as it is for the envelope section noted above.
It would make sense that any implementation that is meant to read these files would check each section header for endian-ness to have the greatest possible compatability.
I have been doing this testing on two iTunes library files. One that was created in iTunes on macOS Mojave (and subsequently imported into Apple Music after upgrade), and one that was created in iTunes on Windows.
The sections listed in the Table of Contents above are in the approximate order of the first appearance of each of those file sections (or problems to solve) in the iTunes Music Library.itl file. These headers are also listed in little Endian (x86) order, as that is the most common.
This may never be complete. One thing to keep in mind is that, besides Music, iTunes includes Movies, TV Shows, Podcasts and Audiobooks. I have never Purchased a Movie from the iTunes Store. I only have one Podcast loaded into iTunes. I have never put any Audiobook into iTunes. So any specific data related to those things, I'm unlikely to find.
Offset | Length | Information | Value (example) |
---|---|---|---|
(0) | 4 | File signature | 68 64 66 6D |hdfm| |
(4) | 4 | Envelope length in bytes | 00 00 00 90 (144) |
(8) | 4 | File length in bytes | 00 28 02 E9 (2622185) |
(12) | 4 | Unknown | 00 3F 00 01 |
(16) | 1 | Length of Version String at (17) | 00 3F 00 01 |
(17) | max 31 | Version of iTunes | 12.10.3.1\0 |
(48) | 8 | How many msdh sections? | 00 00 00 0F (15) |
(52) | 8 | Library Persistent ID, 64bit Value | 3888862EEF15AA20 |
(60) | 4 | Unknown | 00 00 00 6F |
... | 4 | ... | ... |
(88) | 4 | Unknown | 00 00 00 64 |
(92) | 4 | Max Crypt Size (See crypt size formula) | 00 01 90 00 (102400) |
(96) | 4 | Unknown | 00 00 00 00 |
(100) | 4 | TZ Offset | FF FF C7 C0 (-14400 seconds)/GMT-0400/"US Eastern" |
(104) | 4 | Unknown | 00 00 00 00 |
(112) | 4 | Library Date * | DA 1C F1 09 (3659329801) *2019-12-16T08:30:01Z |
... | 4 | ... | ... |
* Dates are expressed in Seconds since 1-Jan-1904 Midnight & should be converted with the TZ Offset.
If Max Crypt Size is smaller than the File size, use the Max Crypt Size directly.
Crypt Size = File Size - Envelope Length - ((File Size - Envelope Length) mod 16)
Starting with the byte offset (Envelope length in Bytes), the Crypt Size of the file needs to be decrypted using the standard AES128-ECB algorythm. OpenSSL and macOS built-in libraries can do this in C/C++. In Perl, use Crypt::Cypher. A key is necessary to successfully unencrypt this.
Once unencrypted, the payload must be expanded/inflated via zlib, including the rest of the file (if any) larger than the initial Max Crypt Size.
Almost all* sections follow this beginning pattern, with differences following these first 8 bytes.
Offset | Length | Information | Value (example) |
---|---|---|---|
(0) | 4 | Section signature | xxxx |
(4) | 4 | Next Section Offset | 38 00 (56) |
These section headers follow the base pattern as described above:
msdh, mfdh, mhgh, mlah, miah, mlih, miih, mlth, mith, mlqh, miqh, stsh,
mlph, miph, mtph, mlsh, msph, mlrh, mprh.
*NOTE: mhoh sections do not follow this pattern.
Back to Table of Contents.
This section appears multiple times through a library.
Observed msdh SubTypes (contains):
Occurs multiple times. Marks transitions between major sections of the file.
Offset | Length | Information | Value (example) |
---|---|---|---|
(0) | 4 | Section signature | 6D 73 64 68 |msdh| |
(4) | 4 | Section Length | 60 00 00 00 (96) |
(8) | 4 | Associated Data Length | F0 00 00 00 (240) |
(12) | 4 | Section SubType | 10 00 00 00 (16) |
... | 4 | Zeroes | 00 00 00 00 (0) |
NOTES:
msdh SubType 3 ends at a section of just binary data.
This data has no self-identified length.
msdh SubType 0x0013 (19) ends at an XML block
with no self-identified length.
msdh SubType 4 ends at an escaped URI string
with no self-identified length.
These sections can only be parsed
using the Associated Data Length which is an offset which
points to the beginning of the next msdh section, from the begging
of its containing msdh section.
In general, when parsing, if an msdh section is either marked with an unknown SubSection or followed by an otherwise unregistered signature, it would be best to use the Associated Data Length to skip the associated data (possibly registering a warning, or telemetry for a bug report).
Back to Table of Contents.
This section appears once as the File Envelope, and once as the second section within the encrypted and compressed section of the file.
Offset | Length | Information | Value (example) |
---|---|---|---|
(0) | 4 | Section signature | 6D 66 64 68 |mfdh| |
(4) | 4 | Section Length | 90 00 00 00 (144) |
(8) | 4 | Uncompressed File Length (includes envelope) | 92 F3 00 01 (16839570) |
(12) | 4 | Unknown | ... |
(16) | 1 | Length of Version at (17) | 09 (9) |
(17) | max 31 | iTunes Version (NULL terminated) | 12.10.3.1\0 |
(48) | 4 | msdh Count | 0F 00 00 00 (15) |
(52) | 8 | Library Persistent ID | 3888862EEF15AA20 |
... | 4 | Unknown | ... |
(92) | 4 | Max Crypt Size | 00 01 90 00 (102400) |
... | 4 | Unknown | ... |
(92) | 4 | Max Crypt Size | 00 01 90 00 (102400) |
... | 4 | Unknown | ... |
(100) | 4 | Library Date * | 09 F1 1C DA (3659329801) *2019-12-16T08:30:01Z |
... | 4 | Unknown | ... |
Back to Table of Contents.
This section appears only once in a library.
Offset | Length | Information | Value (example) |
---|---|---|---|
(0) | 4 | Section signature | 6D 68 67 68 |mhgh| |
(4) | 4 | Section Length | 18 01 00 00 (280) |
(8) | 4 | mhoh Count | 07 00 00 00 (7) |
... | ... | Unknown | ... |
(55) | 1 | List Size (unknown) | 02 00 00 00 (2) |
... | 4 | Unknown | ... |
Back to Table of Contents.
This section appears only once in a library.
Offset | Length | Information | Value (example) |
---|---|---|---|
(0) | 4 | Section signature | 6D 6C 61 68 |mlah| |
(4) | 4 | Section Length | 5C 00 00 00 (92) |
(8) | 4 | miah Count | 5C 00 00 00 (92) |
... | ... | Unknown | ... |
Back to Table of Contents.
This section appears the number of times as specified by the containing mlah section at offset 8.
Offset | Length | Information | Value (example) |
---|---|---|---|
(0) | 4 | Section signature | 6D 69 61 68 |miah| |
(4) | 4 | Section Length | 58 00 00 00 (88) |
(8) | 4 | Associated Data Length | FB 00 00 00 (251) |
(12) | 4 | mhoh Count | 03 00 00 00 (3) |
... | ... | Unknown | ... |
(32) | 8 | Album miah Persistent ID | 032F315934465CBC |
(40) | 1 | Album Rating (percent) | 28 (40) *two stars of five |
(41) | 1 | Rated Manual or Auto (1=Manual, 0x20=Auto) | 20 (32) *Automatically Rated by iTunes |
... | ... | Unknown | ... |
Back to Table of Contents.
This section appears only once in a library.
Offset | Length | Information | Value (example) |
---|---|---|---|
(0) | 4 | Section signature | 6D 68 67 68 |mhgh| |
(4) | 4 | Section Length | 18 01 00 00 (280) |
(8) | 4 | miih Count | 07 00 00 00 (7) |
... | ... | Unknown | ... |
Back to Table of Contents.
This section appears the number of times as specified by the containing mlih section at offset 8.
Offset | Length | Information | Value (example) |
---|---|---|---|
(0) | 4 | Section signature | 6D 69 69 68 |miih| |
(4) | 4 | Section Length | 58 00 00 00 (88) |
(8) | 4 | Associated Data Length | FB 00 00 00 (251) |
(12) | 4 | mhoh Count | 03 00 00 00 (3) |
... | ... | Unknown | ... |
(20) | ... | Artist (miih) Persistent ID | E26AA55123388FD3 |
... | ... | Unknown | ... |
Back to Table of Contents.
This section appears multiple times in an iTunes Library.
Offset | Length | Information | Value (example) |
---|---|---|---|
(0) | 4 | Section signature | 6D 6C 74 68 |mlth| |
(4) | 4 | Section Length | 5C 00 00 00 (92) |
(8) | 4 | mith Count | 39 00 00 00 (57) |
... | ... | Zeroes | 00 00 00 00 |
Back to Table of Contents.
This section appears the number of times as specified by the containing mlth section at offset 8.
Offset | Length | Information | Value (example) |
---|---|---|---|
(0) | 4 | Section signature | 6D 69 74 68 |mith| |
(4) | 4 | Section Length | F4 02 00 00 (756) |
(8) | 4 | Associated Data Length | 25 08 00 00 (2085) |
(12) | 4 | mhoh Count | 0B 00 00 00 (11) |
(16) | 4 | Track Short ID | 85 00 00 00 / 0x00000085 |
... | ... | Unknown | ... |
(76) | 4 | Play Count | 03 00 00 00 (3) |
... | ... | Unknown | ... |
(108) | 1 | Rating | 14 (20) *One Star |
(109) | 1 | Unknown | ... |
(110) | 1 | Unchecked | 00 (0) *Checked |
... | ... | Unknown | ... |
(120) | 4 | Date Added | 56 3D 24 C4 (3290709334) *2008-04-10T21:55:34Z |
... | ... | Unknown | ... |
(128) | 8 | Album miah Persistent ID | 032F315934465CBC |
(136) | 8 | File Type Signature | 0 .. 0 20 41 34 4D | A4M| *"M4A " endian swapped. |
... | ... | Unknown | ... |
(420) | 4 | ??FairPlay Version?? | ??? |
... | ... | Unknown | ... |
(720) | 2 | Movement of Work | 02 00 (2) |
(722) | 2 | Movements in Work | 03 00 (3) |
... | ... | Unknown | ... |
NOTES:
Dates are in number of seconds since Jan 1 1904, midnight.
Movement only appears for classical tracks.
FairPlay Version was reported elsewhere, but I haven't been able to verify.
Back to Table of Contents.
This section appears frequently in most other sections.
Every mhoh has a SubType, and what is inside each mhoh can be VERY different depending on that SubType. The section length of a mhoh is indicated at a different offset from other section types. The following table shows the portions that are common to ALL mhoh sections.
Offset | Length | Information | Value (example) |
---|---|---|---|
(0) | 4 | Section signature | 6D 68 6F 68 |mhoh| |
(4) | 4 | Depends, Always 0x18 | 18 00 00 00 (24) |
(8) | 4 | Section Length | 4E 00 00 00 (78) |
(12) | 4 | mhoh SubType | FC 01 (0x01FC) |
... | - | ... | ... |
Back to Table of Contents.
Offset | Length | Information | Value (example) |
---|---|---|---|
(0) | 4 | Section signature | 6D 68 6F 68 |mhoh| |
(4) | 4 | Unused | 18 00 00 00 (24) |
(8) | 4 | Section Length | 39 00 00 00 (57) |
(12) | 4 | mhoh SubType | 06 00 00 00 (0x0006) |
... | - | ... | ... |
(24) | 4 | String Type | 03 00 00 00 (3) |
(28) | 4 | String Length (bytes) | 11 00 00 00 (17) |
... | - | ... | ... |
(40) | per (28) | String | |MPEG-4 video file| |
String Type (24):
Is the encoding of String (28).
0 - URI: Is a UTF-8 (narrow) string representing a
Universal Resource Identifier, usually starting with "http://",
"https://", or "file://".
1 - Wide Characters: is a UTF-16 (wide) string.
Each character is represented by a 2-byte (16 bit) space,
which IS subject to little endian byte swapping.
2 - escaped URI: Is a UTF-8 string representing a URI.
Special characters are
percent encoded.
3 - Narrow Characters: Is a UTF-8 string.
String Length (28): Note that this value will always be 40 less than the Section Length (8).
Back to Table of Contents.
Offset | Length | Information | Value (example) |
---|---|---|---|
(0) | 4 | Section signature | 6D 68 6F 68 |mhoh| |
(4) | 4 | Start of XML | 18 00 00 00 (24) |
(8) | 4 | Section Length | 3B E0 00 00 (57403) |
(12) | 4 | mhoh SubType | 02 02 00 00 (0x0202) |
... | - | ... | ... |
(24) | (see note) | String | |<?xml version="1.0" enc...| (continues) |
String (24): Note that this string length is exactly 24 less than the Section Length (8).
Back to Table of Contents.
Offset | Length | Information | Value (example) |
---|---|---|---|
(0) | 4 | Section signature | 6D 68 6F 68 |mhoh| |
(4) | 4 | Book Start | 18 00 00 00 (24) |
(8) | 4 | Section Length | 66 00 00 00 (102) |
(12) | 4 | mhoh SubType | FC 01 (0x01FC) |
... | - | ... | ... |
(24) | 4 | Vertical Resolution | E0 01 00 00 (480) |
(28) | 4 | Horizontal Resolution | 80 02 00 00 (640) |
... | - | ... | ... |
Back to Table of Contents.
mhoh book sections contain numbers and strings. Strings are marked by 0x0101. The four bytes prior to the 0x0101 will indicate the length of the string. The byte following the 0x0101 will start the first character of that string. These strings might include the separate path components of the item.
Offset | Length | Information | Value (example) |
---|---|---|---|
(0) | 4 | Section signature | 6D 68 6F 68 |mhoh| |
(4) | 4 | Book Start | 18 00 00 00 (24) |
(8) | 4 | Section Length | 66 00 00 00 (102) |
(12) | 4 | mhoh SubType | FC 01 (0x01FC) |
... | - | ... | ... |
(24) | 4 | Book signature | 62 6F 6F 6B |book| |
(28) | 4 | SubSection Length | 4E 00 00 00 (78) |
... | 4 | ... | ... |
(72) | 4 | String Length | 05 00 00 00 (5) |
(76) | 4 | String Indicator | 01 01 00 00 (0x00000101) |
(80) | 4 | String (5 long) | Users |
SubSection Length (28): Note that this length is exactly 24 less than the Section Length (8).
After reading each string, it is important to re-align to a 4 byte offset. For the string shown above, 5 bytes were read. That means 3 bytes must be discarded before the next four bytes can be read.
mhoh book sections are long, and most included data is repeated in another mhoh section (not separated).
There is one string indicated by a 0x0901, with the same setup as the 0x0101 string, except it is further preceeded by a 0x01F5.
... | 4 | ... | ... |
(364) | 4 | String Indicator | F5 01 00 00 (501) |
(368) | 4 | String Length | 08 00 00 00 (8) |
(372) | 4 | String Indicator | 01 09 00 00 (2305) |
(376) | 4 | String (8 long) | file:/// |
... | 4 | ... | ... |
There is one string indicated by a 0x0201, with the same setup as the 0x0101 string, except it is further preceeded by a 0x0501.
... | 4 | ... | ... |
(528) | 4 | String Indicator | 01 05 00 00 (1281) |
(532) | 4 | String Length | DB 00 00 00 (219) |
(536) | 4 | String Indicator | 01 02 00 00 (513) |
(540) | 4 | String (219 long) | 20fec00...(not showing all of this) |
... | 4 | ... | ... |
Back to Table of Contents.
Each of these subtypes have been found, but the data has not yet been identified.
Back to Table of Contents.
Since putting up this page, I have received a handful of submissions from folks who want to see this work further improved. I have never found new insights to this ancient format. As of 2022, I have put this project on a deep pause.
If you think you might be able to help, I make my personal diagnostic script available to you (though I do not publish the decryption key). More information on my personal GitLab:
If you run the above, and figure out some data-point that I've skipped in my layout above, send it to me. I'll be happy to publish it here, and credit you (as I have others on the musicdb page).
Please send submissions to musicdb@vollink.com
This is a low traffic web site, and I will reply to any inquiry unless you specifically ask me not to reply.
Up to Table of Contents.
After many e-mails asking if I can save a corrupted iTunes database file, the answer is no. Apple decided to both compress the entire file PLUS encrypt the first large chunk of it. If the start of the file is corrupted, then the encryption will be broken, and the uncompression will never be able to find its place. If the file is corrupted later, the compression will lose it's place, leaving the remainder of the file unreadable.
I have published the program that I use to poke through my own musicdb files as well as submissions that I get, so feel free to go for it.
Back to Table of Contents.
I would not have been able to get as far as I have without the fine work of Joseph Walton who produced titl. That iTunes itl project in Java was key to my getting the iTunes file cracked.
I also would not have been able to get as far as I have without the fine work of Jean Thomas who produced libitlp for reading iTunes itl format in C. While I had some issues with this library successfully reading the latest iTunes library output Jean's faithful approach to parsing the actual format (and not an interpretation) helped immensely on my taking this task on. Once I'm closer to done, I hope to submit patches for this project to make it work on the latest iTunes libraries (though that may be some time off).
Back to Table of Contents.
Back to Table of Contents.