#include "MainWindow.h" #include "ui_MainWindow.h" #include #include #include #include #include #include #include "Configuration.h" #include "SettingsDialog.h" #include "AppearanceDialog.h" #include "ShortcutsDialog.h" #include "AttachDialog.h" #include "LineEditDialog.h" #include "StringUtil.h" #include "MiscUtil.h" #include "FavouriteTools.h" QString MainWindow::windowTitle = ""; MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); // Build information QAction* buildInfo = new QAction(ToDateString(GetCompileDate()), this); buildInfo->setEnabled(false); ui->menuBar->addAction(buildInfo); // Setup bridge signals connect(Bridge::getBridge(), SIGNAL(updateWindowTitle(QString)), this, SLOT(updateWindowTitleSlot(QString))); connect(Bridge::getBridge(), SIGNAL(addRecentFile(QString)), this, SLOT(addRecentFile(QString))); connect(Bridge::getBridge(), SIGNAL(setLastException(uint)), this, SLOT(setLastException(uint))); connect(Bridge::getBridge(), SIGNAL(menuAddMenuToList(QWidget*, QMenu*, int, int)), this, SLOT(addMenuToList(QWidget*, QMenu*, int, int))); connect(Bridge::getBridge(), SIGNAL(menuAddMenu(int, QString)), this, SLOT(addMenu(int, QString))); connect(Bridge::getBridge(), SIGNAL(menuAddMenuEntry(int, QString)), this, SLOT(addMenuEntry(int, QString))); connect(Bridge::getBridge(), SIGNAL(menuAddSeparator(int)), this, SLOT(addSeparator(int))); connect(Bridge::getBridge(), SIGNAL(menuClearMenu(int)), this, SLOT(clearMenu(int))); connect(Bridge::getBridge(), SIGNAL(menuRemoveMenuEntry(int)), this, SLOT(removeMenuEntry(int))); connect(Bridge::getBridge(), SIGNAL(getStrWindow(QString, QString*)), this, SLOT(getStrWindow(QString, QString*))); connect(Bridge::getBridge(), SIGNAL(setIconMenu(int, QIcon)), this, SLOT(setIconMenu(int, QIcon))); connect(Bridge::getBridge(), SIGNAL(setIconMenuEntry(int, QIcon)), this, SLOT(setIconMenuEntry(int, QIcon))); connect(Bridge::getBridge(), SIGNAL(showCpu()), this, SLOT(displayCpuWidget())); connect(Bridge::getBridge(), SIGNAL(addQWidgetTab(QWidget*)), this, SLOT(addQWidgetTab(QWidget*))); connect(Bridge::getBridge(), SIGNAL(showQWidgetTab(QWidget*)), this, SLOT(showQWidgetTab(QWidget*))); connect(Bridge::getBridge(), SIGNAL(closeQWidgetTab(QWidget*)), this, SLOT(closeQWidgetTab(QWidget*))); connect(Bridge::getBridge(), SIGNAL(executeOnGuiThread(void*)), this, SLOT(executeOnGuiThread(void*))); connect(Bridge::getBridge(), SIGNAL(dbgStateChanged(DBGSTATE)), this, SLOT(dbgStateChangedSlot(DBGSTATE))); // Setup menu API initMenuApi(); addMenuToList(this, ui->menuPlugins, GUI_PLUGIN_MENU); this->showMaximized(); mWindowMainTitle = QCoreApplication::applicationName(); // Set window title setWindowTitle(QString(mWindowMainTitle)); // Load application icon SetApplicationIcon(MainWindow::winId()); // Load recent files loadMRUList(16); // Accept drops setAcceptDrops(true); // Log view mLogView = new LogView(); mLogView->setWindowTitle(tr("Log")); mLogView->setWindowIcon(DIcon("log.png")); mLogView->hide(); // Symbol view mSymbolView = new SymbolView(); mSymbolView->setWindowTitle(tr("Symbols")); mSymbolView->setWindowIcon(DIcon("pdb.png")); mSymbolView->hide(); // Source view mSourceViewManager = new SourceViewerManager(); mSourceViewManager->setWindowTitle(tr("Source")); mSourceViewManager->setWindowIcon(DIcon("source.png")); mSourceViewManager->hide(); connect(mSourceViewManager, SIGNAL(showCpu()), this, SLOT(displayCpuWidget())); // Breakpoints mBreakpointsView = new BreakpointsView(); mBreakpointsView->setWindowTitle(tr("Breakpoints")); mBreakpointsView->setWindowIcon(DIcon("breakpoint.png")); mBreakpointsView->hide(); connect(mBreakpointsView, SIGNAL(showCpu()), this, SLOT(displayCpuWidget())); // Memory map view mMemMapView = new MemoryMapView(); connect(mMemMapView, SIGNAL(showCpu()), this, SLOT(displayCpuWidget())); connect(mMemMapView, SIGNAL(showReferences()), this, SLOT(displayReferencesWidget())); mMemMapView->setWindowTitle(tr("Memory Map")); mMemMapView->setWindowIcon(DIcon("memory-map.png")); mMemMapView->hide(); // Callstack view mCallStackView = new CallStackView(); mCallStackView->setWindowTitle(tr("Call Stack")); mCallStackView->setWindowIcon(DIcon("callstack.png")); connect(mCallStackView, SIGNAL(showCpu()), this, SLOT(displayCpuWidget())); // SEH Chain view mSEHChainView = new SEHChainView(); mSEHChainView->setWindowTitle(tr("SEH")); mSEHChainView->setWindowIcon(DIcon("seh-chain.png")); connect(mSEHChainView, SIGNAL(showCpu()), this, SLOT(displayCpuWidget())); // Script view mScriptView = new ScriptView(); mScriptView->setWindowTitle(tr("Script")); mScriptView->setWindowIcon(DIcon("script-code.png")); mScriptView->hide(); // CPU view mCpuWidget = new CPUWidget(); mCpuWidget->setWindowTitle(tr("CPU")); #ifdef _WIN64 mCpuWidget->setWindowIcon(DIcon("processor64.png")); #else mCpuWidget->setWindowIcon(DIcon("processor32.png")); ui->actionCpu->setIcon(DIcon("processor32.png")); #endif //_WIN64 // Reference manager mReferenceManager = new ReferenceManager(this); Bridge::getBridge()->referenceManager = mReferenceManager; mReferenceManager->setWindowTitle(tr("References")); mReferenceManager->setWindowIcon(DIcon("search.png")); // Thread view mThreadView = new ThreadView(); connect(mThreadView, SIGNAL(showCpu()), this, SLOT(displayCpuWidget())); mThreadView->setWindowTitle(tr("Threads")); mThreadView->setWindowIcon(DIcon("arrow-threads.png")); // Snowman view (decompiler) mSnowmanView = CreateSnowman(this); if(!mSnowmanView) mSnowmanView = (SnowmanView*)new QLabel("
Snowman is disabled...
", this); mSnowmanView->setWindowTitle(tr("Snowman")); mSnowmanView->setWindowIcon(DIcon("snowman.png")); // Notes manager mNotesManager = new NotesManager(this); mNotesManager->setWindowTitle(tr("Notes")); mNotesManager->setWindowIcon(DIcon("notes.png")); // Handles view mHandlesView = new HandlesView(this); mHandlesView->setWindowTitle(tr("Handles")); mHandlesView->setWindowIcon(DIcon("handles.png")); // Graph view mGraphView = new DisassemblerGraphView(this); mGraphView->setWindowTitle(tr("Graph")); mGraphView->setWindowIcon(DIcon("graph.png")); // Create the tab widget mTabWidget = new MHTabWidget(); // Add all widgets to the list mWidgetList.push_back(mCpuWidget); mWidgetNativeNameList.push_back("CPUTab"); mWidgetList.push_back(mGraphView); mWidgetNativeNameList.push_back("GraphTab"); mWidgetList.push_back(mLogView); mWidgetNativeNameList.push_back("LogTab"); mWidgetList.push_back(mNotesManager); mWidgetNativeNameList.push_back("NotesTab"); mWidgetList.push_back(mBreakpointsView); mWidgetNativeNameList.push_back("BreakpointsTab"); mWidgetList.push_back(mMemMapView); mWidgetNativeNameList.push_back("MemoryMapTab"); mWidgetList.push_back(mCallStackView); mWidgetNativeNameList.push_back("CallStackTab"); mWidgetList.push_back(mSEHChainView); mWidgetNativeNameList.push_back("SEHTab"); mWidgetList.push_back(mScriptView); mWidgetNativeNameList.push_back("ScriptTab"); mWidgetList.push_back(mSymbolView); mWidgetNativeNameList.push_back("SymbolsTab"); mWidgetList.push_back(mSourceViewManager); mWidgetNativeNameList.push_back("SourceTab"); mWidgetList.push_back(mReferenceManager); mWidgetNativeNameList.push_back("ReferencesTab"); mWidgetList.push_back(mThreadView); mWidgetNativeNameList.push_back("ThreadsTab"); mWidgetList.push_back(mSnowmanView); mWidgetNativeNameList.push_back("SnowmanTab"); mWidgetList.push_back(mHandlesView); mWidgetNativeNameList.push_back("HandlesTab"); // If LoadSaveTabOrder disabled, load tabs in default order if(!ConfigBool("Miscellaneous", "LoadSaveTabOrder")) loadTabDefaultOrder(); else loadTabSavedOrder(); setCentralWidget(mTabWidget); // Setup the command and status bars setupCommandBar(); setupStatusBar(); // Patch dialog mPatchDialog = new PatchDialog(this); mCalculatorDialog = new CalculatorDialog(this); connect(mCalculatorDialog, SIGNAL(showCpu()), this, SLOT(displayCpuWidget())); // Setup signals/slots connect(mCmdLineEdit, SIGNAL(returnPressed()), this, SLOT(executeCommand())); connect(ui->actionStepOver, SIGNAL(triggered()), this, SLOT(execStepOver())); connect(ui->actionStepInto, SIGNAL(triggered()), this, SLOT(execStepInto())); connect(ui->actionCommand, SIGNAL(triggered()), this, SLOT(setFocusToCommandBar())); connect(ui->actionClose, SIGNAL(triggered()), this, SLOT(execClose())); connect(ui->actionMemoryMap, SIGNAL(triggered()), this, SLOT(displayMemMapWidget())); connect(ui->actionRun, SIGNAL(triggered()), this, SLOT(execRun())); connect(ui->actionRtr, SIGNAL(triggered()), this, SLOT(execRtr())); connect(ui->actionLog, SIGNAL(triggered()), this, SLOT(displayLogWidget())); connect(ui->actionAbout, SIGNAL(triggered()), this, SLOT(displayAboutWidget())); connect(ui->actionOpen, SIGNAL(triggered()), this, SLOT(openFile())); connect(ui->actionPause, SIGNAL(triggered()), this, SLOT(execPause())); connect(ui->actionScylla, SIGNAL(triggered()), this, SLOT(startScylla())); connect(ui->actionRestart, SIGNAL(triggered()), this, SLOT(restartDebugging())); connect(ui->actionBreakpoints, SIGNAL(triggered()), this, SLOT(displayBreakpointWidget())); connect(ui->actioneStepOver, SIGNAL(triggered()), this, SLOT(execeStepOver())); connect(ui->actioneStepInto, SIGNAL(triggered()), this, SLOT(execeStepInto())); connect(ui->actioneRun, SIGNAL(triggered()), this, SLOT(execeRun())); connect(ui->actioneRtr, SIGNAL(triggered()), this, SLOT(execeRtr())); connect(ui->actionRtu, SIGNAL(triggered()), this, SLOT(execRtu())); connect(ui->actionTicnd, SIGNAL(triggered()), this, SLOT(execTicnd())); connect(ui->actionTocnd, SIGNAL(triggered()), this, SLOT(execTocnd())); connect(ui->actionTRBit, SIGNAL(triggered()), this, SLOT(execTRBit())); connect(ui->actionTRByte, SIGNAL(triggered()), this, SLOT(execTRByte())); connect(ui->actionTRWord, SIGNAL(triggered()), this, SLOT(execTRWord())); connect(ui->actionTRNone, SIGNAL(triggered()), this, SLOT(execTRNone())); connect(ui->actionTRTIBT, SIGNAL(triggered()), this, SLOT(execTRTIBT())); connect(ui->actionTRTOBT, SIGNAL(triggered()), this, SLOT(execTRTOBT())); connect(ui->actionTRTIIT, SIGNAL(triggered()), this, SLOT(execTRTIIT())); connect(ui->actionTRTOIT, SIGNAL(triggered()), this, SLOT(execTRTOIT())); connect(ui->actionInstrUndo, SIGNAL(triggered()), this, SLOT(execInstrUndo())); connect(ui->actionSkipNextInstruction, SIGNAL(triggered()), this, SLOT(execSkip())); connect(ui->actionScript, SIGNAL(triggered()), this, SLOT(displayScriptWidget())); connect(ui->actionRunSelection, SIGNAL(triggered()), this, SLOT(runSelection())); connect(ui->actionRunExpression, SIGNAL(triggered(bool)), this, SLOT(runExpression())); connect(ui->actionHideDebugger, SIGNAL(triggered()), this, SLOT(hideDebugger())); connect(ui->actionCpu, SIGNAL(triggered()), this, SLOT(displayCpuWidget())); connect(ui->actionSymbolInfo, SIGNAL(triggered()), this, SLOT(displaySymbolWidget())); connect(ui->actionSource, SIGNAL(triggered()), this, SLOT(displaySourceViewWidget())); connect(mSymbolView, SIGNAL(showCpu()), this, SLOT(displayCpuWidget())); connect(mSymbolView, SIGNAL(showReferences()), this, SLOT(displayReferencesWidget())); connect(mReferenceManager, SIGNAL(showCpu()), this, SLOT(displayCpuWidget())); connect(mGraphView, SIGNAL(showCpu()), this, SLOT(displayCpuWidget())); connect(ui->actionReferences, SIGNAL(triggered()), this, SLOT(displayReferencesWidget())); connect(ui->actionThreads, SIGNAL(triggered()), this, SLOT(displayThreadsWidget())); connect(ui->actionSettings, SIGNAL(triggered()), this, SLOT(openSettings())); connect(ui->actionStrings, SIGNAL(triggered()), this, SLOT(findStrings())); connect(ui->actionCalls, SIGNAL(triggered()), this, SLOT(findModularCalls())); connect(ui->actionAppearance, SIGNAL(triggered()), this, SLOT(openAppearance())); connect(ui->actionShortcuts, SIGNAL(triggered()), this, SLOT(openShortcuts())); connect(ui->actionTopmost, SIGNAL(toggled(bool)), this, SLOT(changeTopmost(bool))); connect(ui->actionCalculator, SIGNAL(triggered()), this, SLOT(openCalculator())); connect(ui->actionPatches, SIGNAL(triggered()), this, SLOT(patchWindow())); connect(ui->actionComments, SIGNAL(triggered()), this, SLOT(displayComments())); connect(ui->actionLabels, SIGNAL(triggered()), this, SLOT(displayLabels())); connect(ui->actionBookmarks, SIGNAL(triggered()), this, SLOT(displayBookmarks())); connect(ui->actionFunctions, SIGNAL(triggered()), this, SLOT(displayFunctions())); connect(ui->actionCheckUpdates, SIGNAL(triggered()), this, SLOT(checkUpdates())); connect(ui->actionCallStack, SIGNAL(triggered()), this, SLOT(displayCallstack())); connect(ui->actionSEHChain, SIGNAL(triggered()), this, SLOT(displaySEHChain())); connect(ui->actionDonate, SIGNAL(triggered()), this, SLOT(donate())); connect(ui->actionReportBug, SIGNAL(triggered()), this, SLOT(reportBug())); connect(ui->actionCrashDump, SIGNAL(triggered()), this, SLOT(crashDump())); connect(ui->actionAttach, SIGNAL(triggered()), this, SLOT(displayAttach())); connect(ui->actionDetach, SIGNAL(triggered()), this, SLOT(detach())); connect(ui->actionChangeCommandLine, SIGNAL(triggered()), this, SLOT(changeCommandLine())); connect(ui->actionManual, SIGNAL(triggered()), this, SLOT(displayManual())); connect(ui->actionNotes, SIGNAL(triggered()), this, SLOT(displayNotesWidget())); connect(ui->actionSnowman, SIGNAL(triggered()), this, SLOT(displaySnowmanWidget())); connect(ui->actionHandles, SIGNAL(triggered()), this, SLOT(displayHandlesWidget())); connect(ui->actionGraph, SIGNAL(triggered()), this, SLOT(displayGraphWidget())); connect(mCpuWidget->getDisasmWidget(), SIGNAL(updateWindowTitle(QString)), this, SLOT(updateWindowTitleSlot(QString))); connect(mCpuWidget->getDisasmWidget(), SIGNAL(displayReferencesWidget()), this, SLOT(displayReferencesWidget())); connect(mCpuWidget->getDisasmWidget(), SIGNAL(displaySourceManagerWidget()), this, SLOT(displaySourceViewWidget())); connect(mCpuWidget->getDisasmWidget(), SIGNAL(displaySnowmanWidget()), this, SLOT(displaySnowmanWidget())); connect(mCpuWidget->getDisasmWidget(), SIGNAL(displayLogWidget()), this, SLOT(displayLogWidget())); connect(mCpuWidget->getDisasmWidget(), SIGNAL(displayGraphWidget()), this, SLOT(displayGraphWidget())); connect(mCpuWidget->getDisasmWidget(), SIGNAL(showPatches()), this, SLOT(patchWindow())); connect(mCpuWidget->getDisasmWidget(), SIGNAL(decompileAt(dsint, dsint)), this, SLOT(decompileAt(dsint, dsint))); connect(mCpuWidget->getDumpWidget(), SIGNAL(displayReferencesWidget()), this, SLOT(displayReferencesWidget())); connect(mCpuWidget->getStackWidget(), SIGNAL(displayReferencesWidget()), this, SLOT(displayReferencesWidget())); connect(mTabWidget, SIGNAL(tabMovedTabWidget(int, int)), this, SLOT(tabMovedSlot(int, int))); connect(Config(), SIGNAL(shortcutsUpdated()), this, SLOT(refreshShortcuts())); // Setup favourite tools menu updateFavouriteTools(); // Set default setttings (when not set) SettingsDialog defaultSettings; lastException = 0; defaultSettings.SaveSettings(); // Don't need to set shortcuts because the code above will signal refreshShortcuts() // Create updatechecker mUpdateChecker = new UpdateChecker(this); // Setup close thread and dialog bCanClose = false; mCloseThread = new MainWindowCloseThread(this); connect(mCloseThread, SIGNAL(canClose()), this, SLOT(canClose())); mCloseDialog = new CloseDialog(this); mCpuWidget->setDisasmFocus(); } MainWindow::~MainWindow() { delete ui; } void MainWindow::setupCommandBar() { mCmdLineEdit = new CommandLineEdit(ui->cmdBar); ui->cmdBar->addWidget(new QLabel(tr("Command: "))); ui->cmdBar->addWidget(mCmdLineEdit); ui->cmdBar->addWidget(mCmdLineEdit->selectorWidget()); } void MainWindow::setupStatusBar() { // Status label (Ready, Paused, ...) mStatusLabel = new StatusLabel(ui->statusBar); mStatusLabel->setText(tr("Ready")); ui->statusBar->addWidget(mStatusLabel); // Log line mLastLogLabel = new StatusLabel(); ui->statusBar->addPermanentWidget(mLastLogLabel, 1); // Time wasted counter QLabel* timeWastedLabel = new QLabel(this); ui->statusBar->addPermanentWidget(timeWastedLabel); mTimeWastedCounter = new TimeWastedCounter(this, timeWastedLabel); } void MainWindow::closeEvent(QCloseEvent* event) { mCloseDialog->show(); mCloseDialog->setFocus(); static volatile bool bExecuteThread = true; if(bExecuteThread) { bExecuteThread = false; CloseSnowman(mSnowmanView); Sleep(100); mCloseThread->start(); } if(bCanClose) { mCloseDialog->allowClose(); mCloseDialog->close(); event->accept(); } else event->ignore(); } void MainWindow::setTab(QWidget* widget) { for(int i = 0; i < mTabWidget->count(); i++) { if(mTabWidget->widget(i) == widget) { mTabWidget->setCurrentIndex(i); break; } } } void MainWindow::loadTabDefaultOrder() { clearTabWidget(); // Setup tabs //TODO for(int i = 0; i < mWidgetList.size(); i++) addQWidgetTab(mWidgetList[i], mWidgetNativeNameList[i]); } void MainWindow::loadTabSavedOrder() { clearTabWidget(); QMap> tabIndexToWidget; // Get tabIndex for each widget and add them to tabIndexToWidget for(int i = 0; i < mWidgetList.size(); i++) { QString tabName = mWidgetNativeNameList[i]; duint tabIndex = Config()->getUint("TabOrder", tabName); if(!tabIndexToWidget.contains(tabIndex)) tabIndexToWidget.insert(tabIndex, std::make_pair(mWidgetList[i], tabName)); else { // Conflicts. Try to find an unused tab index. for(duint j = 0; j < mWidgetList.size(); j++) { auto item = tabIndexToWidget.find(j); if(item == tabIndexToWidget.end()) { tabIndexToWidget.insert(j, std::make_pair(mWidgetList[i], tabName)); break; } } } } // Setup tabs for(auto & widget : tabIndexToWidget) addQWidgetTab(widget.first, widget.second); } void MainWindow::clearTabWidget() { if(mTabWidget->count() <= 0) return; // Remove all tabs starting from the end for(int i = mTabWidget->count() - 1; i >= 0; i--) mTabWidget->removeTab(i); } void MainWindow::setGlobalShortcut(QAction* action, const QKeySequence & key) { action->setShortcut(key); action->setShortcutContext(Qt::ApplicationShortcut); } void MainWindow::refreshShortcuts() { setGlobalShortcut(ui->actionOpen, ConfigShortcut("FileOpen")); setGlobalShortcut(ui->actionAttach, ConfigShortcut("FileAttach")); setGlobalShortcut(ui->actionDetach, ConfigShortcut("FileDetach")); setGlobalShortcut(ui->actionExit, ConfigShortcut("FileExit")); setGlobalShortcut(ui->actionCpu, ConfigShortcut("ViewCpu")); setGlobalShortcut(ui->actionLog, ConfigShortcut("ViewLog")); setGlobalShortcut(ui->actionBreakpoints, ConfigShortcut("ViewBreakpoints")); setGlobalShortcut(ui->actionMemoryMap, ConfigShortcut("ViewMemoryMap")); setGlobalShortcut(ui->actionCallStack, ConfigShortcut("ViewCallStack")); setGlobalShortcut(ui->actionSEHChain, ConfigShortcut("ViewSEHChain")); setGlobalShortcut(ui->actionScript, ConfigShortcut("ViewScript")); setGlobalShortcut(ui->actionSymbolInfo, ConfigShortcut("ViewSymbolInfo")); setGlobalShortcut(ui->actionSource, ConfigShortcut("ViewSource")); setGlobalShortcut(ui->actionReferences, ConfigShortcut("ViewReferences")); setGlobalShortcut(ui->actionThreads, ConfigShortcut("ViewThreads")); setGlobalShortcut(ui->actionPatches, ConfigShortcut("ViewPatches")); setGlobalShortcut(ui->actionComments, ConfigShortcut("ViewComments")); setGlobalShortcut(ui->actionLabels, ConfigShortcut("ViewLabels")); setGlobalShortcut(ui->actionBookmarks, ConfigShortcut("ViewBookmarks")); setGlobalShortcut(ui->actionFunctions, ConfigShortcut("ViewFunctions")); setGlobalShortcut(ui->actionSnowman, ConfigShortcut("ViewSnowman")); setGlobalShortcut(ui->actionHandles, ConfigShortcut("ViewHandles")); setGlobalShortcut(ui->actionGraph, ConfigShortcut("ViewGraph")); setGlobalShortcut(ui->actionRun, ConfigShortcut("DebugRun")); setGlobalShortcut(ui->actioneRun, ConfigShortcut("DebugeRun")); setGlobalShortcut(ui->actionRunSelection, ConfigShortcut("DebugRunSelection")); setGlobalShortcut(ui->actionRunExpression, ConfigShortcut("DebugRunExpression")); setGlobalShortcut(ui->actionPause, ConfigShortcut("DebugPause")); setGlobalShortcut(ui->actionRestart, ConfigShortcut("DebugRestart")); setGlobalShortcut(ui->actionClose, ConfigShortcut("DebugClose")); setGlobalShortcut(ui->actionStepInto, ConfigShortcut("DebugStepInto")); setGlobalShortcut(ui->actioneStepInto, ConfigShortcut("DebugeStepInto")); setGlobalShortcut(ui->actionStepIntoSource, ConfigShortcut("DebugStepIntoSource")); setGlobalShortcut(ui->actionStepOver, ConfigShortcut("DebugStepOver")); setGlobalShortcut(ui->actioneStepOver, ConfigShortcut("DebugeStepOver")); setGlobalShortcut(ui->actionStepOverSource, ConfigShortcut("DebugStepOverSource")); setGlobalShortcut(ui->actionRtr, ConfigShortcut("DebugRtr")); setGlobalShortcut(ui->actioneRtr, ConfigShortcut("DebugeRtr")); setGlobalShortcut(ui->actionRtu, ConfigShortcut("DebugRtu")); setGlobalShortcut(ui->actionCommand, ConfigShortcut("DebugCommand")); setGlobalShortcut(ui->actionSkipNextInstruction, ConfigShortcut("DebugSkipNextInstruction")); setGlobalShortcut(ui->actionTicnd, ConfigShortcut("DebugTraceIntoConditional")); setGlobalShortcut(ui->actionTocnd, ConfigShortcut("DebugTraceOverConditional")); setGlobalShortcut(ui->actionTRBit, ConfigShortcut("DebugEnableTraceRecordBit")); setGlobalShortcut(ui->actionTRNone, ConfigShortcut("DebugTraceRecordNone")); setGlobalShortcut(ui->actionInstrUndo, ConfigShortcut("DebugInstrUndo")); setGlobalShortcut(ui->actionScylla, ConfigShortcut("PluginsScylla")); setGlobalShortcut(actionManageFavourites, ConfigShortcut("FavouritesManage")); setGlobalShortcut(ui->actionSettings, ConfigShortcut("OptionsPreferences")); setGlobalShortcut(ui->actionAppearance, ConfigShortcut("OptionsAppearance")); setGlobalShortcut(ui->actionShortcuts, ConfigShortcut("OptionsShortcuts")); setGlobalShortcut(ui->actionTopmost, ConfigShortcut("OptionsTopmost")); setGlobalShortcut(ui->actionReloadStylesheet, ConfigShortcut("OptionsReloadStylesheet")); setGlobalShortcut(ui->actionAbout, ConfigShortcut("HelpAbout")); setGlobalShortcut(ui->actionDonate, ConfigShortcut("HelpDonate")); setGlobalShortcut(ui->actionCheckUpdates, ConfigShortcut("HelpCheckForUpdates")); setGlobalShortcut(ui->actionCalculator, ConfigShortcut("HelpCalculator")); setGlobalShortcut(ui->actionReportBug, ConfigShortcut("HelpReportBug")); setGlobalShortcut(ui->actionManual, ConfigShortcut("HelpManual")); setGlobalShortcut(ui->actionCrashDump, ConfigShortcut("HelpCrashDump")); setGlobalShortcut(ui->actionStrings, ConfigShortcut("ActionFindStrings")); setGlobalShortcut(ui->actionCalls, ConfigShortcut("ActionFindIntermodularCalls")); } //Reads recent files list from settings void MainWindow::loadMRUList(int maxItems) { mMaxMRU = maxItems; for(int i = 0; i < mMaxMRU; i++) { char currentFile[MAX_SETTING_SIZE] = ""; if(!BridgeSettingGet("Recent Files", QString().sprintf("%.2d", i + 1).toUtf8().constData(), currentFile)) break; if(QString(currentFile).size() && QFile(currentFile).exists()) mMRUList.push_back(currentFile); } mMRUList.removeDuplicates(); updateMRUMenu(); } //save recent files to settings void MainWindow::saveMRUList() { BridgeSettingSet("Recent Files", 0, 0); //clear mMRUList.removeDuplicates(); int mruSize = mMRUList.size(); for(int i = 0; i < mruSize; i++) { if(QFile(mMRUList.at(i)).exists()) BridgeSettingSet("Recent Files", QString().sprintf("%.2d", i + 1).toUtf8().constData(), mMRUList.at(i).toUtf8().constData()); } } void MainWindow::addMRUEntry(QString entry) { if(!entry.size()) return; //remove duplicate entry if it exists removeMRUEntry(entry); mMRUList.insert(mMRUList.begin(), entry); if(mMRUList.size() > mMaxMRU) mMRUList.erase(mMRUList.begin() + mMaxMRU, mMRUList.end()); } void MainWindow::removeMRUEntry(QString entry) { if(!entry.size()) return; QList::iterator it; for(it = mMRUList.begin(); it != mMRUList.end(); ++it) { if((*it) == entry) { mMRUList.erase(it); break; } } } void MainWindow::updateMRUMenu() { if(mMaxMRU < 1) return; QMenu* fileMenu = ui->menuRecentFiles; QList list = fileMenu->actions(); for(int i = 1; i < list.length(); ++i) fileMenu->removeAction(list.at(i)); //add items to list if(mMRUList.size() > 0) { list = fileMenu->actions(); for(int index = 0; index < mMRUList.size(); ++index) { fileMenu->addAction(new QAction(mMRUList.at(index), this)); fileMenu->actions().last()->setObjectName(QString("MRU").append(QString::number(index))); connect(fileMenu->actions().last(), SIGNAL(triggered()), this, SLOT(openFile())); } } } QString MainWindow::getMRUEntry(int index) { if(index < mMRUList.size()) return mMRUList.at(index); return ""; } void MainWindow::executeCommand() { mCmdLineEdit->execute(); } void MainWindow::execStepOver() { DbgCmdExec("StepOver"); } void MainWindow::execStepInto() { DbgCmdExec("StepInto"); } void MainWindow::setFocusToCommandBar() { mCmdLineEdit->setFocus(); } void MainWindow::execClose() { DbgCmdExec("stop"); } void MainWindow::execRun() { DbgCmdExec("run"); } void MainWindow::execRtr() { DbgCmdExec("rtr"); } void MainWindow::execRtu() { DbgCmdExec("rtu"); } void MainWindow::execTRBit() { mCpuWidget->getDisasmWidget()->ActionTraceRecordBitSlot(); } void MainWindow::execTRByte() { mCpuWidget->getDisasmWidget()->ActionTraceRecordByteSlot(); } void MainWindow::execTRWord() { mCpuWidget->getDisasmWidget()->ActionTraceRecordWordSlot(); } void MainWindow::execTRNone() { mCpuWidget->getDisasmWidget()->ActionTraceRecordDisableSlot(); } void MainWindow::execTRTIBT() { DbgCmdExec("tibt"); } void MainWindow::execTRTOBT() { DbgCmdExec("tobt"); } void MainWindow::execTRTIIT() { DbgCmdExec("tiit"); } void MainWindow::execTRTOIT() { DbgCmdExec("toit"); } void MainWindow::execInstrUndo() { DbgCmdExec("InstrUndo"); } void MainWindow::execTicnd() { if(!DbgIsDebugging()) return; LineEditDialog mLineEdit(this); mLineEdit.setWindowTitle(tr("Enter trace into finishing condition.")); if(mLineEdit.exec() == QDialog::Accepted) DbgCmdExec(QString("ticnd \"%1\"").arg(mLineEdit.editText).toUtf8().constData()); } void MainWindow::execTocnd() { if(!DbgIsDebugging()) return; LineEditDialog mLineEdit(this); mLineEdit.setWindowTitle(tr("Enter trace over finishing condition.")); if(mLineEdit.exec() == QDialog::Accepted) DbgCmdExec(QString("tocnd \"%1\"").arg(mLineEdit.editText).toUtf8().constData()); } void MainWindow::displayMemMapWidget() { showQWidgetTab(mMemMapView); } void MainWindow::displayLogWidget() { showQWidgetTab(mLogView); } void MainWindow::displayScriptWidget() { showQWidgetTab(mScriptView); } void MainWindow::displayAboutWidget() { #ifdef _WIN64 QString title = tr("About x64dbg"); #else QString title = tr("About x32dbg"); #endif //_WIN64 title += QString().sprintf(" v%d", BridgeGetDbgVersion()); QMessageBox msg(QMessageBox::Information, title, "Website:
http://x64dbg.com

Attribution:
Icons8
Yusuke Kamiyamane

Compiled on:
" + ToDateString(GetCompileDate()) + ", " __TIME__); msg.setWindowIcon(DIcon("information.png")); msg.setTextFormat(Qt::RichText); msg.setParent(this, Qt::Dialog); msg.setWindowFlags(msg.windowFlags() & (~Qt::WindowContextHelpButtonHint)); msg.exec(); } void MainWindow::openFile() { QString lastPath, filename; QAction* fileToOpen = qobject_cast(sender()); //if sender is from recent list directly open file, otherwise show dialog if(fileToOpen == NULL || !fileToOpen->objectName().startsWith("MRU") || !(fileToOpen->text().length())) { lastPath = (mMRUList.size() > 0) ? mMRUList.at(0) : 0; filename = QFileDialog::getOpenFileName(this, tr("Open file"), lastPath, tr("Executables (*.exe *.dll);;All files (*.*)")); if(!filename.length()) return; filename = QDir::toNativeSeparators(filename); //convert to native path format (with backlashes) } else { filename = fileToOpen->text(); } DbgCmdExec(QString().sprintf("init \"%s\"", filename.toUtf8().constData()).toUtf8().constData()); //file is from recent menu if(fileToOpen != NULL && fileToOpen->objectName().startsWith("MRU")) { fileToOpen->setObjectName(fileToOpen->objectName().split("U").at(1)); int index = fileToOpen->objectName().toInt(); QString exists = getMRUEntry(index); if(exists.length() == 0) { addMRUEntry(filename); updateMRUMenu(); saveMRUList(); } fileToOpen->setObjectName(fileToOpen->objectName().prepend("MRU")); } //file is from open button bool update = true; if(fileToOpen == NULL || fileToOpen->objectName().compare("actionOpen") == 0) for(int i = 0; i < mMRUList.size(); i++) if(mMRUList.at(i) == filename) { update = false; break; } if(update) { addMRUEntry(filename); updateMRUMenu(); saveMRUList(); } mCpuWidget->setDisasmFocus(); } void MainWindow::execPause() { DbgCmdExec("pause"); } void MainWindow::startScylla() //this is executed { DbgCmdExec("StartScylla"); } void MainWindow::restartDebugging() { if(!mMRUList.size()) return; DbgCmdExec(QString().sprintf("init \"%s\"", mMRUList.at(0).toUtf8().constData()).toUtf8().constData()); mCpuWidget->setDisasmFocus(); } void MainWindow::displayBreakpointWidget() { showQWidgetTab(mBreakpointsView); } void MainWindow::dragEnterEvent(QDragEnterEvent* pEvent) { if(pEvent->mimeData()->hasUrls()) { pEvent->acceptProposedAction(); } } void MainWindow::dropEvent(QDropEvent* pEvent) { if(pEvent->mimeData()->hasUrls()) { QString filename = QDir::toNativeSeparators(pEvent->mimeData()->urls()[0].toLocalFile()); DbgCmdExec(QString().sprintf("init \"%s\"", filename.toUtf8().constData()).toUtf8().constData()); pEvent->acceptProposedAction(); } } void MainWindow::updateWindowTitleSlot(QString filename) { if(filename.length()) { setWindowTitle(mWindowMainTitle + QString(" - ") + filename); windowTitle = filename; } else { setWindowTitle(mWindowMainTitle); windowTitle = mWindowMainTitle; } } void MainWindow::execeStepOver() { DbgCmdExec("eStepOver"); } void MainWindow::execeStepInto() { DbgCmdExec("eStepInto"); } void MainWindow::execeRun() { DbgCmdExec("erun"); } void MainWindow::execeRtr() { DbgCmdExec("ertr"); } void MainWindow::execSkip() { DbgCmdExec("skip"); } void MainWindow::displayCpuWidget() { showQWidgetTab(mCpuWidget); } void MainWindow::displaySymbolWidget() { showQWidgetTab(mSymbolView); } void MainWindow::displaySourceViewWidget() { showQWidgetTab(mSourceViewManager); } void MainWindow::displayReferencesWidget() { showQWidgetTab(mReferenceManager); } void MainWindow::displayThreadsWidget() { showQWidgetTab(mThreadView); } void MainWindow::displaySnowmanWidget() { showQWidgetTab(mSnowmanView); } void MainWindow::displayGraphWidget() { showQWidgetTab(mGraphView); } void MainWindow::hideDebugger() { DbgCmdExec("hide"); } void MainWindow::openSettings() { SettingsDialog* settings = new SettingsDialog(this); connect(settings, SIGNAL(chkSaveLoadTabOrderStateChanged(bool)), this, SLOT(chkSaveloadTabSavedOrderStateChangedSlot(bool))); settings->lastException = lastException; settings->exec(); } void MainWindow::openAppearance() { AppearanceDialog appearance(this); appearance.exec(); } void MainWindow::openCalculator() { mCalculatorDialog->showNormal(); mCalculatorDialog->setFocus(); mCalculatorDialog->setExpressionFocus(); } void MainWindow::openShortcuts() { ShortcutsDialog shortcuts(this); shortcuts.exec(); } void MainWindow::changeTopmost(bool checked) { if(checked) SetWindowPos((HWND)this->winId(), HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE); else SetWindowPos((HWND)this->winId(), HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE); } void MainWindow::addRecentFile(QString file) { addMRUEntry(file); updateMRUMenu(); saveMRUList(); } void MainWindow::setLastException(unsigned int exceptionCode) { lastException = exceptionCode; } void MainWindow::findStrings() { DbgCmdExec(QString("strref " + QString("%1").arg(mCpuWidget->getDisasmWidget()->getSelectedVa(), sizeof(dsint) * 2, 16, QChar('0')).toUpper()).toUtf8().constData()); displayReferencesWidget(); } void MainWindow::findModularCalls() { DbgCmdExec(QString("modcallfind " + QString("%1").arg(mCpuWidget->getDisasmWidget()->getSelectedVa(), sizeof(dsint) * 2, 16, QChar('0')).toUpper()).toUtf8().constData()); displayReferencesWidget(); } const MainWindow::MenuInfo* MainWindow::findMenu(int hMenu) { if(hMenu == -1) return 0; int nFound = -1; for(int i = 0; i < mMenuList.size(); i++) { if(hMenu == mMenuList.at(i).hMenu) { nFound = i; break; } } return nFound == -1 ? 0 : &mMenuList.at(nFound); } void MainWindow::addMenuToList(QWidget* parent, QMenu* menu, int hMenu, int hParentMenu) { if(!findMenu(hMenu)) mMenuList.push_back(MenuInfo(parent, menu, hMenu, hParentMenu)); Bridge::getBridge()->setResult(); } void MainWindow::addMenu(int hMenu, QString title) { const MenuInfo* menu = findMenu(hMenu); if(!menu && hMenu != -1) { Bridge::getBridge()->setResult(-1); return; } int hMenuNew = hMenuNext++; QWidget* parent = hMenu == -1 ? this : menu->parent; QMenu* wMenu = new QMenu(title, parent); wMenu->menuAction()->setVisible(false); mMenuList.push_back(MenuInfo(parent, wMenu, hMenuNew, hMenu)); if(hMenu == -1) //top-level ui->menuBar->addMenu(wMenu); else //deeper level menu->mMenu->addMenu(wMenu); Bridge::getBridge()->setResult(hMenuNew); } void MainWindow::addMenuEntry(int hMenu, QString title) { const MenuInfo* menu = findMenu(hMenu); if(!menu && hMenu != -1) { Bridge::getBridge()->setResult(-1); return; } MenuEntryInfo newInfo; int hEntryNew = hEntryNext++; newInfo.hEntry = hEntryNew; newInfo.hParentMenu = hMenu; QWidget* parent = hMenu == -1 ? this : menu->parent; QAction* wAction = new QAction(title, parent); wAction->setObjectName(QString().sprintf("ENTRY|%d", hEntryNew)); parent->addAction(wAction); connect(wAction, SIGNAL(triggered()), this, SLOT(menuEntrySlot())); newInfo.mAction = wAction; mEntryList.push_back(newInfo); if(hMenu == -1) //top level ui->menuBar->addAction(wAction); else //deeper level { menu->mMenu->addAction(wAction); menu->mMenu->menuAction()->setVisible(true); } Bridge::getBridge()->setResult(hEntryNew); } void MainWindow::addSeparator(int hMenu) { const MenuInfo* menu = findMenu(hMenu); if(menu) { MenuEntryInfo newInfo; newInfo.hEntry = -1; newInfo.hParentMenu = hMenu; newInfo.mAction = menu->mMenu->addSeparator(); mEntryList.push_back(newInfo); } Bridge::getBridge()->setResult(); } void MainWindow::clearMenu(int hMenu) { if(!mMenuList.size() || hMenu == -1) { Bridge::getBridge()->setResult(); return; } const MenuInfo* menu = findMenu(hMenu); //delete menu entries for(int i = mEntryList.size() - 1; i > -1; i--) { if(hMenu == mEntryList.at(i).hParentMenu) //we found an entry that has the menu as parent { QWidget* parent = menu == 0 ? this : menu->parent; parent->removeAction(mEntryList.at(i).mAction); delete mEntryList.at(i).mAction; //delete the entry object mEntryList.erase(mEntryList.begin() + i); } } //recursively delete the menus for(int i = mMenuList.size() - 1; i > -1; i--) { if(hMenu == mMenuList.at(i).hParentMenu) //we found a menu that has the menu as parent { clearMenu(mMenuList.at(i).hMenu); //delete children menus delete mMenuList.at(i).mMenu; //delete the child menu object mMenuList.erase(mMenuList.begin() + i); //delete the child entry } } //hide the empty menu if(menu) menu->mMenu->menuAction()->setVisible(false); Bridge::getBridge()->setResult(); } void MainWindow::initMenuApi() { //256 entries are reserved mEntryList.clear(); hEntryNext = 256; mMenuList.clear(); hMenuNext = 256; } void MainWindow::menuEntrySlot() { QAction* action = qobject_cast(sender()); if(action && action->objectName().startsWith("ENTRY|")) { int hEntry = -1; if(sscanf_s(action->objectName().mid(6).toUtf8().constData(), "%d", &hEntry) == 1) DbgMenuEntryClicked(hEntry); } } void MainWindow::removeMenuEntry(int hEntry) { for(int i = 0; i < mEntryList.size(); i++) { if(mEntryList.at(i).hEntry == hEntry) { const MenuEntryInfo & entry = mEntryList.at(i); const MenuInfo* menu = findMenu(entry.hParentMenu); QWidget* parent = menu == 0 ? this : menu->parent; parent->removeAction(entry.mAction); delete entry.mAction; mEntryList.erase(mEntryList.begin() + i); break; } } Bridge::getBridge()->setResult(); } void MainWindow::setIconMenuEntry(int hEntry, QIcon icon) { for(int i = 0; i < mEntryList.size(); i++) { if(mEntryList.at(i).hEntry == hEntry) { const MenuEntryInfo & entry = mEntryList.at(i); entry.mAction->setIcon(icon); break; } } Bridge::getBridge()->setResult(); } void MainWindow::setIconMenu(int hMenu, QIcon icon) { for(int i = 0; i < mMenuList.size(); i++) { if(mMenuList.at(i).hMenu == hMenu) { const MenuInfo & menu = mMenuList.at(i); menu.mMenu->setIcon(icon); } } Bridge::getBridge()->setResult(); } void MainWindow::runSelection() { if(!DbgIsDebugging()) return; QString command = "bp " + QString("%1").arg(mCpuWidget->getDisasmWidget()->getSelectedVa(), sizeof(dsint) * 2, 16, QChar('0')).toUpper() + ", ss"; if(DbgCmdExecDirect(command.toUtf8().constData())) DbgCmdExecDirect("run"); } void MainWindow::runExpression() { if(!DbgIsDebugging()) return; GotoDialog gotoDialog(this); gotoDialog.setWindowTitle(tr("Enter expression to run to...")); if(gotoDialog.exec() != QDialog::Accepted) return; if(DbgCmdExecDirect(QString("bp \"%1\", ss").arg(gotoDialog.expressionText).toUtf8().constData())) DbgCmdExecDirect("run"); } void MainWindow::getStrWindow(const QString title, QString* text) { LineEditDialog mLineEdit(this); mLineEdit.setWindowTitle(title); bool bResult = true; if(mLineEdit.exec() != QDialog::Accepted) bResult = false; *text = mLineEdit.editText; Bridge::getBridge()->setResult(bResult); } void MainWindow::patchWindow() { if(!DbgIsDebugging()) { SimpleErrorBox(this, tr("Error!"), tr("Patches cannot be shown when not debugging...")); return; } GuiUpdatePatches(); mPatchDialog->showNormal(); mPatchDialog->setFocus(); } void MainWindow::displayComments() { if(!DbgIsDebugging()) return; DbgCmdExec("commentlist"); displayReferencesWidget(); } void MainWindow::displayLabels() { if(!DbgIsDebugging()) return; DbgCmdExec("labellist"); displayReferencesWidget(); } void MainWindow::displayBookmarks() { if(!DbgIsDebugging()) return; DbgCmdExec("bookmarklist"); displayReferencesWidget(); } void MainWindow::displayFunctions() { if(!DbgIsDebugging()) return; DbgCmdExec("functionlist"); displayReferencesWidget(); } void MainWindow::checkUpdates() { mUpdateChecker->checkForUpdates(); } void MainWindow::displayCallstack() { showQWidgetTab(mCallStackView); } void MainWindow::displaySEHChain() { showQWidgetTab(mSEHChainView); } void MainWindow::donate() { QMessageBox msg(QMessageBox::Information, tr("Donate"), tr("All the money will go to x64dbg development.")); msg.setWindowIcon(DIcon("donate.png")); msg.setParent(this, Qt::Dialog); msg.setWindowFlags(msg.windowFlags() & (~Qt::WindowContextHelpButtonHint)); msg.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel); msg.setDefaultButton(QMessageBox::Ok); if(msg.exec() != QMessageBox::Ok) return; QDesktopServices::openUrl(QUrl("http://donate.x64dbg.com")); } void MainWindow::reportBug() { QMessageBox msg(QMessageBox::Information, tr("Report Bug"), tr("You will be taken to a website where you can report a bug.\nMake sure to fill in as much information as possible.")); msg.setWindowIcon(DIcon("bug-report.png")); msg.setParent(this, Qt::Dialog); msg.setWindowFlags(msg.windowFlags() & (~Qt::WindowContextHelpButtonHint)); msg.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel); msg.setDefaultButton(QMessageBox::Ok); if(msg.exec() != QMessageBox::Ok) return; QDesktopServices::openUrl(QUrl("http://report.x64dbg.com")); } void MainWindow::crashDump() { QMessageBox msg(QMessageBox::Critical, tr("Generate crash dump"), tr("This action will crash the debugger and generate a crash dump. You will LOSE ALL YOUR DATA. Do you really want to continue?")); msg.setWindowIcon(DIcon("fatal-error.png")); msg.setParent(this, Qt::Dialog); msg.setWindowFlags(msg.windowFlags() & (~Qt::WindowContextHelpButtonHint)); msg.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel); msg.setDefaultButton(QMessageBox::Cancel); if(msg.exec() != QMessageBox::Ok) return; // Fatal error __debugbreak(); // Congratulations! We survived a fatal error! SimpleWarningBox(this, tr("Have fun debugging the debugger!"), tr("Debugger detected!")); } void MainWindow::displayAttach() { AttachDialog attach(this); attach.exec(); mCpuWidget->setDisasmFocus(); } void MainWindow::detach() { DbgCmdExec("detach"); } void MainWindow::changeCommandLine() { if(!DbgIsDebugging()) return; LineEditDialog mLineEdit(this); mLineEdit.setText(""); mLineEdit.setWindowTitle(tr("Change Command Line")); mLineEdit.setWindowIcon(DIcon("changeargs.png")); size_t cbsize = 0; char* cmdline = 0; if(!DbgFunctions()->GetCmdline(0, &cbsize)) mLineEdit.setText(tr("Cannot get remote command line, use the 'getcmdline' command for more information.")); else { cmdline = new char[cbsize]; DbgFunctions()->GetCmdline(cmdline, 0); mLineEdit.setText(QString(cmdline)); delete[] cmdline; } mLineEdit.setCursorPosition(0); if(mLineEdit.exec() != QDialog::Accepted) return; //pressed cancel if(!DbgFunctions()->SetCmdline((char*)mLineEdit.editText.toUtf8().constData())) SimpleErrorBox(this, tr("Error!"), tr("Could not set command line!")); else { DbgFunctions()->MemUpdateMap(); GuiUpdateMemoryView(); GuiAddStatusBarMessage((tr("New command line: ") + mLineEdit.editText + "\n").toUtf8().constData()); } } void MainWindow::displayManual() { // Open the Windows CHM in the upper directory QDesktopServices::openUrl(QUrl(QUrl::fromLocalFile(QString("%1/../x64dbg.chm").arg(QCoreApplication::applicationDirPath())))); } void MainWindow::decompileAt(dsint start, dsint end) { DecompileAt(mSnowmanView, start, end); } void MainWindow::canClose() { bCanClose = true; close(); } void MainWindow::addQWidgetTab(QWidget* qWidget, QString nativeName) { mTabWidget->addTabEx(qWidget, qWidget->windowIcon(), qWidget->windowTitle(), nativeName); } void MainWindow::addQWidgetTab(QWidget* qWidget) { addQWidgetTab(qWidget, qWidget->windowTitle()); } void MainWindow::showQWidgetTab(QWidget* qWidget) { qWidget->show(); qWidget->setFocus(); setTab(qWidget); } void MainWindow::closeQWidgetTab(QWidget* qWidget) { for(int i = 0; i < mTabWidget->count(); i++) { if(mTabWidget->widget(i) == qWidget) { mTabWidget->DeleteTab(i); break; } } } void MainWindow::executeOnGuiThread(void* cbGuiThread) { ((GUICALLBACK)cbGuiThread)(); } void MainWindow::tabMovedSlot(int from, int to) { for(int i = 0; i < mTabWidget->count(); i++) { // Remove space in widget name and append Tab to get config settings (CPUTab, MemoryMapTab, etc...) //QString tabName = mTabWidget->tabText(i).replace(" ", "") + "Tab"; QString tabName = mTabWidget->getNativeName(i); Config()->setUint("TabOrder", tabName, i); } } void MainWindow::chkSaveloadTabSavedOrderStateChangedSlot(bool state) { if(state) loadTabSavedOrder(); else loadTabDefaultOrder(); } void MainWindow::dbgStateChangedSlot(DBGSTATE state) { if(state == initialized) //fixes a crash when restarting with certain settings in another tab displayCpuWidget(); } void MainWindow::on_actionFaq_triggered() { QDesktopServices::openUrl(QUrl("http://faq.x64dbg.com")); } void MainWindow::on_actionReloadStylesheet_triggered() { QFile f(QString("%1/style.css").arg(QCoreApplication::applicationDirPath())); if(f.open(QFile::ReadOnly | QFile::Text)) { QTextStream in(&f); auto style = in.readAll(); f.close(); qApp->setStyleSheet(style); } else qApp->setStyleSheet(""); ensurePolished(); update(); } void MainWindow::displayNotesWidget() { showQWidgetTab(mNotesManager); } void MainWindow::displayHandlesWidget() { showQWidgetTab(mHandlesView); } void MainWindow::manageFavourites() { FavouriteTools favToolsDialog(this); favToolsDialog.exec(); updateFavouriteTools(); } void MainWindow::updateFavouriteTools() { char buffer[MAX_SETTING_SIZE]; bool isanythingexists = false; ui->menuFavourites->clear(); for(unsigned int i = 1; BridgeSettingGet("Favourite", QString("Tool%1").arg(i).toUtf8().constData(), buffer); i++) { QString exePath = QString::fromUtf8(buffer); QAction* newAction = new QAction(this); newAction->setData(QVariant(QString("Tool,%1").arg(exePath))); if(BridgeSettingGet("Favourite", QString("ToolShortcut%1").arg(i).toUtf8().constData(), buffer)) if(*buffer && strcmp(buffer, "NOT_SET") != 0) setGlobalShortcut(newAction, QKeySequence(QString::fromUtf8(buffer))); if(BridgeSettingGet("Favourite", QString("ToolDescription%1").arg(i).toUtf8().constData(), buffer)) newAction->setText(QString::fromUtf8(buffer)); else newAction->setText(exePath); connect(newAction, SIGNAL(triggered()), this, SLOT(clickFavouriteTool())); ui->menuFavourites->addAction(newAction); isanythingexists = true; } if(isanythingexists) { isanythingexists = false; ui->menuFavourites->addSeparator(); } for(unsigned int i = 1; BridgeSettingGet("Favourite", QString("Script%1").arg(i).toUtf8().constData(), buffer); i++) { QString scriptPath = QString::fromUtf8(buffer); QAction* newAction = new QAction(this); newAction->setData(QVariant(QString("Script,%1").arg(scriptPath))); if(BridgeSettingGet("Favourite", QString("ScriptShortcut%1").arg(i).toUtf8().constData(), buffer)) if(*buffer && strcmp(buffer, "NOT_SET") != 0) setGlobalShortcut(newAction, QKeySequence(QString::fromUtf8(buffer))); if(BridgeSettingGet("Favourite", QString("ScriptDescription%1").arg(i).toUtf8().constData(), buffer)) newAction->setText(QString::fromUtf8(buffer)); else newAction->setText(scriptPath); connect(newAction, SIGNAL(triggered()), this, SLOT(clickFavouriteTool())); ui->menuFavourites->addAction(newAction); isanythingexists = true; } if(isanythingexists) { isanythingexists = false; ui->menuFavourites->addSeparator(); } for(unsigned int i = 1; BridgeSettingGet("Favourite", QString("Command%1").arg(i).toUtf8().constData(), buffer); i++) { QAction* newAction = new QAction(QString::fromUtf8(buffer), this); newAction->setData(QVariant(QString("Command"))); if(BridgeSettingGet("Favourite", QString("CommandShortcut%1").arg(i).toUtf8().constData(), buffer)) if(*buffer && strcmp(buffer, "NOT_SET") != 0) setGlobalShortcut(newAction, QKeySequence(QString::fromUtf8(buffer))); connect(newAction, SIGNAL(triggered()), this, SLOT(clickFavouriteTool())); ui->menuFavourites->addAction(newAction); isanythingexists = true; } if(isanythingexists) ui->menuFavourites->addSeparator(); actionManageFavourites = new QAction(DIcon("star.png"), tr("&Manage Favourite Tools..."), this); ui->menuFavourites->addAction(actionManageFavourites); setGlobalShortcut(actionManageFavourites, ConfigShortcut("FavouritesManage")); connect(ui->menuFavourites->actions().last(), SIGNAL(triggered()), this, SLOT(manageFavourites())); } void MainWindow::clickFavouriteTool() { QAction* action = qobject_cast(sender()); if(action == nullptr) return; QString data = action->data().toString(); if(data.startsWith("Tool,")) { QString toolPath = data.mid(5); duint PID = DbgValFromString("$pid"); toolPath.replace(QString("%PID%"), QString::number(PID), Qt::CaseInsensitive); PROCESS_INFORMATION procinfo; STARTUPINFO startupinfo; memset(&procinfo, 0, sizeof(PROCESS_INFORMATION)); memset(&startupinfo, 0, sizeof(startupinfo)); startupinfo.cb = sizeof(startupinfo); CreateProcessW(nullptr, (LPWSTR)toolPath.toStdWString().c_str(), nullptr, nullptr, FALSE, 0, nullptr, nullptr, &startupinfo, &procinfo); CloseHandle(procinfo.hThread); CloseHandle(procinfo.hProcess); } else if(data.startsWith("Script,")) { QString scriptPath = data.mid(7); DbgScriptUnload(); DbgScriptLoad(scriptPath.toUtf8().constData()); } else if(data.compare("Command") == 0) { DbgCmdExec(action->text().toUtf8().constData()); } } void MainWindow::on_actionStepIntoSource_triggered() { DbgCmdExec("TraceIntoConditional src.line(cip) && !src.disp(cip)"); } void MainWindow::on_actionStepOverSource_triggered() { DbgCmdExec("TraceOverConditional src.line(cip) && !src.disp(cip)"); }