def get_32_bit_cluster_address() -> Mapping: """ Mapping of a FAT32 File Allocation Table Entry :rtype: construct.Mapping """ subcon = Int32ul default = Pass mapping = dict() mapping[0x0] = 'free_cluster' mapping[0x1] = 'last_cluster' mapping[0xffffff7] = 'bad_cluster' for i in range(0xffffff8, 0xfffffff + 1): mapping[i] = 'last_cluster' encmapping = mapping.copy() encmapping['free_cluster'] = 0x0000000 encmapping['bad_cluster'] = 0xffffff7 encmapping['last_cluster'] = 0xfffffff return Mapping( subcon, encoding=encmapping, decoding=mapping, encdefault=default, decdefault=default, )
def get_12_bit_cluster_address() -> Mapping: """ Mapping of a FAT12 File Allocation Table Entry :note: don't use this Mapping to generate the actual bytes to store on filesystem, because they might depend on the next or previous value :rtype: construct.Mapping """ # subcon = Bitwise(Int12ul()) subcon = Int16ul default = Pass mapping = dict() mapping[0x0] = 'free_cluster' mapping[0x1] = 'last_cluster' mapping[0xff7] = 'bad_cluster' for i in range(0xff8, 0xfff + 1): mapping[i] = 'last_cluster' encmapping = mapping.copy() encmapping['free_cluster'] = 0x000 encmapping['bad_cluster'] = 0xff7 encmapping['last_cluster'] = 0xfff return Mapping( subcon, encoding=encmapping, decoding=mapping, encdefault=default, decdefault=default, )
zlib.DEF_MEM_LEVEL, 0 ) data = compressobj.compress(data) data += compressobj.flush() return data # -------------------- Cipher Enums -------------------- # payload encryption method # https://github.com/keepassxreboot/keepassxc/blob/8324d03f0a015e62b6182843b4478226a5197090/src/format/KeePass2.cpp#L24-L26 CipherId = Mapping( GreedyBytes, {'aes256': b'1\xc1\xf2\xe6\xbfqCP\xbeX\x05!j\xfcZ\xff', 'twofish': b'\xadh\xf2\x9fWoK\xb9\xa3j\xd4z\xf9e4l', 'chacha20': b'\xd6\x03\x8a+\x8boL\xb5\xa5$3\x9a1\xdb\xb5\x9a' } ) # protected entry encryption method # https://github.com/dlech/KeePass2.x/blob/149ab342338ffade24b44aaa1fd89f14b64fda09/KeePassLib/Cryptography/CryptoRandomStream.cs#L35 ProtectedStreamId = Mapping( Int32ul, {'none': 0, 'arcfourvariant': 1, 'salsa20': 2, 'chacha20': 3, } )
'key', RepeatUntil(lambda item, a, b: item.next_byte == 0x00, VariantDictionaryItem)), Padding(1) * "null padding") # -------------------- Dynamic Header -------------------- # https://github.com/dlech/KeePass2.x/blob/dbb9d60095ef39e6abc95d708fb7d03ce5ae865e/KeePassLib/Serialization/KdbxFile.cs#L234-L246 DynamicHeaderItem = Struct( "id" / Mapping( Byte, { 'end': 0, 'comment': 1, 'cipher_id': 2, 'compression_flags': 3, 'master_seed': 4, 'encryption_iv': 7, 'kdf_parameters': 11, 'public_custom_data': 12 }), "data" / Prefixed( Int32ul, Switch(this.id, { 'compression_flags': CompressionFlags, 'kdf_parameters': VariantDictionary, 'cipher_id': CipherId }, default=GreedyBytes))) DynamicHeader = DynamicDict( 'id', RepeatUntil(lambda item, a, b: item.id == 'end', DynamicHeaderItem))
key_composite) return transformed_key # -------------------- Dynamic Header -------------------- # https://github.com/dlech/KeePass2.x/blob/dbb9d60095ef39e6abc95d708fb7d03ce5ae865e/KeePassLib/Serialization/KdbxFile.cs#L234-L246 DynamicHeaderItem = Struct( "id" / Mapping( Byte, { 'end': 0, 'comment': 1, 'cipher_id': 2, 'compression_flags': 3, 'master_seed': 4, 'transform_seed': 5, 'transform_rounds': 6, 'encryption_iv': 7, 'protected_stream_key': 8, 'stream_start_bytes': 9, 'protected_stream_id': 10, }), "data" / Prefixed( Int16ul, Switch(this.id, { 'compression_flags': CompressionFlags, 'cipher_id': CipherId, 'transform_rounds': Int32ul, 'protected_stream_id': ProtectedStreamId }, default=GreedyBytes)),
"id" / Byte, "index" / Byte, # convert greeedystring to use this "text" / PascalString(Byte, "ascii"), ) Version = "version" / Struct( "currentrunning" / Enum(Byte, App1=0x01, App2=0x02, Candela=0x31), "hw_version" / Int16ub, "sw_version_app1" / Int16ub, "sw_version_app2" / Int16ub, "beacon_version" / Int16ub, ) SerialNumber = "serialno" / BytesInteger(12) OnOff = "OnOff" / Struct("state" / Mapping(Byte, {True: 0x01, False: 0x02})) # brightness max # 4342 64 000000000000000000000000000000 # brightness min # 4342 01 000000000000000000000000000000 # brightness middle # 4342 31 000000000000000000000000000000 # 1-100 Brightness = "brightness" / Struct("brightness" / Int8ub, ) # Note, requests with (mostly) even, responses with odd RequestType = "reqtype" / Mapping(Byte, { "SetOnOff": 0x40,
HourMinuteSecond = Struct( "time" / HourMinuteAdapter( Struct( "hour" / RawAsInt(Byte), "minute" / RawAsInt(Byte), "second" / RawAsInt(Byte), )), ) # REVIEW: This field should be named if you dont want to discard the parsed value, # and also to allow building it. Statistics = Struct(GreedyBytes, ) # REVIEW: previously this had default=False, current code would fail on other values. # If you need those, use an Adapter to convert between booleans-integers. OnOff = Struct("state" / Mapping(Byte, {True: 0x01, False: 0x02})) RGB = Struct( "red" / Default(Byte, 0), "green" / Default(Byte, 0), "blue" / Default(Byte, 0), ) Color = Struct( Embedded(RGB), "white" / Default(Byte, 0), "brightness" / Default(Byte, 0), ) WeekDayEnum = FlagsEnum(Byte, sun=0x01,