def createFields(self): yield String(self, "header_id", 4, "DataBase Header Markup (\"mhbd\")", charset="ISO-8859-1") yield UInt32(self, "header_length", "Header Length") yield UInt32(self, "entry_length", "Entry Length") yield UInt32(self, "unknown[]") yield UInt32(self, "version_number", "Version Number") yield UInt32(self, "child_number", "Number of Children") yield UInt64(self, "id", "ID for this database") yield UInt16(self, "unknown[]") yield UInt32(self, "unknown[]") yield UInt64(self, "unknown[]") yield UInt16(self, "unknown[]") yield UInt16(self, "hashing_scheme[]", "Algorithm used to calculate the database hash") yield NullBytes(self, "unknown[]", 20) yield String(self, "language_id", 2, "Language ID") yield UInt64(self, "persistent_id", "Library Persistent ID") yield UInt32(self, "unknown[]") yield UInt32(self, "unknown[]") yield RawBytes(self, "hash[]", 20) yield Int32(self, "timezone_offset[]", "Timezone offset in seconds") yield UInt16(self, "unknown[]") yield RawBytes(self, "iphone_hash[]", 45) size = self["header_length"].value - self.current_size / 8 if size > 0: yield NullBytes(self, "padding", size) for i in range(self["child_number"].value): yield DataSet(self, "dataset[]") padding = self.seekByte(self["entry_length"].value, "entry padding") if padding: yield padding
def createFields(self): yield Bytes(self, "magic", 8, "File magic (BOMStore)") yield UInt32(self, "version") # ? yield UInt32(self, "num_objects") yield UInt32(self, "trailer_offset") yield UInt32(self, "trailer_size") yield UInt32(self, "header_offset") yield UInt32(self, "header_size") yield RawBytes(self, "object[]", 512 - 32, "Null object (size 0, offset 0)") self.seekByte(self['trailer_offset'].value) yield BomTrailer(self, "trailer") self.seekByte(self['header_offset'].value) yield RawBytes(self, "header", self['header_size'].value) for entry in self['trailer'].array('entry'): if entry['size'].value == 0: continue self.seekByte(entry['offset'].value) yield RawBytes(self, "object[]", entry['size'].value) for entry in self['trailer'].array('trail'): self.seekByte(entry['offset'].value) yield RawBytes(self, "trail[]", entry['size'].value)
def createFields(self): yield RawBytes(self, "identifier", 4, "some kind of marker (A0461DF0)") yield UInt32(self, "size") yield RawBytes(self, "unknown[]", 16) yield RawBytes(self, "unknown[]", 1) yield SubFile(self, "image", self["size"].value - 17, "Image Data")
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): 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 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): yield String(self, "signature", 4, "PSD signature (8BPS)", charset="ASCII") yield UInt16(self, "version") yield NullBytes(self, "reserved[]", 6) yield UInt16(self, "nb_channels") yield UInt32(self, "width") yield UInt32(self, "height") yield UInt16(self, "depth") yield Enum(UInt16(self, "color_mode"), self.COLOR_MODE) # Mode data yield UInt32(self, "mode_data_size") size = self["mode_data_size"].value if size: yield RawBytes(self, "mode_data", size) # Resources yield Config(self, "config") # Reserved yield UInt32(self, "reserved_data_size") size = self["reserved_data_size"].value if size: yield RawBytes(self, "reserved_data", size) yield Enum(UInt16(self, "compression"), self.COMPRESSION_NAME) size = (self.size - self.current_size) // 8 if size: yield RawBytes(self, "end", size)
def createFields(self): # Header yield Header(self, "header") # Secure Area if self["header"]["arm9_source"].value >= 0x4000 and self["header"][ "arm9_source"].value < 0x8000: secStart = self["header"]["arm9_source"].value & 0xfffff000 self.seekByte(secStart, relative=False) yield SecureArea(self, "secure_area", size=0x8000 - secStart) # ARM9 binary self.seekByte(self["header"]["arm9_source"].value, relative=False) yield RawBytes(self, "arm9_bin", self["header"]["arm9_bin_size"].value) # ARM7 binary self.seekByte(self["header"]["arm7_source"].value, relative=False) yield RawBytes(self, "arm7_bin", self["header"]["arm7_bin_size"].value) # File Name Table if self["header"]["filename_table_size"].value > 0: self.seekByte(self["header"]["filename_table_offset"].value, relative=False) yield FileNameTable( self, "filename_table", size=self["header"]["filename_table_size"].value * 8) # FAT if self["header"]["fat_size"].value > 0: self.seekByte(self["header"]["fat_offset"].value, relative=False) yield FATContent(self, "fat_content", size=self["header"]["fat_size"].value * 8) # banner if self["header"]["banner_offset"].value > 0: self.seekByte(self["header"]["banner_offset"].value, relative=False) yield Banner(self, "banner") # ARM9 overlays if self["header"]["arm9_overlay_src"].value > 0: self.seekByte(self["header"]["arm9_overlay_src"].value, relative=False) numOvls = self["header"]["arm9_overlay_size"].value // (8 * 4) for i in range(numOvls): yield Overlay(self, "arm9_overlay[]") # files if self["header"]["fat_size"].value > 0: for field in self["fat_content"]: if field["end"].value > field["start"].value: self.seekByte(field["start"].value, relative=False) yield SubFile(self, "file[]", field["end"].value - field["start"].value)
def parseEBML(self): yield Unsigned(self, 'size') for i in range(1, self.n_frames): yield Signed(self, 'dsize[]') size = self['size'].value yield RawBytes(self, 'frame[]', size) for i in range(self.n_frames - 1): size += self['dsize[' + str(i) + ']'].value yield RawBytes(self, 'frame[]', size) yield RawBytes(self, 'frame[]', (self._size - self.current_size) // 8)
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): yield String(self, "magic", 4, "Signature (BLP1)") yield Enum(UInt32(self, "compression"), { 0: "JPEG Compression", 1: "Uncompressed" }) yield UInt32(self, "flags") yield UInt32(self, "width") yield UInt32(self, "height") yield Enum( UInt32(self, "type"), { 3: "Uncompressed Index List + Alpha List", 4: "Uncompressed Index List + Alpha List", 5: "Uncompressed Index List" }) yield UInt32(self, "subtype") for i in range(16): yield UInt32(self, "mipmap_offset[]") for i in range(16): yield UInt32(self, "mipmap_size[]") compression = self["compression"].value image_type = self["type"].value width = self["width"].value height = self["height"].value if compression == 0: # JPEG Compression yield UInt32(self, "jpeg_header_len") yield RawBytes(self, "jpeg_header", self["jpeg_header_len"].value, "Shared JPEG Header") else: yield PaletteRGBA(self, "palette", 256) offsets = self.array("mipmap_offset") sizes = self.array("mipmap_size") for i in range(16): if not offsets[i].value or not sizes[i].value: continue padding = self.seekByte(offsets[i].value) if padding: yield padding if compression == 0: yield RawBytes( self, "mipmap[%i]" % i, sizes[i].value, "JPEG data, append to header to recover complete image") elif compression == 1: yield Generic2DArray(self, "mipmap_indexes[%i]" % i, width, height, PaletteIndex, "row", "index", "Indexes into the palette") if image_type in (3, 4): yield Generic2DArray(self, "mipmap_alphas[%i]" % i, width, height, UInt8, "row", "alpha", "Alpha values") width /= 2 height /= 2
def createFields(self): yield textHandler(UInt64(self, "id"), hexadecimal) if self["id"].value == 0xe7ffdeffe7ffdeff: # indicates that secure area is decrypted yield Bytes(self, "fixed[]", 6) # always \xff\xde\xff\xe7\xff\xde yield Crc16( self, "header_crc16", self.stream.readBytes(self.absolute_address + (16 * 8), 2048 - 16)) yield RawBytes(self, "unknown[]", 2048 - 16 - 2) yield Bytes(self, "fixed[]", 2) # always \0\0 else: yield RawBytes(self, "encrypted[]", 2048 - 8)
def createFields(self): yield Enum(UInt8(self, "type", "Volume descriptor type"), self.type_name) yield RawBytes(self, "signature", 5, "ISO 9960 signature (CD001)") if self["signature"].value != b"CD001": raise ParserError("Invalid ISO 9960 volume signature") yield UInt8(self, "version", "Volume descriptor version") cls = self.content_handler.get(self["type"].value, None) if cls: yield cls(self, "content") else: yield RawBytes(self, "raw_content", 2048 - 7)
def createFields(self): yield Bytes(self, "signature", 4, "Usually the magic is 'FILE'") yield UInt16(self, "usa_offset", "Update Sequence Array offset") yield UInt16(self, "usa_count", "Update Sequence Array count") yield UInt64(self, "lsn", "$LogFile sequence number for this record") yield UInt16(self, "sequence_number", "Number of times this mft record has been reused") yield UInt16(self, "link_count", "Number of hard links") yield UInt16(self, "attrs_offset", "Byte offset to the first attribute") yield MFT_Flags(self, "flags") yield UInt32(self, "bytes_in_use", "Number of bytes used in this record") yield UInt32(self, "bytes_allocated", "Number of bytes allocated for this record") yield UInt64(self, "base_mft_record") yield UInt16(self, "next_attr_instance") # The below fields are specific to NTFS 3.1+ (Windows XP and above) yield NullBytes(self, "reserved", 2) yield UInt32(self, "mft_record_number", "Number of this mft record") if self["usa_offset"].value: padding = self.seekByte(self["usa_offset"].value, relative=True) if padding: yield padding yield UInt16(self, "usa_number") for i in range(self["usa_count"].value): yield UInt16(self, "usa_value[]") padding = self.seekByte(self["attrs_offset"].value, relative=True) if padding: yield padding while not self.eof: addr = self.absolute_address + self.current_size if self.stream.readBytes(addr, 4) == b"\xFF\xFF\xFF\xFF": yield Bytes(self, "attr_end_marker", 8) break yield Attribute(self, "attr[]") size = self["bytes_in_use"].value - self.current_size // 8 if size: yield RawBytes(self, "end_rawdata", size) size = (self.size - self.current_size) // 8 if size: yield RawBytes(self, "end_padding", size, "Unused but allocated bytes")
def createRawField(parent, size, name="raw[]", description=None): if size <= 0: raise FieldError("Unable to create raw field of %s bits" % size) if (size % 8) == 0: return RawBytes(parent, name, size // 8, description) else: return RawBits(parent, name, size, description)
def createFields(self): # Header yield PaddingBits(self, "sync", 11, "Synchronize bits (set to 1)", pattern=1) yield Enum(Bits(self, "version", 2, "MPEG audio version"), self.VERSION_NAME) yield Enum(Bits(self, "layer", 2, "MPEG audio layer"), self.LAYER_NAME) yield Bit(self, "crc16", "No CRC16 protection?") # Rates and padding yield Bits(self, "bit_rate", 4, "Bit rate") yield Bits(self, "sampling_rate", 2, "Sampling rate") yield Bit(self, "use_padding", "Stream field use padding?") yield Bit(self, "extension", "Extension") # Channel mode, mode extension, copyright, ... yield Enum(Bits(self, "channel_mode", 2, "Channel mode"), self.CHANNEL_MODE_NAME) yield Bits(self, "mode_ext", 2, "Mode extension") yield Bit(self, "copyright", "Is copyrighted?") yield Bit(self, "original", "Is original?") yield Enum(Bits(self, "emphasis", 2, "Emphasis"), self.EMPHASIS_NAME) size = (self.size - self.current_size) // 8 if size: yield RawBytes(self, "data", size)
def createFields(self): yield String(self, "signature", 4, "AVI header (RIFF)", charset="ASCII") yield filesizeHandler(UInt32(self, "filesize", "File size")) yield String(self, "type", 4, "Content type (\"AVI \", \"WAVE\", ...)", charset="ASCII") # Choose chunk type depending on file type try: chunk_cls = self.VALID_TYPES[self["type"].value][0] except KeyError: chunk_cls = Chunk # Parse all chunks up to filesize while self.current_size < self["filesize"].value * 8 + 8: yield chunk_cls(self, "chunk[]") if not self.eof: yield RawBytes(self, "padding[]", (self.size - self.current_size) // 8)
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 Bytes(self, "signature", 4, r'File signature ("\1pcf")') yield UInt32(self, "nb_toc") entries = [] for index in range(self["nb_toc"].value): entry = TOC(self, "toc[]") yield entry entries.append(entry) entries.sort(key=lambda entry: entry["offset"].value) for entry in entries: size = entry["size"].value padding = self.seekByte(entry["offset"].value) if padding: yield padding maxsize = (self.size - self.current_size) // 8 if maxsize < size: self.warning("Truncate content of %s to %s bytes (was %s)" % ( entry.path, maxsize, size)) size = maxsize if not size: continue if entry["type"].value == 1: yield Properties(self, "properties", entry, "Properties", size=size * 8) elif entry["type"].value == 128: yield GlyphNames(self, "glyph_names", entry, "Glyph names", size=size * 8) else: yield RawBytes(self, "data[]", size, "Content of %s" % entry.path)
def createFields(self): yield String(self, "magic", len(self.MAGIC), 'Magic string (%r)' % self.MAGIC, charset="ASCII") yield UInt8(self, "major_version") yield UInt8(self, "minor_version") yield Enum(UInt8(self, "crypto"), self.CRYPTO_NAMES) yield Enum(UInt8(self, "hash"), self.HASH_NAMES) yield KeyringString(self, "keyring_name") yield TimestampUnix64(self, "mtime") yield TimestampUnix64(self, "ctime") yield Bit(self, "lock_on_idle") yield NullBits(self, "reserved[]", 31, "Reserved for future flags") yield UInt32(self, "lock_timeout") yield UInt32(self, "hash_iterations") yield RawBytes(self, "salt", 8) yield NullBytes(self, "reserved[]", 16) yield Items(self, "items") yield UInt32(self, "encrypted_size") yield Deflate( SubFile(self, "encrypted", self["encrypted_size"].value, "AES128 CBC", parser_class=EncryptedData))
def createFields(self): yield Unsigned(self, 'track') yield Int16(self, 'timecode') if self.parent._name == 'Block': yield NullBits(self, 'reserved[]', 4) yield Bit(self, 'invisible') yield self.lacing() yield NullBits(self, 'reserved[]', 1) elif self.parent._name.startswith('SimpleBlock'): yield Bit(self, 'keyframe') yield NullBits(self, 'reserved', 3) yield Bit(self, 'invisible') yield self.lacing() yield Bit(self, 'discardable') else: yield NullBits(self, 'reserved', 8) return size = (self._size - self.current_size) // 8 lacing = self['lacing'].value if lacing: yield textHandler(GenericInteger(self, 'n_frames', False, 8), lambda chunk: str(chunk.value + 1)) yield Lace(self, lacing - 1, size - 1) else: yield RawBytes(self, 'frame', size)
def createFields(self): yield UInt8(self, "id", "PCX identifier (10)") yield Enum(UInt8(self, "version", "PCX version"), self.version_name) yield Enum(UInt8(self, "compression", "Compression method"), self.compression_name) yield UInt8(self, "bpp", "Bits / pixel") yield UInt16(self, "xmin", "Minimum X") yield UInt16(self, "ymin", "Minimum Y") yield UInt16(self, "xmax", "Width minus one") # value + 1 yield UInt16(self, "ymax", "Height minus one") # value + 1 yield UInt16(self, "horiz_dpi", "Horizontal DPI") yield UInt16(self, "vert_dpi", "Vertical DPI") yield PaletteRGB(self, "palette_4bits", 16, "Palette (4 bits)") yield PaddingBytes(self, "reserved[]", 1) yield UInt8(self, "nb_color_plan", "Number of color plans") yield UInt16(self, "bytes_per_line", "Bytes per line") yield UInt16(self, "color_mode", "Color mode") yield PaddingBytes(self, "reserved[]", 58) if self._size is None: # TODO: is it possible to handle piped input? raise NotImplementedError nb_colors = 256 size = (self._size - self.current_size) // 8 has_palette = self["bpp"].value == 8 if has_palette: size -= nb_colors * 3 yield RawBytes(self, "image_data", size, "Image data") if has_palette: yield PaletteRGB(self, "palette_8bits", nb_colors, "Palette (8 bit)")
def createFields(self): addr = self.absolute_address len = self.stream.searchBytesLength(b':', False, addr, addr + (MAX_STRING_LENGTH + 1) * 8) if len is None: raise ParserError("Torrent: unable to find string separator (':')") if not len: raise ParserError("Torrent: error: no string length!") val = String(self, "length", len, "String length") yield val try: len = int(val.value) except ValueError: len = -1 if len < 0: raise ParserError("Invalid string length (%s)" % makePrintable(val.value, "ASCII")) yield String(self, "separator", 1, "String length/value separator") if not len: self.info("Empty string: len=%i" % len) return if len < 512: yield String(self, "value", len, "String value", charset="ISO-8859-1") else: # Probably raw data yield RawBytes(self, "value", len, "Raw data")
def createFields(self): yield UInt32(self, "size") yield String(self, "name", 22, charset="ASCII", strip=" \0") # Doc says type is always 0, but I've found values of 24 and 96 for # the _same_ song here, just different download sources for the file yield UInt8(self, "type") yield UInt16(self, "samples") num = self["samples"].value self.info(self.createDescription()) if num: yield InstrumentSecondHeader(self, "second_header") yield from self.fixInstrumentHeader() # This part probably wrong sample_size = [] for index in range(num): sample = SampleHeader(self, "sample_header[]") yield sample sample_size.append(sample["length"].value) for size in sample_size: if size: yield RawBytes(self, "sample_data[]", size, "Deltas") else: yield from self.fixInstrumentHeader()
def createFields(self): yield Integer(self, "time", "Delta time in ticks") next = self.stream.readBits(self.absolute_address + self.current_size, 8, self.root.endian) if next & 0x80 == 0: # "Running Status" command if self.prev_command is None: raise ParserError( "Running Status command not preceded by another command.") self.command = self.prev_command.command else: yield Enum(textHandler(UInt8(self, "command"), hexadecimal), self.COMMAND_DESC) self.command = self["command"].value if self.command == 0xFF: yield Enum(textHandler(UInt8(self, "meta_command"), hexadecimal), self.META_COMMAND_DESC) yield UInt8(self, "data_len") size = self["data_len"].value if size: command = self["meta_command"].value if command in self.META_COMMAND_PARSER: parser = self.META_COMMAND_PARSER[command] else: parser = None if parser is not None: yield from parser(self, size) else: yield RawBytes(self, "data", size) else: if self.command not in self.COMMAND_PARSER: raise ParserError("Unknown command: %s" % self["command"].display) parser = self.COMMAND_PARSER[self.command] yield from parser(self)
def createFields(self): yield FIB(self, "FIB", "File Information Block") getOLE2Parser(self.ole2, "table" + str(self["FIB/fWhichTblStm"].value)) padding = (self['FIB/fcMin'].value - self.current_size // 8) if padding: yield NullBytes(self, "padding[]", padding) # Guess whether the file uses UTF16 encoding. is_unicode = False if self['FIB/array2/ccpText'].value * 2 == self['FIB/fcMax'].value - self['FIB/fcMin'].value: is_unicode = True for fieldname, textname in [('Text', 'text'), ('Ftn', 'text_footnote'), ('Hdr', 'text_header'), ('Mcr', 'text_macro'), ('Atn', 'text_annotation'), ('Edn', 'text_endnote'), ('Txbx', 'text_textbox'), ('HdrTxbx', 'text_header_textbox')]: size = self['FIB/array2/ccp' + fieldname].value if size: if is_unicode: yield String(self, textname, size * 2, charset="UTF-16-LE") else: yield Bytes(self, textname, size) padding = (self['FIB/fcMax'].value - self.current_size // 8) if padding: yield RawBytes(self, "padding[]", padding)
def createFields(self): yield ZSTHeader(self, "header", "ZST header") # Offset: 0 yield ZSTcpu(self, "cpu", "ZST cpu registers") # 41 yield ZSTppu(self, "ppu", "ZST CPU registers") # 72 yield RawBytes(self, "wram7E", 65536) # 3091 yield RawBytes(self, "wram7F", 65536) # 68627 yield RawBytes(self, "vram", 65536) # 134163 # TODO: Interpret extra on-cart chip data found at/beyond... 199699 # TODO: Interpret Thumbnail/Screenshot data found at 275291 # 64*56*2(16bit colors) = 7168 padding = self.seekByte(275291, relative=False) if padding is not None: yield padding yield Bytes(self, "thumbnail", 7168, "Thumbnail of playing game in some sort of raw 64x56x16-bit RGB mode?")
def createFields(self): yield UInt8(self, "size", "Total length of this FFN in bytes, minus 1") self._size = self["size"].value * 8 + 8 yield Bits(self, "prq", 2, "Pitch request") yield Bit(self, "fTrueType", "Is font a TrueType font?") yield Bits(self, "reserved[]", 1) yield Bits(self, "ff", 3, "Font Family ID") yield Bits(self, "reserved[]", 1) yield UInt16(self, "wWeight", "Base weight of font") yield UInt8(self, "chs", "Character set identifier") yield UInt8(self, "ixchSzAlt", "Index into name to the name of the alternate font") yield RawBytes(self, "panose", 10) yield RawBytes(self, "fs", 24, "Font Signature") yield CString(self, "name", charset="UTF-16-LE") if self["ixchSzAlt"].value != 0: yield CString(self, "nameAlt", charset="UTF-16-LE")
def createFields(self): yield UInt16(self, "size", "Node size (in bytes)") yield UInt16(self, "data_size") yield Enum(UInt16(self, "type"), self.TYPE_NAME) yield CString(self, "name", charset="UTF-16-LE") size = paddingSize(self.current_size // 8, 4) if size: yield NullBytes(self, "padding[]", size) size = self["data_size"].value if size: if self["type"].value == self.TYPE_STRING: if self.is_32bit: size *= 2 yield String(self, "value", size, charset="UTF-16-LE", truncate="\0") elif self["name"].value == "VS_VERSION_INFO": yield VersionInfoBinary(self, "value", size=size * 8) if self["value/file_flags_mask"].value == 0: self.is_32bit = False else: yield RawBytes(self, "value", size) while 12 <= (self.size - self.current_size) // 8: yield VersionInfoNode(self, "node[]", self.is_32bit) size = (self.size - self.current_size) // 8 if size: yield NullBytes(self, "padding[]", size)
def parseApplicationExtension(parent): yield PascalString8(parent, "app_name", "Application name") while True: size = UInt8(parent, "size[]") if size.value == 0: break yield size if parent["app_name"].value == "NETSCAPE2.0" and size.value == 3: yield Enum(UInt8(parent, "netscape_code"), NETSCAPE_CODE) if parent["netscape_code"].value == 1: yield UInt16(parent, "loop_count") else: yield RawBytes(parent, "raw[]", 2) else: yield RawBytes(parent, "raw[]", size.value) yield NullBytes(parent, "terminator", 1, "Terminator (0)")