def createFields(self): addr = self.absolute_address len = self.stream.searchBytesLength(':', 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", to_unicode=True)) 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 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): yield ZipVersion(self, "version_made_by", "Version made by") # yield from ZipStartCommonFields(self) # PY3 for field in ZipStartCommonFields(self): yield field # Check unicode status charset = zipGetCharset(self) yield UInt16(self, "comment_length", "Comment length") yield UInt16(self, "disk_number_start", "Disk number start") yield UInt16(self, "internal_attr", "Internal file attributes") yield UInt32(self, "external_attr", "External file attributes") yield UInt32(self, "offset_header", "Relative offset of local header") yield String(self, "filename", self["filename_length"].value, "Filename", charset=charset) if 0 < self["extra_length"].value: yield ExtraFields(self, "extra", size=self["extra_length"].value * 8, description="Extra fields") if 0 < self["comment_length"].value: yield String(self, "comment", self["comment_length"].value, "Comment", charset=charset)
def createFields(self): yield String(self, "name", 20, strip='\0') yield GenericVector(self, "samples", 31, SampleInfo, "info") yield UInt8(self, "length") yield UInt8(self, "played_patterns_count") yield GenericVector(self, "patterns", 128, UInt8, "position") yield String(self, "type", 4)
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 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 xrange(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 String(self, "signature", 4, 'Format signature (".snd")', charset="ASCII") yield UInt32(self, "data_ofs", "Data offset") yield filesizeHandler(UInt32(self, "data_size", "Data size")) yield Enum(UInt32(self, "codec", "Audio codec"), self.CODEC_NAME) yield displayHandler( UInt32(self, "sample_rate", "Number of samples/second"), humanFrequency) yield UInt32(self, "channels", "Number of interleaved channels") size = self["data_ofs"].value - self.current_size // 8 if 0 < size: yield String(self, "info", size, "Information", strip=" \0", charset="ISO-8859-1") size = min(self["data_size"].value, (self.size - self.current_size) // 8) yield RawBytes(self, "audio_data", size, "Audio data")
def createFields(self): yield RawBytes(self, "marker", len(self.MAGIC)) yield WhiteSpace(self, "sep[]") yield String(self, "start_attribute_marker", 2) addr = self.absolute_address + self.current_size while self.stream.readBytes(addr, 2) != b'>>': yield WhiteSpace(self, "sep[]") t = PDFName(self, "type[]") yield t name = t.value.decode() self.info("Parsing PDFName '%s'" % name) if name == "Size": yield PDFNumber(self, "size", "Entries in the file cross-reference section") elif name == "Prev": yield PDFNumber(self, "offset") elif name == "Root": yield Catalog(self, "object_catalog") elif name == "Info": yield Catalog(self, "info") elif name == "ID": yield PDFArray(self, "id") elif name == "Encrypt": yield PDFDictionary(self, "decrypt") else: raise ParserError("Don't know trailer type '%s'" % name) addr = self.absolute_address + self.current_size yield String(self, "end_attribute_marker", 2) yield LineEnd(self, "line_end[]") yield String(self, "start_xref", 9) yield LineEnd(self, "line_end[]") yield PDFNumber(self, "cross_ref_table_start_address") yield LineEnd(self, "line_end[]") yield String(self, "end_marker", len(ENDMAGIC)) yield LineEnd(self, "line_end[]")
def createFields(self): size = self._size // 8 # TODO: Strings charset? if self.stream.readBytes(self.absolute_address, 9) == "PeakValue": yield String(self, "text", 9, "Text") size -= 9 yield String(self, "content", size, "Content")
def createFields(self): # Header yield String(self, "magic", 3, "File magic code", charset="ASCII") yield String(self, "version", 3, "GIF version", charset="ASCII") yield ScreenDescriptor(self, "screen") if self["screen/global_map"].value: bpp = (self["screen/size_global_map"].value + 1) yield PaletteRGB(self, "color_map", 1 << bpp, "Color map") self.color_map = self["color_map"] else: self.color_map = None self.images = [] while True: code = Enum(Character(self, "separator[]", "Separator code"), self.separator_name) yield code code = code.value if code == "!": yield Extension(self, "extensions[]") elif code == ",": yield Image(self, "image[]") elif code == ";": # GIF Terminator break else: raise ParserError("Wrong GIF image separator: 0x%02X" % ord(code))
def createFields(self): while self.stream.readBytes(self.absolute_address + self.current_size, 1) == '%': size = getLineEnd(self, 4) if size == 2: yield String(self, "crc32_comment", 1) yield textHandler(UInt16(self, "crc32"), hexadecimal) elif size == 4: yield String(self, "crc32_comment", 1) yield textHandler(UInt32(self, "crc32"), hexadecimal) elif self.stream.readBytes(self.absolute_address + self.current_size, size).isalpha(): yield String(self, "comment[]", size) else: RawBytes(self, "unknown_data[]", size) yield LineEnd(self, "line_end[]") # abs_offset = self.current_size // 8 # TODO: yield objects that read offsets and deduce size from # "/cross_ref_table/sub_section[]/entries/item[]" offsets = [] for subsection in self.array("/cross_ref_table/sub_section"): for obj in subsection.array("entries/item"): if "byte_offset" in obj: # Could be inserted already sorted offsets.append(obj["byte_offset"].value) offsets.append(self["/cross_ref_table"].absolute_address // 8) offsets.sort() for index in xrange(len(offsets) - 1): yield Catalog(self, "object[]", size=offsets[index + 1] - offsets[index])
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, "marker", 5, MAGIC) length = getLineEnd(self, 4) if length is not None: # self.info("Found at position %08X" % len) yield String(self, "version", length - 1) yield LineEnd(self, "line_end") else: self.warning("Can't determine version!")
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 String(self, "dict_start", 2) while not self.eof: addr = self.absolute_address + self.current_size if self.stream.readBytes(addr, 2) != '>>': for field in parsePDFType(self): yield field else: break yield String(self, "dict_end", 2)
def createFields(self): yield String(self, "signature", 4, "Signature (FORM)", charset="ASCII") yield filesizeHandler(UInt32(self, "filesize")) yield String(self, "type", 4, "Form type (AIFF or AIFC)", charset="ASCII") while not self.eof: yield Chunk(self, "chunk[]")
def createFields(self): yield String(self, "start", 1, "Dictionary start delimiter (d)", charset="ASCII") while self.stream.readBytes(self.absolute_address + self.current_size, 1) != "e": yield DictionaryItem(self, "item[]") yield String(self, "end", 1, "Dictionary end delimiter")
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)
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 xrange(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 parseText(self): yield String(self, "text", self["size"].value, strip=" \0", truncate="\0", charset="ISO-8859-1")
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 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): # Signature + version yield String(self, "header", 3, "Header (ID3)", charset="ASCII") yield UInt8(self, "ver_major", "Version (major)") yield UInt8(self, "ver_minor", "Version (minor)") # Check format if self["header"].value != "ID3": raise MatchError("Signature error, should be \"ID3\".") if self["ver_major"].value not in self.VALID_MAJOR_VERSIONS \ or self["ver_minor"].value != 0: raise MatchError( "Unknown ID3 metadata version (2.%u.%u)" % (self["ver_major"].value, self["ver_minor"].value)) # Flags yield Bit(self, "unsync", "Unsynchronisation is used?") yield Bit(self, "ext", "Extended header is used?") yield Bit(self, "exp", "Experimental indicator") yield NullBits(self, "padding[]", 5) # Size yield ID3_Size(self, "size") # All tags while self.current_size < self._size: field = ID3_Chunk(self, "field[]") yield field if field["size"].value == 0: break # Search first byte of the MPEG file padding = self.seekBit(self._size) if padding: yield padding
def createFields(self): yield String(self, "text", self._size // 8, "Text", charset="ISO-8859-1", strip=self.STRIP)
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 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 from ZipStartCommonFields(self) # PY3 for field in ZipStartCommonFields(self): yield field length = self["filename_length"].value if length: filename = String(self, "filename", length, "Filename", charset=zipGetCharset(self)) yield filename self.filename = filename.value if self["extra_length"].value: yield ExtraFields(self, "extra", size=self["extra_length"].value * 8, description="Extra fields") size = self["compressed_size"].value if size > 0: yield self.data(size) elif self["flags/incomplete"].value: # yield from self.resync() # PY3 for field in self.resync(): yield field if self["flags/has_descriptor"].value and self['crc32'].value == 0: yield ZipDataDescriptor(self, "data_desc", "Data descriptor")
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 createFields(self): # Header yield NullBytes(self, "zero_vector", 16) yield GUID(self, "fs_guid") yield UInt64(self, "volume_len") yield String(self, "signature", 4) yield UInt32(self, "attributes") yield UInt16(self, "header_len") yield UInt16(self, "checksum") yield UInt16(self, "ext_header_offset") yield UInt8(self, "reserved") yield UInt8(self, "revision") while True: bm = BlockMap(self, "block_map[]") yield bm if bm['num_blocks'].value == 0 and bm['len'].value == 0: break # TODO must handle extended header # Content while not self.eof: padding = paddingSize(self.current_size // 8, 8) if padding: yield PaddingBytes(self, "padding[]", padding) yield File(self, "file[]")