mirror of
https://github.com/rizinorg/cutter.git
synced 2024-12-18 19:06:10 +00:00
Added a BasicBlock highlighting API
This commit is contained in:
parent
7caabf5350
commit
a93c5e225f
@ -167,6 +167,10 @@ CutterCore::CutterCore(QObject *parent) :
|
||||
// Otherwise r2 may ask the user for input and Cutter would freeze
|
||||
setConfig("scr.interactive", false);
|
||||
|
||||
// Initialize graph node highlighter
|
||||
bbHighlighter = new BasicBlockHighlighter();
|
||||
|
||||
// Initialize Async tasks manager
|
||||
asyncTaskManager = new AsyncTaskManager(this);
|
||||
}
|
||||
|
||||
@ -231,6 +235,7 @@ bool CutterCore::sdbSet(QString path, QString key, QString val)
|
||||
|
||||
CutterCore::~CutterCore()
|
||||
{
|
||||
delete bbHighlighter;
|
||||
r_core_free(this->core_);
|
||||
r_cons_free();
|
||||
}
|
||||
@ -2628,3 +2633,8 @@ QString CutterCore::ansiEscapeToHtml(const QString &text)
|
||||
free(html);
|
||||
return r;
|
||||
}
|
||||
|
||||
BasicBlockHighlighter* CutterCore::getBBHighlighter()
|
||||
{
|
||||
return bbHighlighter;
|
||||
}
|
||||
|
@ -46,6 +46,7 @@ typedef ut64 RVA;
|
||||
class AsyncTaskManager;
|
||||
class CutterCore;
|
||||
#include "plugins/CutterPlugin.h"
|
||||
#include "common/BasicBlockHighlighter.h"
|
||||
|
||||
class RCoreLocked
|
||||
{
|
||||
@ -728,6 +729,7 @@ public:
|
||||
RCoreLocked core() const;
|
||||
|
||||
static QString ansiEscapeToHtml(const QString &text);
|
||||
BasicBlockHighlighter *getBBHighlighter();
|
||||
|
||||
signals:
|
||||
void refreshAll();
|
||||
@ -783,6 +785,7 @@ private:
|
||||
QErrorMessage msgBox;
|
||||
|
||||
bool emptyGraph = false;
|
||||
BasicBlockHighlighter *bbHighlighter;
|
||||
|
||||
};
|
||||
|
||||
|
@ -298,7 +298,8 @@ SOURCES += \
|
||||
dialogs/LoadNewTypesDialog.cpp \
|
||||
widgets/SdbWidget.cpp \
|
||||
common/PythonManager.cpp \
|
||||
plugins/PluginManager.cpp
|
||||
plugins/PluginManager.cpp \
|
||||
common/BasicBlockHighlighter.cpp
|
||||
|
||||
HEADERS += \
|
||||
Cutter.h \
|
||||
@ -411,7 +412,8 @@ HEADERS += \
|
||||
dialogs/LoadNewTypesDialog.h \
|
||||
widgets/SdbWidget.h \
|
||||
common/PythonManager.h \
|
||||
plugins/PluginManager.h
|
||||
plugins/PluginManager.h \
|
||||
common/BasicBlockHighlighter.h
|
||||
|
||||
FORMS += \
|
||||
dialogs/AboutDialog.ui \
|
||||
|
@ -7,6 +7,7 @@
|
||||
<object-type name="CutterCore" />
|
||||
<object-type name="Configuration" />
|
||||
<object-type name="MainWindow" />
|
||||
<object-type name="BasicBlockHighlighter" />
|
||||
<object-type name="CutterDockWidget" />
|
||||
<object-type name="CutterPlugin">
|
||||
<modify-function signature="getName()const">
|
||||
@ -102,4 +103,4 @@
|
||||
</inject-code>
|
||||
</modify-function>
|
||||
</object-type>
|
||||
</typesystem>
|
||||
</typesystem>
|
||||
|
48
src/common/BasicBlockHighlighter.cpp
Normal file
48
src/common/BasicBlockHighlighter.cpp
Normal file
@ -0,0 +1,48 @@
|
||||
#include "BasicBlockHighlighter.h"
|
||||
|
||||
BasicBlockHighlighter::BasicBlockHighlighter()
|
||||
{
|
||||
}
|
||||
|
||||
BasicBlockHighlighter::~BasicBlockHighlighter()
|
||||
{
|
||||
for (BasicBlockIt itr = bbMap.begin(); itr != bbMap.end(); itr++) {
|
||||
delete itr->second;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Highlight the basic block at address
|
||||
*/
|
||||
void BasicBlockHighlighter::highlight(RVA address, const QColor &color)
|
||||
{
|
||||
BasicBlock *block = new BasicBlock;
|
||||
block->address = address;
|
||||
block->color = color;
|
||||
bbMap[address] = block;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Clear the basic block highlighting
|
||||
*/
|
||||
void BasicBlockHighlighter::clear(RVA address)
|
||||
{
|
||||
bbMap.erase(address);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Return a highlighted basic block
|
||||
*
|
||||
* If there is nothing to highlight at specified address, returns nullptr
|
||||
*/
|
||||
BasicBlock *BasicBlockHighlighter::getBasicBlock(RVA address)
|
||||
{
|
||||
BasicBlockIt it;
|
||||
|
||||
it = bbMap.find(address);
|
||||
if (it != bbMap.end()) {
|
||||
return it->second;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
30
src/common/BasicBlockHighlighter.h
Normal file
30
src/common/BasicBlockHighlighter.h
Normal file
@ -0,0 +1,30 @@
|
||||
#ifndef BASICKBLOCKHIGHLIGHTER_H
|
||||
#define BASICKBLOCKHIGHLIGHTER_H
|
||||
|
||||
class BasicBlockHighlighter;
|
||||
|
||||
#include "Cutter.h"
|
||||
#include <map>
|
||||
|
||||
struct BasicBlock {
|
||||
RVA address;
|
||||
QColor color;
|
||||
};
|
||||
|
||||
typedef std::map<RVA, BasicBlock*>::iterator BasicBlockIt;
|
||||
|
||||
class BasicBlockHighlighter
|
||||
{
|
||||
public:
|
||||
BasicBlockHighlighter();
|
||||
~BasicBlockHighlighter();
|
||||
|
||||
void highlight(RVA address, const QColor &color);
|
||||
void clear(RVA address);
|
||||
BasicBlock *getBasicBlock(RVA address);
|
||||
|
||||
private:
|
||||
std::map<RVA, BasicBlock*> bbMap;
|
||||
};
|
||||
|
||||
#endif // BASICBLOCKHIGHLIGHTER_H
|
@ -23,6 +23,7 @@
|
||||
#include "common/CachedFontMetrics.h"
|
||||
#include "common/TempConfig.h"
|
||||
#include "common/SyntaxHighlighter.h"
|
||||
#include "common/BasicBlockHighlighter.h"
|
||||
|
||||
DisassemblerGraphView::DisassemblerGraphView(QWidget *parent)
|
||||
: GraphView(parent),
|
||||
@ -429,8 +430,18 @@ void DisassemblerGraphView::drawBlock(QPainter &p, GraphView::GraphBlock &block)
|
||||
p.setBrush(disassemblyBackgroundColor);
|
||||
}
|
||||
|
||||
// Draw basic block background
|
||||
p.drawRect(blockX, blockY,
|
||||
block.width, block.height);
|
||||
auto bb = Core()->getBBHighlighter()->getBasicBlock(block.entry);
|
||||
if (bb) {
|
||||
QColor color(bb->color);
|
||||
color.setAlphaF(0.5);
|
||||
p.setBrush(color);
|
||||
// Add basic block highlighting transparent color
|
||||
p.drawRect(blockX, blockY,
|
||||
block.width, block.height);
|
||||
}
|
||||
|
||||
// Draw different background for selected instruction
|
||||
if (selected_instruction != RVA_INVALID) {
|
||||
@ -440,39 +451,16 @@ void DisassemblerGraphView::drawBlock(QPainter &p, GraphView::GraphBlock &block)
|
||||
break;
|
||||
}
|
||||
auto selected = instr.addr == selected_instruction;
|
||||
//auto traceCount = dbgfunctions->GetTraceRecordHitCount(instr.addr);
|
||||
auto traceCount = 0;
|
||||
if (selected && traceCount) {
|
||||
p.fillRect(QRect(static_cast<int>(blockX + charWidth), y,
|
||||
static_cast<int>(block.width - (10 + 2 * charWidth)),
|
||||
int(instr.text.lines.size()) * charHeight), disassemblyTracedSelectionColor);
|
||||
} else if (selected) {
|
||||
if (selected) {
|
||||
p.fillRect(QRect(static_cast<int>(blockX + charWidth), y,
|
||||
static_cast<int>(block.width - (10 + 2 * charWidth)),
|
||||
int(instr.text.lines.size()) * charHeight), disassemblySelectionColor);
|
||||
} else if (traceCount) {
|
||||
// Color depending on how often a sequence of code is executed
|
||||
int exponent = 1;
|
||||
while (traceCount >>= 1) //log2(traceCount)
|
||||
exponent++;
|
||||
int colorDiff = (exponent * exponent) / 2;
|
||||
|
||||
// If the user has a light trace background color, substract
|
||||
if (disassemblyTracedColor.blue() > 160)
|
||||
colorDiff *= -1;
|
||||
|
||||
p.fillRect(QRect(static_cast<int>(blockX + charWidth), y,
|
||||
static_cast<int>(block.width - (10 + 2 * charWidth)),
|
||||
int(instr.text.lines.size()) * charHeight),
|
||||
QColor(disassemblyTracedColor.red(),
|
||||
disassemblyTracedColor.green(),
|
||||
std::max(0, std::min(256, disassemblyTracedColor.blue() + colorDiff))));
|
||||
}
|
||||
y += int(instr.text.lines.size()) * charHeight;
|
||||
}
|
||||
}
|
||||
|
||||
// highlight selected tokens
|
||||
// Highlight selected tokens
|
||||
if (highlight_token != nullptr) {
|
||||
int y = static_cast<int>(blockY + (2 * charWidth) + (db.header_text.lines.size() * charHeight));
|
||||
int tokenWidth = mFontMetrics->width(highlight_token->content);
|
||||
@ -508,7 +496,7 @@ void DisassemblerGraphView::drawBlock(QPainter &p, GraphView::GraphBlock &block)
|
||||
}
|
||||
}
|
||||
|
||||
// highlight program counter
|
||||
// Highlight program counter
|
||||
if (PCInBlock) {
|
||||
int y = static_cast<int>(blockY + (2 * charWidth) + (db.header_text.lines.size() * charHeight));
|
||||
for (const Instr &instr : db.instrs) {
|
||||
|
@ -192,8 +192,6 @@ private:
|
||||
QColor disassemblySelectedBackgroundColor;
|
||||
QColor disassemblySelectionColor;
|
||||
QColor PCSelectionColor;
|
||||
QColor disassemblyTracedColor;
|
||||
QColor disassemblyTracedSelectionColor;
|
||||
QColor jmpColor;
|
||||
QColor brtrueColor;
|
||||
QColor brfalseColor;
|
||||
|
@ -52,6 +52,15 @@ void OverviewView::drawBlock(QPainter &p, GraphView::GraphBlock &block)
|
||||
p.setBrush(disassemblyBackgroundColor);
|
||||
p.drawRect(blockX, blockY,
|
||||
block.width, block.height);
|
||||
// Draw basic block highlighting/tracing
|
||||
auto bb = Core()->getBBHighlighter()->getBasicBlock(block.entry);
|
||||
if (bb) {
|
||||
QColor color(bb->color);
|
||||
color.setAlphaF(0.5);
|
||||
p.setBrush(color);
|
||||
p.drawRect(block.x, block.y,
|
||||
block.width, block.height);
|
||||
}
|
||||
}
|
||||
|
||||
void OverviewView::paintEvent(QPaintEvent *event)
|
||||
|
Loading…
Reference in New Issue
Block a user