mirror of
https://github.com/rizinorg/cutter.git
synced 2024-12-19 03:16: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
|
// Otherwise r2 may ask the user for input and Cutter would freeze
|
||||||
setConfig("scr.interactive", false);
|
setConfig("scr.interactive", false);
|
||||||
|
|
||||||
|
// Initialize graph node highlighter
|
||||||
|
bbHighlighter = new BasicBlockHighlighter();
|
||||||
|
|
||||||
|
// Initialize Async tasks manager
|
||||||
asyncTaskManager = new AsyncTaskManager(this);
|
asyncTaskManager = new AsyncTaskManager(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -231,6 +235,7 @@ bool CutterCore::sdbSet(QString path, QString key, QString val)
|
|||||||
|
|
||||||
CutterCore::~CutterCore()
|
CutterCore::~CutterCore()
|
||||||
{
|
{
|
||||||
|
delete bbHighlighter;
|
||||||
r_core_free(this->core_);
|
r_core_free(this->core_);
|
||||||
r_cons_free();
|
r_cons_free();
|
||||||
}
|
}
|
||||||
@ -2628,3 +2633,8 @@ QString CutterCore::ansiEscapeToHtml(const QString &text)
|
|||||||
free(html);
|
free(html);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BasicBlockHighlighter* CutterCore::getBBHighlighter()
|
||||||
|
{
|
||||||
|
return bbHighlighter;
|
||||||
|
}
|
||||||
|
@ -46,6 +46,7 @@ typedef ut64 RVA;
|
|||||||
class AsyncTaskManager;
|
class AsyncTaskManager;
|
||||||
class CutterCore;
|
class CutterCore;
|
||||||
#include "plugins/CutterPlugin.h"
|
#include "plugins/CutterPlugin.h"
|
||||||
|
#include "common/BasicBlockHighlighter.h"
|
||||||
|
|
||||||
class RCoreLocked
|
class RCoreLocked
|
||||||
{
|
{
|
||||||
@ -728,6 +729,7 @@ public:
|
|||||||
RCoreLocked core() const;
|
RCoreLocked core() const;
|
||||||
|
|
||||||
static QString ansiEscapeToHtml(const QString &text);
|
static QString ansiEscapeToHtml(const QString &text);
|
||||||
|
BasicBlockHighlighter *getBBHighlighter();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void refreshAll();
|
void refreshAll();
|
||||||
@ -783,6 +785,7 @@ private:
|
|||||||
QErrorMessage msgBox;
|
QErrorMessage msgBox;
|
||||||
|
|
||||||
bool emptyGraph = false;
|
bool emptyGraph = false;
|
||||||
|
BasicBlockHighlighter *bbHighlighter;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -298,7 +298,8 @@ SOURCES += \
|
|||||||
dialogs/LoadNewTypesDialog.cpp \
|
dialogs/LoadNewTypesDialog.cpp \
|
||||||
widgets/SdbWidget.cpp \
|
widgets/SdbWidget.cpp \
|
||||||
common/PythonManager.cpp \
|
common/PythonManager.cpp \
|
||||||
plugins/PluginManager.cpp
|
plugins/PluginManager.cpp \
|
||||||
|
common/BasicBlockHighlighter.cpp
|
||||||
|
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
Cutter.h \
|
Cutter.h \
|
||||||
@ -411,7 +412,8 @@ HEADERS += \
|
|||||||
dialogs/LoadNewTypesDialog.h \
|
dialogs/LoadNewTypesDialog.h \
|
||||||
widgets/SdbWidget.h \
|
widgets/SdbWidget.h \
|
||||||
common/PythonManager.h \
|
common/PythonManager.h \
|
||||||
plugins/PluginManager.h
|
plugins/PluginManager.h \
|
||||||
|
common/BasicBlockHighlighter.h
|
||||||
|
|
||||||
FORMS += \
|
FORMS += \
|
||||||
dialogs/AboutDialog.ui \
|
dialogs/AboutDialog.ui \
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
<object-type name="CutterCore" />
|
<object-type name="CutterCore" />
|
||||||
<object-type name="Configuration" />
|
<object-type name="Configuration" />
|
||||||
<object-type name="MainWindow" />
|
<object-type name="MainWindow" />
|
||||||
|
<object-type name="BasicBlockHighlighter" />
|
||||||
<object-type name="CutterDockWidget" />
|
<object-type name="CutterDockWidget" />
|
||||||
<object-type name="CutterPlugin">
|
<object-type name="CutterPlugin">
|
||||||
<modify-function signature="getName()const">
|
<modify-function signature="getName()const">
|
||||||
|
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/CachedFontMetrics.h"
|
||||||
#include "common/TempConfig.h"
|
#include "common/TempConfig.h"
|
||||||
#include "common/SyntaxHighlighter.h"
|
#include "common/SyntaxHighlighter.h"
|
||||||
|
#include "common/BasicBlockHighlighter.h"
|
||||||
|
|
||||||
DisassemblerGraphView::DisassemblerGraphView(QWidget *parent)
|
DisassemblerGraphView::DisassemblerGraphView(QWidget *parent)
|
||||||
: GraphView(parent),
|
: GraphView(parent),
|
||||||
@ -429,8 +430,18 @@ void DisassemblerGraphView::drawBlock(QPainter &p, GraphView::GraphBlock &block)
|
|||||||
p.setBrush(disassemblyBackgroundColor);
|
p.setBrush(disassemblyBackgroundColor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Draw basic block background
|
||||||
p.drawRect(blockX, blockY,
|
p.drawRect(blockX, blockY,
|
||||||
block.width, block.height);
|
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
|
// Draw different background for selected instruction
|
||||||
if (selected_instruction != RVA_INVALID) {
|
if (selected_instruction != RVA_INVALID) {
|
||||||
@ -440,39 +451,16 @@ void DisassemblerGraphView::drawBlock(QPainter &p, GraphView::GraphBlock &block)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
auto selected = instr.addr == selected_instruction;
|
auto selected = instr.addr == selected_instruction;
|
||||||
//auto traceCount = dbgfunctions->GetTraceRecordHitCount(instr.addr);
|
if (selected) {
|
||||||
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) {
|
|
||||||
p.fillRect(QRect(static_cast<int>(blockX + charWidth), y,
|
p.fillRect(QRect(static_cast<int>(blockX + charWidth), y,
|
||||||
static_cast<int>(block.width - (10 + 2 * charWidth)),
|
static_cast<int>(block.width - (10 + 2 * charWidth)),
|
||||||
int(instr.text.lines.size()) * charHeight), disassemblySelectionColor);
|
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;
|
y += int(instr.text.lines.size()) * charHeight;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// highlight selected tokens
|
// Highlight selected tokens
|
||||||
if (highlight_token != nullptr) {
|
if (highlight_token != nullptr) {
|
||||||
int y = static_cast<int>(blockY + (2 * charWidth) + (db.header_text.lines.size() * charHeight));
|
int y = static_cast<int>(blockY + (2 * charWidth) + (db.header_text.lines.size() * charHeight));
|
||||||
int tokenWidth = mFontMetrics->width(highlight_token->content);
|
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) {
|
if (PCInBlock) {
|
||||||
int y = static_cast<int>(blockY + (2 * charWidth) + (db.header_text.lines.size() * charHeight));
|
int y = static_cast<int>(blockY + (2 * charWidth) + (db.header_text.lines.size() * charHeight));
|
||||||
for (const Instr &instr : db.instrs) {
|
for (const Instr &instr : db.instrs) {
|
||||||
|
@ -192,8 +192,6 @@ private:
|
|||||||
QColor disassemblySelectedBackgroundColor;
|
QColor disassemblySelectedBackgroundColor;
|
||||||
QColor disassemblySelectionColor;
|
QColor disassemblySelectionColor;
|
||||||
QColor PCSelectionColor;
|
QColor PCSelectionColor;
|
||||||
QColor disassemblyTracedColor;
|
|
||||||
QColor disassemblyTracedSelectionColor;
|
|
||||||
QColor jmpColor;
|
QColor jmpColor;
|
||||||
QColor brtrueColor;
|
QColor brtrueColor;
|
||||||
QColor brfalseColor;
|
QColor brfalseColor;
|
||||||
|
@ -52,6 +52,15 @@ void OverviewView::drawBlock(QPainter &p, GraphView::GraphBlock &block)
|
|||||||
p.setBrush(disassemblyBackgroundColor);
|
p.setBrush(disassemblyBackgroundColor);
|
||||||
p.drawRect(blockX, blockY,
|
p.drawRect(blockX, blockY,
|
||||||
block.width, block.height);
|
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)
|
void OverviewView::paintEvent(QPaintEvent *event)
|
||||||
|
Loading…
Reference in New Issue
Block a user