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
This commit is contained in:
Itay Cohen 2018-08-12 19:20:16 +03:00 committed by xarkes
parent 4e3d857239
commit bf07f2a002
15 changed files with 117 additions and 38 deletions

@ -1 +1 @@
Subproject commit c9ec8b54b9ba32ba6712f319825f8d032e573e68
Subproject commit 404e4a1b74df7941c3ff7511f5396e1e1736ce37

View File

@ -1078,6 +1078,25 @@ QList<BreakpointDescription> CutterCore::getBreakpoints()
return ret;
}
QList<RVA> CutterCore::getBreakpointsAddresses()
{
QList<BreakpointDescription> bps = getBreakpoints();
BreakpointDescription bp;
QList<RVA> bpAddresses;
foreach (bp, bps)
{
bpAddresses << bp.addr;
}
return bpAddresses;
}
bool CutterCore::isBreakpoint(QList<RVA> breakpoints, RVA addr)
{
return breakpoints.contains(addr);
}
QJsonDocument CutterCore::getBacktrace()
{
return cmdj("dbtj");

View File

@ -518,6 +518,8 @@ public:
void delAllBreakpoints();
void enableBreakpoint(RVA addr);
void disableBreakpoint(RVA addr);
bool isBreakpoint(QList<RVA> breakpoints, RVA addr);
QList<RVA> getBreakpointsAddresses();
QString getActiveDebugPlugin();
QStringList getDebugPlugins();
void setDebugPlugin(QString plugin);

View File

@ -206,8 +206,6 @@ border-top: 0px;
<addaction name="separator"/>
<addaction name="actionLock"/>
<addaction name="actionTabs_on_Top"/>
<addaction name="separator"/>
<addaction name="actionPreferences"/>
</widget>
<widget class="QMenu" name="menuHelp">
<property name="title">
@ -222,6 +220,8 @@ border-top: 0px;
<addaction name="actionSearch"/>
<addaction name="actionUndoSeek"/>
<addaction name="actionRedoSeek"/>
<addaction name="separator"/>
<addaction name="actionPreferences"/>
</widget>
<widget class="QMenu" name="addDebugWidgets">
<property name="title">

View File

@ -6,7 +6,7 @@
<rect>
<x>0</x>
<y>0</y>
<width>296</width>
<width>506</width>
<height>310</height>
</rect>
</property>

View File

@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>545</width>
<height>450</height>
<height>526</height>
</rect>
</property>
<property name="windowTitle">
@ -17,7 +17,7 @@
<item>
<widget class="QTabWidget" name="asmOptionsTab">
<property name="currentIndex">
<number>1</number>
<number>0</number>
</property>
<widget class="QWidget" name="asmStyleTab">
<attribute name="title">

View File

@ -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();
}

View File

@ -31,6 +31,7 @@ private slots:
void updateOptionsFromVars();
void on_maxColsSpinBox_valueChanged(int value);
void on_graphOffsetCheckBox_toggled(bool checked);
};

View File

@ -13,16 +13,28 @@
<property name="windowTitle">
<string>Graph</string>
</property>
<layout class="QFormLayout" name="formLayout">
<item row="0" column="0">
<widget class="QLabel" name="maxColsLabel">
<property name="geometry">
<rect>
<x>30</x>
<y>10</y>
<width>141</width>
<height>18</height>
</rect>
</property>
<property name="text">
<string>Maximum Line Length:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QSpinBox" name="maxColsSpinBox">
<property name="geometry">
<rect>
<x>190</x>
<y>10</y>
<width>104</width>
<height>23</height>
</rect>
</property>
<property name="minimum">
<number>10</number>
</property>
@ -33,8 +45,19 @@
<number>5</number>
</property>
</widget>
</item>
</layout>
<widget class="QCheckBox" name="graphOffsetCheckBox">
<property name="geometry">
<rect>
<x>30</x>
<y>44</y>
<width>162</width>
<height>22</height>
</rect>
</property>
<property name="text">
<string>Show offsets (graph.offset) </string>
</property>
</widget>
</widget>
<resources/>
<connections/>

View File

@ -22,7 +22,7 @@ static const QHash<QString, QVariant> 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<QString, QVariant> 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>();
QFont font = s.value("font", QFont("Inconsolata", 11)).value<QFont>();
return font;
}

View File

@ -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) {

View File

@ -197,6 +197,7 @@ private:
void seekInstruction(bool previous_instr);
CutterSeekableWidget *seekable = nullptr;
QList<QShortcut *> shortcuts;
QList<RVA> breakpoints;
QColor disassemblyBackgroundColor;
QColor disassemblySelectedBackgroundColor;

View File

@ -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()) {

View File

@ -61,6 +61,8 @@ private:
RVA readDisassemblyOffset(QTextCursor tc);
bool eventFilter(QObject *obj, QEvent *event);
QList<RVA> breakpoints;
void setupFonts();
void setupColors();

View File

@ -35,6 +35,7 @@ void QuickFilterView::clearFilter()
void QuickFilterView::closeFilter()
{
ui->filterLineEdit->setText("");
hide();
emit filterClosed();
}