def createFields(self): yield Bit(self, "drop_frame") yield Bits(self, "time_hh", 5) yield Bits(self, "time_mm", 6) yield PaddingBits(self, "time_pad[]", 1) yield Bits(self, "time_ss", 6) yield Bits(self, "time_ff", 6) yield Bit(self, "closed_group") yield Bit(self, "broken_group") yield PaddingBits(self, "pad[]", 5)
def parseFontHeader(self): yield UInt16(self, "maj_ver", "Major version") yield UInt16(self, "min_ver", "Minor version") yield UInt16(self, "font_maj_ver", "Font major version") yield UInt16(self, "font_min_ver", "Font minor version") yield textHandler(UInt32(self, "checksum"), hexadecimal) yield Bytes(self, "magic", 4, r"Magic string (\x5F\x0F\x3C\xF5)") if self["magic"].value != "\x5F\x0F\x3C\xF5": raise ParserError("TTF: invalid magic of font header") # Flags yield Bit(self, "y0", "Baseline at y=0") yield Bit(self, "x0", "Left sidebearing point at x=0") yield Bit(self, "instr_point", "Instructions may depend on point size") yield Bit(self, "ppem", "Force PPEM to integer values for all") yield Bit(self, "instr_width", "Instructions may alter advance width") yield Bit(self, "vertical", "e laid out vertically?") yield PaddingBits(self, "reserved[]", 1) yield Bit(self, "linguistic", "Requires layout for correct linguistic rendering?") yield Bit(self, "gx", "Metamorphosis effects?") yield Bit(self, "strong", "Contains strong right-to-left glyphs?") yield Bit(self, "indic", "contains Indic-style rearrangement effects?") yield Bit(self, "lossless", "Data is lossless (Agfa MicroType compression)") yield Bit(self, "converted", "Font converted (produce compatible metrics)") yield Bit(self, "cleartype", "Optimised for ClearType") yield Bits(self, "adobe", 2, "(used by Adobe)") yield UInt16(self, "unit_per_em", "Units per em") if not(16 <= self["unit_per_em"].value <= 16384): raise ParserError("TTF: Invalid unit/em value") yield UInt32(self, "created_high") yield TimestampMac32(self, "created") yield UInt32(self, "modified_high") yield TimestampMac32(self, "modified") yield UInt16(self, "xmin") yield UInt16(self, "ymin") yield UInt16(self, "xmax") yield UInt16(self, "ymax") # Mac style yield Bit(self, "bold") yield Bit(self, "italic") yield Bit(self, "underline") yield Bit(self, "outline") yield Bit(self, "shadow") yield Bit(self, "condensed", "(narrow)") yield Bit(self, "expanded") yield PaddingBits(self, "reserved[]", 9) yield UInt16(self, "lowest", "Smallest readable size in pixels") yield Enum(UInt16(self, "font_dir", "Font direction hint"), DIRECTION_NAME) yield Enum(UInt16(self, "ofst_format"), {0: "short offsets", 1: "long"}) yield UInt16(self, "glyph_format", "(=0)")
def createFields(self): yield Bytes(self, "signature", 2, "New executable signature (NE)") yield UInt8(self, "link_ver", "Linker version number") yield UInt8(self, "link_rev", "Linker revision number") yield UInt16(self, "entry_table_ofst", "Offset to the entry table") yield UInt16(self, "entry_table_size", "Length (in bytes) of the entry table") yield PaddingBytes(self, "reserved[]", 4) yield Bit(self, "is_dll", "Is a dynamic-link library (DLL)?") yield Bit(self, "is_win_app", "Is a Windows application?") yield PaddingBits(self, "reserved[]", 9) yield Bit(self, "first_seg_code", "First segment contains code that loads the application?") yield NullBits(self, "reserved[]", 1) yield Bit(self, "link_error", "Load even if linker detects errors?") yield NullBits(self, "reserved[]", 1) yield Bit(self, "is_lib", "Is a library module?") yield UInt16(self, "auto_data_seg", "Automatic data segment number") yield filesizeHandler(UInt16(self, "local_heap_size", "Initial size (in bytes) of the local heap")) yield filesizeHandler(UInt16(self, "stack_size", "Initial size (in bytes) of the stack")) yield textHandler(UInt32(self, "cs_ip", "Value of CS:IP"), hexadecimal) yield textHandler(UInt32(self, "ss_sp", "Value of SS:SP"), hexadecimal) yield UInt16(self, "nb_entry_seg_tab", "Number of entries in the segment table") yield UInt16(self, "nb_entry_modref_tab", "Number of entries in the module-reference table") yield filesizeHandler(UInt16(self, "size_nonres_name_tab", "Number of bytes in the nonresident-name table")) yield UInt16(self, "seg_tab_ofs", "Segment table offset") yield UInt16(self, "rsrc_ofs", "Resource offset") yield UInt16(self, "res_name_tab_ofs", "Resident-name table offset") yield UInt16(self, "mod_ref_tab_ofs", "Module-reference table offset") yield UInt16(self, "import_tab_ofs", "Imported-name table offset") yield UInt32(self, "non_res_name_tab_ofs", "Nonresident-name table offset") yield UInt16(self, "nb_mov_ent_pt", "Number of movable entry points") yield UInt16(self, "log2_sector_size", "Log2 of the segment sector size") yield UInt16(self, "nb_rsrc_seg", "Number of resource segments") yield Bit(self, "unknown_os_format", "Operating system format is unknown") yield PaddingBits(self, "reserved[]", 1) yield Bit(self, "os_windows", "Operating system is Microsoft Windows") yield NullBits(self, "reserved[]", 6) yield Bit(self, "is_win20_prot", "Is Windows 2.x application running in version 3.x protected mode") yield Bit(self, "is_win20_font", "Is Windows 2.x application supporting proportional fonts") yield Bit(self, "fast_load", "Contains a fast-load area?") yield NullBits(self, "reserved[]", 4) yield UInt16(self, "fastload_ofs", "Fast-load area offset (in sector)") yield UInt16(self, "fastload_size", "Fast-load area length (in sector)") yield NullBytes(self, "reserved[]", 2) yield textHandler(UInt16(self, "win_version", "Expected Windows version number"), hexadecimal)
def createFields(self): if self.stream.readBits(self.absolute_address, 2, self.endian) == 1: # MPEG version 2 yield Bits(self, "sync[]", 2) yield SCR(self, "scr") yield Bit(self, "sync[]") yield Bits(self, "scr_ext", 9) yield Bit(self, "sync[]") yield Bits(self, "mux_rate", 22) yield Bits(self, "sync[]", 2) yield PaddingBits(self, "reserved", 5, pattern=1) yield Bits(self, "stuffing_length", 3) count = self["stuffing_length"].value if count: yield PaddingBytes(self, "stuffing", count, pattern="\xff") else: # MPEG version 1 yield Bits(self, "sync[]", 4) yield Bits(self, "scr_a", 3) yield Bit(self, "sync[]") yield Bits(self, "scr_b", 15) yield Bit(self, "sync[]") yield Bits(self, "scr_c", 15) yield Bits(self, "sync[]", 2) yield Bits(self, "mux_rate", 22) yield Bit(self, "sync[]")
def createFields(self): # Header yield PaddingBits(self, "sync", 11, "Synchronize bits (set to 1)", pattern=1) yield Enum(Bits(self, "version", 2, "MPEG audio version"), self.VERSION_NAME) yield Enum(Bits(self, "layer", 2, "MPEG audio layer"), self.LAYER_NAME) yield Bit(self, "crc16", "No CRC16 protection?") # Rates and padding yield Bits(self, "bit_rate", 4, "Bit rate") yield Bits(self, "sampling_rate", 2, "Sampling rate") yield Bit(self, "use_padding", "Stream field use padding?") yield Bit(self, "extension", "Extension") # Channel mode, mode extension, copyright, ... yield Enum(Bits(self, "channel_mode", 2, "Channel mode"), self.CHANNEL_MODE_NAME) yield Bits(self, "mode_ext", 2, "Mode extension") yield Bit(self, "copyright", "Is copyrighted?") yield Bit(self, "original", "Is original?") yield Enum(Bits(self, "emphasis", 2, "Emphasis"), self.EMPHASIS_NAME) size = (self.size - self.current_size) / 8 if size: yield RawBytes(self, "data", size)
def createFields(self): yield textHandler(UInt32(self, "crc32"), hexadecimal) yield UInt16(self, "size") yield UInt16( self, "uncompressed_size", "If this is 0, this block is continued in a subsequent cabinet") if self["/flags/has_reserved"].value and self[ "/reserved_data_size"].value: yield RawBytes(self, "reserved_data", self["/reserved_data_size"].value, "Per-datablock reserved area") compr_method = self.parent.folder["compr_method"].value if compr_method == 0: # Uncompressed yield RawBytes(self, "data", self["size"].value, "Folder Data") self.parent.uncompressed_data += self["data"].value elif compr_method == 1: # MSZIP yield String(self, "mszip_signature", 2, "MSZIP Signature (CK)") yield DeflateBlock(self, "deflate_block", self.parent.uncompressed_data) padding = paddingSize(self.current_size, 8) if padding: yield PaddingBits(self, "padding[]", padding) self.parent.uncompressed_data = self["deflate_block"].uncomp_data elif compr_method == 2: # Quantum yield RawBytes(self, "compr_data", self["size"].value, "Compressed Folder Data") elif compr_method == 3: # LZX group = getattr(self.parent.folder, "lzx_group", None) field = CustomFragment(self, "data", self["size"].value * 8, LZXStream, "LZX data fragment", group) self.parent.folder.lzx_group = field.group yield field
def createFields(self): yield UInt32(self, "off_data", "Offset of data") yield UInt16(self, "cf_data") yield Enum(Bits(self, "compr_method", 4, "Compression method"), COMPRESSION_NAME) yield Bits(self, "compr_level", 5, "Compression level") yield PaddingBits(self, "padding", 7)
def createPaddingField(parent, nbits, name="padding[]", description=None): if nbits <= 0: raise FieldError("Unable to create padding of %s bits" % nbits) if (nbits % 8) == 0: return PaddingBytes(parent, name, nbits / 8, description) else: return PaddingBits(parent, name, nbits, description)
def createFields(self): yield SubTileBitmap(self, "sub_tile_bitmap") #yield Bits(self, "sub_tile_bitmap", 16) yield Bits(self, "layer", 4) yield Bits(self, "num_tags", 4) for i in range(self["num_tags"].value): yield UIntVbe(self, "tag_id[]") yield Bit(self, "have_name") yield Bit(self, "have_house_number") yield Bit(self, "have_ref") yield Bit(self, "have_label_position") yield Bit(self, "have_num_way_blocks") yield Enum(Bit(self, "coord_encoding"), CoordinateEncoding) yield PaddingBits(self, "pad[]", 2) if self["have_name"].value: yield VbeString(self, "name") if self["have_house_number"].value: yield VbeString(self, "house_number") if self["have_ref"].value: yield VbeString(self, "ref") if self["have_label_position"].value: yield IntVbe(self, "label_lat_diff") yield IntVbe(self, "label_lon_diff") numWayDataBlocks = 1 if self["have_num_way_blocks"].value: yield UIntVbe(self, "num_way_blocks") numWayDataBlocks = self["num_way_blocks"].value for i in range(numWayDataBlocks): yield WayData(self, "way_data[]")
def createFields(self): yield Bytes(self, "header", 4, r"PE header signature (PE\0\0)") if self["header"].value != "PE\0\0": raise ParserError("Invalid PE header signature") yield Enum(UInt16(self, "cpu", "CPU type"), self.cpu_name) yield UInt16(self, "nb_section", "Number of sections") yield TimestampUnix32(self, "creation_date", "Creation date") yield UInt32(self, "ptr_to_sym", "Pointer to symbol table") yield UInt32(self, "nb_symbols", "Number of symbols") yield UInt16(self, "opt_hdr_size", "Optional header size") yield Bit(self, "reloc_stripped", "If true, don't contain base relocations.") yield Bit(self, "exec_image", "Executable image?") yield Bit(self, "line_nb_stripped", "COFF line numbers stripped?") yield Bit(self, "local_sym_stripped", "COFF symbol table entries stripped?") yield Bit(self, "aggr_ws", "Aggressively trim working set") yield Bit(self, "large_addr", "Application can handle addresses greater than 2 GB") yield NullBits(self, "reserved", 1) yield Bit(self, "reverse_lo", "Little endian: LSB precedes MSB in memory") yield Bit(self, "32bit", "Machine based on 32-bit-word architecture") yield Bit(self, "is_stripped", "Debugging information removed?") yield Bit( self, "swap", "If image is on removable media, copy and run from swap file") yield PaddingBits(self, "reserved2", 1) yield Bit(self, "is_system", "It's a system file") yield Bit(self, "is_dll", "It's a dynamic-link library (DLL)") yield Bit(self, "up", "File should be run only on a UP machine") yield Bit(self, "reverse_hi", "Big endian: MSB precedes LSB in memory")
def createFields(self): if self["/have_debug"].value: yield String(self, "signature", 32) if not self['signature'].value.startswith("***POIStart"): raise ValueError yield IntVbe(self, "lat_diff") yield IntVbe(self, "lon_diff") yield Bits(self, "layer", 4) yield Bits(self, "num_tags", 4) for i in range(self["num_tags"].value): yield UIntVbe(self, "tag_id[]") yield Bit(self, "have_name") yield Bit(self, "have_house_number") yield Bit(self, "have_ele") yield PaddingBits(self, "pad[]", 5) if self["have_name"].value: yield VbeString(self, "name") if self["have_house_number"].value: yield VbeString(self, "house_number") if self["have_ele"].value: yield IntVbe(self, "ele")
def createFields(self): self.osconfig = self.parent.osconfig yield UInt32(self, "size") yield UInt32(self, "count") for i in range(self["count"].value): yield PropertyContent(self, "item[]") n = paddingSize(self.current_size, 32) if n: yield PaddingBits(self, "padding[]", n)
def createFields(self): yield UInt32(self, "offset", "Offset to data (from file start)") yield UInt16(self, "data_blocks", "Number of data blocks which are in this cabinet") yield Enum(Bits(self, "compr_method", 4, "Compression method"), COMPRESSION_NAME) if self["compr_method"].value in [ 2, 3 ]: # Quantum or LZX use compression level yield PaddingBits(self, "padding[]", 4) yield Bits(self, "compr_level", 5, "Compression level") yield PaddingBits(self, "padding[]", 3) else: yield PaddingBits(self, "padding[]", 12) if self["../flags/has_reserved"].value and self[ "../reserved_folder_size"].value: yield RawBytes(self, "reserved_folder", self["../reserved_folder_size"].value, "Per-folder reserved area")
def createFields(self): if self.frame["../type"].value in [0xC0, 0xC1]: # yay, huffman coding! if not hasattr(self, "huffman_tables"): self.huffman_tables = {} for huffman in self.parent.array("huffman"): for table in huffman["content"].array("huffman_table"): for _dummy_ in table: # exhaust table, so the huffman tree is built pass self.huffman_tables[table["table_class"].value, table["index"].value] = table.tree components = [] # sos_comp, samples max_vert = 0 max_horiz = 0 for component in self.scan.array("component"): for sof_comp in self.frame.array("component"): if sof_comp["component_id"].value == component["component_id"].value: vert = sof_comp["vert_sample"].value horiz = sof_comp["horiz_sample"].value components.append((component, vert * horiz)) max_vert = max(max_vert, vert) max_horiz = max(max_horiz, horiz) mcu_height = alignValue(self.frame["height"].value, 8 * max_vert) // (8 * max_vert) mcu_width = alignValue(self.frame["width"].value, 8 * max_horiz) // (8 * max_horiz) if self.restart_interval and self.restart_offset > 0: mcu_number = self.restart_interval * self.restart_offset else: mcu_number = 0 initial_mcu = mcu_number while True: if (self.restart_interval and mcu_number != initial_mcu and mcu_number % self.restart_interval == 0) or\ mcu_number == mcu_height * mcu_width: padding = paddingSize(self.current_size, 8) if padding: yield PaddingBits(self, "padding[]", padding) # all 1s last_byte = self.stream.readBytes(self.absolute_address + self.current_size - 8, 1) if last_byte == '\xFF': next_byte = self.stream.readBytes(self.absolute_address + self.current_size, 1) if next_byte != '\x00': raise FieldError("Unexpected byte sequence %r!"%(last_byte + next_byte)) yield NullBytes(self, "stuffed_byte[]", 1) break for sos_comp, num_units in components: for interleave_count in range(num_units): yield JpegHuffmanImageUnit(self, "block[%i]component[%i][]" % (mcu_number, sos_comp["component_id"].value), self.huffman_tables[0, sos_comp["dc_coding_table"].value], self.huffman_tables[1, sos_comp["ac_coding_table"].value]) mcu_number += 1 else: self.warning("Sorry, only supporting Baseline & Extended Sequential JPEG images so far!") return
def createFields(self): uncomp_data = "" blk = DeflateBlock(self, "compressed_block[]", uncomp_data) yield blk uncomp_data = blk.uncomp_data while not blk["final"].value: blk = DeflateBlock(self, "compressed_block[]", uncomp_data) yield blk uncomp_data = blk.uncomp_data padding = paddingSize(self.current_size + self.absolute_address, 8) # align on byte boundary if padding: yield PaddingBits(self, "padding[]", padding) self.uncompressed_data = uncomp_data
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): self.uncompressed_data = "" self.r0 = 1 self.r1 = 1 self.r2 = 1 yield Bit(self, "filesize_indicator") if self["filesize_indicator"].value: yield UInt32(self, "filesize") while self.current_size < self.size: block = LZXBlock(self, "block[]") yield block if self.size - self.current_size < 16: padding = paddingSize(self.address + self.current_size, 16) if padding: yield PaddingBits(self, "padding[]", padding) break
def createFields(self): end = False while not end: marker = self.stream.readBits( self.absolute_address + self.current_size, 48, self.endian) if marker == self.START_BLOCK: yield Bzip2Block(self, "block[]") elif marker == self.END_STREAM: yield textHandler( Bits(self, "stream_end", 48, "End-of-stream marker"), hexadecimal) yield textHandler( UInt32(self, "crc32", "CRC32 for entire stream"), hexadecimal) padding = paddingSize(self.current_size, 8) if padding: yield PaddingBits(self, "padding[]", padding) end = True else: raise ParserError("Invalid marker 0x%02X!" % marker)
def createFields(self): yield IntVbe(self, "lat_diff") yield IntVbe(self, "lon_diff") yield Bits(self, "layer", 4) yield Bits(self, "num_tags", 4) for i in range(self["num_tags"].value): yield UIntVbe(self, "tag_id[]") yield Bit(self, "have_name") yield Bit(self, "have_house_number") yield Bit(self, "have_ele") yield PaddingBits(self, "pad[]", 5) if self["have_name"].value: yield VbeString(self, "name") if self["have_house_number"].value: yield VbeString(self, "house_number") if self["have_ele"].value: yield IntVbe(self, "ele")
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 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 padding = paddingSize(self.current_size + self.absolute_address, 8) # align on byte boundary 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!") if self["len"].value: # null stored blocks produced by some encoders (e.g. PIL) 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 xrange(144): length_tree[(8, i + 48)] = i for i in xrange(144, 256): length_tree[(9, i + 256)] = i for i in xrange(256, 280): length_tree[(7, i - 256)] = i for i in xrange(280, 288): length_tree[(8, i - 88)] = i for i in xrange(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): padding = 0 position = 0 while True: next = ord( self.parent.stream.readBytes( self.absolute_address + self.current_size + position, 1)) if next == 0xff: padding += 1 position += 8 elif padding: yield PaddingBytes(self, "pad[]", padding) padding = None position = 0 elif 0x40 <= next <= 0x7f: yield Bits(self, "scale_marker", 2) # 1 yield Bit(self, "scale") scale = self['scale'].value if scale: scaleval = 1024 else: scaleval = 128 yield textHandler(Bits(self, "size", 13), lambda field: str(field.value * scaleval)) elif 0x00 <= next <= 0x3f: yield Bits(self, "ts_marker", 2) # 0 yield Bit(self, "has_pts") yield Bit(self, "has_dts") if self['has_pts'].value: yield Timestamp(self, "pts") if self['has_dts'].value: yield PaddingBits(self, "pad[]", 4) yield Timestamp(self, "dts") if self.current_size % 8 == 4: yield PaddingBits(self, "pad[]", 4) break elif 0x80 <= next <= 0xbf: # MPEG-2 extension yield PacketElement(self, "pkt") break else: # 0xc0 - 0xfe: unknown break length = self["../length"].value - self.current_size // 8 if length: tag = self['../tag'].value group = self.root.streamgroups[tag] parname = self.parent._name if parname.startswith('audio'): frag = CustomFragment(self, "data", length * 8, MpegAudioFile, group=group) elif parname.startswith('video'): frag = CustomFragment(self, "data", length * 8, VideoStream, group=group) else: frag = CustomFragment(self, "data", length * 8, None, group=group) self.root.streamgroups[tag] = frag.group yield frag
def createFields(self): yield Bits(self, "stream_index", 7) yield PaddingBits(self, "reserved", 9) yield displayHandler(UInt32(self, "avg_bitrate"), humanBitRate)
def createFields(self): yield UInt32(self, "length", "Length of this structure") if not self["length"].value: return yield UInt32(self, "first_offset_pos", "Position of first offset") has_unicode_paths = (self["first_offset_pos"].value == 0x24) yield Bit(self, "on_local_volume") yield Bit(self, "on_network_volume") yield PaddingBits(self, "reserved[]", 30) yield UInt32( self, "local_info_offset", "Offset to local volume table; only meaningful if on_local_volume = 1" ) yield UInt32( self, "local_pathname_offset", "Offset to local base pathname; only meaningful if on_local_volume = 1" ) yield UInt32( self, "remote_info_offset", "Offset to network volume table; only meaningful if on_network_volume = 1" ) yield UInt32(self, "pathname_offset", "Offset of remaining pathname") if has_unicode_paths: yield UInt32( self, "local_pathname_unicode_offset", "Offset to Unicode version of local base pathname; only meaningful if on_local_volume = 1" ) yield UInt32(self, "pathname_unicode_offset", "Offset to Unicode version of remaining pathname") if self["on_local_volume"].value: padding = self.seekByte(self["local_info_offset"].value) if padding: yield padding yield LocalVolumeTable(self, "local_volume_table", "Local Volume Table") padding = self.seekByte(self["local_pathname_offset"].value) if padding: yield padding yield CString(self, "local_base_pathname", "Local Base Pathname") if has_unicode_paths: padding = self.seekByte( self["local_pathname_unicode_offset"].value) if padding: yield padding yield CString(self, "local_base_pathname_unicode", "Local Base Pathname in Unicode", charset="UTF-16-LE") if self["on_network_volume"].value: padding = self.seekByte(self["remote_info_offset"].value) if padding: yield padding yield NetworkVolumeTable(self, "network_volume_table") padding = self.seekByte(self["pathname_offset"].value) if padding: yield padding yield CString(self, "final_pathname", "Final component of the pathname") if has_unicode_paths: padding = self.seekByte(self["pathname_unicode_offset"].value) if padding: yield padding yield CString(self, "final_pathname_unicode", "Final component of the pathname in Unicode", charset="UTF-16-LE") padding = self.seekByte(self["length"].value) if padding: yield padding
def createFields(self): yield Bits(self, "reserved[]", 2) yield Bit(self, "byte_big_endian") yield Bit(self, "bit_big_endian") yield Bits(self, "scan_unit", 2) yield textHandler(PaddingBits(self, "reserved[]", 26), hexadecimal)
def createFields(self): yield Bits(self, "block_type", 3) yield Bits(self, "block_size", 24) self.uncompressed_size = self["block_size"].value self.compression_level = self.root.compr_level self.window_size = self.WINDOW_SIZE[self.compression_level] self.block_type = self["block_type"].value curlen = len(self.parent.uncompressed_data) if self.block_type in (1, 2): # Verbatim or aligned offset block if self.block_type == 2: for i in xrange(8): yield Bits(self, "aligned_len[]", 3) aligned_tree = build_tree( [self['aligned_len[%d]' % i].value for i in xrange(8)]) yield LZXPreTreeEncodedTree(self, "main_tree_start", 256) yield LZXPreTreeEncodedTree(self, "main_tree_rest", self.window_size * 8) main_tree = build_tree(self["main_tree_start"].lengths + self["main_tree_rest"].lengths) yield LZXPreTreeEncodedTree(self, "length_tree", 249) length_tree = build_tree(self["length_tree"].lengths) current_decoded_size = 0 while current_decoded_size < self.uncompressed_size: if (curlen + current_decoded_size) % 32768 == 0 and ( curlen + current_decoded_size) != 0: padding = paddingSize(self.address + self.current_size, 16) if padding: yield PaddingBits(self, "padding[]", padding) field = HuffmanCode(self, "main_code[]", main_tree) if field.realvalue < 256: field._description = "Literal value %r" % chr( field.realvalue) current_decoded_size += 1 self.parent.uncompressed_data += chr(field.realvalue) yield field continue position_header, length_header = divmod( field.realvalue - 256, 8) info = self.POSITION_SLOTS[position_header] if info[2] == 0: if info[0] == 0: position = self.parent.r0 field._description = "Position Slot %i, Position [R0] (%i)" % ( position_header, position) elif info[0] == 1: position = self.parent.r1 self.parent.r1 = self.parent.r0 self.parent.r0 = position field._description = "Position Slot %i, Position [R1] (%i)" % ( position_header, position) elif info[0] == 2: position = self.parent.r2 self.parent.r2 = self.parent.r0 self.parent.r0 = position field._description = "Position Slot %i, Position [R2] (%i)" % ( position_header, position) else: position = info[0] - 2 self.parent.r2 = self.parent.r1 self.parent.r1 = self.parent.r0 self.parent.r0 = position field._description = "Position Slot %i, Position %i" % ( position_header, position) else: field._description = "Position Slot %i, Positions %i to %i" % ( position_header, info[0] - 2, info[1] - 2) if length_header == 7: field._description += ", Length Values 9 and up" yield field length_field = HuffmanCode(self, "length_code[]", length_tree) length = length_field.realvalue + 9 length_field._description = "Length Code %i, total length %i" % ( length_field.realvalue, length) yield length_field else: field._description += ", Length Value %i (Huffman Code %i)" % ( length_header + 2, field.value) yield field length = length_header + 2 if info[2]: if self.block_type == 1 or info[2] < 3: # verbatim extrafield = Bits( self, "position_extra[%s" % field.name.split('[')[1], info[2]) position = extrafield.value + info[0] - 2 extrafield._description = "Position Extra Bits (%i), total position %i" % ( extrafield.value, position) yield extrafield else: # aligned offset position = info[0] - 2 if info[2] > 3: extrafield = Bits( self, "position_verbatim[%s" % field.name.split('[')[1], info[2] - 3) position += extrafield.value * 8 extrafield._description = "Position Verbatim Bits (%i), added position %i" % ( extrafield.value, extrafield.value * 8) yield extrafield if info[2] >= 3: extrafield = HuffmanCode( self, "position_aligned[%s" % field.name.split('[')[1], aligned_tree) position += extrafield.realvalue extrafield._description = "Position Aligned Bits (%i), total position %i" % ( extrafield.realvalue, position) yield extrafield self.parent.r2 = self.parent.r1 self.parent.r1 = self.parent.r0 self.parent.r0 = position self.parent.uncompressed_data = extend_data( self.parent.uncompressed_data, length, position) current_decoded_size += length elif self.block_type == 3: # Uncompressed block padding = paddingSize(self.address + self.current_size, 16) if padding: yield PaddingBits(self, "padding[]", padding) else: yield PaddingBits(self, "padding[]", 16) self.endian = LITTLE_ENDIAN yield UInt32(self, "r[]", "New value of R0") yield UInt32(self, "r[]", "New value of R1") yield UInt32(self, "r[]", "New value of R2") self.parent.r0 = self["r[0]"].value self.parent.r1 = self["r[1]"].value self.parent.r2 = self["r[2]"].value yield RawBytes(self, "data", self.uncompressed_size) self.parent.uncompressed_data += self["data"].value if self["block_size"].value % 2: yield PaddingBits(self, "padding", 8) else: raise ParserError("Unknown block type %d!" % self.block_type)