def createFields(self): yield String(self, "magic", 4, "ITSF", charset="ASCII") yield UInt32(self, "version") yield UInt32(self, "header_size", "Total header length (in bytes)") yield UInt32(self, "one") yield UInt32(self, "last_modified") yield Enum(UInt32(self, "lang_id", "Windows Language ID"), LANGUAGE_ID) yield GUID(self, "dir_uuid", "{7C01FD10-7BAA-11D0-9E0C-00A0-C922-E6EC}") yield GUID(self, "stream_uuid", "{7C01FD11-7BAA-11D0-9E0C-00A0-C922-E6EC}") yield UInt64(self, "filesize_offset") yield filesizeHandler(UInt64(self, "filesize_len")) yield UInt64(self, "dir_offset") yield filesizeHandler(UInt64(self, "dir_len")) if 3 <= self["version"].value: yield UInt64(self, "data_offset")
def createFields(self): yield String(self, "magic", 4, "ITSP", charset="ASCII") yield UInt32(self, "version", "Version (=1)") yield filesizeHandler( UInt32(self, "size", "Length (in bytes) of the directory header (84)")) yield UInt32(self, "unknown[]", "(=10)") yield filesizeHandler( UInt32(self, "block_size", "Directory block size")) yield UInt32(self, "density", "Density of quickref section, usually 2") yield UInt32(self, "index_depth", "Depth of the index tree") yield Int32(self, "nb_dir", "Chunk number of root index chunk") yield UInt32(self, "first_pmgl", "Chunk number of first PMGL (listing) chunk") yield UInt32(self, "last_pmgl", "Chunk number of last PMGL (listing) chunk") yield Int32(self, "unknown[]", "-1") yield UInt32(self, "nb_dir_chunk", "Number of directory chunks (total)") yield Enum(UInt32(self, "lang_id", "Windows language ID"), LANGUAGE_ID) yield GUID(self, "system_uuid", "{5D02926A-212E-11D0-9DF9-00A0C922E6EC}") yield filesizeHandler(UInt32(self, "size2", "Same value than size")) yield Int32(self, "unknown[]", "-1") yield Int32(self, "unknown[]", "-1") yield Int32(self, "unknown[]", "-1")
def createFields(self): # Header yield NullBytes(self, "zero_vector", 16) yield GUID(self, "fs_guid") yield UInt64(self, "volume_len") yield String(self, "signature", 4) yield UInt32(self, "attributes") yield UInt16(self, "header_len") yield UInt16(self, "checksum") yield UInt16(self, "ext_header_offset") yield UInt8(self, "reserved") yield UInt8(self, "revision") while True: bm = BlockMap(self, "block_map[]") yield bm if bm['num_blocks'].value == 0 and bm['len'].value == 0: break # TODO must handle extended header # Content while not self.eof: padding = paddingSize(self.current_size // 8, 8) if padding: yield PaddingBytes(self, "padding[]", padding) yield File(self, "file[]")
def createFields(self): yield GUID(self, "file_id") yield TimedeltaWin64(self, "entry_interval") yield UInt32(self, "max_pckt_count") yield UInt32(self, "entry_count") for index in xrange(self["entry_count"].value): yield SimpleIndexEntry(self, "entry[]")
def createFields(self): yield Bytes(self, "endian", 2, "Endian (0xFF 0xFE for Intel)") yield UInt16(self, "format", "Format (0)") yield UInt8(self, "os_version") yield UInt8(self, "os_revision") yield Enum(UInt16(self, "os_type"), OS_NAME) yield GUID(self, "format_id") yield UInt32(self, "section_count") if MAX_SECTION_COUNT < self["section_count"].value: raise ParserError("OLE2: Too much sections (%s)" % self["section_count"].value) section_indexes = [] for index in xrange(self["section_count"].value): section_index = SummaryIndex(self, "section_index[]") yield section_index section_indexes.append(section_index) for section_index in section_indexes: self.seekByte(section_index["offset"].value) yield SummarySection(self, "section[]") size = (self.size - self.current_size) // 8 if 0 < size: yield NullBytes(self, "end_padding", size)
def createFields(self): yield UInt32(self, "size") yield RawBytes(self, "tag", 4) size = self["size"].value if size == 1: # 64-bit size yield UInt64(self, "size64") size = self["size64"].value - 16 elif size == 0: # Unbounded atom if self._size is None: size = (self.parent.size - self.parent.current_size) / 8 - 8 else: size = (self.size - self.current_size) / 8 else: size = size - 8 if self['tag'].value == 'uuid': yield GUID(self, "usertag") tag = self["usertag"].value size -= 16 else: tag = self["tag"].value if size > 0: if tag in self.tag_info: handler, name, desc = self.tag_info[tag] yield handler(self, name, desc, size=size * 8) else: yield RawBytes(self, "data", size)
def createFields(self): bytes = self.stream.readBytes(self.absolute_address, 4) if bytes == "\0R\0\0": charset = "UTF-16-BE" else: charset = "UTF-16-LE" yield String(self, "name", 64, charset=charset, truncate="\0") yield UInt16(self, "namelen", "Length of the name") yield Enum(UInt8(self, "type", "Property type"), self.TYPE_NAME) yield Enum(UInt8(self, "decorator", "Decorator"), self.DECORATOR_NAME) yield SECT(self, "left") yield SECT(self, "right") yield SECT(self, "child", "Child node (valid for storage and root types)") yield GUID(self, "clsid", "CLSID of this storage (valid for storage and root types)") yield NullBytes(self, "flags", 4, "User flags") yield TimestampWin64( self, "creation", "Creation timestamp(valid for storage and root types)") yield TimestampWin64( self, "lastmod", "Modify timestamp (valid for storage and root types)") yield SECT( self, "start", "Starting SECT of the stream (valid for stream and root types)") if self["/header/bb_shift"].value == 9: yield filesizeHandler( UInt32(self, "size", "Size in bytes (valid for stream and root types)")) yield NullBytes(self, "padding", 4) else: yield filesizeHandler( UInt64(self, "size", "Size in bytes (valid for stream and root types)"))
def createFields(self): yield GUID(self, "guid") yield filesizeHandler(UInt64(self, "size")) size = self["size"].value - self.current_size / 8 if 0 < size: if self.handler: yield self.handler(self, "content", size=size * 8) else: yield RawBytes(self, "content", size)
def createFields(self): # Header yield UInt24(self, "size") yield Enum(UInt8(self, "type"), EFI_SECTION_TYPE) section_type = self["type"].value if section_type == EFI_SECTION_COMPRESSION: yield UInt32(self, "uncomp_len") yield Enum(UInt8(self, "comp_type"), self.COMPRESSION_TYPE) elif section_type == EFI_SECTION_FREEFORM_SUBTYPE_GUID: yield GUID(self, "sub_type_guid") elif section_type == EFI_SECTION_GUID_DEFINED: yield GUID(self, "section_definition_guid") yield UInt16(self, "data_offset") yield UInt16(self, "attributes") elif section_type == EFI_SECTION_USER_INTERFACE: yield CString(self, "file_name", charset="UTF-16-LE") elif section_type == EFI_SECTION_VERSION: yield UInt16(self, "build_number") yield CString(self, "version", charset="UTF-16-LE") # Content content_size = (self.size - self.current_size) // 8 if content_size == 0: return if section_type == EFI_SECTION_COMPRESSION: compression_type = self["comp_type"].value if compression_type == 1: while not self.eof: yield RawBytes(self, "compressed_content", content_size) else: while not self.eof: yield FileSection(self, "section[]") elif section_type == EFI_SECTION_FIRMWARE_VOLUME_IMAGE: yield FirmwareVolume(self, "firmware_volume") else: yield RawBytes( self, "content", content_size, EFI_SECTION_TYPE.get(self["type"].value, "Unknown Section Type"))
def createFields(self): # Header yield GUID(self, "name") yield UInt16(self, "integrity_check") yield Enum(UInt8(self, "type"), EFI_FV_FILETYPE) yield UInt8(self, "attributes") yield UInt24(self, "size") yield UInt8(self, "state") # Content while not self.eof: yield FileSection(self, "section[]")
def createFields(self): yield GUID(self, "type") yield GUID(self, "error_correction") yield UInt64(self, "time_offset") yield UInt32(self, "data_len") yield UInt32(self, "error_correct_len") yield Bits(self, "stream_index", 7) yield Bits(self, "reserved[]", 8) yield Bit(self, "encrypted", "Content is encrypted?") yield UInt32(self, "reserved[]") size = self["data_len"].value if size: tag = self["type"].value if tag in Object.TAG_INFO: name, parser = Object.TAG_INFO[tag][0:2] yield parser(self, name, size=size * 8) else: yield RawBytes(self, "data", size) size = self["error_correct_len"].value if size: yield RawBytes(self, "error_correct", size)
def createFields(self): yield GUID(self, "guid") yield filesizeHandler(UInt64(self, "file_size")) yield TimestampWin64(self, "creation_date") yield UInt64(self, "pckt_count") yield TimedeltaWin64(self, "play_duration") yield TimedeltaWin64(self, "send_duration") yield UInt64(self, "preroll") yield Bit(self, "broadcast", "Is broadcast?") yield Bit(self, "seekable", "Seekable stream?") yield PaddingBits(self, "reserved[]", 30) yield filesizeHandler(UInt32(self, "min_pckt_size")) yield filesizeHandler(UInt32(self, "max_pckt_size")) yield displayHandler(UInt32(self, "max_bitrate"), humanBitRate)
def createFields(self): # Header yield UInt16(self, "version", "Version (=1)") yield Bytes(self, "endian", 2, "Endian (\\xfe\\xff for little endian)") yield UInt8(self, "os_version") yield UInt8(self, "os_revision") yield Enum(UInt16(self, "os"), OS_NAME) yield Int32(self, "unused", "(=-1)") yield GUID(self, "clsid") # User type yield PascalString32(self, "user_type", strip="\0") # Clipboard format if self["os"].value == OS_MAC: yield Int32(self, "unused[]", "(=-2)") yield String(self, "clipboard_format", 4) else: yield PascalString32(self, "clipboard_format", strip="\0") if self._current_size // 8 == self.datasize: return #-- OLE 2.01 --- # Program ID yield PascalString32(self, "prog_id", strip="\0") if self["os"].value != OS_MAC: # Magic number yield textHandler( UInt32(self, "magic", "Magic number (0x71B239F4)"), hexadecimal) # Unicode version yield PascalStringWin32(self, "user_type_unicode", strip="\0") yield PascalStringWin32(self, "clipboard_format_unicode", strip="\0") yield PascalStringWin32(self, "prog_id_unicode", strip="\0") size = self.datasize - ( self._current_size // 8 ) # _current_size because current_size returns _current_max_size if size: yield NullBytes(self, "end_padding", size) if self.datasize < self.size // 8: yield RawBytes(self, "slack_space", (self.size // 8) - self.datasize)
def createFields(self): # Header yield UInt16(self, "version", "Version (=1)") yield textHandler( UInt16(self, "endian", "Endian (0xFF 0xFE for Intel)"), hexadecimal) yield UInt8(self, "os_version") yield UInt8(self, "os_revision") yield Enum(UInt16(self, "os_type"), OS_NAME) yield Int32(self, "unused", "(=-1)") yield GUID(self, "clsid") # User type yield PascalString32(self, "user_type", strip="\0") # Clipboard format if self["os_type"].value == OS_MAC: yield Int32(self, "unused[]", "(=-2)") yield String(self, "clipboard_format", 4) else: yield PascalString32(self, "clipboard_format", strip="\0") if self.current_size == self.size: return #-- OLE 2.01 --- # Program ID yield PascalString32(self, "prog_id", strip="\0") if self["os_type"].value != OS_MAC: # Magic number yield textHandler( UInt32(self, "magic", "Magic number (0x71B239F4)"), hexadecimal) # Unicode version yield PascalStringWin32(self, "user_type_unicode", strip="\0") yield PascalStringWin32(self, "clipboard_format_unicode", strip="\0") yield PascalStringWin32(self, "prog_id_unicode", strip="\0") size = (self.size - self.current_size) // 8 if size: yield NullBytes(self, "end_padding", size)
def createFields(self): yield GUID(self, "clsid", "16 bytes GUID used by some apps") yield UInt16(self, "ver_min", "Minor version") yield UInt16(self, "ver_maj", "Minor version") yield Bytes(self, "endian", 2, "Endian (0xFFFE for Intel)") yield UInt16(self, "bb_shift", "Log, base 2, of the big block size") yield UInt16(self, "sb_shift", "Log, base 2, of the small block size") yield NullBytes(self, "reserved[]", 6, "(reserved)") yield UInt32( self, "csectdir", "Number of SECTs in directory chain for 4 KB sectors (version 4)") yield UInt32(self, "bb_count", "Number of Big Block Depot blocks") yield SECT(self, "bb_start", "Root start block") yield NullBytes(self, "transaction", 4, "Signature used for transactions (must be zero)") yield UInt32(self, "threshold", "Maximum size for a mini stream (typically 4096 bytes)") yield SECT(self, "sb_start", "Small Block Depot start block") yield UInt32(self, "sb_count") yield SECT(self, "db_start", "First block of DIFAT") yield UInt32(self, "db_count", "Number of SECTs in DIFAT")
def createFields(self): yield UInt16(self, "length", "Length of Item ID Entry") if not self["length"].value: return yield Enum(UInt8(self, "type"), self.ITEM_TYPE) entrytype = self["type"].value if entrytype in (0x1F, 0x2E, 0x70): # GUID yield RawBytes(self, "dummy", 1, "should be 0x50") yield GUID(self, "guid") elif entrytype in (0x23, 0x25, 0x29, 0x2F): # Drive yield String(self, "drive", self["length"].value - 3, strip="\0") elif entrytype in (0x30, 0x31, 0x32): yield RawBytes(self, "dummy", 1, "should be 0x00") yield UInt32(self, "size", "size of file; 0 for folders") yield DateTimeMSDOS32(self, "date_time", "File/folder date and time") yield MSDOSFileAttr16(self, "attribs", "File/folder attributes") yield CString(self, "name", "File/folder name") if self.root.hasUnicodeNames(): # Align to 2-bytes n = paddingSize(self.current_size // 8, 2) if n: yield PaddingBytes(self, "pad", n) yield UInt16(self, "length_w", "Length of wide struct member") yield RawBytes(self, "unknown[]", 6) yield DateTimeMSDOS32(self, "creation_date_time", "File/folder creation date and time") yield DateTimeMSDOS32(self, "access_date_time", "File/folder last access date and time") yield RawBytes(self, "unknown[]", 4) yield CString(self, "unicode_name", "File/folder name", charset="UTF-16-LE") yield RawBytes(self, "unknown[]", 2) else: yield CString(self, "name_short", "File/folder short name") elif entrytype in (0x41, 0x42, 0x46): yield RawBytes(self, "unknown[]", 2) yield CString(self, "name") yield CString(self, "protocol") yield RawBytes(self, "unknown[]", 2) elif entrytype == 0x47: # Whole Network yield RawBytes(self, "unknown[]", 2) yield CString(self, "name") elif entrytype == 0xC3: # Network Share yield RawBytes(self, "unknown[]", 2) yield CString(self, "name") yield CString(self, "protocol") yield CString(self, "description") yield RawBytes(self, "unknown[]", 2) else: yield RawBytes(self, "raw", self["length"].value - 3)
def createFields(self): yield Enum(GUID(self, "exclusion_type"), self.mutex_name) yield UInt16(self, "nb_stream") for index in xrange(self["nb_stream"].value): yield UInt16(self, "stream[]")
def createFields(self): yield Enum(UInt16(self, "WindowsVersion"), self.PRODUCT_VERSION) yield UInt16(self, "FileVersion") yield GUID(self, "JobUUID") yield UInt16(self, "AppNameOffset", "App Name Length Offset") yield UInt16( self, "TriggerOffset", "Contains the offset in bytes within the .JOB file where the task triggers are located." ) yield UInt16( self, "ErrorRetryCount", "Contains the number of execute attempts that are attempted for the task if the task fails to start." ) yield UInt16( self, "ErrorRetryInterval", "Contains the interval, in minutes, between successive retries") yield UInt16( self, "IdleDeadline", "Contains a maximum time in minutes to wait for the machine to become idle for Idle Wait minutes." ) yield UInt16( self, "IdleWait", "Contains a value in minutes. The machine remains idle for this many minutes before it runs the task" ) yield UInt32(self, "Priority") yield UInt32(self, "MaxRunTime", "Maximum run time in milliseconds") yield UInt32( self, "ExitCode", "This contains the exit code of the executed task upon the completion of that task." ) yield Enum(UInt32(self, "Status"), self.TASK_STATUS) yield Bit(self, "Interactive", "Can Task interact with user?") yield Bit(self, "DeleteWhenDone", "Remove the task file when done?") yield Bit(self, "Disabled", "Is Task disabled?") yield Bit( self, "StartOnlyIfIdle", "Task begins only if computer is not in use at the scheduled time") yield Bit( self, "KillOnIdleEnd", "Kill task if user input is detected, terminating idle state?") yield Bit(self, "DontStartIfOnBatteries") yield Bit(self, "KillIfGoingOnBatteries") yield Bit(self, "RunOnlyIfDocked") yield Bit(self, "HiddenTask") yield Bit(self, "RunIfConnectedToInternet") yield Bit(self, "RestartOnIdleResume") yield Bit( self, "SystemRequired", "Can task cause system to resume or awaken if system is sleeping?") yield Bit(self, "OnlyIfUserLoggedOn") yield Bit(self, "ApplicationNameExists", "Does task have an application name defined?") yield Bit(self, "Unused[]") yield Bit(self, "Unused[]") yield RawBytes(self, "flags", 2) yield UInt16(self, "LastRunYear") yield UInt16(self, "LastRunMonth") yield UInt16(self, "LastRunWeekday", "Sunday=0,Saturday=6") yield UInt16(self, "LastRunDay") yield UInt16(self, "LastRunHour") yield UInt16(self, "LastRunMinute") yield UInt16(self, "LastRunSecond") yield UInt16(self, "LastRunMillisecond") yield UInt16(self, "RunningInstanceCount") yield PascalStringWin16(self, "AppNameLength", strip='\0') yield PascalStringWin16(self, "Parameters", strip='\0') yield PascalStringWin16(self, "WorkingDirectory", strip='\0') yield PascalStringWin16(self, "Author", strip='\0') yield PascalStringWin16(self, "Comment", strip='\0') yield UInt16(self, "UserDataSize") #todo: read optional userdata yield UInt16(self, "ReservedDataSize") if self["ReservedDataSize"].value == 8: yield Enum( UInt32( self, "StartError", "contains the HRESULT error from the most recent attempt to start the task" ), self.TASK_STATUS) yield UInt32(self, "TaskFlags") elif self["ReservedDataSize"].value: yield RawBytes(self, "Reserved", self["ReservedDataSize"].value) yield UInt16(self, "TriggerCount", "size of the array of triggers") for i in xrange(self["TriggerCount"].value): yield TaskTrigger(self, "Trigger[]")
def createFields(self): yield GUID(self, "file_id") yield UInt64(self, "packet_count") yield PaddingBytes(self, "reserved", 2) size = (self.size - self.current_size) / 8 yield RawBytes(self, "data", size)
def createFields(self): yield GUID(self, "reserved[]") yield UInt32(self, "count") for index in xrange(self["count"].value): yield Codec(self, "codec[]")
def createFields(self): yield GUID(self, "reserved[]") yield UInt16(self, "reserved[]") yield UInt32(self, "size") if self["size"].value: yield RawBytes(self, "data", self["size"].value)
def createFields(self): yield UInt32(self, "signature", "Shortcut signature (0x0000004C)") yield GUID(self, "guid", "Shortcut GUID (00021401-0000-0000-C000-000000000046)") yield Bit(self, "has_shell_id", "Is the Item ID List present?") yield Bit(self, "target_is_file", "Is a file or a directory?") yield Bit(self, "has_description", "Is the Description field present?") yield Bit(self, "has_rel_path", "Is the relative path to the target available?") yield Bit(self, "has_working_dir", "Is there a working directory?") yield Bit(self, "has_cmd_line_args", "Are there any command line arguments?") yield Bit(self, "has_custom_icon", "Is there a custom icon?") yield Bit(self, "has_unicode_names", "Are Unicode names used?") yield Bit(self, "force_no_linkinfo") yield Bit(self, "has_exp_sz") yield Bit(self, "run_in_separate") yield Bit(self, "has_logo3id", "Is LOGO3 ID info present?") yield Bit(self, "has_darwinid", "Is the DarwinID info present?") yield Bit(self, "runas_user", "Is the target run as another user?") yield Bit(self, "has_exp_icon_sz", "Is custom icon information available?") yield Bit(self, "no_pidl_alias") yield Bit(self, "force_unc_name") yield Bit(self, "run_with_shim_layer") yield PaddingBits(self, "reserved[]", 14, "Flag bits reserved for future use") yield MSDOSFileAttr32(self, "target_attr") yield TimestampWin64(self, "creation_time") yield TimestampWin64(self, "modification_time") yield TimestampWin64(self, "last_access_time") yield filesizeHandler(UInt32(self, "target_filesize")) yield UInt32(self, "icon_number") yield Enum(UInt32(self, "show_window"), self.SHOW_WINDOW_STATE) yield textHandler( UInt8(self, "hot_key", "Hot key used for quick access"), text_hot_key) yield Bit(self, "hot_key_shift", "Hot key: is Shift used?") yield Bit(self, "hot_key_ctrl", "Hot key: is Ctrl used?") yield Bit(self, "hot_key_alt", "Hot key: is Alt used?") yield PaddingBits(self, "hot_key_reserved", 21, "Hot key: (reserved)") yield NullBytes(self, "reserved[]", 8) if self["has_shell_id"].value: yield ItemIdList(self, "item_idlist", "Item ID List") if self["target_is_file"].value: yield FileLocationInfo(self, "file_location_info", "File Location Info") if self["has_description"].value: yield LnkString(self, "description") if self["has_rel_path"].value: yield LnkString(self, "relative_path", "Relative path to target") if self["has_working_dir"].value: yield LnkString(self, "working_dir", "Working directory (dir to start target in)") if self["has_cmd_line_args"].value: yield LnkString(self, "cmd_line_args", "Command Line Arguments") if self["has_custom_icon"].value: yield LnkString(self, "custom_icon", "Custom Icon Path") while not self.eof: yield ExtraInfo(self, "extra_info[]")
def createFields(self): yield UInt16(self, "length", "Length of Item ID Entry") if not self["length"].value: return yield Enum(UInt8(self, "type"), self.ITEM_TYPE) entrytype = self["type"].value if entrytype in (0x1F, 0x70): # GUID yield RawBytes(self, "dummy", 1, "should be 0x50") yield GUID(self, "guid") elif entrytype == 0x2E: # Shell extension yield RawBytes(self, "dummy", 1, "should be 0x50") if self["dummy"].value == '\0': yield UInt16(self, "length_data", "Length of shell extension-specific data") if self["length_data"].value: yield RawBytes(self, "data", self["length_data"].value, "Shell extension-specific data") yield GUID(self, "handler_guid") yield GUID(self, "guid") elif entrytype in (0x23, 0x25, 0x29, 0x2F): # Drive yield String(self, "drive", self["length"].value - 3, strip="\0") elif entrytype in (0x30, 0x31, 0x32, 0x61, 0xb1): yield RawBytes(self, "dummy", 1, "should be 0x00") yield UInt32(self, "size", "size of file; 0 for folders") yield DateTimeMSDOS32(self, "date_time", "File/folder date and time") yield MSDOSFileAttr16(self, "attribs", "File/folder attributes") yield CString(self, "name", "File/folder name") if self.root.hasUnicodeNames(): # Align to 2-bytes n = paddingSize(self.current_size // 8, 2) if n: yield PaddingBytes(self, "pad", n) yield UInt16(self, "length_w", "Length of wide struct member") yield RawBytes(self, "unknown[]", 6) yield DateTimeMSDOS32(self, "creation_date_time", "File/folder creation date and time") yield DateTimeMSDOS32(self, "access_date_time", "File/folder last access date and time") yield RawBytes(self, "unknown[]", 2) yield UInt16( self, "length_next", "Length of next two strings (if zero, ignore this field)") yield CString(self, "unicode_name", "File/folder name", charset="UTF-16-LE") if self["length_next"].value: yield CString(self, "localized_name", "Localized name") yield RawBytes(self, "unknown[]", 2) else: yield CString(self, "name_short", "File/folder short name") elif entrytype in (0x41, 0x42, 0x46): yield RawBytes(self, "unknown[]", 2) yield CString(self, "name") yield CString(self, "protocol") yield RawBytes(self, "unknown[]", 2) elif entrytype == 0x47: # Whole Network yield RawBytes(self, "unknown[]", 2) yield CString(self, "name") elif entrytype == 0xC3: # Network Share yield RawBytes(self, "unknown[]", 2) yield CString(self, "name") yield CString(self, "protocol") yield CString(self, "description") yield RawBytes(self, "unknown[]", 2) elif entrytype == 0x4C: # Web Folder yield RawBytes(self, "unknown[]", 5) yield TimestampWin64(self, "modification_time") yield UInt32(self, "unknown[]") yield UInt32(self, "unknown[]") yield UInt32(self, "unknown[]") yield LnkString(self, "name") yield RawBytes(self, "padding[]", 2) yield LnkString(self, "address") if self["address/length"].value: yield RawBytes(self, "padding[]", 2) else: yield RawBytes(self, "raw", self["length"].value - 3)