def createFields(self): yield Bit(self, "final", "Is this the final block?") # BFINAL yield Enum( Bits(self, "compression_type", 2), # BTYPE { 0: "None", 1: "Fixed Huffman", 2: "Dynamic Huffman", 3: "Reserved" }) if self["compression_type"].value == 0: # no compression # align on byte boundary padding = paddingSize(self.current_size + self.absolute_address, 8) if padding: yield PaddingBits(self, "padding[]", padding) yield Int16(self, "len") yield Int16(self, "nlen", "One's complement of len") if self["len"].value != ~self["nlen"].value: raise ParserError( "len must be equal to the one's complement of nlen!") # null stored blocks produced by some encoders (e.g. PIL) if self["len"].value: yield RawBytes(self, "data", self["len"].value, "Uncompressed data") return elif self["compression_type"].value == 1: # Fixed Huffman length_tree = {} # (size, huffman code): value distance_tree = {} for i in range(144): length_tree[(8, i + 48)] = i for i in range(144, 256): length_tree[(9, i + 256)] = i for i in range(256, 280): length_tree[(7, i - 256)] = i for i in range(280, 288): length_tree[(8, i - 88)] = i for i in range(32): distance_tree[(5, i)] = i elif self["compression_type"].value == 2: # Dynamic Huffman yield Bits(self, "huff_num_length_codes", 5, "Number of Literal/Length Codes, minus 257") yield Bits(self, "huff_num_distance_codes", 5, "Number of Distance Codes, minus 1") yield Bits(self, "huff_num_code_length_codes", 4, "Number of Code Length Codes, minus 4") code_length_code_lengths = [0] * 19 # confusing variable name... for i in self.CODE_LENGTH_ORDER[:self["huff_num_code_length_codes"] .value + 4]: field = Bits(self, "huff_code_length_code[%i]" % i, 3, "Code lengths for the code length alphabet") yield field code_length_code_lengths[i] = field.value code_length_tree = build_tree(code_length_code_lengths) length_code_lengths = [] distance_code_lengths = [] for numcodes, name, lengths in ( (self["huff_num_length_codes"].value + 257, "length", length_code_lengths), (self["huff_num_distance_codes"].value + 1, "distance", distance_code_lengths)): while len(lengths) < numcodes: field = HuffmanCode(self, "huff_%s_code[]" % name, code_length_tree) value = field.realvalue if value < 16: prev_value = value field._description = "Literal Code Length %i (Huffman Code %i)" % ( value, field.value) yield field lengths.append(value) else: info = { 16: (3, 6, 2), 17: (3, 10, 3), 18: (11, 138, 7) }[value] if value == 16: repvalue = prev_value else: repvalue = 0 field._description = "Repeat Code %i, Repeating value (%i) %i to %i times (Huffman Code %i)" % ( value, repvalue, info[0], info[1], field.value) yield field extrafield = Bits( self, "huff_%s_code_extra[%s" % (name, field.name.split('[')[1]), info[2]) num_repeats = extrafield.value + info[0] extrafield._description = "Repeat Extra Bits (%i), total repeats %i" % ( extrafield.value, num_repeats) yield extrafield lengths += [repvalue] * num_repeats length_tree = build_tree(length_code_lengths) distance_tree = build_tree(distance_code_lengths) else: raise ParserError("Unsupported compression type 3!") while True: field = HuffmanCode(self, "length_code[]", length_tree) value = field.realvalue if value < 256: field._description = "Literal Code %r (Huffman Code %i)" % ( chr(value), field.value) yield field self.uncomp_data += chr(value) if value == 256: field._description = "Block Terminator Code (256) (Huffman Code %i)" % field.value yield field break elif value > 256: info = self.LENGTH_SYMBOLS[value] if info[2] == 0: field._description = "Length Code %i, Value %i (Huffman Code %i)" % ( value, info[0], field.value) length = info[0] yield field else: field._description = "Length Code %i, Values %i to %i (Huffman Code %i)" % ( value, info[0], info[1], field.value) yield field extrafield = Bits( self, "length_extra[%s" % field.name.split('[')[1], info[2]) length = extrafield.value + info[0] extrafield._description = "Length Extra Bits (%i), total length %i" % ( extrafield.value, length) yield extrafield field = HuffmanCode(self, "distance_code[]", distance_tree) value = field.realvalue info = self.DISTANCE_SYMBOLS[value] if info[2] == 0: field._description = "Distance Code %i, Value %i (Huffman Code %i)" % ( value, info[0], field.value) distance = info[0] yield field else: field._description = "Distance Code %i, Values %i to %i (Huffman Code %i)" % ( value, info[0], info[1], field.value) yield field extrafield = Bits( self, "distance_extra[%s" % field.name.split('[')[1], info[2]) distance = extrafield.value + info[0] extrafield._description = "Distance Extra Bits (%i), total length %i" % ( extrafield.value, distance) yield extrafield self.uncomp_data = extend_data(self.uncomp_data, length, distance)
def createFields(self): yield Enum(UInt32(self, "tag", "Tag"), self.tag_name_dict) yield Enum(UInt32(self, "type", "Type"), Item.type_name) yield UInt32(self, "offset", "Offset") yield UInt32(self, "count", "Count")
def parseROP2(parser): yield Enum(UInt16(parser, "operation"), ROP2_DESC)
def parsePenIndirect(parser): yield Enum(UInt16(parser, "pen_style"), PEN_STYLE) yield UInt16(parser, "pen_width") yield UInt16(parser, "pen_height") yield RGBA(parser, "color")
def createFields(self): yield String(self, "header_id", 4, "Track Item Header Markup (\"mhit\")", charset="ISO-8859-1") yield UInt32(self, "header_length", "Header Length") yield UInt32(self, "entry_length", "Entry Length") yield UInt32(self, "string_number", "Number of Strings") yield UInt32(self, "unique_id", "Unique ID") yield UInt32(self, "visible_tag", "Visible Tag") yield String(self, "file_type", 4, "File Type") yield Enum(UInt8(self, "x1_type", "Extended Type 1"), self.x1_type_name) yield Enum(UInt8(self, "x2_type", "Extended type 2"), self.x2_type_name) yield UInt8(self, "compilation_flag", "Compilation Flag") yield UInt8(self, "rating", "Rating") yield TimestampMac32(self, "last_modified", "Time of the last modification of the track") yield filesizeHandler(UInt32(self, "size", "Track size in bytes")) yield displayHandler( UInt32(self, "length", "Track length in milliseconds"), humanDuration) yield UInt32(self, "track_number", "Number of this track") yield UInt32(self, "total_track", "Total number of tracks") yield UInt32(self, "year", "Year of the track") yield UInt32(self, "bitrate", "Bitrate") yield UInt32(self, "samplerate", "Sample Rate") yield UInt32(self, "volume", "volume") yield UInt32(self, "start_time", "Start playing at, in milliseconds") yield UInt32(self, "stop_time", "Stop playing at, in milliseconds") yield UInt32(self, "soundcheck", "SoundCheck preamp") yield UInt32(self, "playcount_1", "Play count of the track") yield UInt32(self, "playcount_2", "Play count of the track when last synced") yield TimestampMac32(self, "last_played_time", "Time the song was last played") yield UInt32(self, "disc_number", "disc number in multi disc sets") yield UInt32(self, "total_discs", "Total number of discs in the disc set") yield UInt32(self, "userid", "User ID in the DRM scheme") yield TimestampMac32(self, "added_date", "Date when the item was added") yield UInt32(self, "bookmark_time", "Bookmark time for AudioBook") yield UInt64( self, "dbid", "Unique DataBase ID for the song (identical in mhit and in mhii)") yield UInt8(self, "checked", "song is checked") yield UInt8(self, "application_rating", "Last Rating before change") yield UInt16(self, "BPM", "BPM of the track") yield UInt16(self, "artwork_count", "number of artworks for this item") yield UInt16(self, "unknown[]") yield UInt32(self, "artwork_size", "Total size of artworks in bytes") yield UInt32(self, "unknown[]") yield Float32(self, "sample_rate_2", "Sample Rate express in float") yield UInt32(self, "released_date", "Date of release in Music Store or in Podcast") yield UInt16(self, "unknown[]") yield UInt16(self, "explicit_flag[]", "Explicit flag") yield UInt32(self, "unknown[]") yield UInt32(self, "unknown[]") yield UInt32(self, "skip_count[]", "Skip Count") yield TimestampMac32(self, "last_skipped", "Date when the item was last skipped") yield UInt8(self, "has_artwork", "0x01 for track with artwork, 0x02 otherwise") yield UInt8(self, "skip_wen_shuffling", "Skip that track when shuffling") yield UInt8(self, "remember_playback_position", "Remember playback position") yield UInt8(self, "flag4", "Flag 4") yield UInt64(self, "dbid2", "Unique DataBase ID for the song (identical as above)") yield UInt8(self, "lyrics_flag", "Lyrics Flag") yield UInt8(self, "movie_file_flag", "Movie File Flag") yield UInt8(self, "played_mark", "Track has been played") yield UInt8(self, "unknown[]") yield UInt32(self, "unknown[]") yield UInt32(self, "pregap[]", "Number of samples of silence before the song starts") yield UInt64( self, "sample_count", "Number of samples in the song (only for WAV and AAC files)") yield UInt32(self, "unknown[]") yield UInt32(self, "postgap[]", "Number of samples of silence at the end of the song") yield UInt32(self, "unknown[]") yield Enum(UInt32(self, "media_type", "Media Type for video iPod"), self.media_type_name) yield UInt32(self, "season_number", "Season Number") yield UInt32(self, "episode_number", "Episode Number") yield UInt32(self, "unknown[]") yield UInt32(self, "unknown[]") yield UInt32(self, "unknown[]") yield UInt32(self, "unknown[]") yield UInt32(self, "unknown[]") yield UInt32(self, "unknown[]") yield UInt32(self, "unknown[]") yield UInt32( self, "gapless_data[]", "The size in bytes from first Sync Frame until the 8th before the last frame." ) yield UInt32(self, "unknown[]") yield UInt16(self, "gaplessTrackFlag[]", "1 if track has gapless data") yield UInt16(self, "gaplessAlbumFlag[]", "1 if track uses crossfading in iTunes") yield RawBytes(self, "unknown[]", 20) yield UInt32(self, "unknown[]") yield UInt32(self, "unknown[]") yield UInt32(self, "unknown[]") yield UInt32(self, "unknown[]") yield UInt16(self, "unknown[]") yield UInt16(self, "album_id[]", "Album ID (used to link tracks with MHIAs)") yield RawBytes(self, "unknown[]", 52) yield UInt32(self, "mhii_link[]", "Artwork ID (used to link tracks with MHIIs)") padding = self.seekByte(self["header_length"].value, "header padding") if padding: yield padding # while ((self.stream.readBytes(0, 4) == 'mhod') and ((self.current_size/8) < self["entry_length"].value)): for i in xrange(self["string_number"].value): yield DataObject(self, "data[]") padding = self.seekBit(self._size, "entry padding") if padding: yield padding
def createFields(self): yield UInt32(self, "length", "Length of this structure") if not self["length"].value: return yield Enum( textHandler( UInt32(self, "signature", "Signature determining the function of this structure"), hexadecimal), self.INFO_TYPE) if self["signature"].value == 0xA0000003: # Hostname and Other Stuff yield UInt32(self, "remaining_length") yield UInt32(self, "unknown[]") yield String( self, "hostname", 16, "Computer hostname on which shortcut was last modified", strip="\0") yield RawBytes(self, "unknown[]", 32) yield RawBytes(self, "unknown[]", 32) elif self["signature"].value == 0xA0000005: # Special Folder Info yield Enum( UInt32(self, "special_folder_id", "ID of the special folder"), self.SPECIAL_FOLDER) yield UInt32(self, "offset", "Offset to Item ID entry") elif self["signature"].value in (0xA0000001, 0xA0000006, 0xA0000007): if self["signature"].value == 0xA0000001: # Link Target Information object_name = "target" # DarwinID (Windows Installer ID) Information elif self["signature"].value == 0xA0000006: object_name = "darwinID" else: # Custom Icon Details object_name = "icon_path" yield CString(self, object_name, "Data (ASCII format)", charset="ASCII") # 260*2 = size of next part remaining = self["length"].value - self.current_size // 8 - 260 * 2 if remaining: yield RawBytes(self, "slack_space[]", remaining, "Data beyond end of string") yield CString(self, object_name + '_unicode', "Data (Unicode format)", charset="UTF-16-LE", truncate="\0") remaining = self["length"].value - self.current_size // 8 if remaining: yield RawBytes(self, "slack_space[]", remaining, "Data beyond end of string") elif self["signature"].value == 0xA0000002: # Console Window Properties yield ColorTableIndex(self, "color_text", 4, "Screen text color index") yield ColorTableIndex(self, "color_bg", 4, "Screen background color index") yield NullBytes(self, "reserved[]", 1) yield ColorTableIndex(self, "color_popup_text", 4, "Pop-up text color index") yield ColorTableIndex(self, "color_popup_bg", 4, "Pop-up background color index") yield NullBytes(self, "reserved[]", 1) yield UInt16(self, "buffer_width", "Screen buffer width (character cells)") yield UInt16(self, "buffer_height", "Screen buffer height (character cells)") yield UInt16(self, "window_width", "Window width (character cells)") yield UInt16(self, "window_height", "Window height (character cells)") yield UInt16(self, "position_left", "Window distance from left edge (screen coords)") yield UInt16(self, "position_top", "Window distance from top edge (screen coords)") yield UInt32(self, "font_number") yield UInt32(self, "input_buffer_size") yield UInt16(self, "font_width", "Font width in pixels; 0 for a non-raster font") yield UInt16( self, "font_height", "Font height in pixels; equal to the font size for non-raster fonts" ) yield UInt32(self, "font_family") yield UInt32(self, "font_weight") yield String(self, "font_name_unicode", 64, "Font Name (Unicode format)", charset="UTF-16-LE", truncate="\0") yield UInt32(self, "cursor_size", "Relative size of cursor (% of character size)") yield Enum( UInt32(self, "full_screen", "Run console in full screen?"), self.BOOL_ENUM) yield Enum( UInt32( self, "quick_edit", "Console uses quick-edit feature (using mouse to cut & paste)?" ), self.BOOL_ENUM) yield Enum( UInt32(self, "insert_mode", "Console uses insertion mode?"), self.BOOL_ENUM) yield Enum( UInt32(self, "auto_position", "System automatically positions window?"), self.BOOL_ENUM) yield UInt32(self, "history_size", "Size of the history buffer (in lines)") yield UInt32( self, "history_count", "Number of history buffers (each process gets one up to this limit)" ) yield Enum( UInt32( self, "history_no_dup", "Automatically eliminate duplicate lines in the history buffer?" ), self.BOOL_ENUM) for index in range(16): yield ColorRef(self, "color[]") elif self["signature"].value == 0xA0000004: # Console Codepage Information yield UInt32(self, "codepage", "Console's code page") else: yield RawBytes(self, "raw", self["length"].value - self.current_size // 8)
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)
def createFields(self): yield Bits(self, "unused[]", 4) yield Bit(self, "16bits") yield Bits(self, "unused[]", 1) yield Enum(Bits(self, "loop_mode", 2), SAMPLE_LOOP_MODE)
def createFields(self): yield textHandler(UInt8(self, "zip_version", "ZIP version"), ZipRevision) yield Enum(UInt8(self, "host_os", "ZIP Host OS"), self.HOST_OS)
def createFields(self): yield Enum(UInt8(self, "compression", "Compression method"), self.COMPRESSION_NAME)
def createFields(self): yield Enum(UInt32(self, "mode", "Layer mode"), self.MODE_NAME)
def createFields(self): yield Enum(Bits(self, "ext_type", 4), self.EXT_TYPE) ext_type = self['ext_type'].value if ext_type == 1: # Sequence extension yield Bits(self, 'profile_and_level', 8) yield Bit(self, 'progressive_sequence') yield Bits(self, 'chroma_format', 2) yield Bits(self, 'horiz_size_ext', 2) yield Bits(self, 'vert_size_ext', 2) yield Bits(self, 'bit_rate_ext', 12) yield Bits(self, 'pad[]', 1) yield Bits(self, 'vbv_buffer_size_ext', 8) yield Bit(self, 'low_delay') yield Bits(self, 'frame_rate_ext_n', 2) yield Bits(self, 'frame_rate_ext_d', 5) elif ext_type == 2: # Sequence Display extension yield Bits(self, 'video_format', 3) yield Bit(self, 'color_desc_present') if self['color_desc_present'].value: yield UInt8(self, 'color_primaries') yield UInt8(self, 'transfer_characteristics') yield UInt8(self, 'matrix_coeffs') yield Bits(self, 'display_horiz_size', 14) yield Bits(self, 'pad[]', 1) yield Bits(self, 'display_vert_size', 14) yield NullBits(self, 'pad[]', 3) elif ext_type == 8: yield Bits(self, 'f_code[0][0]', 4, description="forward horizontal") yield Bits(self, 'f_code[0][1]', 4, description="forward vertical") yield Bits(self, 'f_code[1][0]', 4, description="backward horizontal") yield Bits(self, 'f_code[1][1]', 4, description="backward vertical") yield Bits(self, 'intra_dc_precision', 2) yield Bits(self, 'picture_structure', 2) yield Bit(self, 'top_field_first') yield Bit(self, 'frame_pred_frame_dct') yield Bit(self, 'concealment_motion_vectors') yield Bit(self, 'q_scale_type') yield Bit(self, 'intra_vlc_format') yield Bit(self, 'alternate_scan') yield Bit(self, 'repeat_first_field') yield Bit(self, 'chroma_420_type') yield Bit(self, 'progressive_frame') yield Bit(self, 'composite_display') if self['composite_display'].value: yield Bit(self, 'v_axis') yield Bits(self, 'field_sequence', 3) yield Bit(self, 'sub_carrier') yield Bits(self, 'burst_amplitude', 7) yield Bits(self, 'sub_carrier_phase', 8) yield NullBits(self, 'pad[]', 2) else: yield NullBits(self, 'pad[]', 6) else: yield RawBits(self, "raw[]", 4)
def createFields(self): yield Enum(UInt32(self, "type"), self.TYPE_NAME) yield UInt32(self, "format") yield filesizeHandler(UInt32(self, "size")) yield UInt32(self, "offset")
def createFields(self): yield Enum(textHandler(UInt32(self, "type"), hexadecimal), self.ATTR_NAME) yield UInt32(self, "size") yield UInt8(self, "non_resident", "Non-resident flag") yield UInt8(self, "name_length", "Name length in bytes") yield UInt16(self, "name_offset", "Name offset") yield UInt16(self, "flags") yield textHandler(UInt16(self, "attribute_id"), hexadecimal) if self['non_resident'].value: yield UInt64(self, "runlist_start", "Starting Virtual Cluster Number of the runlist") yield UInt64(self, "runlist_stop", "Ending Virtual Cluster Number of the runlist") yield UInt16(self, "runlist_offset", "Offset to the runlist") yield UInt16(self, "compression_unit", "Compression unit size") yield UInt32(self, "unused[]") yield UInt64(self, "size_allocated", "Allocated size of the attribute content") yield UInt64(self, "size_actual", "Actual size of the attribute content") yield UInt64(self, "size_initialized", "Initialized size of the attribute content") if self['name_length'].value: padding = self.seekByte(self['name_offset'].value) if padding: yield padding yield String(self, "name", self['name_length'].value * 2, charset="UTF-16-LE") padding = self.seekByte(self['runlist_offset'].value) if padding: yield padding yield RunList(self, "runlist") else: yield UInt32(self, "length_attr", "Length of the Attribute") yield UInt16(self, "offset_attr", "Offset of the Attribute") yield UInt8(self, "indexed_flag") if self['name_length'].value: padding = self.seekByte(self['name_offset'].value) if padding: yield padding yield String(self, "name", self['name_length'].value * 2, charset="UTF-16-LE") padding = self.seekByte(self['offset_attr'].value) if padding: yield padding if self._parser: yield from self._parser(self) else: size = self["length_attr"].value if size: yield RawBytes(self, "data", size) size = (self.size - self.current_size) // 8 if size: yield PaddingBytes(self, "end_padding", size)
def createFields(self): yield Enum(UInt8(self, "typecode"), TYPECODE_NAMES) yield SerializedContent(self, "classDesc") self.root.newHandle(self) yield SerializedContent(self, "enumConstantName")
def createFields(self): yield String(self, "magic", 4, "Signature (BLP2)") yield Enum(UInt32(self, "compression", "Compression type"), { 0: "JPEG Compressed", 1: "Uncompressed or DXT/S3TC compressed" }) yield Enum(UInt8(self, "encoding", "Encoding type"), { 1: "Raw", 2: "DXT/S3TC Texture Compression (a.k.a. DirectX)" }) yield UInt8(self, "alpha_depth", "Alpha channel depth, in bits (0 = no alpha)") yield Enum( UInt8(self, "alpha_encoding", "Encoding used for alpha channel"), { 0: "DXT1 alpha (0 or 1 bit alpha)", 1: "DXT3 alpha (4 bit alpha)", 7: "DXT5 alpha (8 bit interpolated alpha)" }) yield Enum( UInt8(self, "has_mips", "Are mip levels present?"), { 0: "No mip levels", 1: "Mip levels present; number of levels determined by image size" }) yield UInt32(self, "width", "Base image width") yield UInt32(self, "height", "Base image height") for i in range(16): yield UInt32(self, "mipmap_offset[]") for i in range(16): yield UInt32(self, "mipmap_size[]") yield PaletteRGBA(self, "palette", 256) compression = self["compression"].value encoding = self["encoding"].value alpha_depth = self["alpha_depth"].value alpha_encoding = self["alpha_encoding"].value width = self["width"].value height = self["height"].value if compression == 0: # JPEG Compression yield UInt32(self, "jpeg_header_len") yield RawBytes(self, "jpeg_header", self["jpeg_header_len"].value, "Shared JPEG Header") offsets = self.array("mipmap_offset") sizes = self.array("mipmap_size") for i in range(16): if not offsets[i].value or not sizes[i].value: continue padding = self.seekByte(offsets[i].value) if padding: yield padding if compression == 0: yield RawBytes( self, "mipmap[%i]" % i, sizes[i].value, "JPEG data, append to header to recover complete image") elif compression == 1 and encoding == 1: yield Generic2DArray(self, "mipmap_indexes[%i]" % i, height, width, PaletteIndex, "row", "index", "Indexes into the palette") if alpha_depth == 1: yield GenericVector(self, "mipmap_alphas[%i]" % i, height, width, Bit, "row", "is_opaque", "Alpha values") elif alpha_depth == 8: yield GenericVector(self, "mipmap_alphas[%i]" % i, height, width, UInt8, "row", "alpha", "Alpha values") elif compression == 1 and encoding == 2: block_height = alignValue(height, 4) // 4 block_width = alignValue(width, 4) // 4 if alpha_depth in [0, 1] and alpha_encoding == 0: yield Generic2DArray(self, "mipmap[%i]" % i, block_height, block_width, DXT1, "row", "block", "DXT1-compressed image blocks") elif alpha_depth == 8 and alpha_encoding == 1: yield Generic2DArray(self, "mipmap[%i]" % i, block_height, block_width, DXT3, "row", "block", "DXT3-compressed image blocks") elif alpha_depth == 8 and alpha_encoding == 7: yield Generic2DArray(self, "mipmap[%i]" % i, block_height, block_width, DXT5, "row", "block", "DXT5-compressed image blocks") width /= 2 height /= 2
def createFields(self): yield Enum(UInt8(self, "typecode"), TYPECODE_NAMES) yield Int32(self, "handle")
def createFields(self): yield Enum(UInt8(self, "typecode"), TYPECODE_NAMES) yield SerializedContent(self, "classDesc") self.root.newHandle(self) yield ObjectValue(self, "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 Enum(UInt8(self, "typecode"), TYPECODE_NAMES) self.root.newHandle(self) yield PascalString16(self, "value", charset="UTF-8")
def parseCreateBrushIndirect(parser): yield Enum(UInt16(parser, "brush_style"), BRUSH_STYLE) yield RGBA(parser, "color") yield Enum(UInt16(parser, "brush_hatch"), HATCH_STYLE)
def createFields(self): yield Enum(UInt8(self, "typecode"), TYPECODE_NAMES) self.root.resetHandles()
def parseVideo(parent, size): yield Enum(Bits(parent, "frame_type", 4, "Frame type"), FRAME_TYPE) yield Enum(Bits(parent, "codec", 4, "Video codec"), VIDEO_CODEC_NAME) if 1 < size: yield RawBytes(parent, "data", size - 1)
def createFields(self): yield Enum(UInt8(self, "typecode"), TYPECODE_NAMES) yield UInt32(self, "size") if self['size'].value: yield RawBytes(self, "data", self['size'].value)
def createFields(self): yield UInt32(self, "inodes_count", "Total inode count") yield UInt32(self, "blocks_count", "Total block count") yield UInt32(self, "r_blocks_count", "Reserved (superuser-only) block count") yield UInt32(self, "free_blocks_count", "Free block count") yield UInt32(self, "free_inodes_count", "Free inode count") yield UInt32(self, "first_data_block", "First data block") yield UInt32(self, "log_block_size", "Block size = 2**(10+log_block_size)") yield UInt32(self, "log_frag_size", "Cluster size = 2**log_frag_size") yield UInt32(self, "blocks_per_group", "Blocks per group") yield UInt32(self, "frags_per_group", "Fragments per group") yield UInt32(self, "inodes_per_group", "Inodes per group") yield TimestampUnix32(self, "mtime", "Mount time") yield TimestampUnix32(self, "wtime", "Write time") yield UInt16(self, "mnt_count", "Mount count since the last fsck") yield UInt16(self, "max_mnt_count", "Max mount count before fsck is needed") yield UInt16(self, "magic", "Magic number (0xEF53)") yield Enum(UInt16(self, "state", "File system state"), self.state_desc) yield Enum(UInt16(self, "errors", "Behaviour when detecting errors"), self.error_handling_desc) yield UInt16(self, "minor_rev_level", "Minor revision level") yield TimestampUnix32(self, "last_check", "Time of last check") yield textHandler( UInt32(self, "check_interval", "Maximum time between checks"), self.postMaxTime) yield Enum(UInt32(self, "creator_os", "Creator OS"), self.os_name) yield Enum(UInt32(self, "rev_level", "Revision level"), self.revision_levels) yield UInt16(self, "def_resuid", "Default uid for reserved blocks") yield UInt16(self, "def_resgid", "Default gid for reserved blocks") yield UInt32(self, "first_ino", "First non-reserved inode") yield UInt16(self, "inode_size", "Size of inode structure") yield UInt16(self, "block_group_nr", "Block group # of this superblock") yield FeatureCompatFlags( self, "feature_compat", "Compatible feature set (can mount even if these features are unsupported)" ) yield FeatureIncompatFlags( self, "feature_incompat", "Incompatible feature set (must support all features to mount)") yield FeatureROCompatFlags( self, "feature_ro_compat", "Read-only compatible feature set (can only mount r/o if a feature is unsupported)" ) yield UUID(self, "uuid", "128-bit UUID for volume") yield String(self, "volume_name", 16, "Volume name", strip="\0") yield String(self, "last_mounted", 64, "Directory where last mounted", strip="\0") yield UInt32(self, "compression", "For compression (algorithm usage bitmap)") yield UInt8(self, "prealloc_blocks", "Number of blocks to try to preallocate") yield UInt8(self, "prealloc_dir_blocks", "Number to preallocate for directories") yield UInt16(self, "reserved_gdt_blocks", "Number of reserved GDT entries for future expansion") yield RawBytes(self, "journal_uuid", 16, "UUID of journal superblock") yield UInt32(self, "journal_inum", "Inode number of journal file") yield UInt32( self, "journal_dev", "Device number of journal file (if ext_journal feature is set)") yield UInt32(self, "last_orphan", "Start of list of orphaned inodes to delete") # ext3 stuff yield RawBytes(self, "hash_seed", 16, "Seeds used for the directory indexing hash algorithm") yield Enum( UInt8(self, "def_hash_version", "Default hash version for directory indexing"), self.htree_hash_algo_desc) yield UInt8(self, "jnl_backup_type", "Does jnl_blocks contain a backup of i_block and i_size?") yield UInt16(self, "desc_size", "Size of group descriptors (if 64bit feature is set)") yield DefaultMountOptionFlags(self, "default_mount_opts", "Default mount options") yield UInt32( self, "first_meta_bg", "First metablock block group (if meta_bg feature is set)") yield TimestampUnix32(self, "mkfs_time", "When the filesystem was created") yield RawBytes(self, "jnl_blocks", 17 * 4, "Backup of the journal inode's i_block and i_size") yield PaddingBytes(self, "reserved[]", (1024 << self['log_block_size'].value) - self.current_size // 8)
def createFields(self): yield Enum(UInt8(self, "typecode"), TYPECODE_NAMES) self.root.resetHandles() yield SerializedObject(self, "object") self.root.resetHandles()
def parsePolyFillMode(parser): yield Enum(UInt16(parser, "operation"), POLYFILL_MODE)
def createFields(self): yield Enum(UInt8(self, "typecode"), TYPECODE_NAMES) self.root.newHandle(self) yield LongString(self, "value")
def parseEmfMappingMode(parser): yield Enum(Int32(parser, "mapping_mode"), EMF_MAPPING_MODE)
def createFields(self): yield Enum( Bits(self, "marker_type", 4), { 0: "Simple", 1: "Int", 2: "Real", 3: "Date", 4: "Data", 5: "ASCII String", 6: "UTF-16-BE String", 8: "UID", 10: "Array", 13: "Dict", }) markertype = self['marker_type'].value if markertype == 0: # Simple (Null) yield Enum(Bits(self, "value", 4), { 0: "Null", 8: "False", 9: "True", 15: "Fill Byte", }) if self['value'].display == "False": self.xml = lambda prefix: prefix + "<false/>" elif self['value'].display == "True": self.xml = lambda prefix: prefix + "<true/>" else: self.xml = lambda prefix: prefix + "" elif markertype == 1: # Int yield Bits(self, "size", 4, "log2 of number of bytes") size = self['size'].value # 8-bit (size=0), 16-bit (size=1) and 32-bit (size=2) numbers are unsigned # 64-bit (size=3) numbers are signed yield GenericInteger(self, "value", (size >= 3), (2**size) * 8) self.xml = lambda prefix: prefix + \ "<integer>%s</integer>" % self['value'].value elif markertype == 2: # Real yield Bits(self, "size", 4, "log2 of number of bytes") if self['size'].value == 2: # 2**2 = 4 byte float yield Float32(self, "value") elif self['size'].value == 3: # 2**3 = 8 byte float yield Float64(self, "value") else: # FIXME: What is the format of the real? yield Bits(self, "value", (2**self['size'].value) * 8) self.xml = lambda prefix: prefix + \ "<real>%s</real>" % self['value'].value elif markertype == 3: # Date yield Bits(self, "extra", 4, "Extra value, should be 3") # Use a heuristic to determine which epoch to use def cvt_time(v): v = timedelta(seconds=v) epoch2001 = datetime(2001, 1, 1) epoch1970 = datetime(1970, 1, 1) if (epoch2001 + v - datetime.today()).days > 5 * 365: return epoch1970 + v return epoch2001 + v yield displayHandler(Float64(self, "value"), lambda x: humanDatetime(cvt_time(x))) self.xml = lambda prefix: prefix + "<date>%sZ</date>" % (cvt_time( self['value'].value).isoformat()) elif markertype == 4: # Data yield BPListSize(self, "size") if self['size'].value: yield Bytes(self, "value", self['size'].value) self.xml = lambda prefix: prefix + \ "<data>\n%s\n%s</data>" % ( self['value'].value.encode('base64').strip(), prefix) else: self.xml = lambda prefix: prefix + '<data></data>' elif markertype == 5: # ASCII String yield BPListSize(self, "size") if self['size'].value: yield String(self, "value", self['size'].value, charset="ASCII") self.xml = lambda prefix: prefix + \ "<string>%s</string>" % ( self['value'].value.replace('&', '&').encode('iso-8859-1')) else: self.xml = lambda prefix: prefix + '<string></string>' elif markertype == 6: # UTF-16-BE String yield BPListSize(self, "size") if self['size'].value: yield String(self, "value", self['size'].value * 2, charset="UTF-16-BE") self.xml = lambda prefix: prefix + \ "<string>%s</string>" % ( self['value'].value.replace('&', '&').encode('utf-8')) else: self.xml = lambda prefix: prefix + '<string></string>' elif markertype == 8: # UID yield Bits(self, "size", 4, "Number of bytes minus 1") yield GenericInteger(self, "value", False, (self['size'].value + 1) * 8) self.xml = lambda prefix: prefix + "" # no equivalent? elif markertype == 10: # Array yield BPListSize(self, "size") size = self['size'].value if size: yield BPListArray(self, "value", size) self.xml = lambda prefix: self['value'].createXML(prefix) elif markertype == 13: # Dict yield BPListSize(self, "size") yield BPListDict(self, "value", self['size'].value) self.xml = lambda prefix: self['value'].createXML(prefix) else: yield Bits(self, "value", 4) self.xml = lambda prefix: ''