Padding(12), "num_facts" / Byte, "num_facts_actions" / Byte, Padding(2), Array( 16, "data" / Struct("type" / Int32ul, "id" / Int16ul, Padding( 2), Array(4, "params" / Int32ul)))))) ai = "ai" / Struct( "has_ai" / Int32ul, # if true, parse AI "yep" / If( this.has_ai == 1, IfThenElse( lambda ctx: ctx._.version == Version.DE, Find( b'\00' * 4096, None ), # The ai structure in DE seems to have changed, for now we simply skip it "ais" / Struct( "max_strings" / Int16ul, "num_strings" / Int16ul, Padding(4), Array( this.num_strings, "strings" / PascalString(lengthfield="name_length" / Int32ul, encoding='latin1')), Padding(6), Array(8, script), Padding(104), Array(80, "timers" / Int32sl), Array(256, "shared_goals" / Int32sl), Padding(4096), ))))
# encrypted payload is split into multiple data blocks with hashes PayloadBlock = Struct( "block_index" / Checksum(Int32ul, lambda this: this._index, this), "block_hash_offset" / Tell, Padding(32), "block_data" / Prefixed(Int32ul, GreedyBytes), # block_hash has to be at the end with a pointer because it needs to # come after other fields "block_hash" / Pointer( this.block_hash_offset, IfThenElse( len_(this.block_data) == 0, Checksum(Bytes(32), lambda _: b'\x00' * 32, this), Checksum( Bytes(32), lambda block_data: hashlib.sha256(block_data).digest(), this.block_data, # exception=PayloadChecksumError ))), ) PayloadBlocks = RepeatUntil( lambda item, a, b: len(item.block_data) == 0, # and item.block_hash == b'\x00' * 32, PayloadBlock) # -------------------- Payload Decryption/Decompression -------------------- # Compressed Bytes <---> Stream Start Bytes, Decompressed XML UnpackedPayload = Reparsed(
return json.loads(decoded) except Exception as ex: # log the error when decrypted bytes couldn't be loaded # after trying all quirk adaptions if i == len(decrypted_quirks) - 1: _LOGGER.error("unable to parse json '%s': %s", decoded, ex) return None Message = Struct( # for building we need data before anything else. "data" / Pointer(32, RawCopy(EncryptionAdapter(GreedyBytes))), "header" / RawCopy( Struct( Const(0x2131, Int16ub), "length" / Rebuild(Int16ub, Utils.get_length), "unknown" / Default(Int32ub, 0x00000000), "device_id" / Hex(Bytes(4)), "ts" / TimeAdapter(Default(Int32ub, datetime.datetime.utcnow())), ) ), "checksum" / IfThenElse( Utils.is_hello, Bytes(16), Checksum(Bytes(16), Utils.md5, Utils.checksum_field_bytes), ), )
make = "make" / Struct("work_timer" / Float32l) attack = "attack" / Struct( "range" / Float32l, "min_range" / Float32l, "missile_id" / Int16ul, "frame_delay" / Int16ul, "need_to_attack" / Int16ul, "was_same_owner" / Int16ul, "indirect_fire_flag" / Byte, "move_sprite_id" / Int16ul, "fight_sprite_id" / Int16ul, "wait_sprite_id" / Int16ul, "last_target_position" / vector) unit_action = Struct( "type" / Int16ul, "data" / If( lambda ctx: ctx.type > 0, Struct( "state" / IfThenElse( lambda ctx: find_version(ctx) in [Version.AOK, Version.AOC], Byte, Int32ul), "target_object_pointer" / Int32sl, "target_object_pointer2" / Int32sl, "target_object_id" / Int32sl, "target_object_id_2" / Int32sl, "position" / vector, "timer" / Float32l, "target_moved_state" / Byte, "task_id" / Int16ul, "sub_action_value" / Byte, "sub_actions" / LazyBound(lambda x: action_list), "sprite_id" / Int16sl, Embedded("additional" / Switch(lambda ctx: ctx._.type, { 1: move_to, 3: enter, 9: attack, 21: make }, default=Pass))))) action_list = "action_list" / Struct("actions" / RepeatUntil(
"pgm": 16, "stim": 8, "daq": 4, "calpag": 1, } AddressGranularity = Enum(BitsInteger(2), BYTE=0b00, WORD=0b01, DWORD=0b10, RESERVED=0b11) ByteOrder = Enum(BitsInteger(1), INTEL=0, MOTOROLA=1) # byte-order dependent types Int16u = IfThenElse(this._.byteOrder == ByteOrder.INTEL, Int16ul, Int16ub) Int16s = IfThenElse(this._.byteOrder == ByteOrder.INTEL, Int16sl, Int16sb) Int32u = IfThenElse(this._.byteOrder == ByteOrder.INTEL, Int32ul, Int32ub) Int32s = IfThenElse(this._.byteOrder == ByteOrder.INTEL, Int32sl, Int32sb) CommModeBasic = BitStruct( "optional" / Flag, # The OPTIONAL flag indicates whether additional # information on supported types of Communication mode # is available. The master can get that additional # information with GET_COMM_MODE_INFO "slaveBlockMode" / Flag, Padding(3), "addressGranularity" / AddressGranularity, "byteOrder" / ByteOrder, )
) RESOURCE_VALUES = { "dbg": 32, "pgm": 16, "stim": 8, "daq": 4, "calpag": 1, } AddressGranularity = Enum(BitsInteger(2), BYTE=0b00, WORD=0b01, DWORD=0b10, RESERVED=0b11) ByteOrder = Enum(BitsInteger(1), INTEL=0, MOTOROLA=1) # byte-order dependent types Int16u = IfThenElse(this._.byteOrder == ByteOrder.INTEL, Int16ul, Int16ub) Int32u = IfThenElse(this._.byteOrder == ByteOrder.INTEL, Int32ul, Int32ub) Int64u = IfThenElse(this._.byteOrder == ByteOrder.INTEL, Int64ul, Int64ub) CommModeBasic = BitStruct( "optional" / Flag, # The OPTIONAL flag indicates whether additional # information on supported types of Communication mode # is available. The master can get that additional # information with GET_COMM_MODE_INFO "slaveBlockMode" / Flag, Padding(3), "addressGranularity" / AddressGranularity, "byteOrder" / ByteOrder, ) ConnectResponsePartial = Struct("resource" / ResourceType, "commModeBasic" / CommModeBasic)
if obj.minute: # we encode all minute values to h:30 hour |= 0x01 return (obj.day, year, hour, obj.month) class DeviceSerialAdapter(Adapter): """ Adapter to decode the device serial number. """ def _decode(self, obj, context, path): return bytearray(n - 0x30 for n in obj).decode() Status = "Status" / Struct( "cmd" / Const(PROP_INFO_RETURN, Int8ub), Const( 0x01, Int8ub), "mode" / ModeFlags, "valve" / Int8ub, Const( 0x04, Int8ub), "target_temp" / TempAdapter(Int8ub), "away" / IfThenElse(lambda ctx: ctx.mode.AWAY, AwayDataAdapter( Bytes(4)), Optional(Bytes(4))), "presets" / Optional( Struct( "window_open_temp" / TempAdapter(Int8ub), "window_open_time" / WindowOpenTimeAdapter(Int8ub), "comfort_temp" / TempAdapter(Int8ub), "eco_temp" / TempAdapter(Int8ub), "offset" / TempOffsetAdapter(Int8ub), ))) Schedule = "Schedule" / Struct( "cmd" / Enum(Int8ub, **NAME_TO_CMD), "day" / Enum(Int8ub, **NAME_TO_DAY), "base_temp" / TempAdapter(Int8ub), "next_change_at" / TimeAdapter(Int8ub), "hours" / GreedyRange( Struct(
"doppleganger" / Flag, "go_to_sleep" / Flag, "object_id" / Int32ul, "facet" / Byte, "x" / Float32l, "y" / Float32l, "z" / Float32l, "screen_offset_x" / Int16ul, "screen_offset_y" / Int16ul, "shadow_offset_x" / Int16ul, "shadow_offset_y" / Int16ul, "selected_group" / If(lambda ctx: find_version(ctx) == Version.AOK, Byte), ResourceEnum("resource_type" / Int16sl), "amount" / Float32l, "worker_count" / IfThenElse(lambda ctx: find_save_version(ctx) == 12.36, Int32ul, Byte), "current_damage" / Byte, "damaged_lately_timer" / Byte, "under_attack" / Byte, "pathing_group_len" / Int32ul, "pathing_group" / Array(lambda ctx: ctx.pathing_group_len, "object_id" / Int32ul), "group_id" / Int32sl, "roo_already_called" / Byte, "de_static_unk1" / If(lambda ctx: find_version(ctx) == Version.DE, Bytes(19)), "has_sprite_list" / Byte, "sprite_list" / If(lambda ctx: ctx.has_sprite_list != 0, RepeatUntil(lambda x, lst, ctx: lst[-1].type == 0, sprite_list)), "hd_extension" / If(
# Specialization for loading float data faster TaggedFloat64 = ExprAdapter( Struct(Const('tag' / Int16ul, 5), 'value' / Float64l), encoder=lambda obj, ctx: Container(tag=obj.tag, value=obj.value), decoder=lambda obj, ctx: obj.value) DataList = Struct( 'size' / Int64ul, OnDemand(Array(lambda ctx: ctx.size, TaggedFloat64)), Const('\xc0\xff\xee\x01') # XXX: probably useful ) # XXX: hacks bad_strings = ('\xc0\xff\xee\x01\x00\x00', '\x01#Eg\x00\x00') Property = Struct( 'peek' / Peek(String(6)), Embedded( IfThenElse(this.peek in bad_strings, Padding(6), Struct('label' / VBString, 'TaggedData' / TaggedData)))) Properties = GreedyRange(Property) LabeledDataList = Struct('label' / VBString, Padding(18), 'DataList' / Embedded(DataList)) DataSet = Struct( 'number' / Int64ul, # XXX: may have more than two. Might use ctx.number to decide? 'LabeledDataList' / Array(2, LabeledDataList), 'Properties' / Properties) if __name__ == '__main__': def main(): ap = ArgumentParser() ap.add_argument('-v', '--verbose', action='store_true') ap.add_argument('--xml',
), "command" / Default(IPMessageCommand, 0x00), "sub_command" / Default(Int8ub, 0x00), "wt" / Default(Int8ub, 0x00), # WT - 14 "sb" / Default(Int8ub, 0x00), # SB: 0 "cryptor_code" / Default( Enum(Int8ub, none=0, aes_256_ecb=1, old_module=0xEE), "none"), "_not_used" / Padding(1, b"\xee"), "sequence_id" / Default(Int8ub, 0xEE), ), b"\xee", ), "payload" / Default( IfThenElse( this.header.flags.encrypt, EncryptionAdapter(Aligned(16, GreedyBytes, b"\xee")), Bytes(this.header.length), ), b"", ), ) IPMessageResponse = Struct( "header" / Aligned( 16, Struct( "sof" / Const(0xAA, Int8ub), "length" / Rebuild( Int16ul, lambda ctx: len(ctx._.payload) if "payload" in ctx._ else 0), "message_type" / Default(IPMessageType, 0x01),
def scan(self, data, file, options, expire_at): with io.BytesIO(data) as lnk_io: lnk_data = lnk_io.read() UnicodeString = "UnicodeString" / Struct( "Length" / Int32ul, "Characters" / StringEncoded(Bytes(this.Length * 2), "utf16")) LinkTargetIDList = "LinkTargetIDList" / Struct( "IDListSize" / Int16ul, "ItemID" / GreedyRange( Struct( "ItemIDSize" / Int16ul, "Data" / Bytes(this.ItemIDSize - 2), )), "TerminalID" / Int16ul) TypedPropertyValue = "TypedPropertyValue" / Struct( "Type" / Enum(Int16ul, VT_EMPTY=0x0000, VT_NULL=0x0001, VT_I2=0x0002, VT_I4=0x0003, VT_R4=0x0004, VT_R8=0x0005, VT_CY=0x0006, VT_DATE=0x0007, VT_BSTR=0x0008, VT_ERROR=0x000A, VT_BOOL=0x000B, VT_DECIMAL=0x000E, VT_I1=0x0010, VT_UI1=0x0011, VT_UI2=0x0012, VT_UI4=0x0013, VT_I8=0x0014, VT_UI8=0x0015, VT_INT=0x0016, VT_UINT=0x0017, VT_LPSTR=0x001E, VT_LPWSTR=0x001F, VT_FILETIME=0x0040, VT_BLOB=0x0041, VT_STREAM=0x0042, VT_STORAGE=0x0043, VT_STREAMED_Object=0x0044, VT_STORED_Object=0x0045, VT_BLOB_Object=0x0046, VT_CF=0x0047, VT_CLSID=0x0048, VT_VERSIONED_STREAM=0x0049, VT_I2_2=0x1002, VT_I4_2=0x1003, VT_R4_2=0x1004, VT_R8_2=0x1005, VT_CY_2=0x1006, VT_DATE_2=0x1007, VT_BSTR_2=0x1008, VT_ERROR_2=0x100A, VT_BOOL_2=0x100B, VT_VARIANT_2=0x100C, VT_I1_2=0x1010, VT_UI1_2=0x1011, VT_UI2_2=0x1012, VT_UI4_2=0x1013, VT_I8_2=0x1014, VT_UI8_2=0x1015, VT_LPSTR_2=0x101E, VT_LPWSTR_2=0x101F, VT_FILETIME_2=0x1040, VT_CF_2=0x1047, VT_CLSID_2=0x1048, VT_I2_3=0x2002, VT_I4_3=0x2003, VT_R4_3=0x2004, VT_R8_3=0x2005, VT_CY_3=0x2006, VT_DATE_3=0x2007, VT_BSTR_3=0x2008, VT_ERROR_3=0x200A, VT_BOOL_3=0x200B, VT_VARIANT_3=0x200C, VT_DECIMAL_3=0x200E, VT_I1_3=0x2010, VT_UI1_3=0x2011, VT_UI2_3=0x2012, VT_UI4_3=0x2013, VT_INT_3=0x2016, VT_UINT_3=0x2017), "Padding" / Bytes(2), # "Value" / If(this.Type=='VT_LPWSTR', UnicodeString) ) ExtraData = "ExtraData" / Struct( "BlockSize" / Int32ul, "BlockSignature" / Int32ul, "ConsoleDataBlock" / If( this.BlockSignature == 0xA0000002, Struct( "FileAttributes" / Enum(Int16ul, FOREGROUND_BLUE=0x001, FOREGROUND_GREEN=0x002, FOREGROUND_RED=0x004, FOREGROUND_INTENSITY=0x008, BACKGROUND_BLUE=0x010, BACKGROUND_GREEN=0x020, BACKGROUND_RED=0x040, BACKGROUND_INTENSITY=0x0080), "PopupFillAttributes" / Enum(Int16ul, FOREGROUND_BLUE=0x001, FOREGROUND_GREEN=0x002, FOREGROUND_RED=0x004, FOREGROUND_INTENSITY=0x008, BACKGROUND_BLUE=0x010, BACKGROUND_GREEN=0x020, BACKGROUND_RED=0x040, BACKGROUND_INTENSITY=0x0080), "ScreenBufferSizeX" / Int16ul, "ScreenBufferSizeY" / Int16ul, "WindowSizeX" / Int16ul, "WindowSizeY" / Int16ul, "WindowOriginX" / Int16ul, "WindowOriginY" / Int16ul, "Unused1" / Bytes(4), "Unused2" / Bytes(4), "FontSize" / Int32ul, "FontFamily" / Enum(Int32ul, FF_DONTCARE=0x0000, FF_ROMAN=0x0010, FF_SWISS=0x0020, FF_MODERN=0x0030, FF_SCRIPT=0x0040, FF_DECORATIVE=0x0050, TMPF_NONE=0x0000, TMPF_FIXED_PITCH=0x0001, TMPF_VECTOR=0x0002, TMPF_TRUETYPE=0x0004, TMPF_DEVICE=0x0004), "FontWeight" / Int32ul, "FaceName" / Bytes(64), "CursorSize" / Int32ul, "FullScreen" / Int32ul, "QuickEdit" / Int32ul, "InsertMode" / Int32ul, "AutoPosition" / Int32ul, "HistoryBufferSize" / Int32ul, "NumberOfHistoryBuffers" / Int32ul, "HistoryNoDup" / Int32ul, "ColorTable" / Bytes(64))), "ConsoleFEDataBlock" / If(this.BlockSignature == 0xA0000004, Struct("CodePage" / Int32ul)), "DarwinDataBlock" / If( this.BlockSignature == 0xA0000006, Struct("TargetAnsi" / CString("utf8"), "TargetUnicode" / CString("utf16"))), "EnvironmentVariableDataBlock" / If( this.BlockSignature == 0xA0000001, Struct("TargetAnsi" / CString("utf8"), "TargetUnicode" / CString("utf16"))), "IconEnvironmentDataBlock" / If( this.BlockSignature == 0xA0000007, Struct("TargetAnsi" / CString("utf8"), "TargetUnicode" / CString("utf16"))), "KnownFolderDataBlock" / If(this.BlockSignature == 0xA000000B, Struct( "KnownFolderID" / Bytes(16), "Offset" / Int32ul, )), "PropertyStoreDataBlock" / If( this.BlockSignature == 0xA0000009, Struct("PropertyStore" / Struct( # "StoreSize" / Int32ul, "SerializedPropertyStorage" / Struct( "StorageSize" / Int32ul, "Version" / Int32ul, "FormatID" / Bytes(16), "StringName" / IfThenElse( this.FormatID == b'\xd5\xcd\xd5\x05\x2e\x9c\x10\x1b\x93\x97\x08\x00\x2b\x2c\xf9\xae', Struct("ValueSize" / Int32ul, "NameSize" / Int32ul, "Reserved" / Bytes(1), "Name" / CString("utf16"), "TypedPropertyValue" / TypedPropertyValue), Struct("ValueSize" / Int32ul, "Id" / Int32ul, "Reserved" / Bytes(1), "TypedPropertyValue" / TypedPropertyValue)), )))), "ShimDataBlock" / If(this.BlockSignature == 0xA0000008, Struct("LayerName" / CString("utf16"))), "SpecialFolderDataBlock" / If( this.BlockSignature == 0xA0000005, Struct( "SpecialFolderID" / Int32ul, "Offset" / Int32ul, "LinkTargetIDList" / LinkTargetIDList, )), "TrackerDataBlock" / If( this.BlockSignature == 0xA0000003, Struct("Length" / Int32ul, "Version" / Int32ul, "MachineID" / Bytes(16), "Droid" / Bytes(32), "DroidBirth" / Bytes(32))), "VistaAndAboveIDListDataBlock" / If( this.BlockSignature == 0xA000000C, Struct( "ItemIDList" / GreedyRange( Struct( "ItemIDSize" / Int16ul, "Data" / Bytes(this.ItemIDSize - 2), )), "TerminalID" / Int16ul)), ) ShellLinkHeader = "ShellLinkHeader" / Struct( "HeaderSize" / Int32ul, "LinkCLSID" / Bytes(16), "LinkFlags" / BitsSwapped( BitStruct( "HasLinkTargetIDList" / Flag, "HasLinkInfo" / Flag, "HasName" / Flag, "HasRelativePath" / Flag, "HasWorkingDir" / Flag, "HasArguments" / Flag, "HasIconLocation" / Flag, "IsUnicode" / Flag, "ForceNoLinkInfo" / Flag, "HasExpString" / Flag, "RunInSeparateProcess" / Flag, "Unused1" / Flag, "HasDarwinID" / Flag, "RunAsUser" / Flag, "HasExpIcon" / Flag, "NoPidlAlias" / Flag, "Unused2" / Flag, "RunWithShimLayer" / Flag, "ForceNoLinkTrack" / Flag, "EnableTargetMetadata" / Flag, "DisableLinkPathTracking" / Flag, "DisableKnownFolderTracking" / Flag, "DisableKnownFolderAlias" / Flag, "AllowLinkToLink" / Flag, "UnaliasOnSave" / Flag, "PreferEnvironmentPath" / Flag, "KeepLocalIDListForUNCTarget" / Flag, Flag, Flag, Flag, Flag, Flag)), "FileAttributes" / BitsSwapped( BitStruct( "FILE_ATTRIBUTE_READONLY" / Flag, "FILE_ATTRIBUTE_READONLY" / Flag, "FILE_ATTRIBUTE_SYSTEM" / Flag, "Reserved1" / Flag, "FILE_ATTRIBUTE_DIRECTORY" / Flag, "FILE_ATTRIBUTE_ARCHIVE" / Flag, "Reserved2" / Flag, "FILE_ATTRIBUTE_NORMAL" / Flag, "FILE_ATTRIBUTE_TEMPORARY" / Flag, "FILE_ATTRIBUTE_SPARSE_FILE" / Flag, "FILE_ATTRIBUTE_REPARSE_POINT" / Flag, "FILE_ATTRIBUTE_COMPRESSED" / Flag, "FILE_ATTRIBUTE_OFFLINE" / Flag, "FILE_ATTRIBUTE_NOT_CONTENT_INDEXED" / Flag, "FILE_ATTRIBUTE_ENCRYPTED" / Flag, Flag, Flag, Flag, Flag, Flag, Flag, Flag, Flag, Flag, Flag, Flag, Flag, Flag, Flag, Flag, Flag, Flag)), "CreationTime" / Bytes(8), "AccessTime" / Bytes(8), "WriteTime" / Bytes(8), "FileSize" / Int32ul, "IconIndex" / Int32sl, "ShowCommand" / Enum( Int32ul, SW_HIDE=0x00000000, SW_NORMAL=0x00000001, SW_SHOWMINIMIZED=0x00000002, SW_SHOWMAXIMIZED=0x00000003, SW_SHOWNOACTIVATE=0x00000004, SW_SHOW=0x00000005, SW_MINIMIZE=0x00000006, SW_SHOWMINNOACTIVE=0x00000007, SW_SHOWNA=0x00000008, SW_RESTORE=0x00000009, SW_SHOWDEFAULT=0x0000000a, ), "HotKey" / Struct("LowByte" / Int8ul, "HighByte" / Int8ul), "Reserved1" / Bytes(2), "Reserved2" / Bytes(4), "Reserved3" / Bytes(4)) CommonNetworkRelativeLink = "CommonNetworkRelativeLink" / Struct( "CommonNetworkRelativeLinkSize" / Int32ul, "CommonNetworkRelativeLinkFlags" / BitsSwapped( BitStruct("ValidDevice" / Flag, "ValideNetType" / Flag, Flag, Flag, Flag, Flag, Flag, Flag, Flag, Flag, Flag, Flag, Flag, Flag, Flag, Flag, Flag, Flag, Flag, Flag, Flag, Flag, Flag, Flag, Flag, Flag, Flag, Flag, Flag, Flag, Flag, Flag)), "NetNameOffset" / Int32ul, "DeviceNameOffset" / Int32ul, "NetworkProviderType" / If( this.CommonNetworkRelativeLinkFlags.ValideNetType, Enum(Int32ul, WNNC_NET_AVID=0x001A0000, WNNC_NET_DOCUSPACE=0x001B0000, WNNC_NET_MANGOSOFT=0x001C0000, WNNC_NET_SERNET=0x001D0000, WNNC_NET_RIVERFRONT1=0X001E0000, WNNC_NET_RIVERFRONT2=0x001F0000, WNNC_NET_DECORB=0x0020000, WNNC_NET_PROTSTOR=0x00210000, WNNC_NET_FJ_REDIR=0x00220000, WNNC_NET_DISTINCT=0x00230000, WNNC_NET_TWINS=0x00240000, WNNC_NET_RDR2SAMPLE=0x00250000, WNNC_NET_CSC=0x00260000, WNNC_NET_3IN1=0x00270000, WNNC_NET_EXTENDNET=0x00290000, WNNC_NET_STAC=0x002A0000, WNNC_NET_FOXBAT=0x002B0000, WNNC_NET_YAHOO=0x002C0000, WNNC_NET_EXIFS=0x002D0000, WNNC_NET_DAV=0x002E0000, WNNC_NET_KNOWARE=0x002F0000, WNNC_NET_OBJECT_DIRE=0x00300000, WNNC_NET_MASFAX=0x00310000, WNNC_NET_HOB_NFS=0x00320000, WNNC_NET_SHIVA=0x00330000, WNNC_NET_IBMAL=0x00340000, WNNC_NET_LOCK=0x00350000, WNNC_NET_TERMSRV=0x00360000, WNNC_NET_SRT=0x00370000, WNNC_NET_QUINCY=0x00380000, WNNC_NET_OPENAFS=0x00390000, WNNC_NET_AVID1=0X003A0000, WNNC_NET_DFS=0x003B0000, WNNC_NET_KWNP=0x003C0000, WNNC_NET_ZENWORKS=0x003D0000, WNNC_NET_DRIVEONWEB=0x003E0000, WNNC_NET_VMWARE=0x003F0000, WNNC_NET_RSFX=0x00400000, WNNC_NET_MFILES=0x00410000, WNNC_NET_MS_NFS=0x00420000, WNNC_NET_GOOGLE=0x00430000)), If(this.NetNameOffset > 0x00000014, "NetNameOffsetUnicode" / Int32ul), If(this.NetNameOffset > 0x00000014, "DeviceNameOffsetUnicode" / Int32ul), "NetName" / CString("utf8"), If(this.NetNameOffset > 0x00000014, "DeviceName" / CString("utf8")), If(this.NetNameOffset > 0x00000014, "NetNameUnicode" / CString("utf16")), ) LinkInfo = "LinkInfo" / Struct( "LinkInfoSize" / Int32ul, "LinkInfoHeaderSize" / Int32ul, "LinkInfoFlags" / BitsSwapped( BitStruct("VolumeIDAndLocalBasePath" / Flag, "CommonNetworkRelativeLinkAndPathSuffix" / Flag, Flag, Flag, Flag, Flag, Flag, Flag, Flag, Flag, Flag, Flag, Flag, Flag, Flag, Flag, Flag, Flag, Flag, Flag, Flag, Flag, Flag, Flag, Flag, Flag, Flag, Flag, Flag, Flag, Flag, Flag)), "VolumeIDOffset" / Int32ul, "LocalBasePathOffset" / Int32ul, "CommonNetworkRelativeLinkOffset" / Int32ul, "CommonPathSuffixOffset" / Int32ul, "LocalBasePathOffsetUnicode" / If(this.LinkInfoHeaderSize >= 0x24, Int32ul), "CommonPathSuffixOffsetUnicode" / If(this.LinkInfoHeaderSize >= 0x24, Int32ul), "VolumeID" / Struct( "VolumeIDSize" / Int32ul, "DriveType" / Enum(Int32ul, DRIVE_UNKNOWN=0x00000000, DRIVE_NO_ROOT_DIR=0x00000001, DRIVE_REMOVABLE=0x00000002, DRIVE_FIXED=0x00000003, DRIVE_REMOTE=0x00000004, DRIVE_CDROM=0x00000005, DRIVE_RAMDISK=0x00000006), "DriveSerialNumber" / Int32ul, "VolumeLabelOffset" / Int32ul, "VolumeLabelOffsetUnicode" / If(this.VolumeLabelOffset == 0x14, Int32ul), "Data" / CString("utf8"), ), "LocalBasePath" / If(this.LinkInfoFlags.VolumeIDAndLocalBasePath, CString("utf8")), "CommonNetworkRelativeLink" / If(this.CommonNetworkRelativeLinkOffset, CommonNetworkRelativeLink), "CommonPathSuffix" / CString("utf8"), "LocalBasePathUnicode" / If(this.LinkInfoHeaderSize == 0x24, If(this.LocalBasePathOffsetUnicode, CString("utf16"))), "CommonPathSuffixUnicode" / If(this.LinkInfoHeaderSize == 0x24, If(this.CommonPathSuffixOffsetUnicode, CString("utf16"))), ) header = ShellLinkHeader.parse(lnk_data) offset = header.HeaderSize try: if header.LinkFlags.HasLinkTargetIDList: linktargetidlist = LinkTargetIDList.parse(data[offset:]) offset += linktargetidlist.IDListSize + 2 except: self.flags.append("Unable to parse LinkTargetIDList") try: if header.LinkFlags.HasLinkInfo: linkinfo = LinkInfo.parse(data[offset:]) if linkinfo.VolumeID.DriveType: self.event['DriveType'] = linkinfo.VolumeID.DriveType if linkinfo.VolumeID.DriveSerialNumber: self.event["DriveSerialNumber"] = '{0:x}'.format( linkinfo.VolumeID.DriveSerialNumber) if linkinfo.VolumeID.Data: self.event["VolumeLabel"] = linkinfo.VolumeID.Data if linkinfo.LocalBasePath: self.event["LocalBasePath"] = linkinfo.LocalBasePath if linkinfo.CommonNetworkRelativeLink: commonnetworkrelativelink = CommonNetworkRelativeLink.parse( data[offset + linkinfo.CommonNetworkRelativeLinkOffset:]) self.event["NetName"] = commonnetworkrelativelink.NetName offset += linkinfo.LinkInfoSize except: self.flags.append("Unable to parse LinkInfo") StringData = "StringData" / Struct( "CountCharacters" / Int16ul, "String" / IfThenElse(header.LinkFlags.IsUnicode, StringEncoded(Bytes(this.CountCharacters * 2), "utf16"), StringEncoded(Bytes(this.CountCharacters), "utf8"))) try: if header.LinkFlags.HasName: NAME_STRING = StringData.parse(data[offset:]) self.event["NAME_STRING"] = NAME_STRING.String if header.LinkFlags.IsUnicode: offset += (len(NAME_STRING.String) * 2 + 2) else: offset += (len(NAME_STRING.String) + 2) except: self.flags.append("Unable to parse NAME_STRING") try: if header.LinkFlags.HasRelativePath: RELATIVE_PATH = StringData.parse(data[offset:]) self.event["RELATIVE_PATH"] = RELATIVE_PATH.String if header.LinkFlags.IsUnicode: offset += (len(RELATIVE_PATH.String) * 2 + 2) else: offset += (len(RELATIVE_PATH.String) + 2) except: self.flags.append("Unable to parse RELATIVE_PATH") try: if header.LinkFlags.HasWorkingDir: WORKING_DIR = StringData.parse(data[offset:]) self.event["WORKING_DIR"] = WORKING_DIR.String if header.LinkFlags.IsUnicode: offset += (len(WORKING_DIR.String) * 2 + 2) else: offset += (len(WORKING_DIR.String) + 2) except: self.flags.append("Unable to parse WORKING_DIR") try: if header.LinkFlags.HasArguments: COMMAND_LINE_ARGUMENTS = StringData.parse(data[offset:]) self.event[ "COMMAND_LINE_ARGUMENTS"] = COMMAND_LINE_ARGUMENTS.String if header.LinkFlags.IsUnicode: offset += (len(COMMAND_LINE_ARGUMENTS.String) * 2 + 2) else: offset += (len(COMMAND_LINE_ARGUMENTS.String) + 2) except: self.flags.append("Unable to parse COMMAND_LINE_ARGUMENTS") try: if header.LinkFlags.HasIconLocation: ICON_LOCATION = StringData.parse(data[offset:]) self.event["ICON_LOCATION"] = ICON_LOCATION.String if header.LinkFlags.IsUnicode: offset += (len(ICON_LOCATION.String) * 2 + 2) else: offset += (len(ICON_LOCATION.String) + 2) except: self.flags.append("Unable to parse ICON_LOCATION") try: blocksize = True while blocksize: try: extradata = ExtraData.parse(data[offset:]) blocksize = extradata.BlockSize except: break try: if extradata.IconEnvironmentDataBlock: self.event[ "IconTarget"] = extradata.IconEnvironmentDataBlock.TargetAnsi except: self.flags.append( "Unable to parse IconEnvironmentDataBlock") if extradata.TrackerDataBlock: self.event[ "MachineID"] = extradata.TrackerDataBlock.MachineID.strip( b'\x00') self.event["MAC"] = str( uuid.UUID(bytes_le=extradata.TrackerDataBlock. Droid[16:])).split('-')[-1] offset += extradata.BlockSize except: self.flags.append("Unable to parse ExtraDataBlock")
raise Exception("Invalid year, possible [2000,2099]") year = obj.year - 2000 hour = obj.hour * 2 if obj.minute: # we encode all minute values to h:30 hour |= 0x01 return (obj.day, year, hour, obj.month) Status = "Status" / Struct( "cmd" / Const(PROP_INFO_RETURN, Int8ub), Const(0x01, Int8ub), "mode" / ModeFlags, "valve" / Int8ub, Const(0x04, Int8ub), "target_temp" / TempAdapter(Int8ub), "away" / IfThenElse(lambda ctx: ctx.mode.AWAY, AwayDataAdapter(Byte[4]), GreedyBytes), ) Schedule = "Schedule" / Struct( "cmd" / Enum(Int8ub, **NAME_TO_CMD), "day" / Enum(Int8ub, **NAME_TO_DAY), "base_temp" / TempAdapter(Int8ub), "next_change_at" / TimeAdapter(Int8ub), "hours" / GreedyRange(Struct( "target_temp" / TempAdapter(Int8ub), "next_change_at" / TimeAdapter(Int8ub), )), )
"explored" / Int32ul, Padding(4), "all" / Int32ul, "mode" / Int32ul, "score" / Int32ul, "time" / Int32ul, ) # Disabled techs, units, and buildings. disables = "disables" / Struct( Padding(4), Padding(64), IfThenElse( lambda ctx: ctx._._.version != Version.DE, Struct( Array(16, "num_disabled_techs" / Int32ul), Array(16, Array(30, Padding(4))), Array(16, "num_disabled_units" / Int32ul), Array(16, Array(30, Padding(4))), Array(16, "num_disabled_buildings" / Int32ul), Array(16, Array(20, Padding(4))), ), Padding(196)), Padding(12)) # Game settings. game_settings = "game_settings" / Struct( Array(16, AgeEnum("starting_ages" / Int32sl)), Padding(4), Padding(8), "map_id" / If(lambda ctx: ctx._._.version != Version.AOK, Int32ul), Peek("difficulty_id" / Int32ul), DifficultyEnum( "difficulty" / Int32ul), "lock_teams" / Int32ul, If( lambda ctx: ctx._._.version == Version.DE, Struct(Padding(29), If(lambda ctx: ctx._._._.save_version >= 13.07, Padding(1)))),