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 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 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 Bytes(self, "header", 4, r"PE header signature (PE\0\0)") if self["header"].value != b"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): 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) if group is None: field.group.args["compr_level"] = self.parent.folder["compr_level"].value self.parent.folder.lzx_group = field.group yield field
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): 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 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): 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 Bit(self, "dir_prealloc", "Directory preallocation") yield Bit(self, "imagic_inodes", "imagic inodes - use unclear") yield Bit(self, "has_journal", "Has a journal") yield Bit(self, "ext_attr", "Supports extended attributes") yield Bit(self, "resize_inode", "Has reserved GDT blocks for FS expansion") yield Bit(self, "dir_index", "Has directory indices") yield Bit(self, "lazy_bg", "Lazy block groups (not used by Linux)") yield Bit(self, "exclude_inode", "Exclude inode (deprecated)") yield Bit(self, "exclude_bitmap", "Exclude bitmap (unused)") yield Bit(self, "sparse_super2", "Sparse Super Block v2") yield PaddingBits(self, "reserved[]", 22)
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 # align on byte boundary padding = paddingSize(self.current_size + self.absolute_address, 8) 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 TimedeltaMillisWin64(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): if self.stream.readBits(self.absolute_address, 2, self.endian) == 1: # MPEG version 2 yield Bits(self, "sync[]", 2) yield SCRExt(self, "scr") 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 Timestamp(self, "scr") yield Bit(self, "sync[]") yield Bits(self, "mux_rate", 22) yield Bit(self, "sync[]")
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 Bit(self, "compression", "Compression") yield Bit(self, "filetype", "Directory entries record file type") yield Bit(self, "recover", "FS needs recovery") yield Bit(self, "journal_dev", "FS has a separate journal device") yield Bit(self, "meta_bg", "Meta block groups") yield Bit(self, "reserved[]") yield Bit(self, "extents", "Files use extents") yield Bit(self, "64bit", "FS can have up to 2^64 blocks") yield Bit(self, "mmp", "Multiple mount protection") yield Bit(self, "flex_bg", "Flexible block groups") yield Bit(self, "ea_inode", "Inodes can be used for large xattrs") yield Bit(self, "reserved[]") yield Bit(self, "dirdata", "Data in directory entry") yield Bit(self, "csum_seed", "Metadata checksum seed in the superblock") yield Bit(self, "largedir", "Large directory >2GB, or 3-level htree") yield Bit(self, "inline_data", "Data in inode") yield Bit(self, "encrypt", "Encrypted inodes present") yield PaddingBits(self, "reserved[]", 15)
def createFields(self): yield Bit(self, "sparse_super", "Sparse superblocks") yield Bit(self, "large_file", "The FS has been used to store a file >2GiB") yield Bit(self, "btree_dir") yield Bit( self, "huge_file", "The FS has files whose sizes are in units of logical blocks") yield Bit(self, "gdt_csum", "Group descriptors have checksums") yield Bit(self, "dir_nlink", "ext3 32k subdir limit does not apply") yield Bit(self, "extra_isize", "FS has large inodes") yield Bit(self, "has_snapshot", "FS has a snapshot") yield Bit(self, "quota", "FS has quotas") yield Bit( self, "bigalloc", "FS supports allocating extents in units of clusters (fragments)") yield Bit(self, "metadata_csum", "FS supports metadata checksums") yield Bit(self, "replica", "FS supports replicas") yield Bit(self, "readonly", "FS is readonly") yield PaddingBits(self, "reserved[]", 19)
def createFields(self): yield Bit(self, "debug", "Print debug info upon mount") yield Bit(self, "bsdgroups", "New files take the gid of the containing dir") yield Bit(self, "xattr_user", "Support userspace-provided xattrs") yield Bit(self, "acl", "Support POSIX access control lists") yield Bit(self, "uid16", "Do not support 32-bit UIDs") yield Enum(Bits(self, "jmode", 2, "Journaling mode"), { 0: "none", 1: "data", 2: "ordered", 3: "wback" }) yield Bit(self, "reserved[]") yield Bit(self, "nobarrier", "Disable write flushes") yield Bit( self, "block_validity", "Track metadata blocks to avoid treating them as data blocks") yield Bit(self, "discard", "Tell the storage device when blocks become unused") yield Bit(self, "nodelalloc", "Disable delayed allocation") yield PaddingBits(self, "reserved[]", 20)
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, "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 range(8): yield Bits(self, "aligned_len[]", 3) aligned_tree = build_tree( [self['aligned_len[%d]' % i].value for i in range(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 createFields(self): yield Bit(self, "inode_uninit", "inode table and bitmap are not initialized") yield Bit(self, "block_uninit", "block bitmap is not initialized") yield Bit(self, "inode_zeroed", "inode table is zeroed") yield PaddingBits(self, "reserved[]", 13)
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 # align on byte boundary padding = paddingSize(self.current_size + self.absolute_address, 8) if padding: yield PaddingBits(self, "padding[]", padding) yield Int16(self, "len") yield Int16(self, "nlen", "One's complement of len") if self["len"].value != ~self["nlen"].value: raise ParserError( "len must be equal to the one's complement of nlen!") # null stored blocks produced by some encoders (e.g. PIL) if self["len"].value: yield RawBytes(self, "data", self["len"].value, "Uncompressed data") return elif self["compression_type"].value == 1: # Fixed Huffman length_tree = {} # (size, huffman code): value distance_tree = {} for i in range(144): length_tree[(8, i + 48)] = i for i in range(144, 256): length_tree[(9, i + 256)] = i for i in range(256, 280): length_tree[(7, i - 256)] = i for i in range(280, 288): length_tree[(8, i - 88)] = i for i in range(32): distance_tree[(5, i)] = i elif self["compression_type"].value == 2: # Dynamic Huffman yield Bits(self, "huff_num_length_codes", 5, "Number of Literal/Length Codes, minus 257") yield Bits(self, "huff_num_distance_codes", 5, "Number of Distance Codes, minus 1") yield Bits(self, "huff_num_code_length_codes", 4, "Number of Code Length Codes, minus 4") code_length_code_lengths = [0] * 19 # confusing variable name... for i in self.CODE_LENGTH_ORDER[:self["huff_num_code_length_codes"] .value + 4]: field = Bits(self, "huff_code_length_code[%i]" % i, 3, "Code lengths for the code length alphabet") yield field code_length_code_lengths[i] = field.value code_length_tree = build_tree(code_length_code_lengths) length_code_lengths = [] distance_code_lengths = [] for numcodes, name, lengths in ( (self["huff_num_length_codes"].value + 257, "length", length_code_lengths), (self["huff_num_distance_codes"].value + 1, "distance", distance_code_lengths)): while len(lengths) < numcodes: field = HuffmanCode(self, "huff_%s_code[]" % name, code_length_tree) value = field.realvalue if value < 16: prev_value = value field._description = "Literal Code Length %i (Huffman Code %i)" % ( value, field.value) yield field lengths.append(value) else: info = { 16: (3, 6, 2), 17: (3, 10, 3), 18: (11, 138, 7) }[value] if value == 16: repvalue = prev_value else: repvalue = 0 field._description = "Repeat Code %i, Repeating value (%i) %i to %i times (Huffman Code %i)" % ( value, repvalue, info[0], info[1], field.value) yield field extrafield = Bits( self, "huff_%s_code_extra[%s" % (name, field.name.split('[')[1]), info[2]) num_repeats = extrafield.value + info[0] extrafield._description = "Repeat Extra Bits (%i), total repeats %i" % ( extrafield.value, num_repeats) yield extrafield lengths += [repvalue] * num_repeats length_tree = build_tree(length_code_lengths) distance_tree = build_tree(distance_code_lengths) else: raise ParserError("Unsupported compression type 3!") while True: field = HuffmanCode(self, "length_code[]", length_tree) value = field.realvalue if value < 256: field._description = "Literal Code %r (Huffman Code %i)" % ( chr(value), field.value) yield field self.uncomp_data += chr(value) if value == 256: field._description = "Block Terminator Code (256) (Huffman Code %i)" % field.value yield field break elif value > 256: info = self.LENGTH_SYMBOLS[value] if info[2] == 0: field._description = "Length Code %i, Value %i (Huffman Code %i)" % ( value, info[0], field.value) length = info[0] yield field else: field._description = "Length Code %i, Values %i to %i (Huffman Code %i)" % ( value, info[0], info[1], field.value) yield field extrafield = Bits( self, "length_extra[%s" % field.name.split('[')[1], info[2]) length = extrafield.value + info[0] extrafield._description = "Length Extra Bits (%i), total length %i" % ( extrafield.value, length) yield extrafield field = HuffmanCode(self, "distance_code[]", distance_tree) value = field.realvalue info = self.DISTANCE_SYMBOLS[value] if info[2] == 0: field._description = "Distance Code %i, Value %i (Huffman Code %i)" % ( value, info[0], field.value) distance = info[0] yield field else: field._description = "Distance Code %i, Values %i to %i (Huffman Code %i)" % ( value, info[0], info[1], field.value) yield field extrafield = Bits( self, "distance_extra[%s" % field.name.split('[')[1], info[2]) distance = extrafield.value + info[0] extrafield._description = "Distance Extra Bits (%i), total length %i" % ( extrafield.value, distance) yield extrafield self.uncomp_data = extend_data(self.uncomp_data, length, distance)
def createFields(self): 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 == b'\xFF': next_byte = self.stream.readBytes( self.absolute_address + self.current_size, 1) if next_byte != b'\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): 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): 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, "stream_index", 7) yield PaddingBits(self, "reserved", 9) yield displayHandler(UInt32(self, "avg_bitrate"), humanBitRate)