def createFields(self): yield ABCMultinameIndex(self, "name_index") yield Enum(Bits(self, "kind", 4), self.TRAIT_KIND) yield Enum(Bit(self, "is_final"), {True: 'final', False: 'virtual'}) yield Enum(Bit(self, "is_override"), {True: 'override', False: 'new'}) yield Bit(self, "has_metadata") yield Bits(self, "unused", 1) kind = self["kind"].value if kind in (0, 6): # slot, const yield FlashU30(self, "slot_id") yield ABCMultinameIndex(self, "type_index") # TODO reference appropriate constant pool using value_kind yield FlashU30(self, "value_index") if self['value_index'].value != 0: yield UInt8(self, "value_kind") elif kind in (1, 2, 3): # method, getter, setter yield FlashU30(self, "disp_id") yield ABCMethodIndex(self, "method_info") elif kind == 4: # class yield FlashU30(self, "disp_id") yield FlashU30(self, "class_info") elif kind == 5: # function yield FlashU30(self, "disp_id") yield ABCMethodIndex(self, "method_info") if self['has_metadata'].value: yield ABCObjectArray(self, "metadata", FlashU30)
def createFields(self): yield Bit(self, "has_private") yield Bit(self, "has_pack_lgth") yield Bit(self, "has_pack_seq") yield Bit(self, "has_pstd_buffer") yield Bits(self, "sync[]", 3) # =7 yield Bit(self, "has_extension2") if self["has_private"].value: yield RawBytes(self, "private", 16) if self["has_pack_lgth"].value: yield UInt8(self, "pack_lgth") if self["has_pack_seq"].value: yield Bit(self, "sync[]") # =True yield Bits(self, "pack_seq_counter", 7) yield Bit(self, "sync[]") # =True yield Bit(self, "mpeg12_id") yield Bits(self, "orig_stuffing_length", 6) if self["has_pstd_buffer"].value: yield Bits(self, "sync[]", 2) # =1 yield Enum(Bit(self, "pstd_buffer_scale"), {True: "128 bytes", False: "1024 bytes"}) yield Bits(self, "pstd_size", 13)
def createFields(self): yield Bits(self, "version", 4, "Version") yield Bits(self, "hdr_size", 4, "Header size divided by 5") # Type of service yield Enum(Bits(self, "precedence", 3, "Precedence"), self.precedence_name) yield Bit(self, "low_delay", "If set, low delay, else normal delay") yield Bit(self, "high_throu", "If set, high throughput, else normal throughput") yield Bit(self, "high_rel", "If set, high relibility, else normal") yield NullBits(self, "reserved[]", 2, "(reserved for future use)") yield UInt16(self, "length") yield UInt16(self, "id") yield NullBits(self, "reserved[]", 1) yield Bit(self, "df", "Don't fragment") yield Bit(self, "more_frag", "There are more fragments? if not set, it's the last one") yield Bits(self, "frag_ofst_lo", 5) yield UInt8(self, "frag_ofst_hi") yield UInt8(self, "ttl", "Type to live") yield Enum(UInt8(self, "protocol"), self.PROTOCOL_NAME) yield textHandler(UInt16(self, "checksum"), hexadecimal) yield IPv4_Address(self, "src") yield IPv4_Address(self, "dst") size = (self.size - self.current_size) // 8 if size: yield RawBytes(self, "options", size)
def createFields(self): if self._m2ts: yield Bits(self, "c", 2) yield Bits(self, "ats", 32 - 2) yield textHandler(UInt8(self, "sync", 8), hexadecimal) if self["sync"].value != 0x47: raise ParserError("MPEG-2 TS: Invalid synchronization byte") yield Bit(self, "has_error") yield Bit(self, "payload_unit_start") yield Bit(self, "priority") yield Enum( textHandler(Bits(self, "pid", 13, "Program identifier"), hexadecimal), self.PID) yield Bits(self, "scrambling_control", 2) yield Bit(self, "has_adaptation") yield Bit(self, "has_payload") yield Bits(self, "counter", 4) if self["has_adaptation"].value: yield AdaptationField(self, "adaptation_field") if self["has_payload"].value: size = 188 if self._m2ts: size += 4 size -= (self.current_size // 8) yield RawBytes(self, "payload", size) if self["has_error"].value: yield RawBytes(self, "error_correction", 16)
def createFields(self): # Need the compression info from the parent, and that is the byte # following method = self.stream.readBits( self.absolute_address + 16, 16, LITTLE_ENDIAN) yield Bit(self, "is_encrypted", "File is encrypted?") if method == 6: yield Bit(self, "use_8k_sliding", "Use 8K sliding dictionary (instead of 4K)") yield Bit(self, "use_3shannon", "Use a 3 Shannon-Fano tree (instead of 2 Shannon-Fano)") elif method in (8, 9): NAME = { 0: "Normal compression", 1: "Maximum compression", 2: "Fast compression", 3: "Super Fast compression" } yield Enum(Bits(self, "method", 2), NAME) elif method == 14: # LZMA yield Bit(self, "lzma_eos", "LZMA stream is ended with a EndOfStream marker") yield Bit(self, "unused[]") else: yield Bits(self, "compression_info", 2) yield Bit(self, "has_descriptor", "Compressed data followed by descriptor?") yield Bit(self, "enhanced_deflate", "Reserved for use with method 8") yield Bit(self, "is_patched", "File is compressed with patched data?") yield Bit(self, "strong_encrypt", "Strong encryption (version >= 50)") yield Bits(self, "unused[]", 4, "Unused") yield Bit(self, "uses_unicode", "Filename and comments are in UTF-8") yield Bit(self, "incomplete", "Reserved by PKWARE for enhanced compression.") yield Bit(self, "encrypted_central_dir", "Selected data values in the Local Header are masked") yield Bits(self, "unused[]", 2, "Unused")
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): # CM yield Enum(Bits(self, "compression_method", 4), { 8: "deflate", 15: "reserved" }) # CINFO yield Bits(self, "compression_info", 4, "base-2 log of the window size") yield Bits(self, "flag_check_bits", 5) # FCHECK yield Bit(self, "flag_dictionary_present") # FDICT yield Enum( Bits(self, "flag_compression_level", 2), # FLEVEL { 0: "Fastest", 1: "Fast", 2: "Default", 3: "Maximum, Slowest" }) if self["flag_dictionary_present"].value: yield textHandler( UInt32(self, "dict_checksum", "ADLER32 checksum of dictionary information"), hexadecimal) yield DeflateData(self, "data", self.stream, description="Compressed Data") yield textHandler( UInt32(self, "data_checksum", "ADLER32 checksum of compressed data"), hexadecimal)
def createFields(self): yield Bits(self, "version", 4) yield Bits(self, "instance", 12) yield Enum(UInt16(self, "type"), PowerPointDocument.OBJ_TYPES) yield UInt32(self, "length") self._size = self["length"].value * 8 + 64 obj_type = self["type"].display obj_len = self["length"].value # type 1064 (RoundTripCustomTableStyles12) may appear to be a # container, but it is not. if self["version"].value == 0xF and self["type"].value != 1064: while (self.current_size) // 8 < obj_len + 8: yield PowerPointDocument.PowerPointObject(self, "object[]") elif obj_len: if obj_type == "FontEntityAtom": yield String(self, "data", obj_len, charset="UTF-16-LE", truncate="\0", strip="\0") elif obj_type == "TextCharsAtom": yield String(self, "data", obj_len, charset="UTF-16-LE") elif obj_type == "TextBytesAtom": yield String(self, "data", obj_len, charset="ASCII") elif hasattr(PowerPointDocument, obj_type): field = getattr(PowerPointDocument, obj_type)(self, "data") field._size = obj_len * 8 yield field else: yield RawBytes(self, "data", obj_len)
def createFields(self): yield Bits(self, "ts_32_30", 3) yield Bit(self, "sync[]") # =True yield Bits(self, "ts_29_15", 15) yield Bit(self, "sync[]") # =True yield Bits(self, "ts_14_0", 15) yield Bit(self, "sync[]") # =True
def createFields(self): yield Bits(self, "unused", 2) yield Bit(self, "is_tonable") yield Bit(self, "16bits") yield Bit(self, "loop_bidir") yield Bit(self, "loop") yield Enum(Bits(self, "origin", 2), self.TYPES)
def createFields(self): yield UInt8(self, "length") yield Bit(self, "discontinuity_indicator") yield Bit(self, "random_access_indicator") yield Bit(self, "es_prio_indicator") yield Bit(self, "has_pcr") yield Bit(self, "has_opcr") yield Bit(self, "has_splice_point") yield Bit(self, "private_data") yield Bit(self, "has_extension") if self['has_pcr'].value: yield Bits(self, "pcr_base", 33) yield Bits(self, "pcr_ext", 9) if self['has_opcr'].value: yield Bits(self, "opcr_base", 33) yield Bits(self, "opcr_ext", 9) if self['has_splice_point'].value: yield Bits(self, "splice_countdown", 8) stuff_len = ((self['length'].value + 1) * 8) - self.current_size if self['length'].value and stuff_len: yield RawBits(self, 'stuffing', stuff_len)
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): padding = 0 position = 0 streamlength = self["../length"].value while position < streamlength * 8: 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, "sync", 14, "Sync code: 11111111111110") yield Bit(self, "reserved[]") yield Bit(self, "blocking_strategy") yield Bits(self, "block_size", 4) yield Enum(Bits(self, "sample_rate", 4), self.SAMPLE_RATES) yield Bits(self, "channel_assign", 4) yield Bits(self, "sample_size", 3) yield Bit(self, "reserved[]")
def createFields(self): yield Bit(self, "readonly") yield Bit(self, "hidden") yield Bit(self, "system") yield Bits(self, "reserved[]", 2) yield Bit(self, "archive", "Has the file been modified since the last backup?") yield Bit(self, "exec", "Run file after extraction?") yield Bit(self, "name_is_utf", "Is the filename using UTF-8?") yield Bits(self, "reserved[]", 8)
def createFields(self): comp_id = UInt8(self, "component_id") yield comp_id if not (1 <= comp_id.value <= self["../nr_components"].value): raise ParserError("JPEG error: Invalid component-id") yield Bits(self, "dc_coding_table", 4, "DC entropy coding table destination selector") yield Bits(self, "ac_coding_table", 4, "AC entropy coding table destination selector")
def createFields(self): yield textHandler(Bits(self, "unused[]", 8, "Unused flag bits"), hexadecimal) yield Bit(self, "has_added_size", "Additional field indicating additional size") yield Bit( self, "is_ignorable", "Old versions of RAR should ignore this block when copying data") yield Bits(self, "unused[]", 6)
def createFields(self): yield Bits(self, "scr_32_30", 3) yield Bit(self, "sync[]") # =True yield Bits(self, "scr_29_15", 15) yield Bit(self, "sync[]") # =True yield Bits(self, "scr_14_0", 15) yield Bit(self, "sync[]") # =True yield Bits(self, "scr_ext", 9) yield Bit(self, "sync[]") # =True
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): for i in range(20): yield Bits(self, "pretree_lengths[]", 4) pre_tree = build_tree( [self['pretree_lengths[%d]' % x].value for x in range(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 parseVorbisHeader(parent): yield UInt32(parent, "vorbis_version") yield UInt8(parent, "audio_channels") yield UInt32(parent, "audio_sample_rate") yield UInt32(parent, "bitrate_maximum") yield UInt32(parent, "bitrate_nominal") yield UInt32(parent, "bitrate_minimum") yield Bits(parent, "blocksize_0", 4) yield Bits(parent, "blocksize_1", 4) yield UInt8(parent, "framing_flag")
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 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 Bits(self, "nbits", 5) nbits = self["nbits"].value if not nbits: raise ParserError("SWF parser: Invalid RECT field size (0)") yield Bits(self, "xmin", nbits, "X minimum in twips") yield Bits(self, "xmax", nbits, "X maximum in twips") yield Bits(self, "ymin", nbits, "Y minimum in twips") yield Bits(self, "ymax", nbits, "Y maximum in twips") size = paddingSize(self.current_size, 8) if size: yield NullBits(self, "padding", size)
def createFields(self): header = UInt8(self, "header") yield header if header.value == 0: return offlen = header.value >> 4 lenlen = header.value & 0xf if lenlen: yield Bits(self, "length", lenlen * 8) if offlen: yield Bits(self, "offset", offlen * 8)
def parseAudio(parent, size): yield Enum(Bits(parent, "codec", 4, "Audio codec"), AUDIO_CODEC_NAME) yield Enum(Bits(parent, "sampling_rate", 2, "Sampling rate"), SAMPLING_RATE_TEXT) yield Bit(parent, "is_16bit", "16-bit or 8-bit per sample") yield Bit(parent, "is_stereo", "Stereo or mono channel") size -= 1 if 0 < size: if parent["codec"].value == AUDIO_CODEC_MP3: yield Frame(parent, "music_data", size=size * 8) else: yield RawBytes(parent, "music_data", size)
def createFields(self): yield UInt8(self, "nr_components") for index in range(self["nr_components"].value): yield SOSComponent(self, "component[]") yield UInt8(self, "spectral_start", "Start of spectral or predictor selection") yield UInt8(self, "spectral_end", "End of spectral selection") yield Bits(self, "bit_pos_high", 4, "Successive approximation bit position high") yield Bits( self, "bit_pos_low", 4, "Successive approximation bit position low or point transform")
def parseSMPTEOffset(parser, size): yield RawBits(parser, "padding", 1) yield Enum(Bits(parser, "frame_rate", 2), { 0: "24 fps", 1: "25 fps", 2: "30 fps (drop frame)", 3: "30 fps" }) yield Bits(parser, "hour", 5) yield UInt8(parser, "minute") yield UInt8(parser, "second") yield UInt8(parser, "frame") yield UInt8(parser, "subframe", "100 subframes per frame")
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): # Code based on function get_dqt() (jdmarker.c from libjpeg62) yield Bits(self, "is_16bit", 4) yield Bits(self, "index", 4) if self["index"].value >= 4: raise ParserError("Invalid quantification index (%s)" % self["index"].value) if self["is_16bit"].value: coeff_type = UInt16 else: coeff_type = UInt8 for index in range(64): natural = JPEG_NATURAL_ORDER[index] yield coeff_type(self, "coeff[%u]" % natural)