What are the contents of the :ms-properties alternate data stream?

368 Views Asked by At

When you store a file in OneDrive, an :ms-properties alternate data stream is added. I opened an example stream using FlexHex (as shown in the image), but I can't tell what type of structure those bytes might represent. Does anyone know?

enter image description here

Actually, based on the 1SPS sequence, I think it might be a prop store or a shell bag or something. For reference. And this. But I'm not sure if that's right.

2

There are 2 best solutions below

2
Simon Mourier On BEST ANSWER

They are just serialized Windows properties. You can write and read these files (as streams) using builtin Windows implementation of IPropertyStore, for example using the PSCreateMemoryPropertyStore function

Here is a small sample console app that creates a test.props file with one property of string type:

#include <windows.h>
#include <atlbase.h>
#include <atlcom.h>
#include <propsys.h>
#include <propkey.h>
#include <propvarutil.h>

// some COM error handling useful macros
#define WIDEN2(x) L ## x
#define WIDEN(x) WIDEN2(x)
#define __WFILE__ WIDEN(__FILE__)
#define SBTRACE wprintf
#define CHECKHR(expr) {hr=(expr);if(FAILED(hr)){ SBTRACE(L"HR FAILED line:%u file:%s\n", __LINE__, __WFILE__); goto cleanup; } }  
#define HR HRESULT hr=S_OK;

int main()
{
  HR;
  PROPVARIANT pv;
  PropVariantInit(&pv);
  CoInitialize(NULL);
  {
    CComPtr<IPropertyStore> ps;
    CComPtr<IPersistStream> pstream;
    CComPtr<IStream> stream;

    // create the in-memory store
    CHECKHR(PSCreateMemoryPropertyStore(IID_PPV_ARGS(&ps)));

    // define some PROPVARIANT value (here it's a string)
    CHECKHR(InitPropVariantFromString(L"hello world", &pv));

    // any property key would work
    CHECKHR(ps->SetValue(PKEY_ItemNameDisplay, pv));

    // get IPersistStream to be able to load or write
    CHECKHR(ps->QueryInterface(&pstream));

    // create a file stream
    CHECKHR(SHCreateStreamOnFileEx(L"test.props", STGM_WRITE | STGM_CREATE, 0, TRUE, nullptr, &stream));

    // this sample only saves, but you can load from an existing stream
    CHECKHR(pstream->Save(stream, TRUE));
  }

cleanup:
  PropVariantClear(&pv);
  CoUninitialize();
  return 0;
}

Here is the result:

enter image description here

0
Eric On

1SPS is the signature for a serialized property store, which is essentially a key value pair type system. its a standard structure, so its easy to parse, although the data types can make it a bit of a challenge.

It looks like there are some GUIDs in there among the 4 or so. it would be easy enough to parse out those structures as similar things are used in shellbags. it certainly just looks like a series of 1sps blocks which makes it easy.

you already know my email, so if you can extract out a few of these ADS examples, zip them, and send, i can take a closer look. if its warranted, ill even write a new forensic tool to parse them