How to read and manipulate ~/Library/Saved Application State/com.apple.finder.savedState/data.data

Due to a bug in MacOS i've identified that this is the file that is being edited when I make a certain change in MacOS finder.

"~/Library/Saved Application State/com.apple.finder.savedState/data.data"

Right now it is kind of garbeled when opened with TextEditor.

I would like to be able to read this file, and possibly later write back to it.

This file is modified for instance when CMD + I in a finder window and make changes to sort by kind.

That info is not stored in .DS_Store but Finder is saving it in this data.data file.

I would like to write my own stuff into that file.

Is that possible? What tool? plutil could not read it. It is not a plist file.

Other applications are writing similar files so I think it is possible:

enter image description here

Please try to stick to the question so we don't get into various discussions on why I think I need to edit it.


Solution 1:

These savedState resources are used by macOS to support "resuming" applications:

One of the new features in OS X Lion and OS X Mountain Lion is the “Resume” ability for all applications to save their last state, meaning when you relaunch the app or reboot your Mac, the application will “resume” and reopen again showing all of the windows and data that was last in use.

http://osxdaily.com/2011/07/17/delete-specific-application-saved-states-from-mac-os-x-10-7-lion-resume/

I've used these savedState resources to recover command line activity of hackers while responding to computer security incidents.


Within a savedState directory, there are at least two files:

  • windows.plist, and
  • data.data

windows.plist contains window layout information and other metadata. data.data is a file containing encrypted records whose plaintext includes a serialized NSKeyedArchiver blob with application-specific state. You can use the fields NSDataKey from windows.plist as AES keys to decrypt records in data.data using CBC mode with IV | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |.

The layout of an (encrypted) record within data.data is:

typedef struct SavedStateRecord {
    char     magic[4];          // "NSCR"
    char     version[4];        // "1000"
    uint32_t window_id;         // little endian
    uint32_t cipher_text_size;  // little endian
    uint8_t  cipher_text[cipher_text_size];
} SavedStateRecord;

Once the record is decrypted, the layout looks something like:

// little endian
typedef struct SavedStateRecordPlaintext {
    uint32_t unk1;             // often 0x0
    uint32_t class_name_size;
    char     class_name[class_name_size];
    char     magic[4];         // "rchv"
    uint32_t size;

    // This is an NSKeyedArchiver serialized data structure.
    // In practice, a bplist with specific interpretation.
    uint8_t  buf[size];
} SavedStateRecordPlaintext;

From there, you can extract the bplist from the NSKeyedArchiver structure and manipulate it. The interpretation of the bplist state is application-specific.

I've written a parser to support computer forensics that is available here: https://gist.github.com/williballenthin/994db929b1448fdf73baf91207129dec

CrowdStrike also has a parser and resources that are describe here: https://www.crowdstrike.com/blog/reconstructing-command-line-activity-on-macos/