Parse Binary Property Lists in Finder Metadata

For more info on plutil and everything property list related read my book: ‘Property Lists, Preferences and Profiles for Apple Administrators’

macOS and Finder use extended attributes to store plenty of extra information about files. For example, when you download a file in Safari, it stores when a file was downloaded and which website and download URL was used.

As an example, I downloaded the latest Firefox disk image. When you look at the downloaded file in the Terminal, you see an @ after the file mode which tells us this file has additional extended attributes:

$ ls -l ~/Downloads/Firefox\ 55.0.3.dmg 
-rw-r--r--@ 1 armin  staff  51137761 Aug 30 15:11 /Users/armin/Downloads/Firefox 55.0.3.dmg

We can further inspect the extended attributes with the -@ option:

$ ls -l@ ~/Downloads/Firefox\ 55.0.3.dmg 
-rw-r--r--@ 1 armin  staff  51137761 Aug 30 15:11 /Users/armin/Downloads/Firefox 55.0.3.dmg
    com.apple.metadata:kMDItemDownloadedDate          53 
    com.apple.metadata:kMDItemWhereFroms         203 
    com.apple.quarantine          57 

This shows the three extended attributes attached to this file, their names and their sizes in bytes.

When you double-click the dmg file to mount it, the system will store the checksum and file system check result in more extended attributes:

$ ls -l@ ~/Downloads/Firefox\ 55.0.3.dmg 
-rw-r--r--@ 1 armin  staff  51137761 Aug 30 15:11 /Users/armin/Downloads/Firefox 55.0.3.dmg
    com.apple.diskimages.fsck         20 
    com.apple.diskimages.recentcksum          81 
    com.apple.metadata:kMDItemDownloadedDate          53 
    com.apple.metadata:kMDItemWhereFroms         203 
    com.apple.quarantine          57 

To inspect the contents of the extended attributes in further detail, we have to use the xattr command: xattr -l filename will show all extended attributes, or you can use xattr -pl attributename filename to get just a particular one:

$ xattr -pl com.apple.quarantine ~/Downloads/Firefox\ 55.0.3.dmg 
com.apple.quarantine: 0083;59a6b982;Safari;E56EFC36-29AB-4F77-89E6-F4264336060F

The contents of the quarantine attribute is a string with some numbers (presumably a hash) the application that downloaded it (Safari) and a UUID.

The downloaded date however, looks a lot different:

$ xattr -pl com.apple.metadata:kMDItemDownloadedDate ~/Downloads/Firefox\ 55.0.3.dmg 
com.apple.metadata:kMDItemDownloadedDate:
00000000  62 70 6C 69 73 74 30 30 A1 01 33 41 BF 56 F1 02  |bplist00..3A.V..|
00000010  53 AF D9 08 0A 00 00 00 00 00 00 01 01 00 00 00  |S...............|
00000020  00 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00  |................|
00000030  00 00 00 00 13                                   |.....|
00000035

This attribute is some binary data (xattr automatically uses binary representation when it detects a nil byte. The first few bytes in the binary data are bplist which tells us we are working with binary plist format. Unfortunately the rest of the binary plist data is quite unreadable for humans.

We can use xxd to convert the binary representation into actual data and plutil to print the plist:

$ xattr -px com.apple.metadata:kMDItemDownloadedDate ~/Downloads/Firefox\ 55.0.3.dmg | xxd -r -p | plutil -p -
[
  0 => 2017-08-30 13:11:30 +0000
]

Note that the options for xattr changed from -pl to -px which forces the output to be binary data only.

And the same command for the ‘WhereFroms’:

$ xattr -px com.apple.metadata:kMDItemWhereFroms ~/Downloads/Firefox\ 55.0.3.dmg | xxd -r -p | plutil -p -
[
  0 => "https://download-installer.cdn.mozilla.net/pub/firefox/releases/55.0.3/mac/en-US/Firefox%2055.0.3.dmg"
  1 => "https://www.mozilla.org/en-US/firefox/new/?scene=2"
]

This uses plutil’s -p option to just print the data in a human readable form. You can also have plutil convert the plist data into XML:

$ xattr -px com.apple.metadata:kMDItemWhereFroms ~/Downloads/Firefox\ 55.0.3.dmg | xxd -r -p | plutil -convert xml1 -o - -
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<array>
    <string>https://download-installer.cdn.mozilla.net/pub/firefox/releases/55.0.3/mac/en-US/Firefox%2055.0.3.dmg</string>
    <string>https://www.mozilla.org/en-US/firefox/new/?scene=2</string>
</array>
</plist>

or JSON:

$ xattr -px com.apple.metadata:kMDItemWhereFroms ~/Download.0.3.dmg | xxd -r -p | plutil -convert json -r -o - -
[
  "https:\/\/download-installer.cdn.mozilla.net\/pub\/firefox\/releases\/55.0.3\/mac\/en-US\/Firefox%2055.0.3.dmg",
  "https:\/\/www.mozilla.org\/en-US\/firefox\/new\/?scene=2"
]

For more info on plutil and everything property list related read my book: ‘Property Lists, Preferences and Profiles for Apple Administrators’

Leave a Reply

Your email address will not be published. Required fields are marked *