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 UInt16(self, "left", "Left") yield UInt16(self, "top", "Top") yield UInt16(self, "width", "Width") yield UInt16(self, "height", "Height") yield Bits(self, "size_local_map", 3, "log2(size of local map) minus one") yield NullBits(self, "reserved", 2) yield Bit(self, "sort_flag", "Is the local map sorted by decreasing importance?") yield Bit(self, "interlaced", "Interlaced?") yield Bit(self, "has_local_map", "Use local color map?") if self["has_local_map"].value: nb_color = 1 << (1 + self["size_local_map"].value) yield PaletteRGB(self, "local_map", nb_color, "Local color map") yield UInt8(self, "lzw_min_code_size", "LZW Minimum Code Size") group = None while True: size = UInt8(self, "image_block_size[]") if size.value == 0: break yield size block = CustomFragment(self, "image_block[]", size.value * 8, GifImageBlock, "GIF Image Block", group) if group is None: block.group.args["startbits"] = self["lzw_min_code_size"].value group = block.group yield block yield NullBytes(self, "terminator", 1, "Terminator (0)")
def parseProperty(self, property, name_prefix, parser=RawParser): if not property["size"].value: return if property["size"].value < self[ "header/threshold"].value and name_prefix != 'root': return name = "%s[]" % name_prefix first = None previous = None size = 0 fragment_group = None chain = self.getChain(property["start"].value) while True: try: block = next(chain) contiguous = False if first is None: first = block contiguous = True if previous is not None and block == (previous + 1): contiguous = True if contiguous: previous = block size += self.sector_size continue except StopIteration: block = None if first is None: break self.seekBlock(first) desc = "Big blocks %s..%s (%s)" % (first, previous, previous - first + 1) desc += " of %s bytes" % (self.sector_size // 8) field = CustomFragment(self, name, size, parser, desc, fragment_group) if not fragment_group: fragment_group = field.group fragment_group.args["ole2"] = field.root fragment_group.args["datasize"] = property["size"].value fragment_group.args["ole2name"] = property["name"].value yield field if block is None: break first = block previous = block size = self.sector_size
def createFields(self): superblock = self["/superblock"] # Compute number of block and inodes block_count = superblock["blocks_per_group"].value inode_count = superblock["inodes_per_group"].value block_index = self.descriptor.uniq_id * block_count inode_index = self.descriptor.uniq_id * inode_count if (block_count % 8) != 0: raise ParserError("Invalid block count") if (inode_count % 8) != 0: raise ParserError("Invalid inode count") block_count = min(block_count, superblock["blocks_count"].value - block_index) inode_count = min(inode_count, superblock["inodes_count"].value - inode_index) bitmap_block_size = self.root.block_size * 8 block_bitmap_size = (block_count + bitmap_block_size - 1) // bitmap_block_size * bitmap_block_size inode_bitmap_size = (inode_count + bitmap_block_size - 1) // bitmap_block_size * bitmap_block_size self.seekBlock(self.descriptor["block_bitmap"].value) yield BlockBitmap(self, "block_bitmap", block_index, block_count, block_bitmap_size, "Block bitmap") self.seekBlock(self.descriptor["inode_bitmap"].value) yield InodeBitmap(self, "inode_bitmap", inode_index, inode_count, inode_bitmap_size, "Inode bitmap") self.seekBlock(self.descriptor["inode_table"].value) yield InodeTable(self, "inode_table", inode_index, inode_count) inode_bitmap = self['inode_bitmap'] for i, inode in enumerate(self['inode_table'].array('inode')): if not inode_bitmap['item[%d]' % i].value: continue if inode['blocks'].value == 0: continue blocks = inode.array('block') if inode['mode/file_type'].display == 'Directory': parser = Directory else: parser = None group = FragmentGroup(parser=parser) for b in range(12): if not blocks[b].value: continue self.seekBlock(blocks[b].value) yield CustomFragment(self, "inode[%d]block[]" % i, self.root.block_size * 8, None, group=group) if blocks[12].value: # indirect block self.seekBlock(blocks[12].value) indirect = IndirectBlock(self, "inode[%d]indirect" % i, self.root.block_size) yield indirect for b in indirect.array('block'): if not b.value: continue self.seekBlock(b.value) yield CustomFragment(self, "inode[%d]block[]" % i, self.root.block_size * 8, None, group=group) if blocks[13].value: # TODO: double-indirect block pass if blocks[14].value: # TODO: triple-indirect block pass
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