From 808da402da5e93782c4d022bac0af1f42444e427 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=A4rkl?= Date: Sun, 1 Oct 2017 16:36:40 +0200 Subject: [PATCH] Disassembly Options Dialog (#21) * Add AsmOptionsDialog * Add bbline to AsmOptionsDialog, properly handle defaults * Remove now redundant asm options from right click and menu --- src/cutter.cpp | 165 ++++++++++++++++++------------- src/cutter.h | 20 +++- src/cutter.pro | 8 +- src/dialogs/asmoptionsdialog.cpp | 155 +++++++++++++++++++++++++++++ src/dialogs/asmoptionsdialog.h | 49 +++++++++ src/dialogs/asmoptionsdialog.ui | 127 ++++++++++++++++++++++++ src/helpers.cpp | 9 ++ src/helpers.h | 3 + src/mainwindow.cpp | 117 +--------------------- src/mainwindow.h | 10 +- src/mainwindow.ui | 25 +++-- src/optionsdialog.cpp | 20 +--- src/optionsdialog.ui | 153 ++++------------------------ src/radarewebserver.cpp | 4 +- src/settings.h | 38 +++++-- src/widgets/MemoryWidget.cpp | 118 ++++------------------ src/widgets/MemoryWidget.h | 7 -- src/widgets/MemoryWidget.ui | 70 +++---------- src/widgets/consolewidget.cpp | 2 + 19 files changed, 561 insertions(+), 539 deletions(-) create mode 100644 src/dialogs/asmoptionsdialog.cpp create mode 100644 src/dialogs/asmoptionsdialog.h create mode 100644 src/dialogs/asmoptionsdialog.ui diff --git a/src/cutter.cpp b/src/cutter.cpp index cdd184bd..6e8f5cdc 100644 --- a/src/cutter.cpp +++ b/src/cutter.cpp @@ -2,6 +2,7 @@ #include #include "cutter.h" #include "sdb.h" +#include "settings.h" #define DB this->db @@ -50,11 +51,11 @@ CutterCore::CutterCore(QObject *parent) : // IMPLICIT r_bin_iobind (core_->bin, core_->io); // Otherwise r2 may ask the user for input and Cutter would freeze - config("scr.interactive", "false"); + setConfig("scr.interactive", false); // Used by the HTML5 graph - config("http.cors", "true"); - config("http.sandbox", "false"); + setConfig("http.cors", true); + setConfig("http.sandbox", false); //config("http.port", "14170"); // Temporary fixes @@ -457,35 +458,72 @@ QString CutterCore::itoa(ut64 num, int rdx) return QString::number(num, rdx); } -QString CutterCore::config(const QString &k, const QString &v) +void CutterCore::setConfig(const QString &k, const QString &v) { CORE_LOCK(); - QByteArray key = k.toUtf8(); - if (v != NULL) - { - r_config_set(core_->config, key.constData(), v.toUtf8().constData()); - return NULL; - } - return QString(r_config_get(core_->config, key.constData())); + r_config_set(core_->config, k.toUtf8().constData(), v.toUtf8().constData()); } -int CutterCore::config(const QString &k, int v) +void CutterCore::setConfig(const QString &k, int v) { CORE_LOCK(); - QByteArray key = k.toUtf8(); - if (v != -1) - { - r_config_set_i(core_->config, key.constData(), v); - return 0; - } - return r_config_get_i(core_->config, key.constData()); + r_config_set_i(core_->config, k.toUtf8().constData(), static_cast(v)); +} + +void CutterCore::setConfig(const QString &k, bool v) +{ + CORE_LOCK(); + r_config_set_i(core_->config, k.toUtf8().constData(), v ? 1 : 0); } int CutterCore::getConfigi(const QString &k) { CORE_LOCK(); QByteArray key = k.toUtf8(); - return r_config_get_i(core_->config, key.constData()); + return static_cast(r_config_get_i(core_->config, key.constData())); +} + +bool CutterCore::getConfigb(const QString &k) +{ + CORE_LOCK(); + return r_config_get_i(core_->config, k.toUtf8().constData()) != 0; +} + +void CutterCore::triggerAsmOptionsChanged() +{ + emit asmOptionsChanged(); +} + +void CutterCore::resetDefaultAsmOptions() +{ + Settings settings; + setConfig("asm.esil", settings.getAsmESIL()); + setConfig("asm.pseudo", settings.getAsmPseudo()); + setConfig("asm.offset", settings.getAsmOffset()); + setConfig("asm.describe", settings.getAsmDescribe()); + setConfig("asm.stackptr", settings.getAsmStackPointer()); + setConfig("asm.bytes", settings.getAsmBytes()); + setConfig("asm.bytespace", settings.getAsmBytespace()); + setConfig("asm.lbytes", settings.getAsmLBytes()); + setConfig("asm.syntax", settings.getAsmSyntax()); + setConfig("asm.ucase", settings.getAsmUppercase()); + setConfig("asm.bbline", settings.getAsmBBLine()); +} + +void CutterCore::saveDefaultAsmOptions() +{ + Settings settings; + settings.setAsmESIL(getConfigb("asm.esil")); + settings.setAsmPseudo(getConfigb("asm.pseudo")); + settings.setAsmOffset(getConfigb("asm.offset")); + settings.setAsmDescribe(getConfigb("asm.describe")); + settings.setAsmStackPointer(getConfigb("asm.stackptr")); + settings.setAsmBytes(getConfigb("asm.bytes")); + settings.setAsmBytespace(getConfigb("asm.bytespace")); + settings.setAsmLBytes(getConfigb("asm.lbytes")); + settings.setAsmSyntax(getConfig("asm.syntax")); + settings.setAsmUppercase(getConfigb("asm.ucase")); + settings.setAsmBBLine(getConfigb("asm.bbline")); } QString CutterCore::getConfig(const QString &k) @@ -510,9 +548,9 @@ void CutterCore::setOptions(QString key) void CutterCore::setCPU(QString arch, QString cpu, int bits, bool temporary) { - config("asm.arch", arch); - config("asm.cpu", cpu); - config("asm.bits", bits); + setConfig("asm.arch", arch); + setConfig("asm.cpu", cpu); + setConfig("asm.bits", bits); if (!temporary) { default_arch = arch; @@ -524,11 +562,11 @@ void CutterCore::setCPU(QString arch, QString cpu, int bits, bool temporary) void CutterCore::setDefaultCPU() { if (!default_arch.isEmpty()) - config("asm.arch", default_arch); + setConfig("asm.arch", default_arch); if (!default_cpu.isEmpty()) - config("asm.cpu", default_cpu); + setConfig("asm.cpu", default_cpu); if (default_bits) - config("asm.bits", QString::number(default_bits)); + setConfig("asm.bits", QString::number(default_bits)); } QString CutterCore::assemble(const QString &code) @@ -697,60 +735,55 @@ void CutterCore::getOpcodes() void CutterCore::setSettings() { - config("scr.color", "false"); - config("scr.interactive", "false"); - config("asm.lines", "false"); + setConfig("scr.color", false); + setConfig("scr.interactive", false); + setConfig("asm.lines", false); // Intredazting... - //config("asm.linesright", "true"); - //config("asm.lineswidth", "15"); - //config("asm.functions", "false"); - config("hex.pairs", "false"); - config("asm.bytespace", "true"); - config("asm.cmtflgrefs", "false"); - config("asm.cmtright", "true"); - config("asm.cmtcol", "70"); - config("asm.xrefs", "false"); - config("asm.fcnlines", "false"); + //setConfig("asm.linesright", "true"); + //setConfig("asm.lineswidth", "15"); + //setConfig("asm.functions", "false"); + setConfig("hex.pairs", false); + setConfig("asm.cmtflgrefs", false); + setConfig("asm.cmtright", true); + setConfig("asm.cmtcol", 70); + setConfig("asm.xrefs", false); + setConfig("asm.fcnlines", false); - config("asm.tabs", "5"); - config("asm.tabsonce", "true"); - config("asm.tabsoff", "5"); - config("asm.nbytes", "10"); - config("asm.midflags", "2"); - //config("asm.bbline", "true"); + setConfig("asm.tabs", 5); + setConfig("asm.tabsonce", true); + setConfig("asm.tabsoff", 5); + setConfig("asm.nbytes", 10); + setConfig("asm.midflags", 2); + //setConfig("asm.bbline", "true"); - config("anal.hasnext", "true"); - config("asm.fcncalls", "false"); - config("asm.calls", "false"); - config("asm.lines.call", "false"); - config("asm.flgoff", "true"); - config("anal.autoname", "true"); - - // Required for consistency with GUI checkboxes - config("asm.esil", "false"); - config("asm.pseudo", "false"); + setConfig("anal.hasnext", true); + setConfig("asm.fcncalls", false); + setConfig("asm.calls", false); + setConfig("asm.lines.call", false); + setConfig("asm.flgoff", true); + setConfig("anal.autoname", true); // Highlight current node in graphviz - config("graph.gv.current", "true"); + setConfig("graph.gv.current", true); // Fucking pancake xD - config("cfg.fortunes.tts", "false"); + setConfig("cfg.fortunes.tts", false); // Experimenting with asm options - //config("asm.spacy", "true"); // We need to handle blank lines on scroll - //config("asm.section", "true"); // Breaks the disasm and navigation - //config("asm.invhex", "true"); // Needs further testing - //config("asm.flags", "false"); // Add with default true in future + //setConfig("asm.spacy", "true"); // We need to handle blank lines on scroll + //setConfig("asm.section", "true"); // Breaks the disasm and navigation + //setConfig("asm.invhex", "true"); // Needs further testing + //setConfig("asm.flags", "false"); // Add with default true in future // Used by the HTML5 graph - config("http.cors", "true"); - config("http.sandbox", "false"); + setConfig("http.cors", true); + setConfig("http.sandbox", false); //config("http.port", "14170"); // Temporary fixes - //config("http.root","/usr/local/share/radare2/last/www"); - //config("http.root","/usr/local/radare2/osx/share/radare2/1.1.0-git/www"); - //config("bin.rawstr", "true"); + //setConfig("http.root","/usr/local/share/radare2/last/www"); + //setConfig("http.root","/usr/local/radare2/osx/share/radare2/1.1.0-git/www"); + //setConfig("bin.rawstr", "true"); // Graph colors and design cmd("ec graph.true rgb:88FF88"); diff --git a/src/cutter.h b/src/cutter.h index eaabc606..b5f9446c 100644 --- a/src/cutter.h +++ b/src/cutter.h @@ -208,10 +208,16 @@ public: void seek(ut64 offset); ut64 math(const QString &expr); QString itoa(ut64 num, int rdx = 16); - QString config(const QString &k, const QString &v = NULL); - int config(const QString &k, int v); + + void setConfig(const QString &k, const QString &v); + void setConfig(const QString &k, int v); + void setConfig(const QString &k, bool v); + void setConfig(const QString &k, const char *v) { setConfig(k, QString(v)); } + int getConfigi(const QString &k); + bool getConfigb(const QString &k); QString getConfig(const QString &k); + QString assemble(const QString &code); QString disassemble(const QString &hex); QString disassembleSingleInstruction(RVA addr); @@ -268,6 +274,11 @@ public: void addFlag(RVA offset, QString name, RVA size); + void triggerAsmOptionsChanged(); + + void resetDefaultAsmOptions(); + void saveDefaultAsmOptions(); + RCoreLocked core() const; /* fields */ @@ -280,6 +291,11 @@ signals: void flagsChanged(); void commentsChanged(); + /*! + * emitted when config regarding disassembly display changes + */ + void asmOptionsChanged(); + public slots: private: diff --git a/src/cutter.pro b/src/cutter.pro index 1d0dcf0a..b906124b 100644 --- a/src/cutter.pro +++ b/src/cutter.pro @@ -73,7 +73,8 @@ SOURCES += \ dialogs/flagdialog.cpp \ widgets/DisassemblerGraphView.cpp \ widgets/MemoryWidget.cpp \ - utils/RichTextPainter.cpp + utils/RichTextPainter.cpp \ + dialogs/asmoptionsdialog.cpp HEADERS += \ mainwindow.h \ @@ -117,7 +118,9 @@ HEADERS += \ widgets/DisassemblerGraphView.h \ widgets/MemoryWidget.h \ utils/RichTextPainter.h \ - utils/CachedFontMetrics.h + utils/CachedFontMetrics.h \ + dialogs/asmoptionsdialog.h + FORMS += \ mainwindow.ui \ newfiledialog.ui \ @@ -143,6 +146,7 @@ FORMS += \ widgets/consolewidget.ui \ widgets/entrypointwidget.ui \ dialogs/flagdialog.ui \ + dialogs/asmoptionsdialog.ui \ widgets/MemoryWidget.ui RESOURCES += \ diff --git a/src/dialogs/asmoptionsdialog.cpp b/src/dialogs/asmoptionsdialog.cpp new file mode 100644 index 00000000..5993138b --- /dev/null +++ b/src/dialogs/asmoptionsdialog.cpp @@ -0,0 +1,155 @@ + +#include "settings.h" +#include "asmoptionsdialog.h" +#include "ui_asmoptionsdialog.h" + +#include "helpers.h" + +AsmOptionsDialog::AsmOptionsDialog(CutterCore *core, QWidget *parent) : QDialog(parent), ui(new Ui::AsmOptionsDialog) +{ + this->core = core; + + ui->setupUi(this); + + ui->buttonBox->addButton(tr("Save as Defaults"), QDialogButtonBox::ButtonRole::ApplyRole); + + ui->syntaxComboBox->blockSignals(true); + for(const auto &syntax : core->cmdList("e asm.syntax=?")) + ui->syntaxComboBox->addItem(syntax, syntax); + ui->syntaxComboBox->blockSignals(false); + + updateFromVars(); +} + +AsmOptionsDialog::~AsmOptionsDialog() +{ + delete ui; +} + +void AsmOptionsDialog::updateFromVars() +{ + qhelpers::setCheckedWithoutSignals(ui->esilCheckBox, core->getConfigb("asm.esil")); + qhelpers::setCheckedWithoutSignals(ui->pseudoCheckBox, core->getConfigb("asm.pseudo")); + qhelpers::setCheckedWithoutSignals(ui->offsetCheckBox, core->getConfigb("asm.offset")); + qhelpers::setCheckedWithoutSignals(ui->describeCheckBox, core->getConfigb("asm.describe")); + qhelpers::setCheckedWithoutSignals(ui->stackpointerCheckBox, core->getConfigb("asm.stackptr")); + + bool bytesEnabled = core->getConfigb("asm.bytes"); + qhelpers::setCheckedWithoutSignals(ui->bytesCheckBox, bytesEnabled); + qhelpers::setCheckedWithoutSignals(ui->bytespaceCheckBox, core->getConfigb("asm.bytespace")); + ui->bytespaceCheckBox->setEnabled(bytesEnabled); + qhelpers::setCheckedWithoutSignals(ui->lbytesCheckBox, core->getConfigb("asm.lbytes")); + ui->lbytesCheckBox->setEnabled(bytesEnabled); + + QString currentSyntax = core->getConfig("asm.syntax"); + for (int i = 0; i < ui->syntaxComboBox->count(); i++) + { + if (ui->syntaxComboBox->itemData(i) == currentSyntax) + { + ui->syntaxComboBox->blockSignals(true); + ui->syntaxComboBox->setCurrentIndex(i); + ui->syntaxComboBox->blockSignals(false); + break; + } + } + + qhelpers::setCheckedWithoutSignals(ui->uppercaseCheckBox, core->getConfigb("asm.ucase")); + qhelpers::setCheckedWithoutSignals(ui->bblineCheckBox, core->getConfigb("asm.bbline")); +} + + +void AsmOptionsDialog::saveAsDefault() +{ + core->saveDefaultAsmOptions(); +} + +void AsmOptionsDialog::resetToDefault() +{ + core->resetDefaultAsmOptions(); + updateFromVars(); + core->triggerAsmOptionsChanged(); +} + + +void AsmOptionsDialog::on_esilCheckBox_toggled(bool checked) +{ + core->setConfig("asm.esil", checked); + core->triggerAsmOptionsChanged(); +} + +void AsmOptionsDialog::on_pseudoCheckBox_toggled(bool checked) +{ + core->setConfig("asm.pseudo", checked); + core->triggerAsmOptionsChanged(); +} + +void AsmOptionsDialog::on_offsetCheckBox_toggled(bool checked) +{ + core->setConfig("asm.offset", checked); + core->triggerAsmOptionsChanged(); +} + +void AsmOptionsDialog::on_describeCheckBox_toggled(bool checked) +{ + core->setConfig("asm.describe", checked); + core->triggerAsmOptionsChanged(); +} + +void AsmOptionsDialog::on_stackpointerCheckBox_toggled(bool checked) +{ + core->setConfig("asm.stackptr", checked); + core->triggerAsmOptionsChanged(); +} + +void AsmOptionsDialog::on_bytesCheckBox_toggled(bool checked) +{ + core->setConfig("asm.bytes", checked); + ui->bytespaceCheckBox->setEnabled(checked); + ui->lbytesCheckBox->setEnabled(checked); + core->triggerAsmOptionsChanged(); +} + +void AsmOptionsDialog::on_bytespaceCheckBox_toggled(bool checked) +{ + core->setConfig("asm.bytespace", checked); + core->triggerAsmOptionsChanged(); +} + +void AsmOptionsDialog::on_lbytesCheckBox_toggled(bool checked) +{ + core->setConfig("asm.lbytes", checked); + core->triggerAsmOptionsChanged(); +} + +void AsmOptionsDialog::on_syntaxComboBox_currentIndexChanged(int index) +{ + core->setConfig("asm.syntax", ui->syntaxComboBox->itemData(index).toString().toUtf8().constData()); + core->triggerAsmOptionsChanged(); +} + +void AsmOptionsDialog::on_uppercaseCheckBox_toggled(bool checked) +{ + core->setConfig("asm.ucase", checked); + core->triggerAsmOptionsChanged(); +} + +void AsmOptionsDialog::on_bblineCheckBox_toggled(bool checked) +{ + core->setConfig("asm.bbline", checked); + core->triggerAsmOptionsChanged(); +} + +void AsmOptionsDialog::on_buttonBox_clicked(QAbstractButton *button) +{ + switch (ui->buttonBox->buttonRole(button)) + { + case QDialogButtonBox::ButtonRole::ApplyRole: + saveAsDefault(); + break; + case QDialogButtonBox::ButtonRole::ResetRole: + resetToDefault(); + break; + default: + break; + } +} diff --git a/src/dialogs/asmoptionsdialog.h b/src/dialogs/asmoptionsdialog.h new file mode 100644 index 00000000..ba957bd2 --- /dev/null +++ b/src/dialogs/asmoptionsdialog.h @@ -0,0 +1,49 @@ + +#ifndef ASMOPTIONSDIALOG_H +#define ASMOPTIONSDIALOG_H + +#include +#include + +#include "cutter.h" + +namespace Ui +{ + class AsmOptionsDialog; +} + +class AsmOptionsDialog : public QDialog +{ + Q_OBJECT + +public: + explicit AsmOptionsDialog(CutterCore *core, QWidget *parent = nullptr); + ~AsmOptionsDialog(); + +private: + CutterCore *core; + + Ui::AsmOptionsDialog *ui; + + void updateFromVars(); + + void saveAsDefault(); + void resetToDefault(); + +private slots: + void on_esilCheckBox_toggled(bool checked); + void on_pseudoCheckBox_toggled(bool checked); + void on_offsetCheckBox_toggled(bool checked); + void on_describeCheckBox_toggled(bool checked); + void on_stackpointerCheckBox_toggled(bool checked); + void on_bytesCheckBox_toggled(bool checked); + void on_bytespaceCheckBox_toggled(bool checked); + void on_lbytesCheckBox_toggled(bool checked); + void on_syntaxComboBox_currentIndexChanged(int index); + void on_uppercaseCheckBox_toggled(bool checked); + void on_bblineCheckBox_toggled(bool checked); + void on_buttonBox_clicked(QAbstractButton *button); +}; + + +#endif //ASMOPTIONSDIALOG_H diff --git a/src/dialogs/asmoptionsdialog.ui b/src/dialogs/asmoptionsdialog.ui new file mode 100644 index 00000000..384bc075 --- /dev/null +++ b/src/dialogs/asmoptionsdialog.ui @@ -0,0 +1,127 @@ + + + AsmOptionsDialog + + + + 0 + 0 + 415 + 368 + + + + Disassembly Options + + + + QLayout::SetMinAndMaxSize + + + + + Show ESIL instead of assembly (asm.esil) + + + + + + + Show pseudocode instead of assembly (asm.pseudo) + + + + + + + Show offsets (asm.offset) + + + + + + + Show opcode description (asm.describe) + + + + + + + Show stack pointer (asm.stackptr) + + + + + + + Show bytes (asm.bytes) + + + + + + + 16 + + + + + Separate bytes with whitespace (asm.bytespace) + + + + + + + Align bytes to the left (asm.lbytes) + + + + + + + + + + + Syntax (asm.syntax): + + + + + + + + + + + + Uppercase syntax (asm.ucase) + + + + + + + Show empty line after every basic block (asm.bbline) + + + + + + + QDialogButtonBox::RestoreDefaults + + + + + + + Save as Default + + + + + + diff --git a/src/helpers.cpp b/src/helpers.cpp index 974ba3a3..293d5e45 100644 --- a/src/helpers.cpp +++ b/src/helpers.cpp @@ -7,6 +7,7 @@ #include #include #include +#include static QAbstractItemView::ScrollMode scrollMode() @@ -84,4 +85,12 @@ namespace qhelpers tw->setVerticalScrollMode(scrollMode()); } + void setCheckedWithoutSignals(QAbstractButton *button, bool checked) + { + bool blocked = button->signalsBlocked(); + button->blockSignals(true); + button->setChecked(checked); + button->blockSignals(blocked); + } + } // end namespace diff --git a/src/helpers.h b/src/helpers.h index 045a1efe..19a16fbd 100644 --- a/src/helpers.h +++ b/src/helpers.h @@ -9,6 +9,7 @@ class QString; class QTreeWidget; class QTreeWidgetItem; class QAbstractItemView; +class QAbstractButton; namespace qhelpers { @@ -23,6 +24,8 @@ namespace qhelpers const QString &str3 = QString(), const QString &str4 = QString(), const QString &str5 = QString()); void setVerticalScrollMode(QAbstractItemView *tw); + + void setCheckedWithoutSignals(QAbstractButton *button, bool checked); } #endif // HELPERS_H diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 9913fe49..356b8a87 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -4,6 +4,7 @@ #include "dialogs/commentsdialog.h" #include "dialogs/aboutdialog.h" #include "dialogs/renamedialog.h" +#include "dialogs/asmoptionsdialog.h" #include "helpers.h" #include @@ -181,27 +182,6 @@ void MainWindow::initUI() addToolBarBreak(Qt::TopToolBarArea); addToolBar(graphicsBar); - // Asm syntaxes - QList list = core->cmd("e asm.syntax =?").split("\n"); - QString checked = core->getConfig("asm.syntax"); - for (QString syntax : list) - { - if (syntax == "") - { - break; - } - QAction *action = new QAction(ui->menuAsm_syntax); - action->setText(syntax); - action->setCheckable(true); - if (syntax == checked) - { - action->setChecked(true); - } - connect(action, SIGNAL(triggered()), this, SLOT(actionAsm_syntax_triggered())); - asmSyntaxes.append(action); - ui->menuAsm_syntax->addAction(action); - } - /* * Dock Widgets */ @@ -388,63 +368,6 @@ void MainWindow::finalizeOpen() notepadDock->highlightPreview(); } -void MainWindow::applySettings() -{ - Settings settings; - - // Show asm bytes - if (settings.getAsmBytes()) - { - core->config("asm.bytes", "true"); - core->config("asm.cmtcol", "100"); - } - else - { - core->config("asm.bytes", "false"); - core->config("asm.cmtcol", "70"); - } - - // Show opcode description - if (settings.getOpcodeDescription()) - { - core->config("asm.describe", "true"); - } - else - { - core->config("asm.describe", "false"); - } - - // Show stack pointer - if (settings.getStackPointer()) - { - core->config("asm.stackptr", "true"); - } - else - { - core->config("asm.stackptr", "false"); - } - - // Show uppercase dasm - if (settings.getUppercaseDisas()) - { - core->config("asm.ucase", "true"); - } - else - { - core->config("asm.ucase", "false"); - } - - // Show spaces in dasm - if (settings.getSpacy()) - { - core->config("asm.bbline", "true"); - } - else - { - core->config("asm.bbline", "false"); - } -} - void MainWindow::saveProject() { QString project_name = qhelpers::uniqueProjectName(filename); @@ -1094,40 +1017,8 @@ void MainWindow::on_actionRefresh_contents_triggered() refreshVisibleDockWidgets(); } -void MainWindow::on_actionDisplay_Esil_triggered() +void MainWindow::on_actionAsmOptions_triggered() { - int esil = this->core->getConfigi("asm.esil"); - core->config("asm.esil", !esil); - refreshVisibleDockWidgets(); -} - -void MainWindow::on_actionDisplay_Pseudocode_triggered() -{ - int pseudo = this->core->getConfigi("asm.pseudo"); - core->config("asm.pseudo", !pseudo); - refreshVisibleDockWidgets(); -} - -void MainWindow::on_actionDisplay_Offsets_triggered() -{ - bool checked = ui->actionDisplay_Offsets->isChecked(); - memoryDock->showOffsets(checked); - refreshVisibleDockWidgets(); -} - -void MainWindow::actionAsm_syntax_triggered() -{ - QObject *sender = QObject::sender(); - // Uncheck every other choices - for (QAction *action : asmSyntaxes) - { - action->setChecked(false); - } - // Check selected choice - QAction *action = (QAction *) sender; - action->setChecked(true); - // Set r2 config - core->config("asm.syntax", action->text()); - // Refresh views - refreshVisibleDockWidgets(); + auto dialog = new AsmOptionsDialog(core, this); + dialog->show(); } diff --git a/src/mainwindow.h b/src/mainwindow.h index f63a8a40..4ed6a19f 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -57,8 +57,6 @@ public: void initUI(); void finalizeOpen(); - void applySettings(); - void saveProject(); void start_web_server(); @@ -173,13 +171,7 @@ private slots: void on_actionRefresh_contents_triggered(); - void on_actionDisplay_Esil_triggered(); - - void on_actionDisplay_Pseudocode_triggered(); - - void on_actionDisplay_Offsets_triggered(); - - void actionAsm_syntax_triggered(); + void on_actionAsmOptions_triggered(); private: QDockWidget *asmDock; diff --git a/src/mainwindow.ui b/src/mainwindow.ui index b70b8455..f4e74319 100644 --- a/src/mainwindow.ui +++ b/src/mainwindow.ui @@ -7,7 +7,7 @@ 0 0 1013 - 686 + 606 @@ -20,7 +20,7 @@ Cutter - + :/img/logo-small.png:/img/logo-small.png @@ -159,7 +159,7 @@ border-top: 0px; 0 0 1013 - 20 + 22 @@ -173,8 +173,8 @@ border-top: 0px; 273 136 - 148 - 167 + 173 + 181 @@ -204,11 +204,6 @@ border-top: 0px; false - - - Asm syntax - - @@ -220,10 +215,7 @@ border-top: 0px; - - - - + @@ -968,6 +960,11 @@ QToolButton .svg-icon path { Display offsets + + + Disassembly Options + + diff --git a/src/optionsdialog.cpp b/src/optionsdialog.cpp index 36fb4b02..4f12d05b 100644 --- a/src/optionsdialog.cpp +++ b/src/optionsdialog.cpp @@ -49,14 +49,6 @@ OptionsDialog::OptionsDialog(MainWindow *main): for (auto plugin : main->core->getRBinPluginDescriptions("bin")) ui->formatComboBox->addItem(plugin.name, QVariant::fromValue(plugin)); - // Restore settings - QSettings settings; - ui->bytesCheckBox->setChecked(settings.value("bytes").toBool()); - ui->descriptionCheckBox->setChecked(settings.value("describe").toBool()); - ui->stackCheckBox->setChecked(settings.value("stackptr").toBool()); - ui->ucaseCheckBox->setChecked(settings.value("ucase").toBool()); - ui->spacyCheckBox->setChecked(settings.value("bbline").toBool()); - ui->hideFrame->setVisible(false); ui->analoptionsFrame->setVisible(false); @@ -143,19 +135,9 @@ void OptionsDialog::setupAndStartAnalysis(int level, QList advanced) ui->statusLabel->setText(tr("Starting analysis")); //ui->progressBar->setValue(5); - - // Save options in settings - Settings settings; - settings.setAsmBytes(ui->bytesCheckBox->isChecked()); - settings.setOpcodeDescription(ui->descriptionCheckBox->isChecked()); - settings.setStackPointer(ui->stackCheckBox->isChecked()); - settings.setUppercaseDisas(ui->ucaseCheckBox->isChecked()); - settings.setSpacy(ui->spacyCheckBox->isChecked()); - main->initUI(); - // Apply options set above in MainWindow - main->applySettings(); + main->core->resetDefaultAsmOptions(); // Threads stuff // connect signal/slot diff --git a/src/optionsdialog.ui b/src/optionsdialog.ui index d94b008b..f6e99753 100644 --- a/src/optionsdialog.ui +++ b/src/optionsdialog.ui @@ -406,151 +406,34 @@ - + 0 + + QLayout::SetMinimumSize + - - - - 0 - 0 - + + + Load bin information - - Qt::LeftToRight + + true + + + + - background-color: rgb(255, 255, 255); -color: rgb(0, 0, 0); + - - QFrame::NoFrame + + Use virtual addressing - - QFrame::Plain + + true - - - 5 - - - 5 - - - 5 - - - 5 - - - - - QLayout::SetMinimumSize - - - - - QLayout::SetMinimumSize - - - QFormLayout::FieldsStayAtSizeHint - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop - - - 0 - - - - - Load bin information - - - true - - - - - - - - - - Use virtual addressing - - - true - - - - - - - Add space after calls - - - - - - - Display asm bytes - - - true - - - - - - - - - QLayout::SetMinimumSize - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop - - - 0 - - - 0 - - - - - Show opcode description - - - - - - - Show stack pointer - - - - - - - Uppercase disassembly - - - - - - - - diff --git a/src/radarewebserver.cpp b/src/radarewebserver.cpp index 2e8bd559..3e4a6e63 100644 --- a/src/radarewebserver.cpp +++ b/src/radarewebserver.cpp @@ -26,13 +26,13 @@ void RadareWebServer::start() // pretty sure now cutter runs as AppImage //QString defaultPath("/usr/share/radare2/1.5.0-git/www"); - QString defaultHttpRoot(core->config("http.root")); + QString defaultHttpRoot(core->getConfig("http.root")); if (defaultHttpRoot.startsWith("/usr")) { QString path(QCoreApplication::applicationDirPath()); path.replace("bin/", defaultHttpRoot.remove("/usr")); - core->config("http.root", path); + core->setConfig("http.root", path); } } diff --git a/src/settings.h b/src/settings.h index 4685bb1c..5620a4e3 100644 --- a/src/settings.h +++ b/src/settings.h @@ -10,20 +10,38 @@ private: QSettings settings; public: - bool getAsmBytes() const { return settings.value("bytes", false).toBool(); } - void setAsmBytes(bool v) { settings.setValue("bytes", v); } + bool getAsmESIL() const { return settings.value("asm.esil", false).toBool(); } + void setAsmESIL(bool v) { settings.setValue("asm.esil", v); } - bool getOpcodeDescription() const { return settings.value("describe", false).toBool(); } - void setOpcodeDescription(bool v) { settings.setValue("describe", v); } + bool getAsmPseudo() const { return settings.value("asm.pseudo", false).toBool(); } + void setAsmPseudo(bool v) { settings.setValue("asm.pseudo", v); } - bool getStackPointer() const { return settings.value("stackptr", false).toBool(); } - void setStackPointer(bool v) { settings.setValue("stackptr", v); } + bool getAsmOffset() const { return settings.value("asm.offset", true).toBool(); } + void setAsmOffset(bool v) { settings.setValue("asm.offset", v); } - bool getUppercaseDisas() const { return settings.value("ucase", false).toBool(); } - void setUppercaseDisas(bool v) { settings.setValue("ucase", v); } + bool getAsmDescribe() const { return settings.value("asm.describe", false).toBool(); } + void setAsmDescribe(bool v) { settings.setValue("asm.describe", v); } - bool getSpacy() const { return settings.value("spacy", false).toBool(); } - void setSpacy(bool v) { settings.setValue("bbline", v); } + bool getAsmStackPointer() const { return settings.value("asm.stackptr", false).toBool(); } + void setAsmStackPointer(bool v) { settings.setValue("asm.stackptr", v); } + + bool getAsmBytes() const { return settings.value("asm.bytes", false).toBool(); } + void setAsmBytes(bool v) { settings.setValue("asm.bytes", v); } + + bool getAsmBytespace() const { return settings.value("asm.bytespace", false).toBool(); } + void setAsmBytespace(bool v) { settings.setValue("asm.bytespace", v); } + + bool getAsmLBytes() const { return settings.value("asm.lbytes", true).toBool(); } + void setAsmLBytes(bool v) { settings.setValue("asm.lbytes", v); } + + QString getAsmSyntax() const { return settings.value("asm.syntax", "intel").toString(); } + void setAsmSyntax(const QString &v) { settings.setValue("asm.syntax", v); } + + bool getAsmUppercase() const { return settings.value("asm.ucase", false).toBool(); } + void setAsmUppercase(bool v) { settings.setValue("asm.ucase", v); } + + bool getAsmBBLine() const { return settings.value("asm.bbline", false).toBool(); } + void setAsmBBLine(bool v) { settings.setValue("asm.bbline", v); } }; #endif // SETTINGS_H diff --git a/src/widgets/MemoryWidget.cpp b/src/widgets/MemoryWidget.cpp index b569ec6c..9c0fda73 100644 --- a/src/widgets/MemoryWidget.cpp +++ b/src/widgets/MemoryWidget.cpp @@ -104,20 +104,8 @@ MemoryWidget::MemoryWidget(MainWindow *main) : QMenu *memMenu = new QMenu(); ui->memSettingsButton_2->addAction(ui->actionSettings_menu_1); memMenu->addAction(ui->actionSettings_menu_1); - QMenu *hideSide = memMenu->addMenu("Show/Hide"); - hideSide->addAction(ui->actionDisas_ShowHideBytes); - hideSide->addAction(ui->actionSeparate_bytes); - hideSide->addAction(ui->actionRight_align_bytes); - hideSide->addSeparator(); - hideSide->addAction(ui->actionDisasSwitch_case); - hideSide->addAction(ui->actionSeparate_disasm_calls); - hideSide->addAction(ui->actionShow_stack_pointer); ui->memSettingsButton_2->setMenu(memMenu); - // Disable bytes options by default as bytes are not shown - ui->actionSeparate_bytes->setDisabled(true); - ui->actionRight_align_bytes->setDisabled(true); - // Event filter to intercept double clicks in the textbox ui->disasTextEdit_2->viewport()->installEventFilter(this); @@ -200,6 +188,7 @@ MemoryWidget::MemoryWidget(MainWindow *main) : connect(main, SIGNAL(cursorAddressChanged(RVA)), this, SLOT(on_cursorAddressChanged(RVA))); connect(main->core, SIGNAL(flagsChanged()), this, SLOT(updateViews())); connect(main->core, SIGNAL(commentsChanged()), this, SLOT(updateViews())); + connect(main->core, SIGNAL(asmOptionsChanged()), this, SLOT(updateViews())); fillPlugins(); } @@ -889,15 +878,15 @@ void MemoryWidget::on_hexHexText_2_selectionChanged() QString arch = ui->hexArchComboBox_2->currentText(); QString bits = ui->hexBitsComboBox_2->currentText(); - QString oarch = this->main->core->config("asm.arch"); - QString obits = this->main->core->config("asm.bits"); + QString oarch = this->main->core->getConfig("asm.arch"); + QString obits = this->main->core->getConfig("asm.bits"); - this->main->core->config("asm.arch", arch); - this->main->core->config("asm.bits", bits); + this->main->core->setConfig("asm.arch", arch); + this->main->core->setConfig("asm.bits", bits); QString str = this->main->core->cmd("pad " + sel_text); this->hexDisasTextEdit->setPlainText(str); - this->main->core->config("asm.arch", oarch); - this->main->core->config("asm.bits", obits); + this->main->core->setConfig("asm.arch", oarch); + this->main->core->setConfig("asm.bits", obits); //qDebug() << "Selected Arch: " << arch; //qDebug() << "Selected Bits: " << bits; //qDebug() << "Selected Text: " << sel_text; @@ -1040,14 +1029,6 @@ void MemoryWidget::showDisasContextMenu(const QPoint &pt) menu->addSeparator(); menu->addAction(ui->actionXRefs); menu->addSeparator(); - menu->addAction(ui->actionDisas_ShowHideBytes); - menu->addAction(ui->actionSeparate_bytes); - menu->addAction(ui->actionRight_align_bytes); - menu->addSeparator(); - menu->addAction(ui->actionDisasSwitch_case); - menu->addAction(ui->actionSeparate_disasm_calls); - menu->addAction(ui->actionShow_stack_pointer); - menu->addSeparator(); menu->addAction(ui->actionDisasCopy_All); menu->addAction(ui->actionDisasCopy_Bytes); menu->addAction(ui->actionDisasCopy_Disasm); @@ -1216,57 +1197,6 @@ void MemoryWidget::on_hexButton_2_clicked() ui->memSideTabWidget_2->setCurrentIndex(1); } -void MemoryWidget::on_actionDisas_ShowHideBytes_triggered() -{ - this->main->core->cmd("e!asm.bytes"); - - if (this->main->core->cmd("e asm.bytes").trimmed() == "true") - { - ui->actionSeparate_bytes->setDisabled(false); - ui->actionRight_align_bytes->setDisabled(false); - this->main->core->config("asm.cmtcol", "100"); - } - else - { - ui->actionSeparate_bytes->setDisabled(true); - ui->actionRight_align_bytes->setDisabled(true); - this->main->core->config("asm.cmtcol", "70"); - } - - this->refreshDisasm(); -} - -void MemoryWidget::on_actionDisasSwitch_case_triggered() -{ - this->main->core->cmd("e!asm.ucase"); - this->refreshDisasm(); -} - -void MemoryWidget::on_actionSeparate_bytes_triggered() -{ - this->main->core->cmd("e!asm.bytespace"); - this->refreshDisasm(); -} - -void MemoryWidget::on_actionRight_align_bytes_triggered() -{ - this->main->core->cmd("e!asm.lbytes"); - this->refreshDisasm(); -} - -void MemoryWidget::on_actionSeparate_disasm_calls_triggered() -{ - this->main->core->cmd("e!asm.bbline"); - this->refreshDisasm(); -} - - -void MemoryWidget::on_actionShow_stack_pointer_triggered() -{ - this->main->core->cmd("e!asm.stackptr"); - this->refreshDisasm(); -} - void MemoryWidget::on_graphButton_2_clicked() { ui->memTabWidget->setCurrentIndex(2); @@ -1357,43 +1287,43 @@ void MemoryWidget::on_actionFunctionsRename_triggered() void MemoryWidget::on_action8columns_triggered() { - this->main->core->config("hex.cols", "8"); + this->main->core->setConfig("hex.cols", 8); this->refreshHexdump(); } void MemoryWidget::on_action16columns_triggered() { - this->main->core->config("hex.cols", "16"); + this->main->core->setConfig("hex.cols", 16); this->refreshHexdump(); } void MemoryWidget::on_action4columns_triggered() { - this->main->core->config("hex.cols", "4"); + this->main->core->setConfig("hex.cols", 4); this->refreshHexdump(); } void MemoryWidget::on_action32columns_triggered() { - this->main->core->config("hex.cols", "32"); + this->main->core->setConfig("hex.cols", 32); this->refreshHexdump(); } void MemoryWidget::on_action64columns_triggered() { - this->main->core->config("hex.cols", "64"); + this->main->core->setConfig("hex.cols", 64); this->refreshHexdump(); } void MemoryWidget::on_action2columns_triggered() { - this->main->core->config("hex.cols", "2"); + this->main->core->setConfig("hex.cols", 2); this->refreshHexdump(); } void MemoryWidget::on_action1column_triggered() { - this->main->core->config("hex.cols", "1"); + this->main->core->setConfig("hex.cols", 1); this->refreshHexdump(); } @@ -1589,7 +1519,7 @@ void MemoryWidget::create_graph(QString off) //QString fcn = this->main->core->cmdFunctionAt(off); //this->main->add_debug_output("Graph Fcn: " + fcn); ui->graphWebView->setUrl(QUrl("qrc:/graph/html/graph/index.html#" + off)); - QString port = this->main->core->config("http.port"); + QString port = this->main->core->getConfig("http.port"); ui->graphWebView->page()->runJavaScript(QString("r2.root=\"http://localhost:%1\"").arg(port)); QSettings settings; if (settings.value("dark").toBool()) @@ -1917,20 +1847,6 @@ void MemoryWidget::switchTheme(bool dark) } } -void MemoryWidget::on_opcodeDescButton_clicked() -{ - if (ui->opcodeDescButton->isChecked()) - { - ui->opcodeDescText->hide(); - ui->opcodeDescButton->setArrowType(Qt::RightArrow); - } - else - { - ui->opcodeDescText->show(); - ui->opcodeDescButton->setArrowType(Qt::DownArrow); - } -} - void MemoryWidget::selectHexPreview() { // Pre-select arch and bits in the hexdump sidebar @@ -2022,11 +1938,11 @@ void MemoryWidget::showOffsets(bool show) if (show) { this->hexOffsetText->show(); - main->core->config("asm.offset", 1); + main->core->setConfig("asm.offset", 1); } else { this->hexOffsetText->hide(); - main->core->config("asm.offset", 0); + main->core->setConfig("asm.offset", 0); } } diff --git a/src/widgets/MemoryWidget.h b/src/widgets/MemoryWidget.h index a3070e8f..50b966f3 100644 --- a/src/widgets/MemoryWidget.h +++ b/src/widgets/MemoryWidget.h @@ -149,7 +149,6 @@ private slots: void on_actionDisasAdd_comment_triggered(); void on_actionAddFlag_triggered(); void on_actionFunctionsRename_triggered(); - void on_actionDisas_ShowHideBytes_triggered(); void on_hexHexText_2_selectionChanged(); void on_hexArchComboBox_2_currentTextChanged(const QString &arg1); @@ -188,15 +187,9 @@ private slots: void on_decoToolButton_clicked(); void on_previewToolButton_2_clicked(); void on_actionXRefs_triggered(); - void on_actionDisasSwitch_case_triggered(); - void on_actionSeparate_bytes_triggered(); - void on_actionRight_align_bytes_triggered(); - void on_actionSeparate_disasm_calls_triggered(); - void on_actionShow_stack_pointer_triggered(); void on_copyMD5_clicked(); void on_copySHA1_clicked(); void on_simpleGrapgToolButton_clicked(); - void on_opcodeDescButton_clicked(); void seek_back(); void on_memTabWidget_currentChanged(int index); }; diff --git a/src/widgets/MemoryWidget.ui b/src/widgets/MemoryWidget.ui index 92eb54fb..574b455a 100644 --- a/src/widgets/MemoryWidget.ui +++ b/src/widgets/MemoryWidget.ui @@ -513,7 +513,7 @@ border-top: 0px; QTabWidget::South - 2 + 3 false @@ -994,7 +994,7 @@ QToolTip { 0 - + 0 @@ -1015,7 +1015,7 @@ QToolTip { font: 11pt "Monaco"; } - + about:blank @@ -1290,16 +1290,16 @@ p, li { white-space: pre-wrap; } 0 - + Qt::DefaultContextMenu - + about:blank - + 1.000000000000000 @@ -1394,7 +1394,7 @@ border-top: 0px; 0 0 256 - 868 + 878 @@ -1698,7 +1698,7 @@ QToolTip { 0 - + 0 @@ -1717,7 +1717,7 @@ QToolTip { 250 - + qrc:/html/fcn_graph.html @@ -1747,7 +1747,7 @@ QToolTip { 0 - + 0 @@ -1766,7 +1766,7 @@ QToolTip { 250 - + qrc:/html/fcn_radar.html @@ -2899,22 +2899,6 @@ QToolTip { Undefine - - - Show/Hide bytes - - - Show/Hide bytes - - - - - Switch case - - - Switch case - - Copy all @@ -3059,38 +3043,6 @@ QToolTip { XRefs - - - Separate bytes - - - Separate bytes with space - - - - - Right align bytes - - - Right align bytes - - - - - Separate disasm calls - - - Separate disasm calls - - - - - Show stack pointer - - - Show stack pointer - - Add flag diff --git a/src/widgets/consolewidget.cpp b/src/widgets/consolewidget.cpp index 61cfad4a..f838604c 100644 --- a/src/widgets/consolewidget.cpp +++ b/src/widgets/consolewidget.cpp @@ -68,6 +68,8 @@ static const int invalidHistoryPos = -1; static bool isForbidden(const QString &input) { + return false; + static const QRegExp delimiters("[;&]");