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): 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): # First kilobyte: boot sectors yield RawBytes(self, "boot", 1024, "Space for disklabel etc.") # Header yield UInt32(self, "version") yield UInt32(self, "last_page") yield UInt32(self, "nb_badpage") yield UUID(self, "sws_uuid") yield UUID(self, "sws_volume") yield NullBytes(self, "reserved", 117 * 4) # Read bad pages (if any) count = self["nb_badpage"].value if count: if MAX_SWAP_BADPAGES < count: raise ParserError("Invalid number of bad page (%u)" % count) yield GenericVector(self, "badpages", count, UInt32, "badpage") # Read magic padding = self.seekByte(PAGE_SIZE - 10, "padding", null=True) if padding: yield padding yield String(self, "magic", 10, charset="ASCII") # Read all pages yield GenericVector(self, "pages", self["last_page"].value, Page, "page") # Padding at the end padding = self.seekBit(self.size, "end_padding", null=True) if padding: yield padding
def parsePortableExecutable(self): # Read PE header yield PE_Header(self, "pe_header") # Read PE optional header size = self["pe_header/opt_hdr_size"].value rsrc_rva = None if size: yield PE_OptHeader(self, "pe_opt_header", size=size * 8) if "pe_opt_header/resource/rva" in self: rsrc_rva = self["pe_opt_header/resource/rva"].value # Read section headers sections = [] for index in range(self["pe_header/nb_section"].value): section = SectionHeader(self, "section_hdr[]") yield section if section["phys_size"].value: sections.append(section) # Read sections sections.sort(key=lambda field: field["phys_off"].value) for section in sections: self.seekByte(section["phys_off"].value) size = section["phys_size"].value if size: name = section.createSectionName() if rsrc_rva is not None and section["rva"].value == rsrc_rva: yield PE_Resource(self, name, section, size=size * 8) else: yield RawBytes(self, name, 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 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 Bits(self, "version", 4, "Version") yield Bits(self, "hdr_size", 4, "Header size divided by 5") # Type of service yield Enum(Bits(self, "precedence", 3, "Precedence"), self.precedence_name) yield Bit(self, "low_delay", "If set, low delay, else normal delay") yield Bit(self, "high_throu", "If set, high throughput, else normal throughput") yield Bit(self, "high_rel", "If set, high relibility, else normal") yield NullBits(self, "reserved[]", 2, "(reserved for future use)") yield UInt16(self, "length") yield UInt16(self, "id") yield NullBits(self, "reserved[]", 1) yield Bit(self, "df", "Don't fragment") yield Bit(self, "more_frag", "There are more fragments? if not set, it's the last one") yield Bits(self, "frag_ofst_lo", 5) yield UInt8(self, "frag_ofst_hi") yield UInt8(self, "ttl", "Type to live") yield Enum(UInt8(self, "protocol"), self.PROTOCOL_NAME) yield textHandler(UInt16(self, "checksum"), hexadecimal) yield IPv4_Address(self, "src") yield IPv4_Address(self, "dst") size = (self.size - self.current_size) // 8 if size: yield RawBytes(self, "options", size)
def createFields(self): 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): 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): 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])