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 String(self, "header", 2, "File header (MZ)", charset="ASCII") yield UInt16(self, "size_mod_512", "File size in bytes modulo 512") yield UInt16(self, "size_div_512", "File size in bytes divide by 512") yield UInt16(self, "reloc_entries", "Number of relocation entries") yield UInt16(self, "code_offset", "Offset to the code in the file (divided by 16)") yield UInt16(self, "needed_memory", "Memory needed to run (divided by 16)") yield UInt16(self, "max_memory", "Maximum memory needed to run (divided by 16)") yield textHandler( UInt32(self, "init_ss_sp", "Initial value of SP:SS registers"), hexadecimal) yield UInt16(self, "checksum", "Checksum") yield textHandler( UInt32(self, "init_cs_ip", "Initial value of CS:IP registers"), hexadecimal) yield UInt16(self, "reloc_offset", "Offset in file to relocation table") yield UInt16(self, "overlay_number", "Overlay number") yield PaddingBytes(self, "reserved[]", 8, "Reserved") yield UInt16(self, "oem_id", "OEM id") yield UInt16(self, "oem_info", "OEM info") yield PaddingBytes(self, "reserved[]", 20, "Reserved") yield UInt32(self, "next_offset", "Offset to next header (PE or NE)")
def createFields(self): yield textHandler(UInt8(self, "version"), hexadecimal) # TODO: sum of : # TrackEnabled = 1; # TrackInMovie = 2; # TrackInPreview = 4; # TrackInPoster = 8 yield RawBytes(self, "flags", 3) yield TimestampMac32(self, "creation_date") yield TimestampMac32(self, "lastmod_date") yield UInt32(self, "track_id") yield PaddingBytes(self, "reserved[]", 8) yield UInt32(self, "duration") yield PaddingBytes(self, "reserved[]", 8) yield Int16(self, "video_layer", "Middle is 0, negative in front") yield PaddingBytes(self, "other", 2) yield QTFloat32(self, "geom_a", "Width scale") yield QTFloat32(self, "geom_b", "Width rotate") yield QTFloat32(self, "geom_u", "Width angle") yield QTFloat32(self, "geom_c", "Height rotate") yield QTFloat32(self, "geom_d", "Height scale") yield QTFloat32(self, "geom_v", "Height angle") yield QTFloat32(self, "geom_x", "Position X") yield QTFloat32(self, "geom_y", "Position Y") yield QTFloat32(self, "geom_w", "Divider scale") yield QTFloat32(self, "frame_size_width") yield QTFloat32(self, "frame_size_height")
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 createPaddingField(parent, nbits, name="padding[]", description=None): if nbits <= 0: raise FieldError("Unable to create padding of %s bits" % nbits) if (nbits % 8) == 0: return PaddingBytes(parent, name, nbits / 8, description) else: return PaddingBits(parent, name, nbits, description)
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[]")
def createFields(self): yield textHandler(UInt8(self, "version"), hexadecimal) yield RawBytes(self, "flags", 3) yield TimestampMac32(self, "creation_date") yield TimestampMac32(self, "lastmod_date") yield UInt32(self, "time_scale") yield UInt32(self, "duration") yield QTFloat32(self, "play_speed") yield UInt16(self, "volume") yield PaddingBytes(self, "reserved[]", 10) yield QTFloat32(self, "geom_a", "Width scale") yield QTFloat32(self, "geom_b", "Width rotate") yield QTFloat32(self, "geom_u", "Width angle") yield QTFloat32(self, "geom_c", "Height rotate") yield QTFloat32(self, "geom_d", "Height scale") yield QTFloat32(self, "geom_v", "Height angle") yield QTFloat32(self, "geom_x", "Position X") yield QTFloat32(self, "geom_y", "Position Y") yield QTFloat32(self, "geom_w", "Divider scale") yield UInt32(self, "preview_start") yield UInt32(self, "preview_length") yield UInt32(self, "still_poster") yield UInt32(self, "sel_start") yield UInt32(self, "sel_length") yield UInt32(self, "current_time") yield UInt32(self, "next_track")
def createFields(self): if self.stream.readBits(self.absolute_address, 2, self.endian) == 1: # MPEG version 2 yield Bits(self, "sync[]", 2) yield SCR(self, "scr") yield Bit(self, "sync[]") yield Bits(self, "scr_ext", 9) yield Bit(self, "sync[]") yield Bits(self, "mux_rate", 22) yield Bits(self, "sync[]", 2) yield PaddingBits(self, "reserved", 5, pattern=1) yield Bits(self, "stuffing_length", 3) count = self["stuffing_length"].value if count: yield PaddingBytes(self, "stuffing", count, pattern="\xff") else: # MPEG version 1 yield Bits(self, "sync[]", 4) yield Bits(self, "scr_a", 3) yield Bit(self, "sync[]") yield Bits(self, "scr_b", 15) yield Bit(self, "sync[]") yield Bits(self, "scr_c", 15) yield Bits(self, "sync[]", 2) yield Bits(self, "mux_rate", 22) yield Bit(self, "sync[]")
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 xrange(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): # Parse directories depth = 0 subdir = Directory(self, "root") yield subdir subdirs = [subdir] alldirs = [subdir] while subdirs: depth += 1 if MAX_DEPTH < depth: self.error("EXE resource: depth too high (%s), stop parsing directories" % depth) break newsubdirs = [] for index, subdir in enumerate(subdirs): name = "directory[%u][%u][]" % (depth, index) try: for field in self.parseSub(subdir, name, depth): if field.__class__ == Directory: newsubdirs.append(field) yield field except HACHOIR_ERRORS as err: self.error("Unable to create directory %s: %s" % (name, err)) subdirs = newsubdirs alldirs.extend(subdirs) # Create resource list resources = [] for directory in alldirs: for index in directory.array("index"): if not index["is_subdir"].value: resources.append(index) # Parse entries entries = [] for resource in resources: offset = resource["offset"].value if offset is None: continue self.seekByte(offset) entry = Entry(self, "entry[]", inode=resource) yield entry entries.append(entry) entries.sort(key=lambda entry: entry["rva"].value) # Parse resource content for entry in entries: try: offset = self.section.rva2file(entry["rva"].value) padding = self.seekByte(offset, relative=False) if padding: yield padding yield ResourceContent(self, "content[]", entry) except HACHOIR_ERRORS as err: self.warning("Error when parsing entry %s: %s" % (entry.path, err)) size = (self.size - self.current_size) // 8 if size: yield PaddingBytes(self, "padding_end", size)
def createFields(self): while self.current_size < self.size: pos = self.stream.searchBytes( '\0\0\1', self.current_size, self.current_size + 1024 * 1024 * 8) # seek forward by at most 1MB if pos is not None: padsize = pos - self.current_size if padsize: yield PaddingBytes(self, "pad[]", padsize // 8) yield VideoChunk(self, "chunk[]")
def createFields(self): yield displayHandler(UInt32(self, "res_space", "Reserved space"), humanFilesize) yield displayHandler(UInt32(self, "used_space", "Used space"), humanFilesize) yield Bits(self, "file_flags", 8, "(=4)") yield textHandler(UInt16(self, "magic"), hexadecimal) yield Bits(self, "flags", 16) yield displayHandler(UInt16(self, "page_size", "Page size in bytes"), humanFilesize) yield String(self, "structure", 16, strip="\0", charset="ASCII") yield NullBytes(self, "zero", 2) yield UInt16(self, "nb_page_splits", "Number of page splits B+ tree has suffered") yield UInt16(self, "root_page", "Page number of B+ tree root page") yield PaddingBytes(self, "one", 2, pattern="\xFF") yield UInt16(self, "nb_page", "Number of B+ tree pages") yield UInt16(self, "nb_level", "Number of levels of B+ tree") yield UInt16(self, "nb_entry", "Number of entries in B+ tree") size = (self.size - self.current_size)//8 if size: yield PaddingBytes(self, "reserved_space", size)
def createFields(self): if False: yield UInt32(self, "width0") yield UInt32(self, "height0") yield PaddingBytes(self, "reserved[]", 7) yield UInt32(self, "width") yield UInt32(self, "height") yield PaddingBytes(self, "reserved[]", 2) yield UInt16(self, "depth") yield Enum(String(self, "codec", 4, charset="ASCII"), video_fourcc_name) yield NullBytes(self, "padding", 20) else: yield UInt32(self, "width") yield UInt32(self, "height") yield PaddingBytes(self, "reserved[]", 1) yield UInt16(self, "format_data_size") if self["format_data_size"].value < 40: raise ParserError("Unknown format data size") yield BitmapInfoHeader(self, "bmp_info", use_fourcc=True)
def synchronize(self): addr = self.absolute_address start = addr + self.current_size end = min(start + self.MAX_PADDING*8, addr + self.size) padding = findSynchronizeBits(self, start, end) if padding is None: raise ParserError("MPEG audio: Unable to find synchronization bits") if padding: return PaddingBytes(self, "padding[]", padding, "Padding before synchronization") else: return None
def createFields(self): yield String(self, "magic", 4, "PMGI", charset="ASCII") yield filesizeHandler(UInt32(self, "free_space", "Length of free space and/or quickref area at end of directory chunk")) stop = self.size - self["free_space"].value * 8 while self.current_size < stop: yield PMGI_Entry(self, "entry[]") padding = (self.size - self.current_size) // 8 if padding: yield PaddingBytes(self, "padding", padding)
def createFields(self): yield Bytes(self, "signature", 2, "New executable signature (NE)") yield UInt8(self, "link_ver", "Linker version number") yield UInt8(self, "link_rev", "Linker revision number") yield UInt16(self, "entry_table_ofst", "Offset to the entry table") yield UInt16(self, "entry_table_size", "Length (in bytes) of the entry table") yield PaddingBytes(self, "reserved[]", 4) yield Bit(self, "is_dll", "Is a dynamic-link library (DLL)?") yield Bit(self, "is_win_app", "Is a Windows application?") yield PaddingBits(self, "reserved[]", 9) yield Bit(self, "first_seg_code", "First segment contains code that loads the application?") yield NullBits(self, "reserved[]", 1) yield Bit(self, "link_error", "Load even if linker detects errors?") yield NullBits(self, "reserved[]", 1) yield Bit(self, "is_lib", "Is a library module?") yield UInt16(self, "auto_data_seg", "Automatic data segment number") yield filesizeHandler(UInt16(self, "local_heap_size", "Initial size (in bytes) of the local heap")) yield filesizeHandler(UInt16(self, "stack_size", "Initial size (in bytes) of the stack")) yield textHandler(UInt32(self, "cs_ip", "Value of CS:IP"), hexadecimal) yield textHandler(UInt32(self, "ss_sp", "Value of SS:SP"), hexadecimal) yield UInt16(self, "nb_entry_seg_tab", "Number of entries in the segment table") yield UInt16(self, "nb_entry_modref_tab", "Number of entries in the module-reference table") yield filesizeHandler(UInt16(self, "size_nonres_name_tab", "Number of bytes in the nonresident-name table")) yield UInt16(self, "seg_tab_ofs", "Segment table offset") yield UInt16(self, "rsrc_ofs", "Resource offset") yield UInt16(self, "res_name_tab_ofs", "Resident-name table offset") yield UInt16(self, "mod_ref_tab_ofs", "Module-reference table offset") yield UInt16(self, "import_tab_ofs", "Imported-name table offset") yield UInt32(self, "non_res_name_tab_ofs", "Nonresident-name table offset") yield UInt16(self, "nb_mov_ent_pt", "Number of movable entry points") yield UInt16(self, "log2_sector_size", "Log2 of the segment sector size") yield UInt16(self, "nb_rsrc_seg", "Number of resource segments") yield Bit(self, "unknown_os_format", "Operating system format is unknown") yield PaddingBits(self, "reserved[]", 1) yield Bit(self, "os_windows", "Operating system is Microsoft Windows") yield NullBits(self, "reserved[]", 6) yield Bit(self, "is_win20_prot", "Is Windows 2.x application running in version 3.x protected mode") yield Bit(self, "is_win20_font", "Is Windows 2.x application supporting proportional fonts") yield Bit(self, "fast_load", "Contains a fast-load area?") yield NullBits(self, "reserved[]", 4) yield UInt16(self, "fastload_ofs", "Fast-load area offset (in sector)") yield UInt16(self, "fastload_size", "Fast-load area length (in sector)") yield NullBytes(self, "reserved[]", 2) yield textHandler(UInt16(self, "win_version", "Expected Windows version number"), hexadecimal)
def createFields(self): while self.current_size < self.size: pos = self.stream.searchBytes( '\0\0\1', self.current_size, self.current_size + 1024 * 1024 * 8) # seek forward by at most 1MB if pos is not None: padsize = pos - self.current_size if padsize: yield PaddingBytes(self, "pad[]", padsize // 8) chunk = Chunk(self, "chunk[]") try: # force chunk to be processed, so that CustomFragments are complete chunk['content/data'] except: pass yield chunk
def createFields(self): yield UInt32(self, "root_block", "The block number of the root node of the B-tree") yield UInt32( self, "tree_levels", "The number of levels of internal nodes (tree height minus one)") yield UInt32(self, "num_records", "The number of records in the tree") yield UInt32( self, "num_nodes", "The number of nodes in the tree (tree nodes, not including this header block)" ) yield UInt32(self, "unknown", "Always 0x1000, probably the tree node page size") if self.current_size < self.size: yield PaddingBytes(self, "slack", (self.size - self.current_size) // 8, description="slack space")
def yieldChunks(self, obj): while len(self.chunks) > 0: chunk = self.chunks.pop() current_pos = obj.current_size // 8 # Check if padding needed size = chunk.offset - current_pos if size > 0: obj.info("Padding of %u bytes needed: curr=%u offset=%u" % \ (size, current_pos, chunk.offset)) yield PaddingBytes(obj, "padding[]", size) current_pos = obj.current_size // 8 # Find resynch point if needed count = 0 old_off = chunk.offset while chunk.offset < current_pos: count += 1 chunk = self.chunks.pop() # Unfortunaly, we also pass the underlying chunks if chunk == None: obj.info("Couldn't resynch: %u object skipped to reach %u" % \ (count, current_pos)) return # Resynch size = chunk.offset - current_pos if size > 0: obj.info("Skipped %u objects to resynch to %u; chunk offset: %u->%u" % \ (count, current_pos, old_off, chunk.offset)) yield RawBytes(obj, "resynch[]", size) # Yield obj.info("Yielding element of size %u at offset %u" % \ (chunk.size, chunk.offset)) field = chunk.cls(obj, chunk.name, chunk.size, *chunk.args) # Not tested, probably wrong: #if chunk.size: field.static_size = 8*chunk.size yield field if hasattr(field, "getSubChunks"): for sub_chunk in field.getSubChunks(): obj.info("Adding sub chunk: position=%u size=%u name='%s'" % \ (sub_chunk.offset, sub_chunk.size, sub_chunk.name)) self.addChunk(sub_chunk)
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 while self.current_size < stop: yield PMGL_Entry(self, "entry[]") # Padding padding = (self.size - self.current_size) // 8 if padding: yield PaddingBytes(self, "padding", padding)
def createFields(self): yield String(self, "name", 8, charset="ASCII", strip="\0 ") yield filesizeHandler(UInt32(self, "mem_size", "Size in memory")) yield textHandler(UInt32(self, "rva", "RVA (location) in memory"), hexadecimal) yield filesizeHandler( UInt32(self, "phys_size", "Physical size (on disk)")) yield filesizeHandler( UInt32(self, "phys_off", "Physical location (on disk)")) yield PaddingBytes(self, "reserved", 12) # 0x0000000# yield NullBits(self, "reserved[]", 4) # 0x000000#0 yield NullBits(self, "reserved[]", 1) yield Bit(self, "has_code", "Contains code") yield Bit(self, "has_init_data", "Contains initialized data") yield Bit(self, "has_uninit_data", "Contains uninitialized data") # 0x00000#00 yield NullBits(self, "reserved[]", 1) yield Bit(self, "has_comment", "Contains comments?") yield NullBits(self, "reserved[]", 1) yield Bit(self, "remove", "Contents will not become part of image") # 0x0000#000 yield Bit(self, "has_comdata", "Contains comdat?") yield NullBits(self, "reserved[]", 1) yield Bit( self, "no_defer_spec_exc", "Reset speculative exceptions handling bits in the TLB entries") yield Bit(self, "gp_rel", "Content can be accessed relative to GP") # 0x000#0000 yield NullBits(self, "reserved[]", 4) # 0x00#00000 yield NullBits(self, "reserved[]", 4) # 0x0#000000 yield Bit(self, "ext_reloc", "Contains extended relocations?") yield Bit(self, "discarded", "Can be discarded?") yield Bit(self, "is_not_cached", "Is not cachable?") yield Bit(self, "is_not_paged", "Is not pageable?") # 0x#0000000 yield Bit(self, "is_shareable", "Is shareable?") yield Bit(self, "is_executable", "Is executable?") yield Bit(self, "is_readable", "Is readable?") yield Bit(self, "is_writable", "Is writable?")
def createFields(self): yield UInt32(self, "last_block") yield UInt32(self, "count") if self['last_block'].value != 0: for i in xrange(self['count'].value): block = UInt32(self, "child_block[]") yield block link = Link(self, "child_link[]") link.createValue = self.linkValue(block) yield link yield DSRecord(self, "record[]") link = Link(self, "child_link[]") link.createValue = self.linkValue(self['last_block']) yield link else: for i in xrange(self['count'].value): yield DSRecord(self, "record[]") if self.current_size < self.size: yield PaddingBytes(self, "slack", (self.size - self.current_size) // 8, description="slack space")
def getHeaderEndFields(self): instr = self["num_instruments"].value patterns = self["num_patterns"].value # File pointers if instr > 0: yield GenericVector(self, "instr_pptr", instr, UInt16, "offset") if patterns > 0: yield GenericVector(self, "pattern_pptr", patterns, UInt16, "offset") # S3M 3.20 extension if self["creation_version_major"].value >= 3 \ and self["creation_version_minor"].value >= 0x20 \ and self["panning_info"].value == 252: yield GenericVector(self, "channel_panning", 32, ChannelPanning, "channel") # Padding required for 16B alignment size = self._size - self.current_size if size > 0: yield PaddingBytes(self, "padding", size // 8)
def createFields(self): yield UInt32(self, "nblocks") yield UInt32(self, "unknown", description="Always 0") for i in xrange(self['nblocks'].value): yield BlockAddress(self, "block[]") padding = paddingSize(self['nblocks'].value, 256) if padding: yield NullBytes( self, "padding", padding * 4, description= "padding to make the number of blocks a multiple of 256") yield UInt32(self, "ndirs") for i in xrange(self['ndirs'].value): yield BudDirectory(self, "dir[]") for i in xrange(32): yield FreeList(self, "freelist[]") if self.current_size < self.size: yield PaddingBytes(self, "slack", (self.size - self.current_size) // 8, description="slack space")
def createFields(self): yield Enum(textHandler(UInt32(self, "type"), hexadecimal), self.ATTR_NAME) yield UInt32(self, "size") yield UInt8(self, "non_resident", "Non-resident flag") yield UInt8(self, "name_length", "Name length in bytes") yield UInt16(self, "name_offset", "Name offset") yield UInt16(self, "flags") yield textHandler(UInt16(self, "attribute_id"), hexadecimal) yield UInt32(self, "length_attr", "Length of the Attribute") yield UInt16(self, "offset_attr", "Offset of the Attribute") yield UInt8(self, "indexed_flag") yield NullBytes(self, "padding", 1) if self._parser: for field in self._parser(self): yield field else: size = self["length_attr"].value if size: yield RawBytes(self, "data", size) size = (self.size - self.current_size) // 8 if size: yield PaddingBytes(self, "end_padding", size)
def createFields(self): yield UInt8(self, "red", "Red") yield UInt8(self, "green", "Green") yield UInt8(self, "blue", "Blue") yield PaddingBytes(self, "pad", 1, "Padding (must be 0)")
def createFields(self): for field in self.createUnpaddedFields(): yield field size = (self._size - self.current_size) // 8 if size > 0: yield PaddingBytes(self, "padding", size)
def createFields(self): yield UInt16(self, "length", "Length of Item ID Entry") if not self["length"].value: return yield Enum(UInt8(self, "type"), self.ITEM_TYPE) entrytype = self["type"].value if entrytype in (0x1F, 0x70): # GUID yield RawBytes(self, "dummy", 1, "should be 0x50") yield GUID(self, "guid") elif entrytype == 0x2E: # Shell extension yield RawBytes(self, "dummy", 1, "should be 0x50") if self["dummy"].value == '\0': yield UInt16(self, "length_data", "Length of shell extension-specific data") if self["length_data"].value: yield RawBytes(self, "data", self["length_data"].value, "Shell extension-specific data") yield GUID(self, "handler_guid") yield GUID(self, "guid") elif entrytype in (0x23, 0x25, 0x29, 0x2F): # Drive yield String(self, "drive", self["length"].value - 3, strip="\0") elif entrytype in (0x30, 0x31, 0x32, 0x61, 0xb1): yield RawBytes(self, "dummy", 1, "should be 0x00") yield UInt32(self, "size", "size of file; 0 for folders") yield DateTimeMSDOS32(self, "date_time", "File/folder date and time") yield MSDOSFileAttr16(self, "attribs", "File/folder attributes") yield CString(self, "name", "File/folder name") if self.root.hasUnicodeNames(): # Align to 2-bytes n = paddingSize(self.current_size // 8, 2) if n: yield PaddingBytes(self, "pad", n) yield UInt16(self, "length_w", "Length of wide struct member") yield RawBytes(self, "unknown[]", 6) yield DateTimeMSDOS32(self, "creation_date_time", "File/folder creation date and time") yield DateTimeMSDOS32(self, "access_date_time", "File/folder last access date and time") yield RawBytes(self, "unknown[]", 2) yield UInt16( self, "length_next", "Length of next two strings (if zero, ignore this field)") yield CString(self, "unicode_name", "File/folder name", charset="UTF-16-LE") if self["length_next"].value: yield CString(self, "localized_name", "Localized name") yield RawBytes(self, "unknown[]", 2) else: yield CString(self, "name_short", "File/folder short name") elif entrytype in (0x41, 0x42, 0x46): yield RawBytes(self, "unknown[]", 2) yield CString(self, "name") yield CString(self, "protocol") yield RawBytes(self, "unknown[]", 2) elif entrytype == 0x47: # Whole Network yield RawBytes(self, "unknown[]", 2) yield CString(self, "name") elif entrytype == 0xC3: # Network Share yield RawBytes(self, "unknown[]", 2) yield CString(self, "name") yield CString(self, "protocol") yield CString(self, "description") yield RawBytes(self, "unknown[]", 2) elif entrytype == 0x4C: # Web Folder yield RawBytes(self, "unknown[]", 5) yield TimestampWin64(self, "modification_time") yield UInt32(self, "unknown[]") yield UInt32(self, "unknown[]") yield UInt32(self, "unknown[]") yield LnkString(self, "name") yield RawBytes(self, "padding[]", 2) yield LnkString(self, "address") if self["address/length"].value: yield RawBytes(self, "padding[]", 2) else: yield RawBytes(self, "raw", self["length"].value - 3)
def createFields(self): yield UInt32(self, "obj_count") yield PaddingBytes(self, "reserved[]", 2) for index in xrange(self["obj_count"].value): yield Object(self, "object[]")
def createFields(self): yield GUID(self, "file_id") yield UInt64(self, "packet_count") yield PaddingBytes(self, "reserved", 2) size = (self.size - self.current_size) / 8 yield RawBytes(self, "data", size)