def __init__(self, parent, name): n = 0 while 1: ch = parent.stream.readBytes(parent.absolute_address + parent.current_size + n*8, 1) if not ch.isspace(): break n += 1 String.__init__(self, parent, name, n)
def createFields(self): yield String(self, "header_id", 4, "Data Object Header Markup (\"mhod\")", charset="ISO-8859-1") yield UInt32(self, "header_length", "Header Length") yield UInt32(self, "entry_length", "Entry Length") yield Enum(UInt32(self, "type", "type"), self.type_name) if (self["type"].value == 15) or (self["type"].value == 16): yield UInt32(self, "unknown[]") yield UInt32(self, "unknown[]") yield String(self, "string", self._size // 8 - self["header_length"].value, "String Data", charset="UTF-8") elif (self["type"].value == 52): yield UInt32(self, "unknown[]", "unk1") yield UInt32(self, "unknown[]", "unk2") yield Enum(UInt32(self, "sort_index_type", "Sort Index Type"), self.mhod52_sort_index_type_name) yield UInt32(self, "entry_count", "Entry Count") indexes_size = self["entry_count"].value * 4 padding_offset = self["entry_length"].value - indexes_size padding = self.seekByte(padding_offset, "header padding") if padding: yield padding for i in range(self["entry_count"].value): yield UInt32(self, "index[" + str(i) + "]", "Index of the " + str(i) + "nth mhit") elif (self["type"].value < 15) or (self["type"].value > 17) or (self["type"].value >= 200): yield UInt32(self, "unknown[]") yield UInt32(self, "unknown[]") yield UInt32(self, "position", "Position") yield UInt32(self, "length", "String Length in bytes") yield UInt32(self, "unknown[]") yield UInt32(self, "unknown[]") yield String(self, "string", self["length"].value, "String Data", charset="UTF-16-LE") else: padding = self.seekByte(self["header_length"].value, "header padding") if padding: yield padding padding = self.seekBit(self._size, "entry padding") if padding: yield padding
def createFields(self): yield UInt16(self, "length", "Length of this string") if self["length"].value: if self.root.hasUnicodeNames(): yield String(self, "data", self["length"].value * 2, charset="UTF-16-LE") else: yield String(self, "data", self["length"].value, charset="ASCII")
def createFields(self): yield String(self, "sectname", 16, strip="\0") yield String(self, "segname", 16, strip="\0") yield textHandler(UInt64(self, "addr"), hexadecimal) yield textHandler(UInt64(self, "size"), hexadecimal) yield textHandler(UInt32(self, "offset"), hexadecimal) yield textHandler(UInt32(self, "align"), hexadecimal) yield textHandler(UInt32(self, "reloff"), hexadecimal) yield UInt32(self, "nreloc") yield UInt32(self, "flags") yield UInt32(self, "reserved1") yield UInt32(self, "reserved2") yield RawBytes(self, "padding", 4)
def createFields(self): yield self.getType() yield String(self, "filename", 12, strip='\0') for field in self.getInstrumentFields(): yield field yield String(self, "name", 28, strip='\0') yield String(self, "marker", 4, "Either 'SCRS' or '(empty)'", strip='\0')
def createFields(self): yield UInt8(self, "size") self._size = (self['size'].value + 1) * 8 yield Enum(UInt8(self, "type"), self.STREAMTYPE) if self['type'].display.startswith('V'): # Video yield Enum( Bits(self, "resolution", 4), { 1: '480i', 2: '576i', 3: '480p', 4: '1080i', 5: '720p', 6: '1080p', 7: '576p' }) yield Enum( Bits(self, "fps", 4), { 1: '24/1.001', 2: '24', 3: '25', 4: '30/1.001', 6: '50', 7: '60/1.001' }) yield Enum(UInt8(self, "aspect_ratio"), { 0x20: '4:3', 0x30: '16:9' }) elif self['type'].display.startswith('A'): # Audio yield Enum(Bits(self, "channel_layout", 4), { 1: 'Mono', 3: 'Stereo', 6: 'Multi', 12: 'Combi' }) yield Enum( Bits(self, "sample_rate", 4), { 1: '48KHz', 4: '96KHz', 5: '192KHz', 12: '48-192KHz', 14: '48-96KHz' }) yield Enum(String(self, "language", 3), ISO639_2) elif self['type'].display.startswith('T'): # Text subtitle yield UInt8(self, "unknown[]") yield Enum(String(self, "language", 3), ISO639_2) elif self['type'].display.startswith('S'): # Graphics yield Enum(String(self, "language", 3), ISO639_2) else: pass
def createFields(self): yield String(self, "signature", 3, "IDv1 signature (\"TAG\")", charset="ASCII") if self["signature"].value != "TAG": raise MatchError( "Stream doesn't look like ID3v1 (wrong signature)!") # TODO: Charset of below strings? yield String(self, "song", 30, "Song title", strip=" \0", charset="ISO-8859-1") yield String(self, "author", 30, "Author", strip=" \0", charset="ISO-8859-1") yield String(self, "album", 30, "Album title", strip=" \0", charset="ISO-8859-1") yield String(self, "year", 4, "Year", strip=" \0", charset="ISO-8859-1") # TODO: Write better algorithm to guess ID3v1 version version = self.getVersion() if version in ("v1.1", "v1.1b"): if version == "v1.1b": # ID3 v1.1b yield String(self, "comment", 29, "Comment", strip=" \0", charset="ISO-8859-1") yield UInt8(self, "track_nb", "Track number") else: # ID3 v1.1 yield String(self, "comment", 30, "Comment", strip=" \0", charset="ISO-8859-1") yield Enum(UInt8(self, "genre", "Genre"), self.GENRE_NAME) else: # ID3 v1.0 yield String(self, "comment", 31, "Comment", strip=" \0", charset="ISO-8859-1")
def createFields(self): yield String(self, "magic", 4) yield String(self, "version", 4, strip='\0') yield textHandler(UInt32(self, "checksum"), hexadecimal) yield RawBytes(self, "signature", 20, description="SHA1 sum over all subsequent data") yield filesizeHandler(UInt32(self, "filesize")) yield UInt32(self, "size", description="Header size") self._size = self['size'].value * 8 yield textHandler(UInt32(self, "endian"), hexadecimal) yield UInt32(self, "link_count") yield UInt32(self, "link_offset") yield UInt32(self, "map_offset", description="offset to map footer") yield UInt32(self, "string_count", description="number of entries in string table") yield UInt32(self, "string_offset", description="offset to string table") yield UInt32(self, "type_desc_count", description="number of entries in type descriptor table") yield UInt32(self, "type_desc_offset", description="offset to type descriptor table") yield UInt32( self, "meth_desc_count", description="number of entries in method descriptor table") yield UInt32(self, "meth_desc_offset", description="offset to method descriptor table") yield UInt32(self, "field_count", description="number of entries in field table") yield UInt32(self, "field_offset", description="offset to field table") yield UInt32(self, "method_count", description="number of entries in method table") yield UInt32(self, "method_offset", description="offset to method table") yield UInt32(self, "class_count", description="number of entries in class table") yield UInt32(self, "class_offset", description="offset to class table") yield UInt32(self, "data_size", description="size of data region") yield UInt32(self, "data_offset", description="offset to data region")
def createFields(self): iff_start = self.absolute_address yield String(self, "endian", 2, "Endian ('II' or 'MM')", charset="ASCII") if self["endian"].value == "II": self.endian = LITTLE_ENDIAN else: self.endian = BIG_ENDIAN yield UInt16(self, "version", "TIFF version number") yield UInt32(self, "img_dir_ofs", "Next image directory offset") yield String(self, "cr_identifier", 2, "Canon Raw marker", charset="ASCII") yield UInt8(self, "cr_major_version", "Canon Raw major version number") yield UInt8(self, "cr_minor_version", "Canon Raw minor version number") yield textHandler( UInt32(self, "cr_raw_ifd_offset", "Offset to Raw IFD"), hexadecimal) offsets = [(self['img_dir_ofs'].value, 'ifd[]', IFD)] while offsets: offset, name, klass = offsets.pop(0) self.seekByte(offset + iff_start // 8, relative=False) ifd = klass(self, name, iff_start) yield ifd for entry in ifd.array('entry'): tag = entry['tag'].value if tag in IFD_TAGS: name, klass = IFD_TAGS[tag] offsets.append((ifd.getEntryValues(entry)[0].value, name + '[]', klass)) if ifd['next'].value != 0: offsets.append((ifd['next'].value, 'ifd[]', IFD)) for ifd in self.array('ifd'): offs = (off for off, byte in getStrips(ifd)) self.seekByte(min(offs), relative=False) image = ImageFile(self, "image[]", "Image File", ifd) yield image
def createFields(self): if not self.LFN: yield String(self, "name", 8, "DOS file name (padded with spaces)", strip=' ', charset="ASCII") yield String(self, "ext", 3, "DOS file extension (padded with spaces)", strip=' ', charset="ASCII") yield Bit(self, "read_only") yield Bit(self, "hidden") yield Bit(self, "system") yield Bit(self, "volume_label") yield Bit(self, "directory") yield Bit(self, "archive") yield Bit(self, "device") yield Bit(self, "unused") yield RawBytes(self, "reserved", 1, "Something about the case") yield Date(self, "create") yield Date(self, "access") if self.parent.parent.version > 16: yield UInt16(self, "cluster_hi") else: yield UInt16(self, "ea_index") yield Date(self, "modify") yield UInt16(self, "cluster_lo") size = UInt32(self, "size") yield size if self.process: del self.process target_size = size.value if self["directory"].value: if target_size: size.error("(FAT) value must be zero") target_size = 0 elif not target_size: return self.target_size = 8 * target_size yield InodeLink(self, "data") else: yield UInt8(self, "seq_no", "Sequence Number") yield String(self, "name[]", 10, "(5 UTF-16 characters)", charset="UTF-16-LE") yield UInt8(self, "magic", "Magic number (15)") yield NullBytes(self, "reserved", 1, "(always 0)") yield UInt8(self, "checksum", "Checksum of DOS file name") yield String(self, "name[]", 12, "(6 UTF-16 characters)", charset="UTF-16-LE") yield UInt16(self, "first_cluster", "(always 0)") yield String(self, "name[]", 4, "(2 UTF-16 characters)", charset="UTF-16-LE")
def createFields(self): yield PowerPointDocument.PowerPointObject(self, "current_user") if self.current_size < self.size: yield String(self, "unicode_name", self["current_user/data/lenUserName"].value * 2, charset="UTF-16-LE")
def createFields(self): yield UInt32(self, "size") yield String(self, "tag", 4, charset="ASCII") size = self["size"].value if size == 1: # 64-bit size yield UInt64(self, "size64") size = self["size64"].value - 16 elif size == 0: # Unbounded atom if self._size is None: size = (self.parent.size - self.parent.current_size) // 8 - 8 else: size = (self.size - self.current_size) // 8 else: size = size - 8 if self['tag'].value == 'uuid': yield GUID(self, "usertag") tag = self["usertag"].value size -= 16 else: tag = self["tag"].value if size > 0: if tag in self.tag_info: handler, name, desc = self.tag_info[tag] yield handler(self, name, desc, size=size * 8) else: yield RawBytes(self, "data", size)
def createFields(self): yield String(self, "name", 32, strip="\0") yield PaddingBytes(self, "unknown[]", 32, pattern="\xCC") yield UInt32(self, "flags") yield UInt32(self, "id") yield UInt32(self, "type") yield Int32(self, "mesh_id") yield UInt32(self, "depth") yield Int32(self, "parent_offset") yield UInt32(self, "nchildren") yield UInt32(self, "first_child_offset") yield UInt32(self, "next_sibling_offset") yield Vertex(self, "pivot") yield Vertex(self, "position") yield Float32(self, "pitch") yield Float32(self, "yaw") yield Float32(self, "roll") for index in range(4): yield Vertex(self, "unknown_vertex[]") if self["parent_offset"].value != 0: yield UInt32(self, "parent_id") if self["first_child_offset"].value != 0: yield UInt32(self, "first_child_id") if self["next_sibling_offset"].value != 0: yield UInt32(self, "next_sibling_id")
def createFields(self): bytes = self.stream.readBytes(self.absolute_address, 4) if bytes == b"\0R\0\0": charset = "UTF-16-BE" else: charset = "UTF-16-LE" yield String(self, "name", 64, charset=charset, truncate="\0") yield UInt16(self, "namelen", "Length of the name") yield Enum(UInt8(self, "type", "Property type"), self.TYPE_NAME) yield Enum(UInt8(self, "decorator", "Decorator"), self.DECORATOR_NAME) yield SECT(self, "left") yield SECT(self, "right") yield SECT(self, "child", "Child node (valid for storage and root types)") yield GUID(self, "clsid", "CLSID of this storage (valid for storage and root types)") yield NullBytes(self, "flags", 4, "User flags") yield TimestampWin64( self, "creation", "Creation timestamp(valid for storage and root types)") yield TimestampWin64( self, "lastmod", "Modify timestamp (valid for storage and root types)") yield SECT( self, "start", "Starting SECT of the stream (valid for stream and root types)") if self["/header/bb_shift"].value == 9: yield filesizeHandler( UInt32(self, "size", "Size in bytes (valid for stream and root types)")) yield NullBytes(self, "padding", 4) else: yield filesizeHandler( UInt64(self, "size", "Size in bytes (valid for stream and root types)"))
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, "filename", 56, truncate="\0") yield filesizeHandler(UInt32(self, "size")) yield SubFile(self, "data", self["size"].value, filename=self["filename"].value)
def createFields(self): yield String(self, "magic", 4, "File signature (MARC)", charset="ASCII") yield UInt32(self, "version") yield UInt32(self, "nb_file") files = [] for index in range(self["nb_file"].value): item = FileIndex(self, "file[]") yield item if item["filesize"].value: files.append(item) files.sort(key=lambda item: item["offset"].value) for index in files: padding = self.seekByte(index["offset"].value) if padding: yield padding size = index["filesize"].value desc = "File %s" % index["filename"].value yield SubFile(self, "data[]", size, desc, filename=index["filename"].value)
def createFields(self): yield Bytes(self, "signature", 4, r'ELF signature ("\x7fELF")') yield Enum(UInt8(self, "class", "Class"), self.CLASS_NAME) if self["class"].value == 1: ElfLongWord = UInt32 else: ElfLongWord = UInt64 yield Enum(UInt8(self, "endian", "Endian"), self.ENDIAN_NAME) yield UInt8(self, "file_version", "File version") yield Enum(UInt8(self, "osabi_ident", "OS/syscall ABI identification"), self.OSABI_NAME) yield UInt8(self, "abi_version", "syscall ABI version") yield String(self, "pad", 7, "Pad") yield Enum(UInt16(self, "type", "File type"), self.TYPE_NAME) yield Enum(UInt16(self, "machine", "Machine type"), self.MACHINE_NAME) yield UInt32(self, "version", "ELF format version") yield textHandler(ElfLongWord(self, "entry", "Entry point"), hexadecimal) yield ElfLongWord(self, "phoff", "Program header file offset") yield ElfLongWord(self, "shoff", "Section header file offset") yield UInt32(self, "flags", "Architecture-specific flags") yield UInt16(self, "ehsize", "Elf header size (this header)") yield UInt16(self, "phentsize", "Program header entry size") yield UInt16(self, "phnum", "Program header entry count") yield UInt16(self, "shentsize", "Section header entry size") yield UInt16(self, "shnum", "Section header entry count") yield UInt16(self, "shstrndx", "Section header string table index")
def createFields(self): yield String(self, "signature", 3, "SWF format signature", charset="ASCII") yield UInt8(self, "version") yield filesizeHandler(UInt32(self, "filesize")) if self["signature"].value != "CWS": yield RECT(self, "rect") yield FixedFloat16(self, "frame_rate") yield UInt16(self, "frame_count") while not self.eof: yield Tag(self, "tag[]") else: size = (self.size - self.current_size) // 8 if has_deflate: data = Deflate(Bytes(self, "compressed_data", size), False) def createInputStream(cis, source=None, **args): stream = cis(source=source) header = StringInputStream("FWS" + self.stream.readBytes(3 * 8, 5)) args.setdefault("tags", []).append(("class", SwfFile)) return ConcatStream((header, stream), source=stream.source, **args) data.setSubIStream(createInputStream) yield data else: yield Bytes(self, "compressed_data", size)
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 createFields(self): yield String(self, "name", 32, strip="\0") yield UInt32(self, "id") yield UInt32(self, "geometry_mode") yield UInt32(self, "lighting_mode") yield UInt32(self, "texture_mode") yield UInt32(self, "nmesh_vertices") yield UInt32(self, "ntexture_vertices") yield UInt32(self, "nfaces") nb_vert = self["nmesh_vertices"].value if nb_vert: yield Vector(self, "vertices", nb_vert, Vertex, "vertex") if self["ntexture_vertices"].value: yield Vector(self, "texture vertices", self["ntexture_vertices"].value, MapUV, "texture_vertex") if nb_vert: yield Vector(self, "light vertices", nb_vert, Float32, "extra_light") yield Vector(self, "unknown[]", nb_vert, Float32, "unknown") if self["nfaces"].value: yield Vector(self, "faces", self["nfaces"].value, Face, "face") if nb_vert: yield Vector(self, "vertex normals", nb_vert, Vertex, "normal") yield UInt32(self, "has_shadow") yield Float32(self, "unknown[]") yield Float32(self, "radius") yield Vertex(self, "unknown[]") yield Vertex(self, "unknown[]")
def createFields(self): start = self.absolute_address size = self.stream.searchBytesLength(b"\0", False, start) if size > 0: self.info("Command: %s" % self.stream.readBytes(start, size)) yield String(self, "command", size, strip='\0') yield RawBytes(self, "parameter", (self._size // 8) - size)
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") for field in self.fixInstrumentHeader(): yield field # This part probably wrong sample_size = [] for index in xrange(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: for field in self.fixInstrumentHeader(): yield field
def TIFF(self): iff_start = self.absolute_address + self.current_size yield String(self, "endian", 2, "Endian ('II' or 'MM')", charset="ASCII") if self["endian"].value not in ("II", "MM"): raise ParserError("Invalid endian!") if self["endian"].value == "II": self.endian = LITTLE_ENDIAN else: self.endian = BIG_ENDIAN yield UInt16(self, "version", "TIFF version number") yield UInt32(self, "img_dir_ofs", "Next image directory offset") offsets = [(self['img_dir_ofs'].value, 'ifd[]', IFD)] while offsets: offset, name, klass = offsets.pop(0) self.seekByte(offset + iff_start // 8, relative=False) ifd = klass(self, name, iff_start) yield ifd for entry in ifd.array('entry'): tag = entry['tag'].value if tag in IFD_TAGS: name, klass = IFD_TAGS[tag] offsets.append( (ifd.getEntryValues(entry)[0].value, name + '[]', klass)) elif tag == IFDEntry.SUBIFD_POINTERS: for val in ifd.getEntryValues(entry): offsets.append((val.value, ifd.name + '[]', IFD)) if ifd['next'].value != 0: offsets.append((ifd['next'].value, 'ifd[]', IFD))
def createFields(self): # Headers yield String(self, "header", 6, "Header (Exif\\0\\0)", charset="ASCII") if self["header"].value != "Exif\0\0": raise ParserError("Invalid EXIF signature!") iff_start = self.absolute_address + self.current_size ifds = [] for field in TIFF(self): yield field if isinstance(field, IFD): ifds.append(field) for ifd in ifds: data = {} for i, entry in enumerate(ifd.array('entry')): data[entry['tag'].display] = entry if 'JPEGInterchangeFormat' in data and 'JPEGInterchangeFormatLength' in data: offs = ifd.getEntryValues( data['JPEGInterchangeFormat'])[0].value size = ifd.getEntryValues( data['JPEGInterchangeFormatLength'])[0].value if size == 0: continue self.seekByte(offs + iff_start // 8, relative=False) yield SubFile(self, "thumbnail[]", size, "Thumbnail (JPEG file)", mime_type="image/jpeg")
def parseCommon(self): yield UInt16(self, "nb_channel") yield UInt32(self, "nb_sample") yield UInt16(self, "sample_size") yield Float80(self, "sample_rate") yield Enum(String(self, "codec", 4, strip="\0", charset="ASCII"), CODEC_NAME)
def createFields(self): yield String(self, "signature", 2, "Header (\"BM\")", charset="ASCII") yield UInt32(self, "file_size", "File size (bytes)") yield PaddingBytes(self, "reserved", 4, "Reserved") yield UInt32(self, "data_start", "Data start position") yield BmpHeader(self, "header") # Compute number of color header = self["header"] bpp = header["bpp"].value if 0 < bpp <= 8: if "used_colors" in header and header["used_colors"].value: nb_color = header["used_colors"].value else: nb_color = (1 << bpp) else: nb_color = 0 # Color palette (if any) if nb_color: yield PaletteRGBA(self, "palette", nb_color) # Seek to data start field = self.seekByte(self["data_start"].value) if field: yield field # Image pixels size = min(self["file_size"].value - self["data_start"].value, (self.size - self.current_size) // 8) yield parseImageData(self, "pixels", size, header)
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): yield String(self, "magic", 4, "ITSP", charset="ASCII") yield UInt32(self, "version", "Version (=1)") yield filesizeHandler( UInt32(self, "size", "Length (in bytes) of the directory header (84)")) yield UInt32(self, "unknown[]", "(=10)") yield filesizeHandler( UInt32(self, "block_size", "Directory block size")) yield UInt32(self, "density", "Density of quickref section, usually 2") yield UInt32(self, "index_depth", "Depth of the index tree") yield Int32(self, "nb_dir", "Chunk number of root index chunk") yield UInt32(self, "first_pmgl", "Chunk number of first PMGL (listing) chunk") yield UInt32(self, "last_pmgl", "Chunk number of last PMGL (listing) chunk") yield Int32(self, "unknown[]", "-1") yield UInt32(self, "nb_dir_chunk", "Number of directory chunks (total)") yield Enum(UInt32(self, "lang_id", "Windows language ID"), LANGUAGE_ID) yield GUID(self, "system_uuid", "{5D02926A-212E-11D0-9DF9-00A0C922E6EC}") yield filesizeHandler(UInt32(self, "size2", "Same value than size")) yield Int32(self, "unknown[]", "-1") yield Int32(self, "unknown[]", "-1") yield Int32(self, "unknown[]", "-1")
def createFields(self): # Header yield String(self, "magic", 4, "PMGL", charset="ASCII") yield filesizeHandler( Int32( self, "free_space", "Length of free space and/or quickref area at end of directory chunk" )) yield Int32(self, "unknown") yield Int32(self, "previous", "Chunk number of previous listing chunk") yield Int32(self, "next", "Chunk number of previous listing chunk") # Entries stop = self.size - self["free_space"].value * 8 entry_count = 0 while self.current_size < stop: yield PMGL_Entry(self, "entry[]") entry_count += 1 # Padding quickref_frequency = 1 + (1 << self["/dir/itsp/density"].value) num_quickref = (entry_count // quickref_frequency) if entry_count % quickref_frequency == 0: num_quickref -= 1 print(self.current_size // 8, quickref_frequency, num_quickref) padding = (self["free_space"].value - (num_quickref * 2 + 2)) if padding: yield PaddingBytes(self, "padding", padding) for i in range(num_quickref * quickref_frequency, 0, -quickref_frequency): yield UInt16(self, "quickref[%i]" % i) yield UInt16(self, "entry_count")
def createFields(self): yield CWord(self, "name_len") yield String(self, "name", self["name_len"].value, charset="UTF-8") yield CWord(self, "section", "Section number that the entry data is in.") yield CWord(self, "start", "Start offset of the data") yield filesizeHandler(CWord(self, "length", "Length of the data"))
def __init__(self, parent, name, nbytes, description=None, strip=' \0', charset='ISO-8859-1', *args, **kwargs): String.__init__(self, parent, name, nbytes, description, strip, charset, *args, **kwargs)