Reverse-engineering the Foobar2000 index file format
I've been using Foobar2000 as my music player for over a decade. On mobile, I've switched to Plex, after Google shut down yet another service (Google Music). It's always been a hassle to keep my playlists in sync, so I finally wrote a Foobar2000 → Plex synchronization tool.
One of the challenges was to extract the Foobar2000 playlist data that is stored in a binary
index.dat file. As the file format description is not publicly available, I had to reverse-engineer it myself. 🕵️♂️
Opening the binary
index.dat file in a text editor doesn't make much sense. You can spot some plain-text data (e.g. "Library" = playlist name), but the rest is gibberish. That's because most of the data needs to be interpreted differently than a byte to char conversion.
Foobar2000 is closed-source, so there's only limited information available about its internals. There's an unofficial documentation, but it only describes the playlist format, not the
index.dat file. It was useful nonetheless, as it brings up two concepts:
- A fixed-length "magic signature" header that can be skipped
- Prepending the number of bytes of variable-length data
Both principles apply to the
index.dat file as well. Let's open this file with a hex viewer:
- The first line doesn't contain any meaningful data and can be skipped.
- Do you notice the
07 00 00 00byte sequence right before "Library"? It is the hexadecimal number of bytes that the following field takes up ("Library" = 7 bytes / characters). This principle is used throughout the file for storing all the variable-length playlist data.
For people interested in the actual format description, here is my final result.
Here are the first 24 bytes of data:
- 16 bytes: File header (a)
- 4 bytes: Number of playlists (b)
- 4 bytes: Unknown
Then, the following structure repeats itself for every playlist:
- 4 bytes: Playlist name length
xbytes: Playlist name (d)
- 4 bytes: Unknown
- 2 bytes: Playlist metadata length
ybytes: Playlist metadata (f)
- 2 bytes: Unknown
- 4 bytes: Number of playlist files
ztimes 16 bytes: Playlist file names (16 bytes per file name) (h)
Some final notes:
- If a playlist doesn't contain any tracks, there is no respective playlist file.
- Foobar2000 splits large playlists into multiple files.