def onFastPathFragment(self, pdu: PlayerPDU): parser = BasicFastPathParser(ParserMode.CLIENT) pdu = parser.parse(pdu.payload) for event in pdu.events: reassembledEvent = self.reassembleEvent(event) if reassembledEvent is not None: self.onFastPathOutput(reassembledEvent)
def onFastPathOutput(self, pdu: PlayerPDU): parser = BasicFastPathParser(ParserMode.CLIENT) pdu = parser.parse(pdu.payload) for event in pdu.events: reassembledEvent = self.reassembleEvent(event) if reassembledEvent is not None: if isinstance(reassembledEvent, FastPathBitmapEvent): self.onFastPathBitmap(reassembledEvent)
def onFastPathInput(self, pdu: PlayerPDU): parser = BasicFastPathParser(ParserMode.SERVER) pdu = parser.parse(pdu.payload) for event in pdu.events: if isinstance(event, FastPathUnicodeEvent): if not event.released: self.onUnicode(event) elif isinstance(event, FastPathMouseEvent): self.onMouse(event) elif isinstance(event, FastPathScanCodeEvent): self.onScanCode(event.scanCode, event.isReleased, event.rawHeaderByte & keyboard.KBDFLAGS_EXTENDED != 0)
def __init__(self, viewer, text): super().__init__() self.viewer = viewer self.text = text self.writeInCaps = False self.inputParser = BasicFastPathParser(ParserMode.SERVER) self.outputParser = BasicFastPathParser(ParserMode.CLIENT) self.clientInfoParser = ClientInfoParser() self.dataParser = SlowPathParser() self.clipboardParser = ClipboardParser() self.outputEventParser = FastPathOutputParser() self.clientConnectionParser = ClientConnectionParser() self.buffer = b""
def __init__(self, transports: List[LayerChainItem]): self.parsers: Dict[PlayerPDUType, Parser] = { PlayerPDUType.FAST_PATH_INPUT: BasicFastPathParser(ParserMode.CLIENT), PlayerPDUType.FAST_PATH_OUTPUT: BasicFastPathParser(ParserMode.SERVER), PlayerPDUType.CLIENT_INFO: ClientInfoParser(), PlayerPDUType.SLOW_PATH_PDU: SlowPathParser(), PlayerPDUType.CLIPBOARD_DATA: ClipboardParser(), PlayerPDUType.CLIENT_DATA: ClientConnectionParser(), } self.topLayers = [] self.recordFilename = None for transport in transports: self.addTransport(transport)
def __init__(self, transportLayers: List[Layer]): self.parsers: Dict[PlayerMessageType, Parser] = { PlayerMessageType.FAST_PATH_INPUT: BasicFastPathParser(ParserMode.CLIENT), PlayerMessageType.FAST_PATH_OUTPUT: BasicFastPathParser(ParserMode.SERVER), PlayerMessageType.CLIENT_INFO: ClientInfoParser(), PlayerMessageType.SLOW_PATH_PDU: SlowPathParser(), PlayerMessageType.CLIPBOARD_DATA: ClipboardParser(), PlayerMessageType.CLIENT_DATA: ClientConnectionParser(), } self.topLayers = [] for transportLayer in transportLayers: self.addTransportLayer(transportLayer)
class PlayerMessageHandler(PlayerMessageObserver): """ Class to manage the display of the RDP player when reading events. """ def __init__(self, viewer, text): super().__init__() self.viewer = viewer self.text = text self.writeInCaps = False self.inputParser = BasicFastPathParser(ParserMode.SERVER) self.outputParser = BasicFastPathParser(ParserMode.CLIENT) self.clientInfoParser = ClientInfoParser() self.dataParser = SlowPathParser() self.clipboardParser = ClipboardParser() self.outputEventParser = FastPathOutputParser() self.clientConnectionParser = ClientConnectionParser() self.buffer = b"" def onConnectionClose(self, pdu: PlayerMessagePDU): self.text.moveCursor(QTextCursor.End) self.text.insertPlainText("\n<Connection closed>") def onOutput(self, pdu: PlayerMessagePDU): pdu = self.outputParser.parse(pdu.payload) for event in pdu.events: reassembledEvent = self.reassembleEvent(event) if reassembledEvent is not None: if isinstance(reassembledEvent, FastPathOrdersEvent): log.debug("Not handling orders event, not coded :)") elif isinstance(reassembledEvent, FastPathBitmapEvent): log.debug("Handling bitmap event %(arg1)s", {"arg1": type(reassembledEvent)}) self.onBitmap(reassembledEvent) else: log.debug("Can't handle output event: %(arg1)s", {"arg1": type(reassembledEvent)}) else: log.debug("Reassembling output event...") def onInput(self, pdu: PlayerMessagePDU): pdu = self.inputParser.parse(pdu.payload) for event in pdu.events: if isinstance(event, FastPathScanCodeEvent): log.debug("handling %(arg1)s", {"arg1": event}) self.onScanCode(event.scancode, not event.isReleased) elif isinstance(event, FastPathMouseEvent): self.onMousePosition(event.mouseX, event.mouseY) else: log.debug("Can't handle input event: %(arg1)s", {"arg1": event}) def onScanCode(self, code: int, isPressed: bool): """ Handle scan code. """ log.debug("Reading scancode %(arg1)s", {"arg1": code}) if code in [0x2A, 0x36]: self.text.moveCursor(QTextCursor.End) self.text.insertPlainText( "\n<LSHIFT PRESSED>" if isPressed else "\n<LSHIFT RELEASED>") self.writeInCaps = not self.writeInCaps elif code == 0x3A and isPressed: self.text.moveCursor(QTextCursor.End) self.text.insertPlainText("\n<CAPSLOCK>") self.writeInCaps = not self.writeInCaps elif isPressed: char = scancodeToChar(code) self.text.moveCursor(QTextCursor.End) self.text.insertPlainText( char if self.writeInCaps else char.lower()) def onMousePosition(self, x: int, y: int): self.viewer.setMousePosition(x, y) def onBitmap(self, event: FastPathBitmapEvent): parsedEvent = self.outputEventParser.parseBitmapEvent(event) for bitmapData in parsedEvent.bitmapUpdateData: self.handleBitmap(bitmapData) def handleBitmap(self, bitmapData: BitmapUpdateData): image = RDPBitmapToQtImage( bitmapData.width, bitmapData.heigth, bitmapData.bitsPerPixel, bitmapData.flags & BitmapFlags.BITMAP_COMPRESSION != 0, bitmapData.bitmapData) self.viewer.notifyImage(bitmapData.destLeft, bitmapData.destTop, image, bitmapData.destRight - bitmapData.destLeft + 1, bitmapData.destBottom - bitmapData.destTop + 1) def onClientInfo(self, pdu: PlayerMessagePDU): clientInfoPDU = self.clientInfoParser.parse(pdu.payload) self.text.insertPlainText( "USERNAME: {}\nPASSWORD: {}\nDOMAIN: {}\n".format( clientInfoPDU.username.replace("\0", ""), clientInfoPDU.password.replace("\0", ""), clientInfoPDU.domain.replace("\0", ""))) self.text.insertPlainText("--------------------\n") def onSlowPathPDU(self, pdu: PlayerMessagePDU): pdu = self.dataParser.parse(pdu.payload) if isinstance(pdu, ConfirmActivePDU): self.viewer.resize( pdu.parsedCapabilitySets[ CapabilityType.CAPSTYPE_BITMAP].desktopWidth, pdu.parsedCapabilitySets[ CapabilityType.CAPSTYPE_BITMAP].desktopHeight) elif isinstance( pdu, UpdatePDU ) and pdu.updateType == SlowPathUpdateType.SLOWPATH_UPDATETYPE_BITMAP: updates = BitmapParser().parseBitmapUpdateData(pdu.updateData) for bitmap in updates: self.handleBitmap(bitmap) elif isinstance(pdu, InputPDU): for event in pdu.events: if isinstance(event, MouseEvent): self.onMousePosition(event.x, event.y) elif isinstance(event, KeyboardEvent): self.onScanCode( event.keyCode, event.flags & KeyboardFlag.KBDFLAGS_DOWN != 0) def onClipboardData(self, pdu: PlayerMessagePDU): formatDataResponsePDU: FormatDataResponsePDU = self.clipboardParser.parse( pdu.payload) self.text.moveCursor(QTextCursor.End) self.text.insertPlainText("\n=============\n") self.text.insertPlainText("CLIPBOARD DATA: {}".format( decodeUTF16LE(formatDataResponsePDU.requestedFormatData))) self.text.insertPlainText("\n=============\n") def onClientData(self, pdu: PlayerMessagePDU): """ Prints the clientName on the screen """ clientDataPDU = self.clientConnectionParser.parse(pdu.payload) self.text.moveCursor(QTextCursor.End) self.text.insertPlainText("--------------------\n") self.text.insertPlainText( f"HOST: {clientDataPDU.coreData.clientName.strip(chr(0))}\n") def reassembleEvent( self, event: FastPathOutputEvent ) -> Optional[Union[FastPathBitmapEvent, FastPathOutputEvent]]: """ Handles FastPath event reassembly as described in https://msdn.microsoft.com/en-us/library/cc240622.aspx :param event: A potentially segmented fastpath output event :return: a FastPathBitmapEvent if a complete PDU has been reassembled, otherwise None. If the event is not fragmented, returns the original event. """ fragmentationFlag = FastPathFragmentation((event.header & 0b00110000) >> 4) if fragmentationFlag == FastPathFragmentation.FASTPATH_FRAGMENT_SINGLE: return event elif fragmentationFlag == FastPathFragmentation.FASTPATH_FRAGMENT_FIRST: self.buffer = event.payload elif fragmentationFlag == FastPathFragmentation.FASTPATH_FRAGMENT_NEXT: self.buffer += event.payload elif fragmentationFlag == FastPathFragmentation.FASTPATH_FRAGMENT_LAST: self.buffer += event.payload event.payload = self.buffer return self.outputEventParser.parseBitmapEvent(event) return None