def output (self): globals.outputln('') globals.outputln("="*globals.OutputWidth) globals.outputln("Master Sector Allocation Table (MSAT)") globals.outputln("-"*globals.OutputWidth) for id in self.secIDs: globals.outputln("sector ID: %5d (pos: %7d)"%(id, 512+id*self.sectorSize))
def __outputRaw(self, name, bytes): if bytes == None: return output("%s: " % name) for byte in bytes: output("%2.2X " % ord(byte)) globals.outputln("")
def __outputRaw (self, name, bytes): if bytes == None: return output("%s: "%name) for byte in bytes: output("%2.2X "%ord(byte)) globals.outputln("")
def output(self): globals.outputln('') globals.outputln("=" * globals.OutputWidth) globals.outputln("Master Sector Allocation Table (MSAT)") globals.outputln("-" * globals.OutputWidth) for id in self.secIDs: globals.outputln("sector ID: %5d (pos: %7d)" % (id, 512 + id * self.sectorSize))
def __printListReport( self, treeNode ): dateInfo = self.__getModifiedTime( treeNode.Entry ) if len( treeNode.HierachicalName ) > 0 : globals.outputln('{0:8d} {1:0<2d}-{2:0<2d}-{3:0<2d} {4:0<2d}:{5:0<2d} {6}'.format(treeNode.Entry.StreamSize, dateInfo.day, dateInfo.month, dateInfo.year, dateInfo.hour, dateInfo.second, treeNode.HierachicalName )) for node in treeNode.Nodes: # ignore the root self.__printListReport( node )
def extract(self, name): self.__parseFile() if self.rootNode != None: entry = self.__findEntryByHierachicalName( self.rootNode, name ) bytes = self.getStreamForEntry( entry ) file = open(entry.Name, 'wb') file.write( bytes ) file.close else: globals.outputln("failed to initialise ole container")
def extract(self, name): self.__parseFile() if self.rootNode != None: entry = self.__findEntryByHierachicalName(self.rootNode, name) bytes = self.getStreamForEntry(entry) file = open(entry.Name, 'wb') file.write(bytes) file.close else: globals.outputln("failed to initialise ole container")
def output (self): globals.outputln('') globals.outputln("="*globals.OutputWidth) globals.outputln("Short Sector Allocation Table (SSAT)") globals.outputln("-"*globals.OutputWidth) if self.params.debug: self.outputRawBytes() globals.outputln("-"*globals.OutputWidth) for i in xrange(0, len(self.array)): item = self.array[i] output("%3d : %3d\n"%(i, item)) self.outputArrayStats()
def output(self): globals.outputln('') globals.outputln("=" * globals.OutputWidth) globals.outputln("Short Sector Allocation Table (SSAT)") globals.outputln("-" * globals.OutputWidth) if self.params.debug: self.outputRawBytes() globals.outputln("-" * globals.OutputWidth) for i in xrange(0, len(self.array)): item = self.array[i] output("%3d : %3d\n" % (i, item)) self.outputArrayStats()
def printRecordDump (self, bytes, recordType): if self.params.noStructOutput and self.params.dumpText: return size = len(bytes) self.__printSep('-', 61, "%4.4Xh: "%recordType, recordType = recordType) for i in xrange(0, size): if (i+1) % 16 == 1: output(self.prefix + "%4.4Xh: "%recordType, recordType = recordType) output("%2.2X "%ord(bytes[i]), recordType = recordType) if (i+1) % 16 == 0 and i != size-1: globals.outputln("", recordType = recordType) if size > 0: globals.outputln("", recordType = recordType) self.__printSep('-', 61, "%4.4Xh: "%recordType, recordType = recordType)
def __printListReport(self, treeNode): dateInfo = self.__getModifiedTime(treeNode.Entry) if len(treeNode.HierachicalName) > 0: globals.outputln( '{0:8d} {1:0<2d}-{2:0<2d}-{3:0<2d} {4:0<2d}:{5:0<2d} {6}'. format(treeNode.Entry.StreamSize, dateInfo.day, dateInfo.month, dateInfo.year, dateInfo.hour, dateInfo.second, treeNode.HierachicalName)) for node in treeNode.Nodes: # ignore the root self.__printListReport(node)
def read (self): globals.outputln("moniker size: %d"%(len(self.strm.bytes)-16)) clsID = self.strm.readBytes(16) globals.outputln("CLS ID: %s"%globals.getRawBytes(clsID, True, False)) globals.outputln("stream data (implemention specific):") globals.dumpBytes(self.strm.readRemainingBytes()) globals.outputln("")
def read(self): globals.outputln("moniker size: %d" % (len(self.strm.bytes) - 16)) clsID = self.strm.readBytes(16) globals.outputln("CLS ID: %s" % globals.getRawBytes(clsID, True, False)) globals.outputln("stream data (implemention specific):") globals.dumpBytes(self.strm.readRemainingBytes()) globals.outputln("")
def __outputSectorChain(self, chain): line = "sector chain: " lineLen = len(line) for id in chain: frag = "%d, " % id fragLen = len(frag) if lineLen + fragLen > 68: globals.outputln(line) line = frag lineLen = fragLen else: line += frag lineLen += fragLen if line[-2:] == ", ": line = line[:-2] lineLen -= 2 if lineLen > 0: globals.outputln(line)
def __outputSectorChain (self, chain): line = "sector chain: " lineLen = len(line) for id in chain: frag = "%d, "%id fragLen = len(frag) if lineLen + fragLen > 68: globals.outputln(line) line = frag lineLen = fragLen else: line += frag lineLen += fragLen if line[-2:] == ", ": line = line[:-2] lineLen -= 2 if lineLen > 0: globals.outputln(line)
def readRecord (self): startPos = self.pos recordInstance = self.readUnsignedInt(2) recordVersion = (recordInstance & 0x000F) recordInstance = recordInstance // 16 recordType = self.readUnsignedInt(2) size = self.readUnsignedInt(4) globals.outputln("", recordType = recordType) self.printRecordHeader(startPos, recordInstance, recordVersion, recordType, size) bytes = self.readBytes(size) recordInfo = None if recordType in recData and len(recData[recordType]) >= 2: recordInfo = recData[recordType] if recordVersion == 0x0F: # substream? recurse into that subSubStrm = PPTDirStream(bytes, self.params, self.prefix+" ", recordInfo) subSubStrm.readRecords() elif (recordInfo is not None and recordInfo[1] == "magic"): if self.isPPT10SpecialData(): # what a mess. PPT10 binary data is just another embedded # stream self.handlePPT10BinaryTags(bytes,recordInfo) elif recordInfo is not None: handler = recordInfo[1](recordType, recordInstance, size, bytes, self.properties, self.prefix) globals.outputln("", recordType = recordType) # call special record handler, if any if handler is not None: handler.output() self.printRecordDump(bytes, recordType) elif size > 0: globals.outputln("", recordType = recordType) self.printRecordDump(bytes, recordType)
def output (self): def printRawBytes (bytes): for b in bytes: output("%2.2X "%ord(b)) output("\n") def printSep (c, w, prefix=''): globals.outputln(prefix + c*w) printSep('=', globals.OutputWidth) globals.outputln("Compound Document Header") printSep('-', globals.OutputWidth) if self.params.debug: globals.dumpBytes(self.bytes[0:512]) printSep('-', globals.OutputWidth) # document ID and unique ID output("Document ID: ") printRawBytes(self.docId) output("Unique ID: ") printRawBytes(self.uId) # revision and version globals.outputln("Revision: %d Version: %d"%(self.revision, self.version)) # byte order output("Byte order: ") if self.byteOrder == ByteOrder.LittleEndian: globals.outputln("little endian") elif self.byteOrder == ByteOrder.BigEndian: globals.outputln("big endian") else: globals.outputln("unknown") # sector size (usually 512 bytes) globals.outputln("Sector size: %d (%d)"%(2**self.secSize, self.secSize)) # short sector size (usually 64 bytes) globals.outputln("Short sector size: %d (%d)"%(2**self.secSizeShort, self.secSizeShort)) # total number of sectors in SAT (equals the number of sector IDs # stored in the MSAT). globals.outputln("Total number of sectors used in SAT: %d"%self.numSecSAT) globals.outputln("Sector ID of the first sector of the directory stream: %d"% self.__secIDFirstDirStrm) globals.outputln("Minimum stream size: %d"%self.minStreamSize) if self.__secIDFirstSSAT == -2: globals.outputln("Sector ID of the first SSAT sector: [none]") else: globals.outputln("Sector ID of the first SSAT sector: %d"%self.__secIDFirstSSAT) globals.outputln("Total number of sectors used in SSAT: %d"%self.numSecSSAT) if self.__secIDFirstMSAT == -2: # There is no more sector ID stored outside the header. globals.outputln("Sector ID of the first MSAT sector: [end of chain]") else: # There is more sector IDs than 109 IDs stored in the header. globals.outputln("Sector ID of the first MSAT sector: %d"%(self.__secIDFirstMSAT)) globals.outputln("Total number of sectors used to store additional MSAT: %d"%self.numSecMSAT)
def printStreamInfo (self): self.__printSep('=', 68) globals.outputln("PPT File Format Dumper by K. Yoshida, T. Behrens & contributors") globals.outputln(" total stream size: %d bytes"%self.size) self.__printSep('=', 68) globals.outputln('')
def output(self, debug=False): globals.outputln('') globals.outputln("=" * globals.OutputWidth) globals.outputln("Directory") if debug: globals.outputln("-" * globals.OutputWidth) globals.outputln("sector(s) used:") for secID in self.sectorIDs: globals.outputln(" sector %d" % secID) globals.outputln("") for secID in self.sectorIDs: globals.outputln("-" * globals.OutputWidth) globals.outputln(" Raw Hex Dump (sector %d)" % secID) globals.outputln("-" * globals.OutputWidth) pos = globals.getSectorPos(secID, self.sectorSize) globals.dumpBytes(self.bytes[pos:pos + self.sectorSize], 128) for entry in self.entries: self.__outputEntry(entry, debug)
def __outputEntry(self, entry, debug): globals.outputln("-" * globals.OutputWidth) if len(entry.Name) > 0: name = entry.Name if ord(name[0]) <= 5: name = "<%2.2Xh>%s" % (ord(name[0]), name[1:]) globals.outputln("name: %s (name buffer size: %d bytes)" % (name, entry.CharBufferSize)) else: globals.outputln("name: [empty] (name buffer size: %d bytes)" % entry.CharBufferSize) if self.params.debug: globals.outputln("-" * globals.OutputWidth) globals.dumpBytes(entry.bytes) globals.outputln("-" * globals.OutputWidth) output("type: ") if entry.Type == Directory.Type.Empty: globals.outputln("empty") elif entry.Type == Directory.Type.LockBytes: globals.outputln("lock bytes") elif entry.Type == Directory.Type.Property: globals.outputln("property") elif entry.Type == Directory.Type.RootStorage: globals.outputln("root storage") elif entry.Type == Directory.Type.UserStorage: globals.outputln("user storage") elif entry.Type == Directory.Type.UserStream: globals.outputln("user stream") else: globals.outputln("[unknown type]") output("node color: ") if entry.NodeColor == Directory.NodeColor.Red: globals.outputln("red") elif entry.NodeColor == Directory.NodeColor.Black: globals.outputln("black") elif entry.NodeColor == Directory.NodeColor.Unknown: globals.outputln("[unknown color]") globals.outputln("linked dir entries: left: %d; right: %d; root: %d" % (entry.DirIDLeft, entry.DirIDRight, entry.DirIDRoot)) self.__outputRaw("unique ID", entry.UniqueID) self.__outputRaw("user flags", entry.UserFlags) self.__outputRaw("time created", entry.TimeCreated) self.__outputRaw("time last modified", entry.TimeModified) output("stream info: ") if entry.StreamSectorID < 0 or entry.StreamSize == 0: globals.outputln("[empty stream]") else: strmLoc = "SAT" if entry.StreamLocation == StreamLocation.SSAT: strmLoc = "SSAT" globals.outputln("(first sector ID: %d; size: %d; location: %s)" % (entry.StreamSectorID, entry.StreamSize, strmLoc)) satObj = None secSize = 0 if entry.StreamLocation == StreamLocation.SAT: satObj = self.SAT secSize = self.header.getSectorSize() elif entry.StreamLocation == StreamLocation.SSAT: satObj = self.SSAT secSize = self.header.getShortSectorSize() if satObj != None: chain = satObj.getSectorIDChain(entry.StreamSectorID) globals.outputln("sector count: %d" % len(chain)) globals.outputln("total sector size: %d" % (len(chain) * secSize)) if self.params.showSectorChain: self.__outputSectorChain(chain)
def printSep (c, w, prefix=''): globals.outputln(prefix + c*w)
def __printHeader(self): globals.outputln("OLE: %s")%self.filePath globals.outputln(" Length Date Time Name") globals.outputln("-------- ---- ---- ----")
def output (self): globals.outputln('') globals.outputln("="*globals.OutputWidth) globals.outputln("Sector Allocation Table (SAT)") globals.outputln("-"*globals.OutputWidth) if self.params.debug: self.outputRawBytes() globals.outputln("-"*globals.OutputWidth) for i in xrange(0, len(self.array)): globals.outputln("%5d: %5d"%(i, self.array[i])) globals.outputln("-"*globals.OutputWidth) self.outputArrayStats()
def output(self): def printRawBytes(bytes): for b in bytes: output("%2.2X " % ord(b)) output("\n") def printSep(c, w, prefix=''): globals.outputln(prefix + c * w) printSep('=', globals.OutputWidth) globals.outputln("Compound Document Header") printSep('-', globals.OutputWidth) if self.params.debug: globals.dumpBytes(self.bytes[0:512]) printSep('-', globals.OutputWidth) # document ID and unique ID output("Document ID: ") printRawBytes(self.docId) output("Unique ID: ") printRawBytes(self.uId) # revision and version globals.outputln("Revision: %d Version: %d" % (self.revision, self.version)) # byte order output("Byte order: ") if self.byteOrder == ByteOrder.LittleEndian: globals.outputln("little endian") elif self.byteOrder == ByteOrder.BigEndian: globals.outputln("big endian") else: globals.outputln("unknown") # sector size (usually 512 bytes) globals.outputln("Sector size: %d (%d)" % (2**self.secSize, self.secSize)) # short sector size (usually 64 bytes) globals.outputln("Short sector size: %d (%d)" % (2**self.secSizeShort, self.secSizeShort)) # total number of sectors in SAT (equals the number of sector IDs # stored in the MSAT). globals.outputln("Total number of sectors used in SAT: %d" % self.numSecSAT) globals.outputln( "Sector ID of the first sector of the directory stream: %d" % self.__secIDFirstDirStrm) globals.outputln("Minimum stream size: %d" % self.minStreamSize) if self.__secIDFirstSSAT == -2: globals.outputln("Sector ID of the first SSAT sector: [none]") else: globals.outputln("Sector ID of the first SSAT sector: %d" % self.__secIDFirstSSAT) globals.outputln("Total number of sectors used in SSAT: %d" % self.numSecSSAT) if self.__secIDFirstMSAT == -2: # There is no more sector ID stored outside the header. globals.outputln( "Sector ID of the first MSAT sector: [end of chain]") else: # There is more sector IDs than 109 IDs stored in the header. globals.outputln("Sector ID of the first MSAT sector: %d" % (self.__secIDFirstMSAT)) globals.outputln( "Total number of sectors used to store additional MSAT: %d" % self.numSecMSAT)
def read (self): ver = self.strm.readUnsignedInt(4) globals.outputln("version: 0x%8.8X"%ver) flags = self.strm.readUnsignedInt(4) globals.outputln("flags: %d"%flags) linkUpdateOption = self.strm.readUnsignedInt(4) globals.outputln("link update option: %d"%linkUpdateOption) reserved = self.strm.readUnsignedInt(4) globals.outputln("") # Reserved moniker (must be ignored) monikerSize = self.strm.readUnsignedInt(4) if monikerSize > 0: strm = MonikerStream(self.strm.readBytes(monikerSize+16)) strm.read() # Relative source moniker (relative path to the linked object) monikerSize = self.strm.readUnsignedInt(4) if monikerSize > 0: strm = MonikerStream(self.strm.readBytes(monikerSize+16)) strm.read() # Absolute source moniker (absolute path to the linked object) monikerSize = self.strm.readUnsignedInt(4) if monikerSize > 0: strm = MonikerStream(self.strm.readBytes(monikerSize+16)) strm.read() clsIDIndicator = self.strm.readSignedInt(4) globals.outputln("cls ID indicator: %d"%clsIDIndicator) clsID = self.strm.readBytes(16) globals.outputln("CLS ID: %s"%globals.getRawBytes(clsID, True, False))
def read (self): # CompObjHeader reserved = self.strm.readBytes(4) ver = self.strm.readUnsignedInt(4) reserved = self.strm.readBytes(20) globals.outputln("version: 0x%4.4X"%ver) # LengthPrefixedAnsiString length = self.strm.readUnsignedInt(4) displayName = self.strm.readBytes(length) if ord(displayName[-1]) != 0x00: # must be null-terminated. raise CompObjStreamError() globals.outputln("display name: " + displayName[:-1]) # ClipboardFormatOrAnsiString marker = self.strm.readUnsignedInt(4) if marker == 0: # Don't do anything. pass elif marker == 0xFFFFFFFF or marker == 0xFFFFFFFE: clipFormatID = self.strm.readUnsignedInt(4) globals.outputln("clipboard format ID: %d"%clipFormatID) else: clipName = self.strm.readBytes(marker) if ord(clipName[-1]) != 0x00: # must be null-terminated. raise CompObjStreamError() globals.outputln("clipboard format name: %s"%clipName[:-1]) # LengthPrefixedAnsiString length = self.strm.readUnsignedInt(4) if length == 0 or length > 0x00000028: # the spec says this stream is now invalid. raise CompObjStreamError() reserved = self.strm.readBytes(length) if ord(reserved[-1]) != 0x00: # must be null-terminated. raise CompObjStreamError() globals.outputln("reserved name : %s"%reserved[:-1]) unicodeMarker = self.strm.readUnsignedInt(4) if unicodeMarker != 0x71B239F4: raise CompObjStreamError() # LengthPrefixedUnicodeString length = self.strm.readUnsignedInt(4) if length > 0: s = globals.getUTF8FromUTF16(self.strm.readBytes(length*2)) globals.outputln("display name (unicode): %s"%s) # ClipboardFormatOrAnsiString marker = self.strm.readUnsignedInt(4) if marker == 0: # Don't do anything. pass elif marker == 0xFFFFFFFF or marker == 0xFFFFFFFE: clipFormatID = self.strm.readUnsignedInt(4) globals.outputln("clipboard format ID: %d"%clipFormatID) else: clipName = globals.getUTF8FromUTF16(self.strm.readBytes(marker*2)) if ord(clipName[-1]) != 0x00: # must be null-terminated. raise CompObjStreamError() globals.outputln("clipboard format name: %s"%clipName[:-1])
def output (self, debug=False): globals.outputln('') globals.outputln("="*globals.OutputWidth) globals.outputln("Directory") if debug: globals.outputln("-"*globals.OutputWidth) globals.outputln("sector(s) used:") for secID in self.sectorIDs: globals.outputln(" sector %d"%secID) globals.outputln("") for secID in self.sectorIDs: globals.outputln("-"*globals.OutputWidth) globals.outputln(" Raw Hex Dump (sector %d)"%secID) globals.outputln("-"*globals.OutputWidth) pos = globals.getSectorPos(secID, self.sectorSize) globals.dumpBytes(self.bytes[pos:pos+self.sectorSize], 128) for entry in self.entries: self.__outputEntry(entry, debug)
def read(self): ver = self.strm.readUnsignedInt(4) globals.outputln("version: 0x%8.8X" % ver) flags = self.strm.readUnsignedInt(4) globals.outputln("flags: %d" % flags) linkUpdateOption = self.strm.readUnsignedInt(4) globals.outputln("link update option: %d" % linkUpdateOption) reserved = self.strm.readUnsignedInt(4) globals.outputln("") # Reserved moniker (must be ignored) monikerSize = self.strm.readUnsignedInt(4) if monikerSize > 0: strm = MonikerStream(self.strm.readBytes(monikerSize + 16)) strm.read() # Relative source moniker (relative path to the linked object) monikerSize = self.strm.readUnsignedInt(4) if monikerSize > 0: strm = MonikerStream(self.strm.readBytes(monikerSize + 16)) strm.read() # Absolute source moniker (absolute path to the linked object) monikerSize = self.strm.readUnsignedInt(4) if monikerSize > 0: strm = MonikerStream(self.strm.readBytes(monikerSize + 16)) strm.read() clsIDIndicator = self.strm.readSignedInt(4) globals.outputln("cls ID indicator: %d" % clsIDIndicator) clsID = self.strm.readBytes(16) globals.outputln("CLS ID: %s" % globals.getRawBytes(clsID, True, False))
def read (self): byteorder = self.strm.readUnsignedInt(2) if byteorder != 0xFFFE: raise PropertySetStreamError() ver = self.strm.readUnsignedInt(2) globals.outputln("version: 0x%4.4X"%ver) sID = self.strm.readUnsignedInt(4) globals.outputln("system identifier: 0x%4.4X"%sID) clsID = self.strm.readBytes(16) globals.outputln("CLS ID: %s"%globals.getRawBytes(clsID, True, False)) sets = self.strm.readUnsignedInt(4) globals.outputln("number of property sets: 0x%4.4X"%sets) fmtID0 = self.strm.readBytes(16) globals.outputln("FMT ID 0: %s"%globals.getRawBytes(fmtID0, True, False)) offset0 = self.strm.readUnsignedInt(4) globals.outputln("offset 0: 0x%4.4X"%offset0) if sets > 1: fmtID1 = self.strm.readBytes(16) globals.outputln("FMT ID 1: %s"%globals.getRawBytes(fmtID0, True, False)) offset1 = self.strm.readUnsignedInt(4) globals.outputln("offset 1: 0x%4.4X\n"%offset1) self.readSet(offset0) if sets > 1: self.strm.setCurrentPos(offset1); self.readSet(offset1)
def __printSep (self, c='-', w=68, prefix=''): globals.outputln(prefix + c*w)
def printSep(c, w, prefix=''): globals.outputln(prefix + c * w)
def __printHeader(self): globals.outputln("OLE: %s") % self.filePath globals.outputln(" Length Date Time Name") globals.outputln("-------- ---- ---- ----")
def readSet(self, setOffset): globals.outputln("-----------------------------") globals.outputln("Property set") globals.outputln("-----------------------------") size = self.strm.readUnsignedInt(4) globals.outputln("size: 0x%4.4X" % size) props = self.strm.readUnsignedInt(4) globals.outputln("number of properties: 0x%4.4X" % props) pos = 0 while pos < props: self.strm.setCurrentPos(setOffset + 8 + pos * 8) id = self.strm.readUnsignedInt(4) offset = self.strm.readUnsignedInt(4) globals.outputln("ID: 0x%4.4X offset: 0x%4.4X" % (id, offset)) self.strm.setCurrentPos(setOffset + offset) type = self.strm.readUnsignedInt(2) padding = self.strm.readUnsignedInt(2) if padding != 0: raise PropertySetStreamError() globals.outputln("type: 0x%4.4X" % type) if type == 2: value = self.strm.readSignedInt(2) globals.outputln("VT_I2: %d" % value) elif type == 0x41: blobSize = self.strm.readUnsignedInt(4) globals.outputln("VT_BLOB size: 0x%4.4X" % blobSize) globals.outputln( "------------------------------------------------------------------------" ) globals.dumpBytes( self.strm.bytes[self.strm.pos:self.strm.pos + blobSize], blobSize) globals.outputln( "------------------------------------------------------------------------" ) else: globals.outputln("unknown type") pos += 1 globals.outputln("")
def outputArrayStats(self): sectorTotal = len(self.array) sectorP = 0 # >= 0 sectorM1 = 0 # -1 sectorM2 = 0 # -2 sectorM3 = 0 # -3 sectorM4 = 0 # -4 sectorMElse = 0 # < -4 sectorLiveTotal = 0 for i in xrange(0, len(self.array)): item = self.array[i] if item >= 0: sectorP += 1 elif item == -1: sectorM1 += 1 elif item == -2: sectorM2 += 1 elif item == -3: sectorM3 += 1 elif item == -4: sectorM4 += 1 elif item < -4: sectorMElse += 1 else: sectorLiveTotal += 1 globals.outputln("total sector count: %4d" % sectorTotal) globals.outputln("* live sector count: %4d" % sectorP) globals.outputln("* end-of-chain sector count: %4d" % sectorM2) # end-of-chain is also live globals.outputln("* free sector count: %4d" % sectorM1) globals.outputln("* SAT sector count: %4d" % sectorM3) globals.outputln("* MSAT sector count: %4d" % sectorM4) globals.outputln("* other sector count: %4d" % sectorMElse)
def __outputEntry (self, entry, debug): globals.outputln("-"*globals.OutputWidth) if len(entry.Name) > 0: name = entry.Name if ord(name[0]) <= 5: name = "<%2.2Xh>%s"%(ord(name[0]), name[1:]) globals.outputln("name: %s (name buffer size: %d bytes)"%(name, entry.CharBufferSize)) else: globals.outputln("name: [empty] (name buffer size: %d bytes)"%entry.CharBufferSize) if self.params.debug: globals.outputln("-"*globals.OutputWidth) globals.dumpBytes(entry.bytes) globals.outputln("-"*globals.OutputWidth) output("type: ") if entry.Type == Directory.Type.Empty: globals.outputln("empty") elif entry.Type == Directory.Type.LockBytes: globals.outputln("lock bytes") elif entry.Type == Directory.Type.Property: globals.outputln("property") elif entry.Type == Directory.Type.RootStorage: globals.outputln("root storage") elif entry.Type == Directory.Type.UserStorage: globals.outputln("user storage") elif entry.Type == Directory.Type.UserStream: globals.outputln("user stream") else: globals.outputln("[unknown type]") output("node color: ") if entry.NodeColor == Directory.NodeColor.Red: globals.outputln("red") elif entry.NodeColor == Directory.NodeColor.Black: globals.outputln("black") elif entry.NodeColor == Directory.NodeColor.Unknown: globals.outputln("[unknown color]") globals.outputln("linked dir entries: left: %d; right: %d; root: %d"% (entry.DirIDLeft, entry.DirIDRight, entry.DirIDRoot)) self.__outputRaw("unique ID", entry.UniqueID) self.__outputRaw("user flags", entry.UserFlags) self.__outputRaw("time created", entry.TimeCreated) self.__outputRaw("time last modified", entry.TimeModified) output("stream info: ") if entry.StreamSectorID < 0 or entry.StreamSize == 0: globals.outputln("[empty stream]") else: strmLoc = "SAT" if entry.StreamLocation == StreamLocation.SSAT: strmLoc = "SSAT" globals.outputln("(first sector ID: %d; size: %d; location: %s)"% (entry.StreamSectorID, entry.StreamSize, strmLoc)) satObj = None secSize = 0 if entry.StreamLocation == StreamLocation.SAT: satObj = self.SAT secSize = self.header.getSectorSize() elif entry.StreamLocation == StreamLocation.SSAT: satObj = self.SSAT secSize = self.header.getShortSectorSize() if satObj != None: chain = satObj.getSectorIDChain(entry.StreamSectorID) globals.outputln("sector count: %d"%len(chain)) globals.outputln("total sector size: %d"%(len(chain)*secSize)) if self.params.showSectorChain: self.__outputSectorChain(chain)
def read(self): byteorder = self.strm.readUnsignedInt(2) if byteorder != 0xFFFE: raise PropertySetStreamError() ver = self.strm.readUnsignedInt(2) globals.outputln("version: 0x%4.4X" % ver) sID = self.strm.readUnsignedInt(4) globals.outputln("system identifier: 0x%4.4X" % sID) clsID = self.strm.readBytes(16) globals.outputln("CLS ID: %s" % globals.getRawBytes(clsID, True, False)) sets = self.strm.readUnsignedInt(4) globals.outputln("number of property sets: 0x%4.4X" % sets) fmtID0 = self.strm.readBytes(16) globals.outputln("FMT ID 0: %s" % globals.getRawBytes(fmtID0, True, False)) offset0 = self.strm.readUnsignedInt(4) globals.outputln("offset 0: 0x%4.4X" % offset0) if sets > 1: fmtID1 = self.strm.readBytes(16) globals.outputln("FMT ID 1: %s" % globals.getRawBytes(fmtID0, True, False)) offset1 = self.strm.readUnsignedInt(4) globals.outputln("offset 1: 0x%4.4X\n" % offset1) self.readSet(offset0) if sets > 1: self.strm.setCurrentPos(offset1) self.readSet(offset1)
def output(self): globals.outputln('') globals.outputln("=" * globals.OutputWidth) globals.outputln("Sector Allocation Table (SAT)") globals.outputln("-" * globals.OutputWidth) if self.params.debug: self.outputRawBytes() globals.outputln("-" * globals.OutputWidth) for i in xrange(0, len(self.array)): globals.outputln("%5d: %5d" % (i, self.array[i])) globals.outputln("-" * globals.OutputWidth) self.outputArrayStats()
def readSet (self, setOffset): globals.outputln("-----------------------------") globals.outputln("Property set") globals.outputln("-----------------------------") size = self.strm.readUnsignedInt(4) globals.outputln("size: 0x%4.4X"%size) props = self.strm.readUnsignedInt(4) globals.outputln("number of properties: 0x%4.4X"%props) pos = 0 while pos < props: self.strm.setCurrentPos(setOffset + 8 + pos*8); id = self.strm.readUnsignedInt(4) offset = self.strm.readUnsignedInt(4) globals.outputln("ID: 0x%4.4X offset: 0x%4.4X"%(id, offset)) self.strm.setCurrentPos(setOffset + offset); type = self.strm.readUnsignedInt(2) padding = self.strm.readUnsignedInt(2) if padding != 0: raise PropertySetStreamError() globals.outputln("type: 0x%4.4X"%type) if type == 2: value = self.strm.readSignedInt(2) globals.outputln("VT_I2: %d"%value) elif type == 0x41: blobSize = self.strm.readUnsignedInt(4) globals.outputln("VT_BLOB size: 0x%4.4X"%blobSize) globals.outputln("------------------------------------------------------------------------") globals.dumpBytes(self.strm.bytes[self.strm.pos:self.strm.pos+blobSize], blobSize) globals.outputln("------------------------------------------------------------------------") else: globals.outputln("unknown type") pos += 1 globals.outputln("")
def outputArrayStats (self): sectorTotal = len(self.array) sectorP = 0 # >= 0 sectorM1 = 0 # -1 sectorM2 = 0 # -2 sectorM3 = 0 # -3 sectorM4 = 0 # -4 sectorMElse = 0 # < -4 sectorLiveTotal = 0 for i in xrange(0, len(self.array)): item = self.array[i] if item >= 0: sectorP += 1 elif item == -1: sectorM1 += 1 elif item == -2: sectorM2 += 1 elif item == -3: sectorM3 += 1 elif item == -4: sectorM4 += 1 elif item < -4: sectorMElse += 1 else: sectorLiveTotal += 1 globals.outputln("total sector count: %4d"%sectorTotal) globals.outputln("* live sector count: %4d"%sectorP) globals.outputln("* end-of-chain sector count: %4d"%sectorM2) # end-of-chain is also live globals.outputln("* free sector count: %4d"%sectorM1) globals.outputln("* SAT sector count: %4d"%sectorM3) globals.outputln("* MSAT sector count: %4d"%sectorM4) globals.outputln("* other sector count: %4d"%sectorMElse)
def read(self): # CompObjHeader reserved = self.strm.readBytes(4) ver = self.strm.readUnsignedInt(4) reserved = self.strm.readBytes(20) globals.outputln("version: 0x%4.4X" % ver) # LengthPrefixedAnsiString length = self.strm.readUnsignedInt(4) displayName = self.strm.readBytes(length) if ord(displayName[-1]) != 0x00: # must be null-terminated. raise CompObjStreamError() globals.outputln("display name: " + displayName[:-1]) # ClipboardFormatOrAnsiString marker = self.strm.readUnsignedInt(4) if marker == 0: # Don't do anything. pass elif marker == 0xFFFFFFFF or marker == 0xFFFFFFFE: clipFormatID = self.strm.readUnsignedInt(4) globals.outputln("clipboard format ID: %d" % clipFormatID) else: clipName = self.strm.readBytes(marker) if ord(clipName[-1]) != 0x00: # must be null-terminated. raise CompObjStreamError() globals.outputln("clipboard format name: %s" % clipName[:-1]) # LengthPrefixedAnsiString length = self.strm.readUnsignedInt(4) if length == 0 or length > 0x00000028: # the spec says this stream is now invalid. raise CompObjStreamError() reserved = self.strm.readBytes(length) if ord(reserved[-1]) != 0x00: # must be null-terminated. raise CompObjStreamError() globals.outputln("reserved name : %s" % reserved[:-1]) unicodeMarker = self.strm.readUnsignedInt(4) if unicodeMarker != 0x71B239F4: raise CompObjStreamError() # LengthPrefixedUnicodeString length = self.strm.readUnsignedInt(4) if length > 0: s = globals.getUTF8FromUTF16(self.strm.readBytes(length * 2)) globals.outputln("display name (unicode): %s" % s) # ClipboardFormatOrAnsiString marker = self.strm.readUnsignedInt(4) if marker == 0: # Don't do anything. pass elif marker == 0xFFFFFFFF or marker == 0xFFFFFFFE: clipFormatID = self.strm.readUnsignedInt(4) globals.outputln("clipboard format ID: %d" % clipFormatID) else: clipName = globals.getUTF8FromUTF16(self.strm.readBytes(marker * 2)) if ord(clipName[-1]) != 0x00: # must be null-terminated. raise CompObjStreamError() globals.outputln("clipboard format name: %s" % clipName[:-1])
def __print (self, text, recordType = -1): globals.outputln(self.prefix + text, recordType = recordType)