def parse(self, data: bytes) -> PlayerMessagePDU: stream = BytesIO(data) length = Uint64LE.unpack(stream) type = PlayerMessageType(Uint16LE.unpack(stream)) timestamp = Uint64LE.unpack(stream) payload = stream.read(length - 18) return PlayerMessagePDU(type, timestamp, payload)
def parse(self, data: bytes) -> PlayerPDU: stream = BytesIO(data) length = Uint64LE.unpack(stream) pduType = PlayerPDUType(Uint16LE.unpack(stream)) timestamp = Uint64LE.unpack(stream) if pduType in self.parsers: return self.parsers[pduType](stream, timestamp) payload = stream.read(length - 18) return PlayerPDU(pduType, timestamp, payload)
def parseDeviceCreateRequest(self, deviceID: int, fileID: int, completionID: int, minorFunction: int, stream: BytesIO) -> DeviceCreateRequestPDU: desiredAccess = Uint32LE.unpack(stream) allocationSize = Uint64LE.unpack(stream) fileAttributes = FileAttributes(Uint32LE.unpack(stream)) sharedAccess = FileShareAccess(Uint32LE.unpack(stream)) createDisposition = FileCreateDisposition(Uint32LE.unpack(stream)) createOptions = FileCreateOptions(Uint32LE.unpack(stream)) pathLength = Uint32LE.unpack(stream) path = stream.read(pathLength) path = decodeUTF16LE(path)[: -1] return DeviceCreateRequestPDU( deviceID, fileID, completionID, minorFunction, desiredAccess, allocationSize, fileAttributes, sharedAccess, createDisposition, createOptions, path )
def parseDeviceReadRequest(self, deviceId: int, fileId: int, completionId: int, minorFunction: int, stream: BytesIO) -> DeviceReadRequestPDU: """ Starting at length, just before offset """ length = Uint32LE.unpack(stream) offset = Uint64LE.unpack(stream) return DeviceReadRequestPDU(deviceId, fileId, completionId, minorFunction, length, offset)
def parseDeviceReadRequest(self, deviceID: int, fileID: int, completionID: int, minorFunction: int, stream: BytesIO) -> DeviceReadRequestPDU: length = Uint32LE.unpack(stream) offset = Uint64LE.unpack(stream) stream.read(20) # Padding return DeviceReadRequestPDU(deviceID, fileID, completionID, minorFunction, length, offset)
def recv(self, data: bytes): """ Parses data to make a RDPPlayerMessagePDU and calls the observer with it. """ stream = BytesIO(data) type = PlayerMessageType(Uint8.unpack(stream)) timestamp = Uint64LE.unpack(stream) payload = stream.read() pdu = PlayerMessagePDU(type, timestamp, payload) self.pduReceived(pdu, forward=False)
def parseFileDownloadResponse( self, stream: BytesIO, timestamp: int) -> PlayerFileDownloadResponsePDU: deviceID = Uint32LE.unpack(stream) pathLength = Uint32LE.unpack(stream) path = stream.read(pathLength).decode() offset = Uint64LE.unpack(stream) payloadLength = Uint32LE.unpack(stream) payload = stream.read(payloadLength) return PlayerFileDownloadResponsePDU(timestamp, deviceID, path, offset, payload)
def parseFileFullDirectoryInformation( self, data: bytes) -> List[FileFullDirectoryInformation]: stream = BytesIO(data) information: [FileFullDirectoryInformation] = [] while stream.tell() < len(data): nextEntryOffset = Uint32LE.unpack(stream) fileIndex = Uint32LE.unpack(stream) creationTime = Uint64LE.unpack(stream) lastAccessTime = Uint64LE.unpack(stream) lastWriteTime = Uint64LE.unpack(stream) lastChangeTime = Uint64LE.unpack(stream) endOfFilePosition = Uint64LE.unpack(stream) allocationSize = Uint64LE.unpack(stream) fileAttributes = FileAttributes(Uint32LE.unpack(stream)) fileNameLength = Uint32LE.unpack(stream) eaSize = Uint32LE.unpack(stream) fileName = stream.read(fileNameLength) if nextEntryOffset != 0: stream.read(8 - stream.tell() % 8) # alignment break fileName = decodeUTF16LE(fileName) info = FileFullDirectoryInformation(fileIndex, creationTime, lastAccessTime, lastWriteTime, lastChangeTime, endOfFilePosition, allocationSize, fileAttributes, eaSize, fileName) information.append(info) return information
def parseDeviceCreateRequest(self, deviceId: int, fileId: int, completionId: int, minorFunction: int, stream: BytesIO) -> DeviceCreateRequestPDU: """ Starting at desiredAccess. """ desiredAccess = Uint32LE.unpack(stream) allocationSize = Uint64LE.unpack(stream) fileAttributes = Uint32LE.unpack(stream) sharedAccess = Uint32LE.unpack(stream) createDisposition = Uint32LE.unpack(stream) createOptions = Uint32LE.unpack(stream) pathLength = Uint32LE.unpack(stream) path = stream.read(pathLength) return DeviceCreateRequestPDU(deviceId, fileId, completionId, minorFunction, desiredAccess, allocationSize, fileAttributes, sharedAccess, createDisposition, createOptions, path)
def parse(stream: BytesIO) -> 'FileDescriptor': fd = FileDescriptor() fd.flags = Uint32LE.unpack(stream) stream.read(32) # reserved1 fd.attribs = Uint32LE.unpack(stream) stream.read(16) # reserved2 fd.lastWrite = Uint64LE.unpack(stream) sizeHi = Uint32LE.unpack(stream) sizeLo = Uint32LE.unpack(stream) fd.size = (sizeHi << 32) | sizeLo filename = stream.read(520) fd.filename = filename.decode('utf-16le').strip('\x00') return fd
def onResponse(self, pdu: FileContentsResponsePDU) -> bool: """ Handle file data. @Returns True if file transfer is complete. """ if not self.prev: # First response always contains file size. self.size = Uint64LE.unpack(BytesIO(pdu.data)) return False received = len(pdu.data) self.handle.write(pdu.data) self.transferred += received if self.transferred == self.size: self.handle.close() return True return False
def parseFileBothDirectoryInformation(self, data: bytes) -> List[FileBothDirectoryInformation]: stream = BytesIO(data) information: [FileBothDirectoryInformation] = [] while stream.tell() < len(data): nextEntryOffset = Uint32LE.unpack(stream) fileIndex = Uint32LE.unpack(stream) creationTime = Uint64LE.unpack(stream) lastAccessTime = Uint64LE.unpack(stream) lastWriteTime = Uint64LE.unpack(stream) lastChangeTime = Uint64LE.unpack(stream) endOfFilePosition = Uint64LE.unpack(stream) allocationSize = Uint64LE.unpack(stream) fileAttributes = FileAttributes(Uint32LE.unpack(stream)) fileNameLength = Uint32LE.unpack(stream) eaSize = Uint32LE.unpack(stream) shortNameLength = Uint8.unpack(stream) # stream.read(1) # reserved (not actually used, WTF Microsoft ????) shortName = stream.read(24)[: min(24, shortNameLength)] fileName = stream.read(fileNameLength) if nextEntryOffset != 0: stream.read(8 - stream.tell() % 8) # alignment break shortName = decodeUTF16LE(shortName) fileName = decodeUTF16LE(fileName) info = FileBothDirectoryInformation( fileIndex, creationTime, lastAccessTime, lastWriteTime, lastChangeTime, endOfFilePosition, allocationSize, fileAttributes, eaSize, shortName, fileName ) information.append(info) return information
def getPDULength(self, data: bytes) -> int: return Uint64LE.unpack(data[:8])
def getPDULength(self, data): return Uint64LE.unpack(data[: 8])