def __init__(self, parent, name, description=None): Bits.__init__(self, parent, name, 8, description) stream = parent.stream addr = self.absolute_address value = 0 while True: bits = stream.readBits(addr, 8, parent.endian) value = (value << 7) + (bits & 127) if not (bits & 128): break addr += 8 self._size += 8 if 32 < self._size: raise ParserError("Integer size is bigger than 32-bit") self.createValue = lambda: value
def createFields(self): yield Bit(self, "sync[]") # =True yield Bits(self, "ext_length", 7) yield NullBits(self, "reserved[]", 8) size = self["ext_length"].value if size: yield RawBytes(self, "ext_bytes", size)
def createFields(self): yield UInt8(self, "id_length", "Length of the image ID field") yield UInt8(self, "palette_type", "Colormap present?") yield Enum(UInt8(self, "codec", "Pixels encoding"), self.CODEC_NAME) yield UInt16(self, "palette_ofs", "Palette absolute file offset") yield UInt16(self, "nb_color", "Number of colors in the palette") yield UInt8(self, "color_map_size", "Size of each palette entry") yield UInt16(self, "x_min") yield UInt16(self, "y_min") yield UInt16(self, "width") yield UInt16(self, "height") yield UInt8(self, "bpp", "Bits per pixel") yield Bits(self, "alpha_depth", 4, "Alpha channel depth") yield Bit( self, "x_flip", "Flip across the X-axis? (If set, columns run right-to-left)") yield Bit(self, "y_flip", "Flip across the Y-axis? (If set, rows run top-to-bottom)") yield RawBits(self, "reserved_flags", 2) if self["id_length"].value: yield RawBytes(self, "image_id", self["id_length"].value) if self["palette_type"].value == 1: yield PaletteRGB(self, "palette", 1 << self["bpp"].value) if self["codec"] in (1, 2, 3): yield Pixels(self, "pixels") else: size = (self.size - self.current_size) // 8 if size: yield RawBytes(self, "raw_pixels", size)
def parseDefineSound(parent, size): yield UInt16(parent, "sound_id") yield Bit(parent, "is_stereo") yield Bit(parent, "is_16bit") yield textHandler(Bits(parent, "rate", 2), bit2hertz) yield Enum(Bits(parent, "codec", 4), SOUND_CODEC) yield UInt32(parent, "sample_count") if parent["codec"].value == SOUND_CODEC_MP3: yield UInt16(parent, "len") size = (parent.size - parent.current_size) // 8 if size: yield RawBytes(parent, "music_data", size)
def createFields(self): yield UInt16(self, "left", "Left") yield UInt16(self, "top", "Top") yield UInt16(self, "width", "Width") yield UInt16(self, "height", "Height") yield Bits(self, "size_local_map", 3, "log2(size of local map) minus one") yield NullBits(self, "reserved", 2) yield Bit(self, "sort_flag", "Is the local map sorted by decreasing importance?") yield Bit(self, "interlaced", "Interlaced?") yield Bit(self, "has_local_map", "Use local color map?") if self["has_local_map"].value: nb_color = 1 << (1 + self["size_local_map"].value) yield PaletteRGB(self, "local_map", nb_color, "Local color map") yield UInt8(self, "lzw_min_code_size", "LZW Minimum Code Size") group = None while True: size = UInt8(self, "image_block_size[]") if size.value == 0: break yield size block = CustomFragment(self, "image_block[]", size.value * 8, GifImageBlock, "GIF Image Block", group) if group is None: block.group.args["startbits"] = self["lzw_min_code_size"].value group = block.group yield block yield NullBytes(self, "terminator", 1, "Terminator (0)")
def createFields(self): yield Enum(UInt16(self, "src"), self.port_name) yield Enum(UInt16(self, "dst"), self.port_name) yield UInt32(self, "seq_num") yield UInt32(self, "ack_num") yield Bits(self, "hdrlen", 6, "Header lenght") yield NullBits(self, "reserved", 2, "Reserved") yield Bit(self, "cgst", "Congestion Window Reduced") yield Bit(self, "ecn-echo", "ECN-echo") yield Bit(self, "urg", "Urgent") yield Bit(self, "ack", "Acknowledge") yield Bit(self, "psh", "Push mmode") yield Bit(self, "rst", "Reset connection") yield Bit(self, "syn", "Synchronize") yield Bit(self, "fin", "Stop the connection") yield UInt16(self, "winsize", "Windows size") yield textHandler(UInt16(self, "checksum"), hexadecimal) yield UInt16(self, "urgent") size = self["hdrlen"].value * 8 - self.current_size while 0 < size: option = TCP_Option(self, "option[]") yield option size -= option.size
def createFields(self): yield UInt16(self, "width", "Width") yield UInt16(self, "height", "Height") yield Bits(self, "size_global_map", 3, "log2(size of global map) minus one") yield Bit(self, "sort_flag", "Is the global map sorted by decreasing importance?") yield Bits(self, "color_res", 3, "Color resolution minus one") yield Bit(self, "global_map", "Has global map?") yield UInt8(self, "background", "Background color") field = UInt8(self, "pixel_aspect_ratio") if field.value: field._description = "Pixel aspect ratio: %f (stored as %i)" % ( (field.value + 15) / 64., field.value) else: field._description = "Pixel aspect ratio: not specified" yield field
def __init__(self, parent, name, description=None): Bits.__init__(self, parent, name, 8, description) stream = self._parent.stream addr = self.absolute_address size = 8 byte = stream.readBits(addr, 8, BIG_ENDIAN) value = byte & 0x7F while byte & 0x80: addr += 8 size += 8 byte = stream.readBits(addr, 8, BIG_ENDIAN) value = (value << 7) + (byte & 0x7F) self._size = size self.createValue = lambda: value
def createFields(self): yield Bits(self, "quantizer_scale", 5) start = self.absolute_address + self.current_size + 3 pos = self.stream.searchBytes( '\0\0\1', start, start + 1024 * 1024 * 8) # seek forward by at most 1MB if pos is None: pos = self.root.size yield RawBits(self, "data", pos - start + 3)
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 __init__(self, parent, name, description=None): Bits.__init__(self, parent, name, 8, description) stream = self._parent.stream addr = self.absolute_address size = 8 value = 0 byte = stream.readBits(addr, 8, BIG_ENDIAN) value = byte & 127 while 128 <= byte: addr += 8 size += 8 if 64 < size: # Arbitrary limit to catch errors raise ParserError("ASN.1: Object identifier is limited 64 bits") byte = stream.readBits(addr, 8, BIG_ENDIAN) value = (value << 7) + (byte & 127) self._size = size self.createValue = lambda: value
def __init__(self, parent, name, signed=False, nbits=30, description=None): Bits.__init__(self, parent, name, 8, description) stream = self._parent.stream addr = self.absolute_address size = 0 value = 0 mult = 1 while True: byte = stream.readBits(addr + size, 8, LITTLE_ENDIAN) value += mult * (byte & 0x7f) size += 8 mult <<= 7 if byte < 128: break self._size = size if signed and (1 << (nbits - 1)) <= value: value -= (1 << nbits) self.createValue = lambda: value
def __init__(self, parent, name, description=None): Bits.__init__(self, parent, name, 8, description) stream = self._parent.stream addr = self.absolute_address size = 8 value = 0 byte = stream.readBits(addr, 8, BIG_ENDIAN) value = byte & 127 while 128 <= byte: addr += 8 size += 8 if 64 < size: # Arbitrary limit to catch errors raise ParserError( "ASN.1: Object identifier is limited 64 bits") byte = stream.readBits(addr, 8, BIG_ENDIAN) value = (value << 7) + (byte & 127) self._size = size self.createValue = lambda: value
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): yield UInt32(self, "size") yield UInt32(self, "index") yield Bits(self, "flags", 8) yield RawBytes(self, "unknown[]", 5) yield UInt16(self, "unknown[]") yield CString(self, "name", charset="UTF-16-LE") if self.current_size // 8 != self['size'].value: yield RawBytes(self, "padding", self['size'].value - self.current_size // 8)
def createFields(self): if self.res_type is None: # immediate subdirectory of the root yield Enum(UInt32(self, "type"), self.TYPE_DESC) else: # sub-subdirectory, "type" field is just an ID yield textHandler(UInt32(self, "type"), lambda field: "ID %d" % field.value) yield Bits(self, "offset", 31) yield Bit(self, "is_subdir")
def createFields(self): yield UInt8(self, "version", "Version") yield Bits(self, "flags", 24, "Flags (=1)") graphics = UInt16(self, "graphicsmode") graphics.createDisplay = lambda: self.graphicsDisplay(graphics) graphics.createDescription = lambda: self.graphicsDescription(graphics) yield graphics yield UInt16(self, "op_red", "Red value for graphics mode") yield UInt16(self, "op_green", "Green value for graphics mode") yield UInt16(self, "op_blue", "Blue value for graphics mode")
def createFields(self): yield UInt8(self, "version", "Version") yield NullBits(self, "flags", 24) yield UInt32(self, "track_id") yield NullBits(self, "reserved", 26) yield Bits(self, "length_size_of_traf_num", 2) yield Bits(self, "length_size_of_trun_num", 2) yield Bits(self, "length_size_of_sample_num", 2) yield UInt32(self, "number_of_entry") for i in xrange(self['number_of_entry'].value): if self['version'].value == 1: yield UInt64(self, "time[%i]" % i) yield UInt64(self, "moof_offset[%i]" % i) else: yield UInt32(self, "time[%i]" % i) yield UInt32(self, "moof_offset[%i]" % i) if self['length_size_of_traf_num'].value == 3: yield UInt64(self, "traf_number[%i]" % i) elif self['length_size_of_traf_num'].value == 2: yield UInt32(self, "traf_number[%i]" % i) elif self['length_size_of_traf_num'].value == 1: yield UInt16(self, "traf_number[%i]" % i) else: yield UInt8(self, "traf_number[%i]" % i) if self['length_size_of_trun_num'].value == 3: yield UInt64(self, "trun_number[%i]" % i) elif self['length_size_of_trun_num'].value == 2: yield UInt32(self, "trun_number[%i]" % i) elif self['length_size_of_trun_num'].value == 1: yield UInt16(self, "trun_number[%i]" % i) else: yield UInt8(self, "trun_number[%i]" % i) if self['length_size_of_sample_num'].value == 3: yield UInt64(self, "sample_number[%i]" % i) elif self['length_size_of_sample_num'].value == 2: yield UInt32(self, "sample_number[%i]" % i) elif self['length_size_of_sample_num'].value == 1: yield UInt16(self, "sample_number[%i]" % i) else: yield UInt8(self, "sample_number[%i]" % i)
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 != b"\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 Bits(self, "year", 8) yield Bits(self, "month", 8) yield Bits(self, "day", 8) yield Bits(self, "hour", 8) yield Bits(self, "minute", 8) yield Bits(self, "second", 8) yield Bits(self, "offset", 8)
def createFields(self): yield UInt8(self, "version") yield NullBits(self, "flags", 24) yield NullBits(self, "reserved[]", 24) yield UInt8(self, "field_size", "Size of each entry in this table, in bits") yield UInt32(self, "count", description="Number of samples") bitsize = self['field_size'].value for i in xrange(self['count'].value): yield Bits(self, "sample_size[]", bitsize) if self.current_size % 8 != 0: yield NullBits(self, "padding[]", 8 - (self.current_size % 8))
def createFields(self): dictionary = {} self.nbits = self.startbits CLEAR_CODE = 2 ** self.nbits END_CODE = CLEAR_CODE + 1 compress_code = CLEAR_CODE + 2 obuf = [] output = [] while True: if compress_code >= 2 ** self.nbits: self.nbits += 1 code = Bits(self, "code[]", self.nbits) if code.value == CLEAR_CODE: if compress_code == 2 ** (self.nbits - 1): # this fixes a bizarre edge case where the reset code could # appear just after the bits incremented. Apparently, the # correct behaviour is to express the reset code with the # old number of bits, not the new... code = Bits(self, "code[]", self.nbits - 1) self.nbits = self.startbits + 1 dictionary = {} compress_code = CLEAR_CODE + 2 obuf = [] code._description = "Reset Code (LZW code %i)" % code.value yield code continue elif code.value == END_CODE: code._description = "End of Information Code (LZW code %i)" % code.value yield code break if code.value < CLEAR_CODE: # literal if obuf: chain = obuf + [code.value] dictionary[compress_code] = chain compress_code += 1 obuf = [code.value] output.append(code.value) code._description = "Literal Code %i" % code.value elif code.value >= CLEAR_CODE + 2: if code.value in dictionary: chain = dictionary[code.value] code._description = "Compression Code %i (found in dictionary as %s)" % ( code.value, rle_repr(chain)) else: chain = obuf + [obuf[0]] code._description = "Compression Code %i (not found in dictionary; guessed to be %s)" % ( code.value, rle_repr(chain)) dictionary[compress_code] = obuf + [chain[0]] compress_code += 1 obuf = chain output += chain code._description += "; Current Decoded Length %i" % len(output) yield code padding = paddingSize(self.current_size, 8) if padding: yield NullBits(self, "padding[]", padding)
def createFields(self): yield Bits(self, "sync[]", 2) # =2 if self["sync[0]"].value != 2: raise ParserError("Unknown video elementary data") yield Bits(self, "is_scrambled", 2) yield Bits(self, "priority", 1) yield Bit(self, "alignment") yield Bit(self, "is_copyrighted") yield Bit(self, "is_original") yield Bit(self, "has_pts", "Presentation Time Stamp") yield Bit(self, "has_dts", "Decode Time Stamp") yield Bit(self, "has_escr", "Elementary Stream Clock Reference") yield Bit(self, "has_es_rate", "Elementary Stream rate") yield Bit(self, "dsm_trick_mode") yield Bit(self, "has_copy_info") yield Bit(self, "has_prev_crc", "If True, previous PES packet CRC follows") yield Bit(self, "has_extension") yield UInt8(self, "size") # Time stamps if self["has_pts"].value: yield Bits(self, "sync[]", 4) # =2, or 3 if has_dts=True yield Timestamp(self, "pts") if self["has_dts"].value: if not (self["has_pts"].value): raise ParserError("Invalid PTS/DTS values") yield Bits(self, "sync[]", 4) # =1 yield Timestamp(self, "dts") if self["has_escr"].value: yield Bits(self, "sync[]", 2) # =0 yield SCR(self, "escr") if self["has_es_rate"].value: yield Bit(self, "sync[]") # =True yield Bits(self, "es_rate", 14) # in units of 50 bytes/second yield Bit(self, "sync[]") # =True if self["has_copy_info"].value: yield Bit(self, "sync[]") # =True yield Bits(self, "copy_info", 7) if self["has_prev_crc"].value: yield textHandler(UInt16(self, "prev_crc"), hexadecimal) # --- Extension --- if self["has_extension"].value: yield VideoExtension1(self, "extension") if self["extension/has_extension2"].value: yield VideoExtension2(self, "extension2")
def createFields(self): # This tag has too many variant forms. if '/tags/' in self.path: yield UInt32(self, "count") for i in xrange(self['count'].value): yield METATAG(self, "tag[]") elif self.stream.readBits(self.absolute_address, 32, self.endian) == 0: yield UInt8(self, "version") yield Bits(self, "flags", 24) yield AtomList(self, "tags") else: yield AtomList(self, "tags")
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 Bits(self, "action_id", 8) if not (self["action_id"].value & 128): return yield UInt16(self, "action_length") size = self["action_length"].value if not size: return if self.parser: yield from self.parser(self, size) else: yield RawBytes(self, "action_data", size)
def DecoderConfigDescriptor(self): yield UInt8(self, "objectTypeIndication") yield Bits(self, "streamType", 6) yield Bit(self, "upStream", 1) yield NullBits(self, "reserved", 1) yield UInt24(self, "bufferSizeDB") yield UInt32(self, "maxBitrate") yield UInt32(self, "avgBitrate") # TODO while not self.eof: yield Descriptor(self, "descr[]")
def createFields(self): yield Bits(self, "day", 5) yield Bits(self, "month", 4) yield Bits(self, "year", 7, "Number of year after 1980") yield Bits(self, "second", 5, "Second/2") yield Bits(self, "minute", 6) yield Bits(self, "hour", 5)
def createFields(self): yield UInt16(self, "wIdent", "Magic Number") yield UInt16(self, "nFib", "File Information Block (FIB) Version") yield UInt16(self, "nProduct", "Product Version") yield Enum(UInt16(self, "lid", "Language ID"), LANGUAGE_ID) yield Int16(self, "pnNext") yield Bit(self, "fDot", "Is the document a document template?") yield Bit(self, "fGlsy", "Is the document a glossary?") yield Bit(self, "fComplex", "Is the document in Complex format?") yield Bit(self, "fHasPic", "Does the document have embedded images?") yield Bits(self, "cQuickSaves", 4, "Number of times the document was quick-saved") yield Bit(self, "fEncrypted", "Is the document encrypted?") yield Bits(self, "fWhichTblStm", 1, "Which table stream (0Table or 1Table) to use") yield Bit(self, "fReadOnlyRecommended", "Should the file be opened read-only?") yield Bit(self, "fWriteReservation", "Is the file write-reserved?") yield Bit(self, "fExtChar", "Does the file use an extended character set?") yield Bit(self, "fLoadOverride") yield Bit(self, "fFarEast") yield Bit(self, "fCrypto") yield UInt16(self, "nFibBack", "Document is backwards compatible down to this FIB version") yield UInt32(self, "lKey", "File encryption key (only if fEncrypted)") yield Enum(UInt8(self, "envr", "Document creation environment"), {0: 'Word for Windows', 1: 'Macintosh Word'}) yield Bit(self, "fMac", "Was this file last saved on a Mac?") yield Bit(self, "fEmptySpecial") yield Bit(self, "fLoadOverridePage") yield Bit(self, "fFutureSavedUndo") yield Bit(self, "fWord97Save") yield Bits(self, "fSpare0", 3) CHARSET = {0: 'Windows ANSI', 256: 'Macintosh'} yield Enum(UInt16(self, "chse", "Character set for document text"), CHARSET) yield Enum(UInt16(self, "chsTables", "Character set for internal table text"), CHARSET) yield UInt32(self, "fcMin", "File offset for the first character of text") yield UInt32(self, "fcMax", "File offset for the last character of text + 1") yield ShortArray(self, "array1", "Array of shorts") yield LongArray(self, "array2", "Array of longs") yield FCLCBArray(self, "array3", "Array of File Offset/Byte Count (FC/LCB) pairs")
def createFields(self): field = HuffmanCode(self, "dc_data", self.dc_tree) field._description = "DC Code %i (Huffman Code %i)" % ( field.realvalue, field.value) + field._description yield field if field.realvalue != 0: extra = Bits(self, "dc_data_extra", field.realvalue) if extra.value < 2 ** (field.realvalue - 1): corrected_value = extra.value + (-1 << field.realvalue) + 1 else: corrected_value = extra.value extra._description = "Extra Bits: Corrected DC Value %i" % corrected_value yield extra data = [] while len(data) < 63: field = HuffmanCode(self, "ac_data[]", self.ac_tree) value_r = field.realvalue >> 4 if value_r: data += [0] * value_r value_s = field.realvalue & 0x0F if value_r == value_s == 0: field._description = "AC Code Block Terminator (0, 0) (Huffman Code %i)" % \ field.value + field._description yield field return field._description = "AC Code %i, %i (Huffman Code %i)" % ( value_r, value_s, field.value) + field._description yield field if value_s != 0: extra = Bits(self, "ac_data_extra[%s" % field.name.split('[')[1], value_s) if extra.value < 2 ** (value_s - 1): corrected_value = extra.value + (-1 << value_s) + 1 else: corrected_value = extra.value extra._description = "Extra Bits: Corrected AC Value %i" % corrected_value data.append(corrected_value) yield extra else: data.append(0)
def createFields(self): yield Bits(self, "width", 12) yield Bits(self, "height", 12) yield Enum(Bits(self, "aspect", 4), self.ASPECT) yield Enum(Bits(self, "frame_rate", 4), self.FRAMERATE) yield Bits(self, "bit_rate", 18, "Bit rate in units of 50 bytes") yield Bits(self, "sync[]", 1) # =1 yield Bits(self, "vbv_size", 10, "Video buffer verifier size, in units of 16768") yield Bit(self, "constrained_params_flag") yield Bit(self, "has_intra_quantizer") if self["has_intra_quantizer"].value: for i in range(64): yield Bits(self, "intra_quantizer[]", 8) yield Bit(self, "has_non_intra_quantizer") if self["has_non_intra_quantizer"].value: for i in range(64): yield Bits(self, "non_intra_quantizer[]", 8)
def parseTry(parent, size): yield Bits(parent, "reserved", 5) catchInReg = Bit(parent, "catch_in_register") yield catchInReg yield Bit(parent, "finally") yield Bit(parent, "catch") yield UInt8(parent, "try_size") yield UInt8(parent, "catch_size") yield UInt8(parent, "finally_size") if catchInReg.value: yield CString(parent, "name") else: yield UInt8(parent, "register")
def createFields(self): # http://www.w3.org/Graphics/JPEG/itu-t81.pdf, page 40-41 yield Enum(Bits(self, "table_class", 4, "Table class"), { 0: "DC or Lossless Table", 1: "AC Table" }) yield Bits(self, "index", 4, "Huffman table destination identifier") for i in range(1, 17): yield UInt8(self, "count[%i]" % i, "Number of codes of length %i" % i) lengths = [] remap = {} for i in range(1, 17): for j in range(self["count[%i]" % i].value): field = UInt8(self, "value[%i][%i]" % (i, j), "Value of code #%i of length %i" % (j, i)) yield field remap[len(lengths)] = field.value lengths.append(i) self.tree = {} for i, j in build_tree(lengths).items(): self.tree[i] = remap[j]
def createFields(self): self.osconfig = self.parent.osconfig if True: yield Enum(Bits(self, "type", 12), self.TYPE_NAME) yield Bit(self, "is_vector") yield NullBits(self, "padding", 32 - 12 - 1) else: yield Enum(Bits(self, "type", 32), self.TYPE_NAME) tag = self["type"].value kw = {} try: handler = self.TYPE_INFO[tag][1] if handler in (self.WidePascalString32, PascalString32): cur = self while not hasattr(cur, 'osconfig'): cur = cur.parent if cur is None: raise LookupError('Cannot find osconfig') osconfig = cur.osconfig if tag == self.TYPE_LPSTR: kw["charset"] = osconfig.charset else: kw["charset"] = osconfig.utf16 elif handler == TimestampWin64: if self.description == "TotalEditingTime": handler = TimedeltaWin64 except LookupError: handler = None if not handler: self.warning("OLE2: Unable to parse property of type %s" % self["type"].display) # raise ParserError( elif self["is_vector"].value: yield UInt32(self, "count") for index in range(self["count"].value): yield handler(self, "item[]", **kw) else: yield handler(self, "value", **kw) self.createValue = lambda: self["value"].value
def createFields(self): for i in xrange(20): yield Bits(self, "pretree_lengths[]", 4) pre_tree = build_tree([self['pretree_lengths[%d]' % x].value for x in xrange(20)]) if not hasattr(self.root, "lzx_tree_lengths_" + self.name): self.lengths = [0] * self.num_elements setattr(self.root, "lzx_tree_lengths_" + self.name, self.lengths) else: self.lengths = getattr(self.root, "lzx_tree_lengths_" + self.name) i = 0 while i < self.num_elements: field = HuffmanCode(self, "tree_code[]", pre_tree) if field.realvalue <= 16: self.lengths[i] = (self.lengths[i] - field.realvalue) % 17 field._description = "Literal tree delta length %i (new length value %i for element %i)" % ( field.realvalue, self.lengths[i], i) i += 1 yield field elif field.realvalue == 17: field._description = "Tree Code 17: Zeros for 4-19 elements" yield field extra = Bits(self, "extra[]", 4) zeros = 4 + extra.value extra._description = "Extra bits: zeros for %i elements (elements %i through %i)" % ( zeros, i, i + zeros - 1) yield extra self.lengths[i:i + zeros] = [0] * zeros i += zeros elif field.realvalue == 18: field._description = "Tree Code 18: Zeros for 20-51 elements" yield field extra = Bits(self, "extra[]", 5) zeros = 20 + extra.value extra._description = "Extra bits: zeros for %i elements (elements %i through %i)" % ( zeros, i, i + zeros - 1) yield extra self.lengths[i:i + zeros] = [0] * zeros i += zeros elif field.realvalue == 19: field._description = "Tree Code 19: Same code for 4-5 elements" yield field extra = Bits(self, "extra[]", 1) run = 4 + extra.value extra._description = "Extra bits: run for %i elements (elements %i through %i)" % (run, i, i + run - 1) yield extra newfield = HuffmanCode(self, "tree_code[]", pre_tree) assert newfield.realvalue <= 16 newfield._description = "Literal tree delta length %i (new length value %i for elements %i through %i)" % ( newfield.realvalue, self.lengths[i], i, i + run - 1) self.lengths[i:i + run] = [(self.lengths[i] - newfield.realvalue) % 17] * run i += run yield newfield
def __init__(self, parent, name, nbits, description="Padding", pattern=None): Bits.__init__(self, parent, name, nbits, description) self.pattern = pattern self._display_pattern = self.checkPattern()
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): 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)
def __init__(self, parent, name, description=None): Bits.__init__(self, parent, name, 32, description)
def __init__(self, parent, name, size, description=None): Bits.__init__(self, parent, name, size, None) self.desc = description
def createDisplay(self): if self._display_pattern: return u"<padding pattern=%s>" % self.pattern else: return Bits.createDisplay(self)
def __init__(self, parent, name): Bits.__init__(self, parent, name, 4)
def createDisplay(self): if self._display_pattern: return "<null>" else: return Bits.createDisplay(self)
def createValue(self): return Bits.createValue(self) - self.bias
def __init__(self, parent, name, signed, size, description=None): if not (8 <= size <= 16384): raise FieldError("Invalid integer size (%s): have to be in 8..16384" % size) Bits.__init__(self, parent, name, size, description) self.signed = signed
def createRawDisplay(self): value = Bits.createValue(self) return unicode(value)
def createValue(self): value = Bits.createValue(self) return 1 + float(value) / (2 ** self.size)
def __init__(self, parent, name, description=None): Bits.__init__(self, parent, name, self.static_size, description=description)
def createRawDisplay(self): return unicode(Bits.createValue(self))
def createValue(self): value = Bits.createValue(self) return durationWin64(value)
def __nonzero__(self): return Bits.createValue(self) != 0
def __init__(self, parent, name, size): Bits.__init__(self, parent, name, size) self.bias = 2 ** (size - 1) - 1
def createValue(self): value = Bits.createValue(self) return handler(value)