def get_user_definition(settings): if ( settings.system_options.user_code_length_6 or settings.system_options.user_code_length_flexible ): code = ExprAdapter( Bytes(3), lambda obj, path: binascii.hexlify(obj) .decode() .rstrip("0") .replace("a", "0") or None, lambda obj, path: binascii.unhexlify(obj.replace("0", "a")), ) else: code = ExprAdapter( Bytes(3), lambda obj, path: binascii.hexlify(obj) .decode() .rstrip("0") .replace("a", "0")[:4] or None, lambda obj, path: binascii.unhexlify((obj + obj[:2]).replace("0", "a")), ) return Struct( "code" / code, "options" / BitsSwapped( BitStruct( "type" / Enum(BitsInteger(2), FullMaster=0x3, Master=0x2, Regular=0x0), "duress" / Flag, "bypass" / Flag, "arm_only" / Flag, "stay_instant_arming" / Flag, "force_arming" / Flag, "all_subsystems" / Flag, ) ), "partitions" / BitsSwapped(Bitwise(StatusFlags(8))), "access" / BitStruct("level" / Nibble, "schedule" / Nibble), "access_options" / Bytes(1), "card_serial_number" / Bytes(3), )
class USBTokenPacket(USBPacket): """ Class representing a token packet. """ FIELDS = {'crc5', 'crc_valid'} DATA_FORMAT = BitsSwapped( BitStruct( "device_address" / BitsInteger(7), "endpoint_number" / BitsInteger(4), "crc5" / BitsInteger(5), )) def validate(self): #parsed = self.parse_data() # TODO: validate crc5 pass def generate_summary(self): return "{} token".format(self.pid.summarize()) def summarize_data(self, summary_length_bytes=8): # NOTE: summary_length_bytes is ignored for a token packet. return "address={}, endpoint=0x{:02x}, direction={}".format( self.device_address, self.endpoint_number, self.direction) def get_detail_fields(self): fields = { 'Length': '{} bytes'.format(len(self.get_raw_data())), 'PID': '{} (0x{:02x})'.format(self.pid.name, self.pid.value), 'Device': '0x{:02x}'.format(self.device_address), 'Endpoint': '0x{:02x}'.format(self.endpoint_number), 'CRC5': '0x{:02x}'.format(self.crc5) } return [(self.generate_summary(), fields)] def get_raw_data(self): # device_address, endpoint, and crc5 are included in self.data. return b''.join([bytes([self.pid]), self.data])
class USBStartOfFrame(USBPacket): """ Class representing a USB start-of-frame (pseudo) packet. """ FIELDS = {'frame_number', 'crc5', 'crc_valid'} DATA_FORMAT = BitsSwapped( BitStruct( "frame_number" / BitsInteger(11), "crc5" / BitsInteger(5), )) def validate(self): #parsed = self.parse_data() # TODO: validate crc5 pass def generate_summary(self): return "{}".format(self.pid.summarize()) def summarize_data(self, summary_length_bytes=8): # NOTE: summary_length_bytes is ignored for a token packet. return "frame={}".format(self.frame_number) def get_detail_fields(self): fields = { 'Length': '{} bytes'.format(len(self.get_raw_data())), 'PID': '{} (0x{:02x})'.format(self.pid.name, self.pid.value), 'Frame Number': '{:0d}'.format(self.frame_number), 'CRC5': '0x{:02x}'.format(self.crc5) } return [(self.generate_summary(), fields)] def get_raw_data(self): # frame number, and crc5 are included in self.data. return b''.join([bytes([self.pid]), self.data])
"system_options" / BitsSwapped( BitStruct( Embedded( Struct( # EVO section data 3030 "pgm1_smoke" / Flag, "no_bell_cut_off" / Flag, "daylight_saving_time" / Flag, "shabbat_feature" / Flag, "battery_charge_current" / Flag, "ac_failure_not_displayed_as_trouble" / Flag, "clear_bell_limit_trouble" / Flag, "combus_speed" / Flag, )), "partitions" / StatusFlags(8), # EVO section data 3031 "siren_output_partition" / StatusFlags(8), # EVO section data 3032 Embedded( Struct( # EVO section data 3033 "multiple_actions_user_menu" / Flag, "user_code_length_flexible" / Flag, "user_code_length_6" / Flag, "power_save_mode" / Flag, "bypass_not_displayed_when_armed" / Flag, "trouble_latch" / Flag, "eol_resistor_on_harwire_zones" / Flag, "atz" / Flag, )), Embedded( Struct( # EVO section data 3034 "wireless_transmitter_supervision_options" / BitsInteger(2), "generate_supervision_failure_on_bypassed_wireless_zone" / Flag, "restrict_arming_on_wireless_transmitter_supervision_failure" / Flag, "tamper_recognition_options" / BitsInteger(2), "generate_tamper_if_detected_on_bypassed_zone" / Flag, "restrict_arming_on_tamper" / Flag, )), Embedded( Struct( # EVO section data 3035 "restrict_arming_on_ac_failure" / Flag, "restrict_arming_on_battery_failure" / Flag, "restrict_arming_on_bell_or_aux_failure" / Flag, "restrict_arming_on_tlm_failure" / Flag, "restrict_arming_on_module_troubles" / Flag, "account_number_transmission" / Flag, "transmit_zone_status_on_serial_port" / Flag, "serial_port_baud_rate_57600" / Flag, )), Embedded( Struct( # EVO section data 3036 "telephone_line_monitoring" / BitsInteger(2), "dialer_reporting" / Flag, "dialing_method" / Flag, "pulse_ratio" / Flag, "busy_tone_detection" / Flag, "switch_to_pulse_dialing" / Flag, "bell_siren_upon_communication_failure" / Flag, )), Embedded( Struct( # EVO section data 3037 "call_back" / Flag, "automatic_event_buffer_transmission" / Flag, "autotest_report_transmission_options" / BitsInteger(2), "keypad_beep_on_successful_arming_disarming_report" / Flag, "alternate_dialing" / Flag, "dial_tone_delay" / Flag, "report_zone_restore" / Flag, )), Embedded( Struct( # EVO section data 3038 "access_control_feature" / Flag, "log_request_for_exit" / Flag, "log_door_left_open_restore" / Flag, "log_door_forced_restore" / Flag, "bulglar_alarm_on_forced_door" / Flag, "skip_exit_delay_when_arming_with_access_card" / Flag, "bulglar_alarm_on_door_left_open" / Flag, "who_has_access_during_clock_loss" / Flag, )), )),
class Reparsed(Adapter): """Bytes <---> Parsed subcon result Takes in bytes and reparses it with subcon_out""" def _decode(self, data, con, path): return subcon_out.parse(data, **con) def _encode(self, obj, con, path): return subcon_out.build(obj, **con) return Reparsed # is the payload compressed? CompressionFlags = BitsSwapped( BitStruct("compression" / Flag, Padding(8 * 4 - 1)) ) # -------------------- Key Computation -------------------- def aes_kdf(key, rounds, key_composite): """Set up a context for AES128-ECB encryption to find transformed_key""" cipher = AES.new(key, AES.MODE_ECB) # get the number of rounds from the header and transform the key_composite transformed_key = key_composite for _ in range(0, rounds): transformed_key = cipher.encrypt(transformed_key) return hashlib.sha256(transformed_key).digest()
"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,
QUEUE_HEADER_LAYOUT = cStruct( Padding(5), "account_flags" / ACCOUNT_FLAGS_LAYOUT, "head" / Int32ul, Padding(4), "count" / Int32ul, Padding(4), "next_seq_num" / Int32ul, Padding(4), ) REQUEST_FLAGS_LAYOUT = BitsSwapped( # Swap to little endian BitStruct( "new_order" / Flag, "cancel_order" / Flag, "bid" / Flag, "post_only" / Flag, "ioc" / Flag, Const(0, BitsInteger(3)), # Padding )) REQUEST_LAYOUT = cStruct( "request_flags" / REQUEST_FLAGS_LAYOUT, "open_order_slot" / Int8ul, "fee_tier" / Int8ul, Padding(5), "max_base_size_or_cancel_id" / Int64ul, "native_quote_quantity_locked" / Int64ul, "order_id" / Bytes(16), "open_orders" / Bytes(32), "client_order_id" / Int64ul,
zones = list([i in obj for i in range(1, 193)]) return self.subcon._build(zones, stream, context, path) PerformZoneAction = Struct( "fields" / RawCopy( Struct( "po" / Struct("command" / Const(0xd0, Int8ub)), "packet_length" / Rebuild( Int8ub, lambda this: this._root._subcons.fields.sizeof() + this ._root._subcons.checksum.sizeof()), "flags" / ZoneFlagBitStruct, "operation" / ZoneActionBitOperation, "_not_used" / Padding(2), "zones" / ZoneAdapter(BitsSwapped(Bitwise(Array(192, Flag)))), )), "checksum" / Checksum( Bytes(1), lambda data: calculate_checksum(data), this.fields.data)) PerformZoneActionResponse = Struct( "fields" / RawCopy( Struct( "po" / BitStruct( "command" / Const(0xd, Nibble), "status" / Struct("reserved" / Flag, "alarm_reporting_pending" / Flag, "Winload_connected" / Flag, "NeWare_connected" / Flag)), "packet_length" / Rebuild( Int8ub, lambda this: this._root._subcons.fields.sizeof() + this ._root._subcons.checksum.sizeof()), "flags" / ZoneFlagBitStruct, "operation" / ZoneActionBitOperation,
# RAY Yield Farming STAKE_INFO_LAYOUT = Struct( "state" / Int64ul, "nonce" / Int64ul, "poolLpTokenAccount" / Bytes(32), "poolRewardTokenAccount" / Bytes(32), "owner" / Bytes(32), "feeOwner" / Bytes(32), "feeY" / Int64ul, "feeX" / Int64ul, "totalReward" / Int64ul, "rewardPerShareNet" / BytesInteger(16), "lastBlock" / Int64ul, "rewardPerBlock" / Int64ul) # Serum Open Orders Book ACCOUNT_FLAGS_LAYOUT = BitsSwapped( # Swap to little endian BitStruct( "initialized" / Flag, "market" / Flag, "open_orders" / Flag, "request_queue" / Flag, "event_queue" / Flag, "bids" / Flag, "asks" / Flag, Const(0, BitsInteger(57)), # Padding )) # Serum Open Orders Book OPEN_ORDERS_LAYOUT = Struct( Padding(5), "account_flags" / ACCOUNT_FLAGS_LAYOUT, "market" / Bytes(32), "owner" / Bytes(32), "base_token_free" / Int64ul, "base_token_total" / Int64ul, "quote_token_free" / Int64ul,
"Filler_42" / SwappedField, # 685 "A Date" / SwappedField, "Filler_44" / SwappedField, DELISTING_DATE / DateShort, "Filler_46" / SwappedField, "Filler_47" / SwappedField, "Filler_48" / SwappedField, "Filler_49" / SwappedField, "Filler_50" / SwappedField, "Filler_51" / SwappedField, "Filler_52" / SwappedField, "Filler_53" / SwappedField, "Filler_54" / SwappedField, "Filler_55" / SwappedField, "Filler_56" / SwappedField, "Filler_57" / SwappedField, "Filler_58" / SwappedField, "Filler_59" / SwappedField, "Filler_60" / SwappedField, "Filler_61" / SwappedField, "Filler_62" / SwappedField, "Filler_63" / SwappedField, "Filler_64" / SwappedField, "Filler_65" / SwappedField, "Filler_66" / SwappedField, "Filler_67" / SwappedField, "Space" / Bytes(396), "Length" / Int32ul) SymbolConstruct = Struct("Header" / Bytes(0x4A0), "Entries" / GreedyRange(BitsSwapped(EntryChunk)))
HIGH, LOW, FUT, RESERVED, MICRO_SEC, MILLI_SEC, SECOND, MINUTE, HOUR, AUX_1, AUX_2, TERMINATOR, ) SwappedField = BitsSwapped(FormatField("<", "f")) DateShort=BitsSwapped(BitStruct( MINUTE / BitsInteger(length=6), # 38 HOUR / BitsInteger(length=5), # 43 DAY / RevBitsInteger(length=5), # Bit 48 Byte 6 MONTH / RevBitsInteger(length=4), # 52 YEAR / RevBitsInteger(length=12), )) Date=BitStruct( FUT / BitsInteger(length=1), # 1 RESERVED / BitsInteger(length=5), # 6 MICRO_SEC / BitsInteger(length=10), # Bit 16 byte 2 MILLI_SEC / BitsInteger(length=10), # 26 SECOND / BitsInteger(length=6), # Bit 32 Byte 4
class SymbolConstructFast: header = "Header" / Bytes(0x4A0) entry_chunk = BitsSwapped(EntryChunk) @classmethod def parse(self, bin): binentries = bin[0x4A0:] num_bytes = len(binentries) numits, offset = divmod(num_bytes, 0x488) # bytes result = {} result["Header"] = self.header.parse(bin[0:0x4A0]) result["Entries"] = [] start = 0x4A0 - offset numits = numits + 1 result["Entries"].append(self.entry_chunk.parse(bin[0x4A0:])) entrybin = bin[start:] for i in range(numits): result["Entries"].append([ self.entry_chunk.parse(entrybin[(i * 40):(i * 40 + 40)]), self.entry_chunk.parse(entrybin[(2 * i * 40):(2 * i * 40 + 40)]), self.entry_chunk.parse(entrybin[(3 * i * 40):(3 * i * 40 + 40)]), self.entry_chunk.parse(entrybin[(4 * i * 40):(4 * i * 40 + 40)]), self.entry_chunk.parse(entrybin[(5 * i * 40):(5 * i * 40 + 40)]), self.entry_chunk.parse(entrybin[(6 * i * 40):(6 * i * 40 + 40)]), self.entry_chunk.parse(entrybin[(7 * i * 40):(7 * i * 40 + 40)]), self.entry_chunk.parse(entrybin[(8 * i * 40):(8 * i * 40 + 40)]), self.entry_chunk.parse(entrybin[(9 * i * 40):(9 * i * 40 + 40)]), self.entry_chunk.parse(entrybin[(10 * i * 40):(10 * i * 40 + 40)]), self.entry_chunk.parse(entrybin[(11 * i * 40):(11 * i * 40 + 40)]), self.entry_chunk.parse(entrybin[(12 * i * 40):(12 * i * 40 + 40)]), self.entry_chunk.parse(entrybin[(13 * i * 40):(13 * i * 40 + 40)]), self.entry_chunk.parse(entrybin[(14 * i * 40):(14 * i * 40 + 40)]), self.entry_chunk.parse(entrybin[(15 * i * 40):(15 * i * 40 + 40)]), self.entry_chunk.parse(entrybin[(16 * i * 40):(16 * i * 40 + 40)]), self.entry_chunk.parse(entrybin[(17 * i * 40):(17 * i * 40 + 40)]), self.entry_chunk.parse(entrybin[(18 * i * 40):(18 * i * 40 + 40)]), self.entry_chunk.parse(entrybin[(19 * i * 40):(19 * i * 40 + 40)]), self.entry_chunk.parse(entrybin[(20 * i * 40):(20 * i * 40 + 40)]), self.entry_chunk.parse(entrybin[(21 * i * 40):(21 * i * 40 + 40)]), self.entry_chunk.parse(entrybin[(22 * i * 40):(22 * i * 40 + 40)]), self.entry_chunk.parse(entrybin[(23 * i * 40):(23 * i * 40 + 40)]), self.entry_chunk.parse(entrybin[(24 * i * 40):(24 * i * 40 + 40)]), self.entry_chunk.parse(entrybin[(25 * i * 40):(25 * i * 40 + 40)]), self.entry_chunk.parse(entrybin[(26 * i * 40):(26 * i * 40 + 40)]), self.entry_chunk.parse(entrybin[(27 * i * 40):(27 * i * 40 + 40)]), self.entry_chunk.parse(entrybin[(28 * i * 40):(28 * i * 40 + 40)]), self.entry_chunk.parse(entrybin[(29 * i * 40):(29 * i * 40 + 40)]), ]) return result
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")