Zeki Turedi
Zeki Turedi

Reputation: 61

Reading Binary Plist files with Python

I am currently using the Plistlib module to read Plist files but I am currently having an issue with it when it comes to Binary Plist files.

I am wanting to read the data into a string to later to be analysed/printed etc. I am wondering if their is anyway of reading in a Binary Plist file without using the plutil function and converting the binary file into XML?

Thank you for your help and time in advance.

Upvotes: 4

Views: 10938

Answers (5)

tomy0000000
tomy0000000

Reputation: 433

I might be 10 years late to answer this question, but for anyone who is looking for this, plistlib is what you're looking for.

Upvotes: 4

orip
orip

Reputation: 75507

Although you specified no plutil, a working solution with it may be useful to others as it's preinstalled on Macs:

import json
from subprocess import Popen, PIPE

def plist_to_dictionary(filename):
    "Pipe the binary plist through plutil and parse the JSON output"
    with open(filename, "rb") as f:
        content = f.read()
    args = ["plutil", "-convert", "json", "-o", "-", "--", "-"]
    p = Popen(args, stdin=PIPE, stdout=PIPE)
    out, err = p.communicate(content)
    return json.loads(out)

print plist_to_dictionary(path_to_plist_file)

Upvotes: 7

kenorb
kenorb

Reputation: 166775

You may look at CFBinaryPList.c source file to see how it is implemented in C.

Based on the file, its format goes like:

HEADER
    magic number ("bplist")
    file format version (currently "0?")

OBJECT TABLE
    variable-sized objects

    Object Formats (marker byte followed by additional info in some cases)
    null    0000 0000           // null object [v"1?"+ only]
    bool    0000 1000           // false
    bool    0000 1001           // true
    url 0000 1100   string      // URL with no base URL, recursive encoding of URL string [v"1?"+ only]
    url 0000 1101   base string // URL with base URL, recursive encoding of base URL, then recursive encoding of URL string [v"1?"+ only]
    uuid    0000 1110           // 16-byte UUID [v"1?"+ only]
    fill    0000 1111           // fill byte
    int 0001 0nnn   ...     // # of bytes is 2^nnn, big-endian bytes
    real    0010 0nnn   ...     // # of bytes is 2^nnn, big-endian bytes
    date    0011 0011   ...     // 8 byte float follows, big-endian bytes
    data    0100 nnnn   [int]   ... // nnnn is number of bytes unless 1111 then int count follows, followed by bytes
    string  0101 nnnn   [int]   ... // ASCII string, nnnn is # of chars, else 1111 then int count, then bytes
    string  0110 nnnn   [int]   ... // Unicode string, nnnn is # of chars, else 1111 then int count, then big-endian 2-byte uint16_t
    string  0111 nnnn   [int]   ... // UTF8 string, nnnn is # of chars, else 1111 then int count, then bytes [v"1?"+ only]
    uid 1000 nnnn   ...     // nnnn+1 is # of bytes
        1001 xxxx           // unused
    array   1010 nnnn   [int]   objref* // nnnn is count, unless '1111', then int count follows
    ordset  1011 nnnn   [int]   objref* // nnnn is count, unless '1111', then int count follows [v"1?"+ only]
    set 1100 nnnn   [int]   objref* // nnnn is count, unless '1111', then int count follows [v"1?"+ only]
    dict    1101 nnnn   [int]   keyref* objref* // nnnn is count, unless '1111', then int count follows
        1110 xxxx           // unused
        1111 xxxx           // unused

OFFSET TABLE
    list of ints, byte size of which is given in trailer
    -- these are the byte offsets into the file
    -- number of these is in the trailer

TRAILER
    byte size of offset ints in offset table
    byte size of object refs in arrays and dicts
    number of offsets in offset table (also is number of objects)
    element # in offset table which is top level object
    offset table offset

Upvotes: 0

Gordon Wrigley
Gordon Wrigley

Reputation: 11785

Biplist https://github.com/wooster/biplist available via easy-install or pip.

Upvotes: 3

Franklin Piat
Franklin Piat

Reputation: 4601

You can use the tool plutil (from libplist from http://www.libimobiledevice.org/) to convert binary to xml plist files (and vice-versa).

Upvotes: 1

Related Questions