From bf07f2a002800190c2892a20e9a860025256208c Mon Sep 17 00:00:00 2001 From: Itay Cohen Date: Sun, 12 Aug 2018 19:20:16 +0300 Subject: [PATCH] UI Improvemetnts + graph.offset implementation (#612) * Add getBreakpointsAddresses to list breakpoints offsets * Add breakpoint highligthing and improve of disassembly UIs * Improve dialogs and positions * Add graph,offset option to preference * Tiny text fix * Updated radare2 sumodule --- radare2 | 2 +- src/Cutter.cpp | 19 ++++++ src/Cutter.h | 2 + src/MainWindow.ui | 4 +- src/dialogs/R2PluginsDialog.ui | 2 +- src/dialogs/preferences/AsmOptionsWidget.ui | 4 +- .../preferences/GraphOptionsWidget.cpp | 6 ++ src/dialogs/preferences/GraphOptionsWidget.h | 1 + src/dialogs/preferences/GraphOptionsWidget.ui | 67 +++++++++++++------ src/utils/Configuration.cpp | 17 +++-- src/widgets/DisassemblerGraphView.cpp | 19 ++++-- src/widgets/DisassemblerGraphView.h | 1 + src/widgets/DisassemblyWidget.cpp | 8 +++ src/widgets/DisassemblyWidget.h | 2 + src/widgets/QuickFilterView.cpp | 1 + 15 files changed, 117 insertions(+), 38 deletions(-) diff --git a/radare2 b/radare2 index c9ec8b54..404e4a1b 160000 --- a/radare2 +++ b/radare2 @@ -1 +1 @@ -Subproject commit c9ec8b54b9ba32ba6712f319825f8d032e573e68 +Subproject commit 404e4a1b74df7941c3ff7511f5396e1e1736ce37 diff --git a/src/Cutter.cpp b/src/Cutter.cpp index b6fa3d1b..e233ddb9 100644 --- a/src/Cutter.cpp +++ b/src/Cutter.cpp @@ -1078,6 +1078,25 @@ QList CutterCore::getBreakpoints() return ret; } + +QList CutterCore::getBreakpointsAddresses() +{ + QList bps = getBreakpoints(); + BreakpointDescription bp; + QList bpAddresses; + foreach (bp, bps) + { + bpAddresses << bp.addr; + } + + return bpAddresses; +} + +bool CutterCore::isBreakpoint(QList breakpoints, RVA addr) +{ + return breakpoints.contains(addr); +} + QJsonDocument CutterCore::getBacktrace() { return cmdj("dbtj"); diff --git a/src/Cutter.h b/src/Cutter.h index e57c8d08..17e33668 100644 --- a/src/Cutter.h +++ b/src/Cutter.h @@ -518,6 +518,8 @@ public: void delAllBreakpoints(); void enableBreakpoint(RVA addr); void disableBreakpoint(RVA addr); + bool isBreakpoint(QList breakpoints, RVA addr); + QList getBreakpointsAddresses(); QString getActiveDebugPlugin(); QStringList getDebugPlugins(); void setDebugPlugin(QString plugin); diff --git a/src/MainWindow.ui b/src/MainWindow.ui index 7983e740..1b1a88f3 100644 --- a/src/MainWindow.ui +++ b/src/MainWindow.ui @@ -206,8 +206,6 @@ border-top: 0px; - - @@ -222,6 +220,8 @@ border-top: 0px; + + diff --git a/src/dialogs/R2PluginsDialog.ui b/src/dialogs/R2PluginsDialog.ui index fdb26ade..6caca9d4 100644 --- a/src/dialogs/R2PluginsDialog.ui +++ b/src/dialogs/R2PluginsDialog.ui @@ -6,7 +6,7 @@ 0 0 - 296 + 506 310 diff --git a/src/dialogs/preferences/AsmOptionsWidget.ui b/src/dialogs/preferences/AsmOptionsWidget.ui index 0bcdfc7a..7f1f645b 100644 --- a/src/dialogs/preferences/AsmOptionsWidget.ui +++ b/src/dialogs/preferences/AsmOptionsWidget.ui @@ -7,7 +7,7 @@ 0 0 545 - 450 + 526 @@ -17,7 +17,7 @@ - 1 + 0 diff --git a/src/dialogs/preferences/GraphOptionsWidget.cpp b/src/dialogs/preferences/GraphOptionsWidget.cpp index 30844b24..e8180a7b 100644 --- a/src/dialogs/preferences/GraphOptionsWidget.cpp +++ b/src/dialogs/preferences/GraphOptionsWidget.cpp @@ -25,6 +25,7 @@ GraphOptionsWidget::~GraphOptionsWidget() {} void GraphOptionsWidget::updateOptionsFromVars() { + qhelpers::setCheckedWithoutSignals(ui->graphOffsetCheckBox, Config()->getConfigBool("graph.offset")); ui->maxColsSpinBox->blockSignals(true); ui->maxColsSpinBox->setValue(Config()->getGraphBlockMaxChars()); ui->maxColsSpinBox->blockSignals(false); @@ -44,3 +45,8 @@ void GraphOptionsWidget::on_maxColsSpinBox_valueChanged(int value) triggerOptionsChanged(); } +void GraphOptionsWidget::on_graphOffsetCheckBox_toggled(bool checked) +{ + Config()->setConfig("graph.offset", checked); + triggerOptionsChanged(); +} diff --git a/src/dialogs/preferences/GraphOptionsWidget.h b/src/dialogs/preferences/GraphOptionsWidget.h index 398779cc..85df7274 100644 --- a/src/dialogs/preferences/GraphOptionsWidget.h +++ b/src/dialogs/preferences/GraphOptionsWidget.h @@ -31,6 +31,7 @@ private slots: void updateOptionsFromVars(); void on_maxColsSpinBox_valueChanged(int value); + void on_graphOffsetCheckBox_toggled(bool checked); }; diff --git a/src/dialogs/preferences/GraphOptionsWidget.ui b/src/dialogs/preferences/GraphOptionsWidget.ui index 05e3ad59..f4b743fc 100644 --- a/src/dialogs/preferences/GraphOptionsWidget.ui +++ b/src/dialogs/preferences/GraphOptionsWidget.ui @@ -13,28 +13,51 @@ Graph - - - - - Maximum Line Length: - - - - - - - 10 - - - 999999999 - - - 5 - - - - + + + + 30 + 10 + 141 + 18 + + + + Maximum Line Length: + + + + + + 190 + 10 + 104 + 23 + + + + 10 + + + 999999999 + + + 5 + + + + + + 30 + 44 + 162 + 22 + + + + Show offsets (graph.offset) + + diff --git a/src/utils/Configuration.cpp b/src/utils/Configuration.cpp index 07669f6e..ae215d95 100644 --- a/src/utils/Configuration.cpp +++ b/src/utils/Configuration.cpp @@ -22,7 +22,7 @@ static const QHash asmOptions = { { "asm.flags.offset", false }, { "asm.emu", false }, { "asm.cmt.right", true }, - { "asm.cmt.col", 70 }, + { "asm.cmt.col", 35 }, { "asm.var.summary", false }, { "asm.bytes", false }, { "asm.size", false }, @@ -37,7 +37,9 @@ static const QHash asmOptions = { { "asm.var.subonly", true }, { "asm.tabs", 5 }, { "asm.tabs.off", 5 }, - { "esil.breakoninvalid", true } + { "asm.marks", false }, + { "esil.breakoninvalid", true }, + { "graph.offset", false} }; @@ -118,7 +120,7 @@ void Configuration::loadDefaultTheme() setColor("gui.cflow", QColor(0, 0, 0)); setColor("gui.dataoffset", QColor(0, 0, 0)); setColor("gui.border", QColor(0, 0, 0)); - setColor("highlight", QColor(210, 210, 255)); + setColor("highlight", QColor(210, 210, 255, 150)); setColor("highlightWord", QColor(210, 210, 255)); // RIP line selection in debug setColor("highlightPC", QColor(214, 255, 210)); @@ -135,6 +137,7 @@ void Configuration::loadDefaultTheme() setColor("gui.navbar.str", QColor(69, 104, 229)); setColor("gui.navbar.sym", QColor(229, 150, 69)); setColor("gui.navbar.empty", QColor(100, 100, 100)); + setColor("gui.breakpoint_background", QColor(233, 143, 143)); } void Configuration::loadBaseDark() @@ -176,6 +179,7 @@ void Configuration::loadBaseDark() setColor("gui.navbar.empty", QColor(100, 100, 100)); // RIP line selection in debug setColor("highlightPC", QColor(87, 26, 7)); + setColor("gui.breakpoint_background", QColor(140, 76, 76)); } void Configuration::loadDarkTheme() @@ -187,15 +191,16 @@ void Configuration::loadDarkTheme() // Disassembly nodes background setColor("gui.alt_background", QColor(28, 31, 36)); // Disassembly nodes background when selected - setColor("gui.disass_selected", QColor(44, 53, 54)); + setColor("gui.disass_selected", QColor(31, 34, 40)); // Disassembly line selected - setColor("highlight", QColor(21, 29, 29)); + setColor("highlight", QColor(21, 29, 29, 150)); setColor("highlightWord", QColor(100, 100, 100)); + } const QFont Configuration::getFont() const { - QFont font = s.value("font", QFont("Inconsolata", 12)).value(); + QFont font = s.value("font", QFont("Inconsolata", 11)).value(); return font; } diff --git a/src/widgets/DisassemblerGraphView.cpp b/src/widgets/DisassemblerGraphView.cpp index 00d1fa60..c2a5f4d3 100644 --- a/src/widgets/DisassemblerGraphView.cpp +++ b/src/widgets/DisassemblerGraphView.cpp @@ -332,6 +332,7 @@ void DisassemblerGraphView::drawBlock(QPainter &p, GraphView::GraphBlock &block) p.setBrush(Qt::gray); p.drawRect(block.x, block.y, block.width, block.height); + breakpoints = Core()->getBreakpointsAddresses(); // Render node DisassemblyBlock &db = disassembly_blocks[block.entry]; @@ -350,6 +351,7 @@ void DisassemblerGraphView::drawBlock(QPainter &p, GraphView::GraphBlock &block) if ((instr.addr <= PCAddr) && (PCAddr <= instr.addr + instr.size)) { PCInBlock = true; } + // TODO: L219 } @@ -359,12 +361,13 @@ void DisassemblerGraphView::drawBlock(QPainter &p, GraphView::GraphBlock &block) } else if (db.indirectcall) { p.setBrush(indirectcallShadowColor); } else { - p.setBrush(QColor(0, 0, 0, 128)); + p.setBrush(QColor(0, 0, 0, 100)); } - p.drawRect(block.x + 4, block.y + 4, - block.width + 4, block.height + 4); - p.setPen(graphNodeColor); + // Node's shadow effect + p.drawRect(block.x + 2, block.y + 2, + block.width, block.height); + p.setPen(QPen(graphNodeColor, 1)); if (block_selected) { p.setBrush(disassemblySelectedBackgroundColor); @@ -436,6 +439,14 @@ void DisassemblerGraphView::drawBlock(QPainter &p, GraphView::GraphBlock &block) y += charHeight; } for (Instr &instr : db.instrs) { + if (Core()->isBreakpoint(breakpoints, instr.addr)) { + p.fillRect(QRect(block.x + charWidth, y, block.width - (10 + 2 * charWidth), + int(instr.text.lines.size()) * charHeight), ConfigColor("gui.breakpoint_background")); + if (instr.addr == selected_instruction) { + p.fillRect(QRect(block.x + charWidth, y, block.width - (10 + 2 * charWidth), + int(instr.text.lines.size()) * charHeight), disassemblySelectionColor); + } + } for (auto &line : instr.text.lines) { int rectSize = qRound(charWidth); if (rectSize % 2) { diff --git a/src/widgets/DisassemblerGraphView.h b/src/widgets/DisassemblerGraphView.h index 3f69d876..d21604a9 100644 --- a/src/widgets/DisassemblerGraphView.h +++ b/src/widgets/DisassemblerGraphView.h @@ -197,6 +197,7 @@ private: void seekInstruction(bool previous_instr); CutterSeekableWidget *seekable = nullptr; QList shortcuts; + QList breakpoints; QColor disassemblyBackgroundColor; QColor disassemblySelectedBackgroundColor; diff --git a/src/widgets/DisassemblyWidget.cpp b/src/widgets/DisassemblyWidget.cpp index 8fb2483a..58f95d3b 100644 --- a/src/widgets/DisassemblyWidget.cpp +++ b/src/widgets/DisassemblyWidget.cpp @@ -209,6 +209,7 @@ void DisassemblyWidget::refreshDisasm(RVA offset) return; } + breakpoints = Core()->getBreakpointsAddresses(); int horizontalScrollValue = mDisasTextEdit->horizontalScrollBar()->value(); mDisasTextEdit->setLockScroll(true); // avoid flicker @@ -224,14 +225,21 @@ void DisassemblyWidget::refreshDisasm(RVA offset) mDisasTextEdit->document()->clear(); QTextCursor cursor(mDisasTextEdit->document()); + QTextBlockFormat regular = cursor.blockFormat(); for (DisassemblyLine line : disassemblyLines) { if (line.offset < topOffset) { // overflow break; } cursor.insertHtml(line.text); + if(Core()->isBreakpoint(breakpoints,line.offset)) { + QTextBlockFormat f; + f.setBackground(ConfigColor("gui.breakpoint_background")); + cursor.setBlockFormat(f); + } auto a = new DisassemblyTextBlockUserData(line); cursor.block().setUserData(a); cursor.insertBlock(); + cursor.setBlockFormat(regular); } if (!disassemblyLines.isEmpty()) { diff --git a/src/widgets/DisassemblyWidget.h b/src/widgets/DisassemblyWidget.h index d574dc67..ba55335b 100644 --- a/src/widgets/DisassemblyWidget.h +++ b/src/widgets/DisassemblyWidget.h @@ -61,6 +61,8 @@ private: RVA readDisassemblyOffset(QTextCursor tc); bool eventFilter(QObject *obj, QEvent *event); + QList breakpoints; + void setupFonts(); void setupColors(); diff --git a/src/widgets/QuickFilterView.cpp b/src/widgets/QuickFilterView.cpp index 6726c32b..c410f30b 100644 --- a/src/widgets/QuickFilterView.cpp +++ b/src/widgets/QuickFilterView.cpp @@ -35,6 +35,7 @@ void QuickFilterView::clearFilter() void QuickFilterView::closeFilter() { + ui->filterLineEdit->setText(""); hide(); emit filterClosed(); }