#!/bin/python # # This implements the composite value types used in settings.dat registry hive # used to store AppContainer settings in Windows Apps aka UWP. # # ApplicationDataCompositeValue class is documented here: # https://docs.microsoft.com/en-us/uwp/api/windows.storage.applicationdatacompositevalue # # The internals of types, values and structures had to be reverse engineered. # # Copyright (c) 2019 Yogesh Khatri # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in all # copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. from __future__ import print_function from __future__ import unicode_literals from datetime import datetime, timedelta from uuid import UUID import binascii import struct REG_COMPOSITE_TYPE = 0x100 # When used in registry to denote value type, the REG_COMPOSITE_TYPE is or'd with one of the # values below. Example: RegUInt8 will be (REG_COMPOSITE_TYPE | RegUint8) # In the serialized ApplicationDataCompositeValue stream, the REG_COMPOSITE_TYPE is not present. RegUint8 = 0x001 RegInt16 = 0x002 RegUint16 = 0x003 RegInt32 = 0x004 RegUint32 = 0x005 RegInt64 = 0x006 RegUint64 = 0x007 RegFloat = 0x008 # aka Single RegDouble = 0x009 RegUnicodeChar = 0x00A RegBoolean = 0x00B RegUnicodeString = 0x00C RegCompositeValue = 0x00D # Application Data Composite Value (Dictionary Object) RegDateTimeOffset = 0x00E # Date as FILETIME RegTimeSpan = 0x00F # Span in 100ns ticks RegGUID = 0x010 RegUnk111 = 0x011 RegUnk112 = 0x012 RegUnk113 = 0x013 RegBytesArray = 0x014 RegInt16Array = 0x015 RegUint16Array = 0x016 RegInt32Array = 0x017 RegUInt32Array = 0x018 RegInt64Array = 0x019 RegUInt64Array = 0x01A RegFloatArray = 0x01B RegDoubleArray = 0x01C RegUnicodeCharArray = 0x01D RegBooleanArray = 0x01E RegUnicodeStringArray = 0x01F def parse_windows_timestamp(qword): # see http://integriography.wordpress.com/2010/01/16/using-phython-to-parse-and-present-windows-64-bit-timestamps/ return datetime.utcfromtimestamp(float(qword) * 1e-7 - 11644473600 ) def ReadUnicodeStringArray(buf): """Read a buffer containing an array of struct { int size; wchar string[size]; } Returns a list of utf8 encoded strings """ strings = [] buf_len = len(buf) pos = 0 while pos < buf_len: item_byte_len = struct.unpack_from(str("