Skip to content

Instantly share code, notes, and snippets.

@hakanai
Last active April 5, 2025 09:10
Show Gist options
  • Save hakanai/3658c461e8643fc408ec65632ac85837 to your computer and use it in GitHub Desktop.
Save hakanai/3658c461e8643fc408ec65632ac85837 to your computer and use it in GitHub Desktop.
Manually disassembled AppleScript .SCPT file

The structure given here possibly only applies to the "jscr" variant, because I see quite different examples out there for "ascr". In particular, "ascr" files don't seem to contain a bplist at all!

AppleScriptHeader: {
    0x0000:  4A 73 4F 73 61 44 41 53 31 2E 30 30 31 2E 30 30
        - magic number?
        - ASCII: "JsOsaDAS1.001.00"
}

PListHeader: {
    0x0010:  62 70 6C 69 73 74 30 30
        - magic for binary property list
        - ASCII: "bplist00"
}

PListTypedValue: {
    0x0018:  D1
        - NSDictionary of length 0x1 follows
            - byte 0:
                - high nibble 0xD = NSDictionary
                - low nibble 0x1 becomes length as it is not 0xF
    0x0019:  01
        - index of first key of dict, in object table
        - corresponds to the first string below

    0x001A:  02
        - index of first value of dict, in object table
        - corresponds to the second string below
}

PListTypedValue: {
    0x001B:  56
        - ASCII-string of length 0x6 follows
            - byte 0:
                - high nibble 0x5 = ASCII string
                - low nibble 0x6 becomes size as it is not 0xF
    0x001C:  73 63 72 69 70 74 
        ASCII: "script"
}

PListTypedValue: {
    0x0022:  5F 10 75
        - ASCII-string of length 0x75 follows
            - byte 0:
                - high nibble 0x5 = ASCII string
                - low nibble 0xF means size is stored following
            - byte 1:
                - high nibble ignored?
                - low nibble 0x0 means 1 additional byte (1->2, 2->4, 3->8)
            - byte 2 becomes the actual length value
    0x0025:  0A 2F 2F 74 65 6C 6C 20 61 70 70 6C 69 63 61 74
            69 6F 6E 20 22 4D 50 6C 61 79 65 72 58 22 0D 0A
            2F 2F 65 6E 64 20 74 65 6C 6C 0A 0A 61 70 70 20
            3D 20 41 70 70 6C 69 63 61 74 69 6F 6E 28 27 51
            75 69 63 6B 54 69 6D 65 20 50 6C 61 79 65 72 2E
            61 70 70 27 29 0A 61 70 70 2E 64 6F 63 75 6D 65
            6E 74 73 5B 30 5D 2E 63 75 72 72 65 6E 74 54 69
            6D 65 28 29 0A
        - ASCII: \xA
                "//tell application \"MPlayerX\"" \xD\xA
                "//end tell" \xA\xA
                "app = Application('QuickTime Player.app')" \xA
                "app.documents[0].currentTime()" \xA
}

OffsetTable: {
    0x009A:  08
        - actual offset 0x18 -> matches where dictionary is stored
    0x009B:  0B
        - actual offset 0x1B -> the first string above
    0x009C:  12
        - actual offset 0x22 -> the second string above
}

PListTrailer: (fixed length 32) {
    0x009D:  00 00 00 00 00
        - (unused padding)
    0x00A2:  00
        - SortVersion (always 0)
    0x00A3:  01
        - OffsetIntSize (offsets in offset table are stored as 1 byte)
    0x00A4:  01
        - ObjectRefSize (object refs are stored as 1 byte)
    0x00A5:  00 00 00 00 00 00 00 03
        - NumObjects (number of offsets in offset table)
    0x00AD:  00 00 00 00 00 00 00 00
        - RootObject (object ref of top-level object)
    0x00B5:  00 00 00 00 00 00 00 8A
        - OffsetTableOffset (offset of the offset table - relative to bplist00 magic)
        - ergo actual offset in this file is 0x9A
}

AppleScriptTrailer: {
    0x00BD:  00
    0x00BE:  6A 73 63 72
        - ASCII "jscr", indicates that the script is written in JScript
        - have also seen "ascr", presumably for AppleScript
    0x00C2:  00 01
        - possibly number of contained plist files?
    0x00C4:  00 0D
        - AppleScript file trailer length?
        - matches length from end of file to start of AppleScriptTrailer, which is also the end of PListTrailer
    0x00C6:  FA DE DE AD
        - AppleScript file trailer magic?
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment