class MainWindow(QtGui.QMainWindow): def __init__(self, fileName=None): super(MainWindow, self).__init__() self.init() self.setCurrentFile('') def about(self): QtGui.QMessageBox.about(self, "About HexEdit", "The HexEdit example is a short Demo of the QHexEdit Widget."); def closeEvent(self, event): self.writeSettings() del self.optionsDialog self.close() def createActions(self): self.openAct = QtGui.QAction(QtGui.QIcon(':/images/open.png'), "&Open...", self, shortcut=QtGui.QKeySequence.Open, statusTip="Open an existing file", triggered=self.open) self.saveAct = QtGui.QAction(QtGui.QIcon(':/images/save.png'), "&Save", self, shortcut=QtGui.QKeySequence.Save, statusTip="Save the document to disk", triggered=self.save) self.saveAsAct = QtGui.QAction("Save &As...", self, shortcut=QtGui.QKeySequence.SaveAs, statusTip="Save the document under a new name", triggered=self.saveAs) self.saveReadable = QtGui.QAction("Save as &Readable...", self, statusTip="Save in a readable format", triggered=self.saveToReadableFile) self.exitAct = QtGui.QAction("E&xit", self, shortcut="Ctrl+Q", statusTip="Exit the application", triggered=self.close) self.undoAct = QtGui.QAction("&Undo", self, shortcut=QtGui.QKeySequence.Undo, triggered=self.hexEdit.undo) self.redoAct = QtGui.QAction("&Redo", self, shortcut=QtGui.QKeySequence.Redo, triggered=self.hexEdit.redo) self.saveSelectionReadable = QtGui.QAction("Save Selection Readable...", self, statusTip="Save selection in a readable format", triggered=self.saveSelectionToReadableFile) self.aboutAct = QtGui.QAction("&About", self, statusTip="Show the application's About box", triggered=self.about) self.findAct = QtGui.QAction("&Find/Replace", self, shortcut=QtGui.QKeySequence.Find, statusTip="Show the Dialog for finding and replacing", triggered=self.showSearchDialog) self.findNextAct = QtGui.QAction("Find &next", self, shortcut=QtGui.QKeySequence.FindNext, statusTip="Find next occurrence of the searched pattern", triggered=self.findNext) self.optionsAct = QtGui.QAction("&Options", self, statusTip="Show the options dialog", triggered=self.showOptionsDialog) def createMenus(self): self.fileMenu = self.menuBar().addMenu("&File") self.fileMenu.addAction(self.openAct) self.fileMenu.addAction(self.saveAct) self.fileMenu.addAction(self.saveAsAct) self.fileMenu.addAction(self.saveReadable) self.fileMenu.addSeparator() self.fileMenu.addAction(self.exitAct) self.editMenu = self.menuBar().addMenu("&Edit") self.editMenu.addAction(self.undoAct) self.editMenu.addAction(self.redoAct) self.editMenu.addAction(self.saveSelectionReadable) self.editMenu.addSeparator() self.editMenu.addAction(self.findAct) self.editMenu.addAction(self.findNextAct) self.editMenu.addSeparator() self.editMenu.addAction(self.optionsAct) self.helpMenu = self.menuBar().addMenu("&Help") self.helpMenu.addAction(self.aboutAct) def createStatusBar(self): # Address Label self.lbAddressName = QtGui.QLabel() self.lbAddressName.setText("Address:") self.statusBar().addPermanentWidget(self.lbAddressName) self.lbAddress = QtGui.QLabel() self.lbAddress.setFrameShape(QtGui.QFrame.Panel) self.lbAddress.setFrameShadow(QtGui.QFrame.Sunken) self.lbAddress.setMinimumWidth(70) self.statusBar().addPermanentWidget(self.lbAddress) self.hexEdit.currentAddressChanged.connect(self.setAddress) # Address Size self.lbSizeName = QtGui.QLabel() self.lbSizeName.setText("Size:") self.statusBar().addPermanentWidget(self.lbSizeName) self.lbSize = QtGui.QLabel() self.lbSize.setFrameShape(QtGui.QFrame.Panel) self.lbSize.setFrameShadow(QtGui.QFrame.Sunken) self.lbSize.setMinimumWidth(70) self.statusBar().addPermanentWidget(self.lbSize) self.hexEdit.currentSizeChanged.connect(self.setSize) # Overwrite Mode label self.lbOverwriteModeName = QtGui.QLabel() self.lbOverwriteModeName.setText("Mode:") self.statusBar().addPermanentWidget(self.lbOverwriteModeName) self.lbOverwriteMode = QtGui.QLabel() self.lbOverwriteMode.setFrameShape(QtGui.QFrame.Panel) self.lbOverwriteMode.setFrameShadow(QtGui.QFrame.Sunken) self.lbOverwriteMode.setMinimumWidth(70) self.statusBar().addPermanentWidget(self.lbOverwriteMode) self.setOverwriteMode(self.hexEdit.overwriteMode()) self.statusBar().showMessage("Ready") def createToolBars(self): self.fileToolBar = self.addToolBar("File") self.fileToolBar.addAction(self.openAct) self.fileToolBar.addAction(self.saveAct) def init(self): self.setAttribute(QtCore.Qt.WA_DeleteOnClose) self.isUntitled = True self.hexEdit = QHexEdit() self.setCentralWidget(self.hexEdit) self.hexEdit.overwriteModeChanged.connect(self.setOverwriteMode) self.optionsDialog = OptionsDialog(self) self.optionsDialog.accepted.connect(self.optionsAccepted) self.searchDialog = SearchDialog(self, self.hexEdit) self.createActions() self.createMenus() self.createToolBars() self.createStatusBar() self.readSettings() def loadFile(self, fileName): file = QtCore.QFile(fileName) if not file.open( QtCore.QFile.ReadOnly | QtCore.QFile.Text): QtGui.QMessageBox.warning(self, "QHexEdit", "Cannot read file %s:\n%s." % (fileName, file.errorString())) return QtGui.QApplication.setOverrideCursor(QtCore.Qt.WaitCursor) self.hexEdit.setData(file.readAll()) QtGui.QApplication.restoreOverrideCursor() self.setCurrentFile(fileName) self.statusBar().showMessage("File loaded", 2000) def open(self): fileName = QtGui.QFileDialog.getOpenFileName(self) if fileName: self.loadFile(fileName) def optionsAccepted(self): self.writeSettings() self.readSettings() def findNext(self): self.searchDialog.findNext() def readSettings(self): settings = QtCore.QSettings() pos = settings.value('pos', QtCore.QPoint(200, 200)).toPoint() size = settings.value('size', QtCore.QSize(610, 460)).toSize() self.move(pos) self.resize(size) self.hexEdit.setAddressArea(settings.value("AddressArea").toBool()) self.hexEdit.setAsciiArea(settings.value("AsciiArea").toBool()); self.hexEdit.setHighlighting(settings.value("Highlighting").toBool()); self.hexEdit.setOverwriteMode(settings.value("OverwriteMode").toBool()); self.hexEdit.setReadOnly(settings.value("ReadOnly").toBool()); self.hexEdit.setHighlightingColor(QtGui.QColor(settings.value("HighlightingColor"))); self.hexEdit.setAddressAreaColor(QtGui.QColor(settings.value("AddressAreaColor"))); self.hexEdit.setSelectionColor(QtGui.QColor(settings.value("SelectionColor"))); self.hexEdit.setFont(QtGui.QFont(settings.value("WidgetFont", QtGui.QFont(QtGui.QFont("Courier New", 10))))) self.hexEdit.setAddressWidth(settings.value("AddressAreaWidth").toInt()[0]); def save(self): if self.isUntitled: return self.saveAs() else: return self.saveFile(self.curFile) def saveAs(self): fileName = QtGui.QFileDialog.getSaveFileName(self, "Save As", self.curFile) if not fileName: return False return self.saveFile(fileName) def showOptionsDialog(self): self.optionsDialog.show() def showSearchDialog(self): self.searchDialog.show() def setAddress(self, address): self.lbAddress.setText('%x' % address) def setOverwriteMode(self, mode): if mode: self.lbOverwriteMode.setText("Overwrite") else: self.lbOverwriteMode.setText("Insert") def setSize(self, size): self.lbSize.setText('%d' % size) def saveFile(self, fileName): file = QtCore.QFile(fileName) if not file.open( QtCore.QFile.WriteOnly | QtCore.QFile.Text): QtGui.QMessageBox.warning(self, "HexEdit", "Cannot write file %s:\n%s." % (fileName, file.errorString())) return False file.write(self.hexEdit.data()) self.setCurrentFile(fileName) self.statusBar().showMessage("File saved", 2000) return True def saveToReadableFile(self): fileName = QtGui.QFileDialog.getSaveFileName(self, "Save To Readable File") if not fileName.isEmpty(): file = open(unicode(fileName), "wb") file.write(str(self.hexEdit.toReadableString())) self.statusBar().showMessage("File saved", 2000); def saveSelectionToReadableFile(self): fileName = QtGui.QFileDialog.getSaveFileName(self, "Save To Readable File") if not fileName.isEmpty(): file = open(unicode(fileName), "wb") file.write(str(self.hexEdit.selectionToReadableString())) self.statusBar().showMessage("File saved", 2000); def setCurrentFile(self, fileName): self.curFile = fileName self.isUntitled = (fileName == "") self.setWindowModified(False) self.setWindowTitle("%s[*] - QHexEdit" % self.strippedName(self.curFile)) def strippedName(self, fullFileName): return QtCore.QFileInfo(fullFileName).fileName() def writeSettings(self): settings = QtCore.QSettings() settings.setValue('pos', self.pos()) settings.setValue('size', self.size())
class MainWindow(QtGui.QMainWindow): def __init__(self, fileName=None): super(MainWindow, self).__init__() self.init() self.setCurrentFile('') def about(self): QtGui.QMessageBox.about( self, "About HexEdit", "The HexEdit example is a short Demo of the QHexEdit Widget.") def closeEvent(self, event): self.writeSettings() del self.optionsDialog self.close() def createActions(self): self.openAct = QtGui.QAction(QtGui.QIcon(':/images/open.png'), "&Open...", self, shortcut=QtGui.QKeySequence.Open, statusTip="Open an existing file", triggered=self.open) self.saveAct = QtGui.QAction(QtGui.QIcon(':/images/save.png'), "&Save", self, shortcut=QtGui.QKeySequence.Save, statusTip="Save the document to disk", triggered=self.save) self.saveAsAct = QtGui.QAction( "Save &As...", self, shortcut=QtGui.QKeySequence.SaveAs, statusTip="Save the document under a new name", triggered=self.saveAs) self.saveReadable = QtGui.QAction( "Save as &Readable...", self, statusTip="Save in a readable format", triggered=self.saveToReadableFile) self.exitAct = QtGui.QAction("E&xit", self, shortcut="Ctrl+Q", statusTip="Exit the application", triggered=self.close) self.undoAct = QtGui.QAction("&Undo", self, shortcut=QtGui.QKeySequence.Undo, triggered=self.hexEdit.undo) self.redoAct = QtGui.QAction("&Redo", self, shortcut=QtGui.QKeySequence.Redo, triggered=self.hexEdit.redo) self.saveSelectionReadable = QtGui.QAction( "Save Selection Readable...", self, statusTip="Save selection in a readable format", triggered=self.saveSelectionToReadableFile) self.aboutAct = QtGui.QAction( "&About", self, statusTip="Show the application's About box", triggered=self.about) self.findAct = QtGui.QAction( "&Find/Replace", self, shortcut=QtGui.QKeySequence.Find, statusTip="Show the Dialog for finding and replacing", triggered=self.showSearchDialog) self.findNextAct = QtGui.QAction( "Find &next", self, shortcut=QtGui.QKeySequence.FindNext, statusTip="Find next occurrence of the searched pattern", triggered=self.findNext) self.optionsAct = QtGui.QAction("&Options", self, statusTip="Show the options dialog", triggered=self.showOptionsDialog) def createMenus(self): self.fileMenu = self.menuBar().addMenu("&File") self.fileMenu.addAction(self.openAct) self.fileMenu.addAction(self.saveAct) self.fileMenu.addAction(self.saveAsAct) self.fileMenu.addAction(self.saveReadable) self.fileMenu.addSeparator() self.fileMenu.addAction(self.exitAct) self.editMenu = self.menuBar().addMenu("&Edit") self.editMenu.addAction(self.undoAct) self.editMenu.addAction(self.redoAct) self.editMenu.addAction(self.saveSelectionReadable) self.editMenu.addSeparator() self.editMenu.addAction(self.findAct) self.editMenu.addAction(self.findNextAct) self.editMenu.addSeparator() self.editMenu.addAction(self.optionsAct) self.helpMenu = self.menuBar().addMenu("&Help") self.helpMenu.addAction(self.aboutAct) def createStatusBar(self): # Address Label self.lbAddressName = QtGui.QLabel() self.lbAddressName.setText("Address:") self.statusBar().addPermanentWidget(self.lbAddressName) self.lbAddress = QtGui.QLabel() self.lbAddress.setFrameShape(QtGui.QFrame.Panel) self.lbAddress.setFrameShadow(QtGui.QFrame.Sunken) self.lbAddress.setMinimumWidth(70) self.statusBar().addPermanentWidget(self.lbAddress) self.hexEdit.currentAddressChanged.connect(self.setAddress) # Address Size self.lbSizeName = QtGui.QLabel() self.lbSizeName.setText("Size:") self.statusBar().addPermanentWidget(self.lbSizeName) self.lbSize = QtGui.QLabel() self.lbSize.setFrameShape(QtGui.QFrame.Panel) self.lbSize.setFrameShadow(QtGui.QFrame.Sunken) self.lbSize.setMinimumWidth(70) self.statusBar().addPermanentWidget(self.lbSize) self.hexEdit.currentSizeChanged.connect(self.setSize) # Overwrite Mode label self.lbOverwriteModeName = QtGui.QLabel() self.lbOverwriteModeName.setText("Mode:") self.statusBar().addPermanentWidget(self.lbOverwriteModeName) self.lbOverwriteMode = QtGui.QLabel() self.lbOverwriteMode.setFrameShape(QtGui.QFrame.Panel) self.lbOverwriteMode.setFrameShadow(QtGui.QFrame.Sunken) self.lbOverwriteMode.setMinimumWidth(70) self.statusBar().addPermanentWidget(self.lbOverwriteMode) self.setOverwriteMode(self.hexEdit.overwriteMode()) self.statusBar().showMessage("Ready") def createToolBars(self): self.fileToolBar = self.addToolBar("File") self.fileToolBar.addAction(self.openAct) self.fileToolBar.addAction(self.saveAct) def init(self): self.setAttribute(QtCore.Qt.WA_DeleteOnClose) self.isUntitled = True self.hexEdit = QHexEdit() self.setCentralWidget(self.hexEdit) self.hexEdit.overwriteModeChanged.connect(self.setOverwriteMode) self.optionsDialog = OptionsDialog(self) self.optionsDialog.accepted.connect(self.optionsAccepted) self.searchDialog = SearchDialog(self, self.hexEdit) self.createActions() self.createMenus() self.createToolBars() self.createStatusBar() self.readSettings() def loadFile(self, fileName): file = QtCore.QFile(fileName) if not file.open(QtCore.QFile.ReadOnly | QtCore.QFile.Text): QtGui.QMessageBox.warning( self, "QHexEdit", "Cannot read file %s:\n%s." % (fileName, file.errorString())) return QtGui.QApplication.setOverrideCursor(QtCore.Qt.WaitCursor) self.hexEdit.setData(file.readAll()) QtGui.QApplication.restoreOverrideCursor() self.setCurrentFile(fileName) self.statusBar().showMessage("File loaded", 2000) def open(self): fileName = QtGui.QFileDialog.getOpenFileName(self) if fileName: self.loadFile(fileName) def optionsAccepted(self): self.writeSettings() self.readSettings() def findNext(self): self.searchDialog.findNext() def readSettings(self): settings = QtCore.QSettings() pos = settings.value('pos', QtCore.QPoint(200, 200)).toPoint() size = settings.value('size', QtCore.QSize(610, 460)).toSize() self.move(pos) self.resize(size) self.hexEdit.setAddressArea(settings.value("AddressArea").toBool()) self.hexEdit.setAsciiArea(settings.value("AsciiArea").toBool()) self.hexEdit.setHighlighting(settings.value("Highlighting").toBool()) self.hexEdit.setOverwriteMode( settings.value("OverwriteMode").toBool()) self.hexEdit.setReadOnly(settings.value("ReadOnly").toBool()) self.hexEdit.setHighlightingColor( QtGui.QColor(settings.value("HighlightingColor"))) self.hexEdit.setAddressAreaColor( QtGui.QColor(settings.value("AddressAreaColor"))) self.hexEdit.setSelectionColor( QtGui.QColor(settings.value("SelectionColor"))) self.hexEdit.setFont( QtGui.QFont( settings.value("WidgetFont", QtGui.QFont(QtGui.QFont("Courier New", 10))))) self.hexEdit.setAddressWidth( settings.value("AddressAreaWidth").toInt()[0]) def save(self): if self.isUntitled: return self.saveAs() else: return self.saveFile(self.curFile) def saveAs(self): fileName = QtGui.QFileDialog.getSaveFileName(self, "Save As", self.curFile) if not fileName: return False return self.saveFile(fileName) def showOptionsDialog(self): self.optionsDialog.show() def showSearchDialog(self): self.searchDialog.show() def setAddress(self, address): self.lbAddress.setText('%x' % address) def setOverwriteMode(self, mode): if mode: self.lbOverwriteMode.setText("Overwrite") else: self.lbOverwriteMode.setText("Insert") def setSize(self, size): self.lbSize.setText('%d' % size) def saveFile(self, fileName): file = QtCore.QFile(fileName) if not file.open(QtCore.QFile.WriteOnly | QtCore.QFile.Text): QtGui.QMessageBox.warning( self, "HexEdit", "Cannot write file %s:\n%s." % (fileName, file.errorString())) return False file.write(self.hexEdit.data()) self.setCurrentFile(fileName) self.statusBar().showMessage("File saved", 2000) return True def saveToReadableFile(self): fileName = QtGui.QFileDialog.getSaveFileName(self, "Save To Readable File") if not fileName.isEmpty(): file = open(unicode(fileName), "wb") file.write(str(self.hexEdit.toReadableString())) self.statusBar().showMessage("File saved", 2000) def saveSelectionToReadableFile(self): fileName = QtGui.QFileDialog.getSaveFileName(self, "Save To Readable File") if not fileName.isEmpty(): file = open(unicode(fileName), "wb") file.write(str(self.hexEdit.selectionToReadableString())) self.statusBar().showMessage("File saved", 2000) def setCurrentFile(self, fileName): self.curFile = fileName self.isUntitled = (fileName == "") self.setWindowModified(False) self.setWindowTitle("%s[*] - QHexEdit" % self.strippedName(self.curFile)) def strippedName(self, fullFileName): return QtCore.QFileInfo(fullFileName).fileName() def writeSettings(self): settings = QtCore.QSettings() settings.setValue('pos', self.pos()) settings.setValue('size', self.size())
class AlanApp(QtWidgets.QMainWindow, design.Ui_MainWindow): def __init__(self): super().__init__() self.setupUi(self) self.client_hexedit = QHexEdit() self.remote_hexedit = QHexEdit() self.client_hexedit.setOverwriteMode(False) self.remote_hexedit.setOverwriteMode(False) self.client_hexedit.setReadOnly(True) self.remote_hexedit.setReadOnly(True) self.client_hexedit_layout.addWidget(self.client_hexedit) self.remote_hexedit_layout.addWidget(self.remote_hexedit) self.client_hexedit.dataChanged.connect(self.update_client_data) self.remote_hexedit.dataChanged.connect(self.update_remote_data) self.tabs.currentChanged.connect(self.tab_changed) self.client_data = bytes() self.remote_data = bytes() self.sig = AlanSignal() self.sig.handle_error.connect(self.showerror) self.sig.recv_data.connect(self.receive_data) self.sig.clear_data.connect(self.clear_data) self.go_button.clicked.connect(self.tcp_handle) self.client_send_button.clicked.connect(self.send_client) self.remote_send_button.clicked.connect(self.send_remote) def showerror(self, title, message, buttons=QtWidgets.QMessageBox.Ok): QtWidgets.QMessageBox.critical(self, title, message, buttons) def update_client_data(self): self.client_data = self.client_hexedit.data() self.tabs.setTabText(self.tabs.indexOf(self.client_hexedit_tab), "Client Data (*)") if not self.client_intercept_checkbox.isChecked(): self.send_client() def update_remote_data(self): self.remote_data = self.remote_hexedit.data() self.tabs.setTabText(self.tabs.indexOf(self.remote_hexedit_tab), "Remote Data (*)") if not self.remote_intercept_checkbox.isChecked(): self.send_remote() def tab_changed(self, index): if index == self.tabs.indexOf(self.client_hexedit_tab): self.tabs.setTabText(index, "Client Data") if index == self.tabs.indexOf(self.remote_hexedit_tab): self.tabs.setTabText(index, "Remote Data") def receive_data(self, data, direction): if direction == "client": self.client_data += data self.client_hexedit.setData(self.client_data) self.client_hexedit.setReadOnly(False) elif direction == "remote": self.remote_data += data self.remote_hexedit.setData(self.remote_data) self.remote_hexedit.setReadOnly(False) else: logging.error("invalid direction in receive_data") return def clear_data(self, direction): if direction == "client": self.client_data = bytes() elif direction == "remote": self.remote_data = bytes() else: logging.error("invalid direction in clear_data") return def started(self): self.client_data = bytes() self.remote_data = bytes() self.go_button.setEnabled(False) self.go_button.setText("running") def finished(self): self.go_button.setEnabled(True) self.go_button.setText("go") def tcp_handle(self): local_ip = self.listen_ip.toPlainText() local_port = int(self.listen_port.toPlainText()) remote_ip = self.remote_ip.toPlainText() remote_port = int(self.remote_port.toPlainText()) logging.info(f"starting listen thread on {local_ip}:{local_port}") self.tcp_server_thread = TCPServer(self, local_ip, local_port, remote_ip, remote_port) self.tcp_server_thread.started.connect(self.started) self.tcp_server_thread.finished.connect(self.finished) self.tcp_server_thread.start() def send_client(self): self.client_hexedit.setReadOnly(True) self.sig.send_data.emit(bytes(self.client_hexedit.data()), "client") def send_remote(self): self.sig.send_data.emit(bytes(self.remote_hexedit.data()), "remote") self.remote_hexedit.setReadOnly(True)