Breakup MemoryWidget (#51)

* Add SidebarWidget from disassembly sidebar

* Remove disassembly sidebar from MemoryWidget

* Add HexdumpWidget from MemoryWidget

* Remove Hexdump from MemoryWidget

* Make PreviewWidget from MemoryWidget

* Some cleanup

* Rename DisassemblyView to DisasseblyWidget
This commit is contained in:
Florian Märkl 2017-10-12 21:55:15 +02:00 committed by xarkes
parent b4867cadef
commit 12e64cf052
19 changed files with 3572 additions and 3653 deletions

View File

@ -40,7 +40,7 @@
#include "utils/Helpers.h" #include "utils/Helpers.h"
#include "dialogs/NewFileDialog.h" #include "dialogs/NewFileDialog.h"
#include "widgets/MemoryWidget.h" #include "widgets/PreviewWidget.h"
#include "widgets/FunctionsWidget.h" #include "widgets/FunctionsWidget.h"
#include "widgets/SectionsWidget.h" #include "widgets/SectionsWidget.h"
#include "widgets/CommentsWidget.h" #include "widgets/CommentsWidget.h"
@ -85,7 +85,7 @@ static void registerCustomFonts()
MainWindow::MainWindow(QWidget *parent) : MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent), QMainWindow(parent),
core(CutterCore::getInstance()), core(CutterCore::getInstance()),
memoryDock(nullptr), previewDock(nullptr),
notepadDock(nullptr), notepadDock(nullptr),
asmDock(nullptr), asmDock(nullptr),
calcDock(nullptr), calcDock(nullptr),
@ -184,16 +184,22 @@ void MainWindow::initUI()
dockWidgets.reserve(14); dockWidgets.reserve(14);
// Add Memory DockWidget // Add Memory DockWidget
this->memoryDock = new MemoryWidget(); this->previewDock = new PreviewWidget(tr("Preview"), this);
dockWidgets.push_back(memoryDock); dockWidgets.push_back(previewDock);
// To use in the future when we handle more than one memory views // To use in the future when we handle more than one memory views
// this->memoryDock->setAttribute(Qt::WA_DeleteOnClose); // this->previewDock->setAttribute(Qt::WA_DeleteOnClose);
// this->add_debug_output( QString::number(this->dockList.length()) ); // this->add_debug_output( QString::number(this->dockList.length()) );
// Add disassembly view (dockable) // Add disassembly view (dockable)
this->disassemblyDock = new DisassemblyView(tr("Disassembly"), this); this->disassemblyDock = new DisassemblyWidget(tr("Disassembly"), this);
dockWidgets.push_back(disassemblyDock); dockWidgets.push_back(disassemblyDock);
sidebarDock = new SidebarWidget(tr("Sidebar"), this);
dockWidgets.push_back(sidebarDock);
hexdumpDock = new HexdumpWidget(tr("Hexdump"), this);
dockWidgets.push_back(hexdumpDock);
// Add graph view as dockable // Add graph view as dockable
graphDock = new QDockWidget(tr("Graph"), this); graphDock = new QDockWidget(tr("Graph"), this);
graphDock->setAllowedAreas(Qt::AllDockWidgetAreas); graphDock->setAllowedAreas(Qt::AllDockWidgetAreas);
@ -244,7 +250,7 @@ void MainWindow::initUI()
// Add Notepad Dock panel // Add Notepad Dock panel
this->notepadDock = new Notepad(this); this->notepadDock = new Notepad(this);
dockWidgets.push_back(notepadDock); dockWidgets.push_back(notepadDock);
connect(memoryDock, SIGNAL(fontChanged(QFont)), notepadDock, SLOT(setFonts(QFont))); connect(previewDock, SIGNAL(fontChanged(QFont)), notepadDock, SLOT(setFonts(QFont)));
//Add Dashboard Dock panel //Add Dashboard Dock panel
this->dashboardDock = new Dashboard(this); this->dashboardDock = new Dashboard(this);
@ -341,8 +347,6 @@ void MainWindow::finalizeOpen()
core->cmd("fs sections"); core->cmd("fs sections");
updateFrames(); updateFrames();
memoryDock->selectHexPreview();
// Restore project notes // Restore project notes
QString notes = this->core->cmd("Pnj"); QString notes = this->core->cmd("Pnj");
//qDebug() << "Notes:" << notes; //qDebug() << "Notes:" << notes;
@ -367,7 +371,7 @@ void MainWindow::finalizeOpen()
addOutput(tr(" > Finished, happy reversing :)")); addOutput(tr(" > Finished, happy reversing :)"));
// Add fortune message // Add fortune message
addOutput("\n" + core->cmd("fo")); addOutput("\n" + core->cmd("fo"));
memoryDock->setWindowTitle("entry0"); //previewDock->setWindowTitle("entry0");
start_web_server(); start_web_server();
showMaximized(); showMaximized();
// Initialize syntax highlighters // Initialize syntax highlighters
@ -408,11 +412,6 @@ void MainWindow::setWebServerState(bool start)
} }
} }
void MainWindow::raiseMemoryDock()
{
memoryDock->raise();
}
void MainWindow::toggleSideBarTheme() void MainWindow::toggleSideBarTheme()
{ {
sideBar->themesButtonToggle(); sideBar->themesButtonToggle();
@ -477,7 +476,7 @@ void MainWindow::readSettings()
void MainWindow::dark() void MainWindow::dark()
{ {
qApp->setStyleSheet("QPlainTextEdit { background-color: rgb(64, 64, 64); color: rgb(222, 222, 222);} QTextEdit { background-color: rgb(64, 64, 64); color: rgb(222, 222, 222);} "); qApp->setStyleSheet("QPlainTextEdit { background-color: rgb(64, 64, 64); color: rgb(222, 222, 222);} QTextEdit { background-color: rgb(64, 64, 64); color: rgb(222, 222, 222);} ");
this->memoryDock->switchTheme(true); this->previewDock->switchTheme(true);
QSettings settings; QSettings settings;
settings.setValue("dark", true); settings.setValue("dark", true);
} }
@ -485,7 +484,7 @@ void MainWindow::dark()
void MainWindow::def_theme() void MainWindow::def_theme()
{ {
qApp->setStyleSheet(""); qApp->setStyleSheet("");
this->memoryDock->switchTheme(false); this->previewDock->switchTheme(false);
QSettings settings; QSettings settings;
settings.setValue("dark", false); settings.setValue("dark", false);
} }
@ -606,27 +605,24 @@ void MainWindow::on_actionTabs_triggered()
if (ui->centralTabWidget->tabPosition() == QTabWidget::South) if (ui->centralTabWidget->tabPosition() == QTabWidget::South)
{ {
ui->centralTabWidget->setTabPosition(QTabWidget::North); ui->centralTabWidget->setTabPosition(QTabWidget::North);
this->memoryDock->memTabWidget->setTabPosition(QTabWidget::North);
this->setTabPosition(Qt::AllDockWidgetAreas, QTabWidget::North); this->setTabPosition(Qt::AllDockWidgetAreas, QTabWidget::North);
} }
else else
{ {
ui->centralTabWidget->setTabPosition(QTabWidget::South); ui->centralTabWidget->setTabPosition(QTabWidget::South);
this->memoryDock->memTabWidget->setTabPosition(QTabWidget::South);
this->setTabPosition(Qt::AllDockWidgetAreas, QTabWidget::South); this->setTabPosition(Qt::AllDockWidgetAreas, QTabWidget::South);
} }
} }
void MainWindow::on_actionMem_triggered() void MainWindow::on_actionMem_triggered()
{ {
//this->memoryDock->show(); //this->previewDock->show();
//this->memoryDock->raise(); //this->previewDock->raise();
MemoryWidget *newMemDock = new MemoryWidget(); PreviewWidget *newMemDock = new PreviewWidget();
this->dockWidgets << newMemDock; this->dockWidgets << newMemDock;
newMemDock->setAttribute(Qt::WA_DeleteOnClose); newMemDock->setAttribute(Qt::WA_DeleteOnClose);
this->tabifyDockWidget(this->memoryDock, newMemDock); this->tabifyDockWidget(this->previewDock, newMemDock);
//newMemDock->refreshDisasm(); //newMemDock->refreshDisasm();
newMemDock->refreshHexdump();
} }
void MainWindow::on_actionEntry_points_triggered() void MainWindow::on_actionEntry_points_triggered()
@ -763,8 +759,10 @@ void MainWindow::restoreDocks()
addDockWidget(Qt::TopDockWidgetArea, this->dashboardDock); addDockWidget(Qt::TopDockWidgetArea, this->dashboardDock);
this->tabifyDockWidget(this->sectionsDock, this->commentsDock); this->tabifyDockWidget(this->sectionsDock, this->commentsDock);
this->tabifyDockWidget(this->dashboardDock, this->disassemblyDock); this->tabifyDockWidget(this->dashboardDock, this->disassemblyDock);
this->tabifyDockWidget(this->dashboardDock, this->sidebarDock);
this->tabifyDockWidget(this->dashboardDock, this->hexdumpDock);
this->tabifyDockWidget(this->dashboardDock, this->graphDock); this->tabifyDockWidget(this->dashboardDock, this->graphDock);
this->tabifyDockWidget(this->dashboardDock, this->memoryDock); this->tabifyDockWidget(this->dashboardDock, this->previewDock);
this->tabifyDockWidget(this->dashboardDock, this->entrypointDock); this->tabifyDockWidget(this->dashboardDock, this->entrypointDock);
this->tabifyDockWidget(this->dashboardDock, this->flagsDock); this->tabifyDockWidget(this->dashboardDock, this->flagsDock);
this->tabifyDockWidget(this->dashboardDock, this->stringsDock); this->tabifyDockWidget(this->dashboardDock, this->stringsDock);
@ -799,7 +797,7 @@ void MainWindow::showDefaultDocks()
const QList<QDockWidget *> defaultDocks = { sectionsDock, const QList<QDockWidget *> defaultDocks = { sectionsDock,
entrypointDock, entrypointDock,
functionsDock, functionsDock,
memoryDock, previewDock,
commentsDock, commentsDock,
stringsDock, stringsDock,
importsDock, importsDock,
@ -807,6 +805,8 @@ void MainWindow::showDefaultDocks()
notepadDock, notepadDock,
graphDock, graphDock,
disassemblyDock, disassemblyDock,
sidebarDock,
hexdumpDock,
dashboardDock dashboardDock
}; };
@ -895,7 +895,7 @@ void MainWindow::on_actionWhite_Theme_triggered()
void MainWindow::on_actionSDB_browser_triggered() void MainWindow::on_actionSDB_browser_triggered()
{ {
this->sdbDock = new SdbDock(this); this->sdbDock = new SdbDock(this);
this->tabifyDockWidget(this->memoryDock, this->sdbDock); this->tabifyDockWidget(this->previewDock, this->sdbDock);
this->sdbDock->setFloating(true); this->sdbDock->setFloating(true);
this->sdbDock->show(); this->sdbDock->show();
} }

View File

@ -5,13 +5,15 @@
#include <QList> #include <QList>
#include <memory> #include <memory>
#include "RadareWebServer.h" #include "RadareWebServer.h"
#include "widgets/DisassemblyView.h" #include "widgets/DisassemblyWidget.h"
#include "widgets/SidebarWidget.h"
#include "widgets/HexdumpWidget.h"
#include "cutter.h" // only needed for ut64 #include "cutter.h" // only needed for ut64
class CutterCore; class CutterCore;
class DockWidget; class DockWidget;
class Omnibar; class Omnibar;
class MemoryWidget; class PreviewWidget;
class Notepad; class Notepad;
class SideBar; class SideBar;
class Highlighter; class Highlighter;
@ -58,10 +60,9 @@ public:
void saveProject(); void saveProject();
void start_web_server(); void start_web_server();
void closeEvent(QCloseEvent *event); void closeEvent(QCloseEvent *event) override;
void readSettings(); void readSettings();
void setFilename(const QString &fn); void setFilename(const QString &fn);
void seek(RVA offset);
void updateFrames(); void updateFrames();
void refreshFunctions(); void refreshFunctions();
void refreshComments(); void refreshComments();
@ -69,7 +70,6 @@ public:
void addDebugOutput(const QString &msg); void addDebugOutput(const QString &msg);
void sendToNotepad(const QString &txt); void sendToNotepad(const QString &txt);
void setWebServerState(bool start); void setWebServerState(bool start);
void raiseMemoryDock();
void toggleSideBarTheme(); void toggleSideBarTheme();
void refreshOmniBar(const QStringList &flags); void refreshOmniBar(const QStringList &flags);
@ -170,13 +170,15 @@ private slots:
private: private:
CutterCore *core; CutterCore *core;
DisassemblyView *disassemblyDock; DisassemblyWidget *disassemblyDock;
SidebarWidget *sidebarDock;
HexdumpWidget *hexdumpDock;
QDockWidget *graphDock; QDockWidget *graphDock;
QDockWidget *asmDock; QDockWidget *asmDock;
QDockWidget *calcDock; QDockWidget *calcDock;
Omnibar *omnibar; Omnibar *omnibar;
SideBar *sideBar; SideBar *sideBar;
MemoryWidget *memoryDock; PreviewWidget *previewDock;
Notepad *notepadDock; Notepad *notepadDock;
bool doLock; bool doLock;

View File

@ -390,6 +390,13 @@ void CutterCore::seek(ut64 offset)
} }
RVA CutterCore::getSeekAddr()
{
return cmd("s").toULongLong(nullptr, 16);
}
bool CutterCore::tryFile(QString path, bool rw) bool CutterCore::tryFile(QString path, bool rw)
{ {

View File

@ -210,6 +210,8 @@ public:
void analyze(int level, QList<QString> advanced); void analyze(int level, QList<QString> advanced);
void seek(QString addr); void seek(QString addr);
void seek(ut64 offset); void seek(ut64 offset);
RVA getSeekAddr();
ut64 math(const QString &expr); ut64 math(const QString &expr);
QString itoa(ut64 num, int rdx = 16); QString itoa(ut64 num, int rdx = 16);

View File

@ -35,7 +35,7 @@ SOURCES += \
main.cpp \ main.cpp \
cutter.cpp \ cutter.cpp \
widgets/DisassemblerGraphView.cpp \ widgets/DisassemblerGraphView.cpp \
widgets/MemoryWidget.cpp \ widgets/PreviewWidget.cpp \
utils/RichTextPainter.cpp \ utils/RichTextPainter.cpp \
dialogs/OptionsDialog.cpp \ dialogs/OptionsDialog.cpp \
dialogs/AboutDialog.cpp \ dialogs/AboutDialog.cpp \
@ -74,12 +74,14 @@ SOURCES += \
widgets/StringsWidget.cpp \ widgets/StringsWidget.cpp \
widgets/SymbolsWidget.cpp \ widgets/SymbolsWidget.cpp \
menus/DisassemblyContextMenu.cpp \ menus/DisassemblyContextMenu.cpp \
widgets/DisassemblyView.cpp widgets/DisassemblyWidget.cpp \
widgets/SidebarWidget.cpp \
widgets/HexdumpWidget.cpp
HEADERS += \ HEADERS += \
cutter.h \ cutter.h \
widgets/DisassemblerGraphView.h \ widgets/DisassemblerGraphView.h \
widgets/MemoryWidget.h \ widgets/PreviewWidget.h \
utils/RichTextPainter.h \ utils/RichTextPainter.h \
utils/CachedFontMetrics.h \ utils/CachedFontMetrics.h \
dialogs/AboutDialog.h \ dialogs/AboutDialog.h \
@ -121,10 +123,12 @@ HEADERS += \
widgets/StringsWidget.h \ widgets/StringsWidget.h \
widgets/SymbolsWidget.h \ widgets/SymbolsWidget.h \
menus/DisassemblyContextMenu.h \ menus/DisassemblyContextMenu.h \
widgets/DisassemblyView.h widgets/DisassemblyWidget.h \
widgets/SidebarWidget.h \
widgets/HexdumpWidget.h
FORMS += \ FORMS += \
widgets/MemoryWidget.ui \ widgets/PreviewWidget.ui \
dialogs/AboutDialog.ui \ dialogs/AboutDialog.ui \
dialogs/AsmOptionsDialog.ui \ dialogs/AsmOptionsDialog.ui \
dialogs/CommentsDialog.ui \ dialogs/CommentsDialog.ui \
@ -149,7 +153,9 @@ FORMS += \
widgets/SectionsDock.ui \ widgets/SectionsDock.ui \
widgets/Sidebar.ui \ widgets/Sidebar.ui \
widgets/StringsWidget.ui \ widgets/StringsWidget.ui \
widgets/SymbolsWidget.ui widgets/SymbolsWidget.ui \
widgets/SidebarWidget.ui \
widgets/HexdumpWidget.ui
RESOURCES += \ RESOURCES += \
resources.qrc resources.qrc

View File

@ -5,7 +5,7 @@
#include "utils/Helpers.h" #include "utils/Helpers.h"
// TODO: remove us // TODO: remove us
#include "widgets/MemoryWidget.h" #include "widgets/PreviewWidget.h"
#include "widgets/Notepad.h" #include "widgets/Notepad.h"
#include "Settings.h" #include "Settings.h"

View File

@ -1,4 +1,4 @@
#include "DisassemblyView.h" #include "DisassemblyWidget.h"
#include "menus/DisassemblyContextMenu.h" #include "menus/DisassemblyContextMenu.h"
#include "dialogs/XrefsDialog.h" #include "dialogs/XrefsDialog.h"
#include "utils/HexAsciiHighlighter.h" #include "utils/HexAsciiHighlighter.h"
@ -6,13 +6,14 @@
#include <QShortcut> #include <QShortcut>
#include <QScrollBar> #include <QScrollBar>
DisassemblyView::DisassemblyView(QWidget *parent) : DisassemblyWidget::DisassemblyWidget(QWidget *parent) :
QDockWidget(parent), QDockWidget(parent),
mDisasTextEdit(new QTextEdit(this)) mDisasTextEdit(new QTextEdit(this))
{ {
// Configure Dock // Configure Dock
this->setWidget(mDisasTextEdit); setWidget(mDisasTextEdit);
this->setAllowedAreas(Qt::AllDockWidgetAreas); setAllowedAreas(Qt::AllDockWidgetAreas);
setObjectName("DisassemblyWidget");
// TODO Use Settings // TODO Use Settings
mDisasTextEdit->setFont(QFont("Monospace", 10)); mDisasTextEdit->setFont(QFont("Monospace", 10));
@ -67,12 +68,12 @@ DisassemblyView::DisassemblyView(QWidget *parent) :
connect(CutterCore::getInstance(), SIGNAL(seekChanged(RVA)), this, SLOT(on_seekChanged(RVA))); connect(CutterCore::getInstance(), SIGNAL(seekChanged(RVA)), this, SLOT(on_seekChanged(RVA)));
} }
DisassemblyView::DisassemblyView(const QString &title, QWidget *parent) : DisassemblyWidget::DisassemblyWidget(const QString &title, QWidget *parent) :
DisassemblyView(parent) DisassemblyWidget(parent)
{ {
this->setWindowTitle(title); this->setWindowTitle(title);
} }
void DisassemblyView::highlightCurrentLine() void DisassemblyWidget::highlightCurrentLine()
{ {
QList<QTextEdit::ExtraSelection> extraSelections; QList<QTextEdit::ExtraSelection> extraSelections;
@ -131,13 +132,13 @@ void DisassemblyView::highlightCurrentLine()
mDisasTextEdit->setExtraSelections(extraSelections); mDisasTextEdit->setExtraSelections(extraSelections);
} }
void DisassemblyView::showDisasContextMenu(const QPoint &pt) void DisassemblyWidget::showDisasContextMenu(const QPoint &pt)
{ {
DisassemblyContextMenu menu(this->readCurrentDisassemblyOffset(), mDisasTextEdit); DisassemblyContextMenu menu(this->readCurrentDisassemblyOffset(), mDisasTextEdit);
menu.exec(mDisasTextEdit->mapToGlobal(pt)); menu.exec(mDisasTextEdit->mapToGlobal(pt));
} }
void DisassemblyView::showXrefsDialog() void DisassemblyWidget::showXrefsDialog()
{ {
// Get current offset // Get current offset
QTextCursor tc = mDisasTextEdit->textCursor(); QTextCursor tc = mDisasTextEdit->textCursor();
@ -153,7 +154,7 @@ void DisassemblyView::showXrefsDialog()
} }
} }
RVA DisassemblyView::readCurrentDisassemblyOffset() RVA DisassemblyWidget::readCurrentDisassemblyOffset()
{ {
// TODO: do this in a different way without parsing the disassembly text // TODO: do this in a different way without parsing the disassembly text
QTextCursor tc = mDisasTextEdit->textCursor(); QTextCursor tc = mDisasTextEdit->textCursor();
@ -171,7 +172,7 @@ RVA DisassemblyView::readCurrentDisassemblyOffset()
return ele.toULongLong(0, 16); return ele.toULongLong(0, 16);
} }
bool DisassemblyView::loadMoreDisassembly() bool DisassemblyWidget::loadMoreDisassembly()
{ {
/* /*
* Add more disasm as the user scrolls * Add more disasm as the user scrolls
@ -251,12 +252,12 @@ bool DisassemblyView::loadMoreDisassembly()
} }
void DisassemblyView::disasmScrolled() void DisassemblyWidget::disasmScrolled()
{ {
loadMoreDisassembly(); loadMoreDisassembly();
} }
void DisassemblyView::refreshDisasm() void DisassemblyWidget::refreshDisasm()
{ {
// TODO Very slow mostly because of the highlight // TODO Very slow mostly because of the highlight
// Prevent further scroll // Prevent further scroll
@ -289,7 +290,7 @@ void DisassemblyView::refreshDisasm()
this->highlightDisasms(); this->highlightDisasms();
} }
void DisassemblyView::on_mDisasTextEdit_cursorPositionChanged() void DisassemblyWidget::on_mDisasTextEdit_cursorPositionChanged()
{ {
// Get current offset // Get current offset
QTextCursor tc = mDisasTextEdit->textCursor(); QTextCursor tc = mDisasTextEdit->textCursor();
@ -344,15 +345,15 @@ void DisassemblyView::on_mDisasTextEdit_cursorPositionChanged()
// Refresh function information at sidebar // Refresh function information at sidebar
ui->fcnNameEdit->setText(at); ui->fcnNameEdit->setText(at);
// FIXME TITLE? // FIXME TITLE?
// this->main->memoryDock->setWindowTitle(at); // this->main->previewDock->setWindowTitle(at);
//this->main->memoryDock->create_graph(ele); //this->main->previewDock->create_graph(ele);
this->setMiniGraph(at); this->setMiniGraph(at);
} }
} }
*/ */
} }
bool DisassemblyView::eventFilter(QObject *obj, QEvent *event) bool DisassemblyWidget::eventFilter(QObject *obj, QEvent *event)
{ {
if ((obj == mDisasTextEdit || obj == mDisasTextEdit->viewport()) && event->type() == QEvent::MouseButtonDblClick) if ((obj == mDisasTextEdit || obj == mDisasTextEdit->viewport()) && event->type() == QEvent::MouseButtonDblClick)
{ {
@ -388,13 +389,13 @@ bool DisassemblyView::eventFilter(QObject *obj, QEvent *event)
return QDockWidget::eventFilter(obj, event); return QDockWidget::eventFilter(obj, event);
} }
void DisassemblyView::on_seekChanged(RVA offset) void DisassemblyWidget::on_seekChanged(RVA offset)
{ {
Q_UNUSED(offset); Q_UNUSED(offset);
refreshDisasm(); refreshDisasm();
} }
void DisassemblyView::highlightDisasms() void DisassemblyWidget::highlightDisasms()
{ {
// Syntax Highliting // Syntax Highliting
// TODO doing new all the time // TODO doing new all the time

View File

@ -5,12 +5,12 @@
#include <QTextEdit> #include <QTextEdit>
#include "cutter.h" #include "cutter.h"
class DisassemblyView : public QDockWidget class DisassemblyWidget : public QDockWidget
{ {
Q_OBJECT Q_OBJECT
public: public:
explicit DisassemblyView(QWidget *parent = nullptr); explicit DisassemblyWidget(QWidget *parent = nullptr);
explicit DisassemblyView(const QString &title, QWidget *parent = nullptr); explicit DisassemblyWidget(const QString &title, QWidget *parent = nullptr);
signals: signals:

View File

@ -1,5 +1,6 @@
#include "MemoryWidget.h"
#include "ui_MemoryWidget.h" #include "HexdumpWidget.h"
#include "ui_HexdumpWidget.h"
#include "DisassemblerGraphView.h" #include "DisassemblerGraphView.h"
#include "MainWindow.h" #include "MainWindow.h"
@ -20,25 +21,17 @@
#include <cassert> #include <cassert>
MemoryWidget::MemoryWidget() : HexdumpWidget::HexdumpWidget(QWidget *parent, Qt::WindowFlags flags) :
ui(new Ui::MemoryWidget), QDockWidget(parent, flags),
ui(new Ui::HexdumpWidget),
core(CutterCore::getInstance()) core(CutterCore::getInstance())
{ {
ui->setupUi(this); ui->setupUi(this);
this->hexOffsetText = ui->hexOffsetText_2; this->hexOffsetText = ui->hexOffsetText_2;
this->hexHexText = ui->hexHexText_2; this->hexHexText = ui->hexHexText_2;
this->hexDisasTextEdit = ui->hexDisasTextEdit_2;
this->hexASCIIText = ui->hexASCIIText_2; this->hexASCIIText = ui->hexASCIIText_2;
this->xrefToTreeWidget_2 = ui->xrefToTreeWidget_2;
this->xreFromTreeWidget_2 = ui->xreFromTreeWidget_2;
this->memTabWidget = ui->memTabWidget;
this->last_fcn = "entry0"; this->hexDisasTextEdit = ui->hexDisasTextEdit_2;
this->last_graph_fcn = 0; //"";
this->last_hexdump_fcn = 0; //"";
disasm_top_offset = 0;
next_disasm_top_offset = 0;
//this->on_actionSettings_menu_1_triggered(); //this->on_actionSettings_menu_1_triggered();
@ -46,29 +39,6 @@ MemoryWidget::MemoryWidget() :
//connect(ui->hexHexText, SIGNAL(cursorPositionChanged()), this, SLOT(highlightHexCurrentLine())); //connect(ui->hexHexText, SIGNAL(cursorPositionChanged()), this, SLOT(highlightHexCurrentLine()));
//highlightHexCurrentLine(); //highlightHexCurrentLine();
// Highlight current line on previews and decompiler
connect(ui->previewTextEdit, SIGNAL(cursorPositionChanged()), this, SLOT(highlightPreviewCurrentLine()));
connect(ui->decoTextEdit, SIGNAL(cursorPositionChanged()), this, SLOT(highlightDecoCurrentLine()));
// Hide memview notebooks tabs
QTabBar *bar = ui->memTabWidget->tabBar();
bar->setVisible(false);
QTabBar *sidebar = ui->memSideTabWidget_2->tabBar();
sidebar->setVisible(false);
QTabBar *preTab = ui->memPreviewTab->tabBar();
preTab->setVisible(false);
// Hide fcn graph notebooks tabs
QTabBar *graph_bar = ui->fcnGraphTabWidget->tabBar();
graph_bar->setVisible(false);
// Debug console
// For QWebEngine debugging see: https://doc.qt.io/qt-5/qtwebengine-debugging.html
//QWebSettings::globalSettings()->setAttribute(QWebSettings::DeveloperExtrasEnabled, true);
// Add margin to function name line edit
ui->fcnNameEdit->setTextMargins(5, 0, 0, 0);
// Normalize fonts for other OS // Normalize fonts for other OS
qhelpers::normalizeEditFont(this->hexOffsetText); qhelpers::normalizeEditFont(this->hexOffsetText);
qhelpers::normalizeEditFont(this->hexHexText); qhelpers::normalizeEditFont(this->hexHexText);
@ -80,10 +50,6 @@ MemoryWidget::MemoryWidget() :
memMenu->addAction(ui->actionSettings_menu_1); memMenu->addAction(ui->actionSettings_menu_1);
ui->memSettingsButton_2->setMenu(memMenu); ui->memSettingsButton_2->setMenu(memMenu);
// Set Splitter stretch factor
ui->splitter->setStretchFactor(0, 10);
ui->splitter->setStretchFactor(1, 1);
// Set hexdump context menu // Set hexdump context menu
ui->hexHexText_2->setContextMenuPolicy(Qt::CustomContextMenu); ui->hexHexText_2->setContextMenuPolicy(Qt::CustomContextMenu);
connect(ui->hexHexText_2, SIGNAL(customContextMenuRequested(const QPoint &)), connect(ui->hexHexText_2, SIGNAL(customContextMenuRequested(const QPoint &)),
@ -108,39 +74,32 @@ MemoryWidget::MemoryWidget() :
connect(ui->hexASCIIText_2->verticalScrollBar(), SIGNAL(valueChanged(int)), connect(ui->hexASCIIText_2->verticalScrollBar(), SIGNAL(valueChanged(int)),
ui->hexHexText_2->verticalScrollBar(), SLOT(setValue(int))); ui->hexHexText_2->verticalScrollBar(), SLOT(setValue(int)));
// Space to switch between disassembly and graph
QShortcut *graph_shortcut = new QShortcut(QKeySequence(Qt::Key_Space), this);
connect(graph_shortcut, SIGNAL(activated()), this, SLOT(cycleViews()));
//graph_shortcut->setContext(Qt::WidgetShortcut);
// Control Disasm and Hex scroll to add more contents // Control Disasm and Hex scroll to add more contents
connect(this->hexASCIIText->verticalScrollBar(), SIGNAL(valueChanged(int)), this, SLOT(hexScrolled())); connect(this->hexASCIIText->verticalScrollBar(), SIGNAL(valueChanged(int)), this, SLOT(hexScrolled()));
connect(core, SIGNAL(seekChanged(RVA)), this, SLOT(on_seekChanged(RVA))); connect(core, SIGNAL(seekChanged(RVA)), this, SLOT(on_seekChanged(RVA)));
//connect(main, SIGNAL(cursorAddressChanged(RVA)), this, SLOT(on_cursorAddressChanged(RVA)));
connect(core, SIGNAL(flagsChanged()), this, SLOT(updateViews()));
connect(core, SIGNAL(commentsChanged()), this, SLOT(updateViews()));
connect(core, SIGNAL(asmOptionsChanged()), this, SLOT(updateViews()));
fillPlugins(); fillPlugins();
} }
HexdumpWidget::HexdumpWidget(const QString &title, QWidget *parent, Qt::WindowFlags flags)
void MemoryWidget::on_seekChanged(RVA addr) : HexdumpWidget(parent, flags)
{ {
updateViews(addr); setWindowTitle(title);
} }
void MemoryWidget::on_cursorAddressChanged(RVA addr)
void HexdumpWidget::on_seekChanged(RVA addr)
{ {
setFcnName(addr); refresh(addr);
get_refs_data(addr);
} }
HexdumpWidget::~HexdumpWidget() {}
/* /*
* Text highlight functions * Text highlight functions
*/ */
void MemoryWidget::highlightHexCurrentLine() void HexdumpWidget::highlightHexCurrentLine()
{ {
QList<QTextEdit::ExtraSelection> extraSelections; QList<QTextEdit::ExtraSelection> extraSelections;
@ -173,7 +132,7 @@ void MemoryWidget::highlightHexCurrentLine()
highlightHexWords(cursor.selectedText()); highlightHexWords(cursor.selectedText());
} }
void MemoryWidget::highlightHexWords(const QString &str) void HexdumpWidget::highlightHexWords(const QString &str)
{ {
QString searchString = str; QString searchString = str;
QTextDocument *document = ui->hexHexText_2->document(); QTextDocument *document = ui->hexHexText_2->document();
@ -204,89 +163,13 @@ void MemoryWidget::highlightHexWords(const QString &str)
cursor.endEditBlock(); cursor.endEditBlock();
} }
void MemoryWidget::highlightPreviewCurrentLine() void HexdumpWidget::refresh(RVA addr)
{ {
if (addr == RVA_INVALID)
QList<QTextEdit::ExtraSelection> extraSelections;
if (ui->previewTextEdit->toPlainText() != "")
{ {
if (ui->previewTextEdit->isReadOnly()) addr = core->getSeekAddr();
{
QTextEdit::ExtraSelection selection;
QColor lineColor = QColor(190, 144, 212);
selection.format.setBackground(lineColor);
selection.format.setProperty(QTextFormat::FullWidthSelection, true);
selection.cursor = ui->previewTextEdit->textCursor();
selection.cursor.clearSelection();
extraSelections.append(selection);
} }
}
ui->previewTextEdit->setExtraSelections(extraSelections);
}
void MemoryWidget::highlightDecoCurrentLine()
{
QList<QTextEdit::ExtraSelection> extraSelections;
if (ui->decoTextEdit->toPlainText() != "")
{
if (ui->decoTextEdit->isReadOnly())
{
QTextEdit::ExtraSelection selection;
QColor lineColor = QColor(190, 144, 212);
selection.format.setBackground(lineColor);
selection.format.setProperty(QTextFormat::FullWidthSelection, true);
selection.cursor = ui->decoTextEdit->textCursor();
selection.cursor.clearSelection();
extraSelections.append(selection);
}
}
ui->decoTextEdit->setExtraSelections(extraSelections);
}
MemoryWidget::~MemoryWidget() {}
void MemoryWidget::setup()
{
setScrollMode();
const QString off = core->cmd("afo entry0").trimmed();
RVA offset = off.toULongLong(0, 16);
updateViews(offset);
//refreshDisasm();
//refreshHexdump(off);
//create_graph(off);
get_refs_data(offset);
//setFcnName(off);
}
void MemoryWidget::refresh()
{
setScrollMode();
// TODO: honor the offset
updateViews(RVA_INVALID);
}
/*
* Content management functions
*/
void MemoryWidget::fillPlugins()
{
// Fill the plugins combo for the hexdump sidebar
ui->hexArchComboBox_2->insertItems(0, core->getAsmPluginNames());
}
void MemoryWidget::refreshHexdump(const QString &where)
{
RCoreLocked lcore = this->core->core(); RCoreLocked lcore = this->core->core();
// Prevent further scroll // Prevent further scroll
disconnect(this->hexASCIIText->verticalScrollBar(), SIGNAL(valueChanged(int)), this, SLOT(hexScrolled())); disconnect(this->hexASCIIText->verticalScrollBar(), SIGNAL(valueChanged(int)), this, SLOT(hexScrolled()));
@ -314,15 +197,8 @@ void MemoryWidget::refreshHexdump(const QString &where)
QString s = ""; QString s = "";
if (!where.isEmpty())
{
this->core->cmd("ss " + where);
}
// Add first the hexdump at block size -- // Add first the hexdump at block size --
this->core->cmd("ss-" + this->core->itoa(hexdumpLength)); QList<QString> ret = this->get_hexdump(RAddressString(addr - hexdumpLength));
//s = this->normalize_addr(this->core->cmd("s"));
QList<QString> ret = this->get_hexdump("");
hexdumpBottomOffset = lcore->offset; hexdumpBottomOffset = lcore->offset;
this->hexOffsetText->setPlainText(ret[0]); this->hexOffsetText->setPlainText(ret[0]);
@ -330,12 +206,9 @@ void MemoryWidget::refreshHexdump(const QString &where)
this->hexASCIIText->setPlainText(ret[2]); this->hexASCIIText->setPlainText(ret[2]);
this->resizeHexdump(); this->resizeHexdump();
// Add then the hexdump at block size ++
this->core->cmd("ss+" + this->core->itoa(hexdumpLength));
// Get address to move cursor to later // Get address to move cursor to later
//QString s = "0x0" + this->core->cmd("s").split("0x")[1].trimmed();
s = this->normalize_addr(this->core->cmd("s")); s = this->normalize_addr(this->core->cmd("s"));
ret = this->get_hexdump(""); ret = this->get_hexdump(RAddressString(addr));
hexdumpBottomOffset = lcore->offset; hexdumpBottomOffset = lcore->offset;
this->hexOffsetText->append(ret[0]); this->hexOffsetText->append(ret[0]);
@ -353,9 +226,20 @@ void MemoryWidget::refreshHexdump(const QString &where)
this->hexOffsetText->moveCursor(QTextCursor::EndOfLine, QTextCursor::MoveAnchor); this->hexOffsetText->moveCursor(QTextCursor::EndOfLine, QTextCursor::MoveAnchor);
connect(this->hexASCIIText->verticalScrollBar(), SIGNAL(valueChanged(int)), this, SLOT(hexScrolled())); connect(this->hexASCIIText->verticalScrollBar(), SIGNAL(valueChanged(int)), this, SLOT(hexScrolled()));
} }
QList<QString> MemoryWidget::get_hexdump(const QString &offset) /*
* Content management functions
*/
void HexdumpWidget::fillPlugins()
{
// Fill the plugins combo for the hexdump sidebar
ui->hexArchComboBox_2->insertItems(0, core->getAsmPluginNames());
}
QList<QString> HexdumpWidget::get_hexdump(const QString &offset)
{ {
RCoreLocked lcore = this->core->core(); RCoreLocked lcore = this->core->core();
QList<QString> ret; QList<QString> ret;
@ -424,14 +308,14 @@ QList<QString> MemoryWidget::get_hexdump(const QString &offset)
return ret; return ret;
} }
void MemoryWidget::resizeHexdump() void HexdumpWidget::resizeHexdump()
{ {
this->hexOffsetText->setMinimumWidth(this->hexOffsetText->document()->size().width()); this->hexOffsetText->setMinimumWidth(this->hexOffsetText->document()->size().width());
this->hexHexText->setMinimumWidth(this->hexHexText->document()->size().width()); this->hexHexText->setMinimumWidth(this->hexHexText->document()->size().width());
this->hexASCIIText->setMinimumWidth(this->hexASCIIText->document()->size().width()); this->hexASCIIText->setMinimumWidth(this->hexASCIIText->document()->size().width());
} }
void MemoryWidget::hexScrolled() void HexdumpWidget::hexScrolled()
{ {
RCoreLocked lcore = this->core->core(); RCoreLocked lcore = this->core->core();
QScrollBar *sb = this->hexASCIIText->verticalScrollBar(); QScrollBar *sb = this->hexASCIIText->verticalScrollBar();
@ -527,7 +411,7 @@ void MemoryWidget::hexScrolled()
} }
} }
void MemoryWidget::on_hexHexText_2_selectionChanged() void HexdumpWidget::on_hexHexText_2_selectionChanged()
{ {
// Get selected partsing type // Get selected partsing type
QString parsing = ui->codeCombo_2->currentText(); QString parsing = ui->codeCombo_2->currentText();
@ -609,12 +493,12 @@ void MemoryWidget::on_hexHexText_2_selectionChanged()
} }
} }
void MemoryWidget::on_hexArchComboBox_2_currentTextChanged(const QString &/*arg1*/) void HexdumpWidget::on_hexArchComboBox_2_currentTextChanged(const QString &/*arg1*/)
{ {
on_hexHexText_2_selectionChanged(); on_hexHexText_2_selectionChanged();
} }
void MemoryWidget::on_hexBitsComboBox_2_currentTextChanged(const QString &/*arg1*/) void HexdumpWidget::on_hexBitsComboBox_2_currentTextChanged(const QString &/*arg1*/)
{ {
on_hexHexText_2_selectionChanged(); on_hexHexText_2_selectionChanged();
} }
@ -623,7 +507,7 @@ void MemoryWidget::on_hexBitsComboBox_2_currentTextChanged(const QString &/*arg1
* Context menu functions * Context menu functions
*/ */
void MemoryWidget::showHexdumpContextMenu(const QPoint &pt) void HexdumpWidget::showHexdumpContextMenu(const QPoint &pt)
{ {
// Set Hexdump popup menu // Set Hexdump popup menu
QMenu *menu = ui->hexHexText_2->createStandardContextMenu(); QMenu *menu = ui->hexHexText_2->createStandardContextMenu();
@ -650,7 +534,7 @@ void MemoryWidget::showHexdumpContextMenu(const QPoint &pt)
delete menu; delete menu;
} }
void MemoryWidget::showHexASCIIContextMenu(const QPoint &pt) void HexdumpWidget::showHexASCIIContextMenu(const QPoint &pt)
{ {
// Set Hex ASCII popup menu // Set Hex ASCII popup menu
QMenu *menu = ui->hexASCIIText_2->createStandardContextMenu(); QMenu *menu = ui->hexASCIIText_2->createStandardContextMenu();
@ -676,61 +560,11 @@ void MemoryWidget::showHexASCIIContextMenu(const QPoint &pt)
menu->exec(ui->hexASCIIText_2->mapToGlobal(pt)); menu->exec(ui->hexASCIIText_2->mapToGlobal(pt));
delete menu; delete menu;
} }
void MemoryWidget::on_showInfoButton_2_clicked()
{
if (ui->showInfoButton_2->isChecked())
{
ui->fcnGraphTabWidget->hide();
ui->showInfoButton_2->setArrowType(Qt::RightArrow);
}
else
{
ui->fcnGraphTabWidget->show();
ui->showInfoButton_2->setArrowType(Qt::DownArrow);
}
}
void MemoryWidget::on_offsetToolButton_clicked()
{
if (ui->offsetToolButton->isChecked())
{
ui->offsetTreeWidget->hide();
ui->offsetToolButton->setArrowType(Qt::RightArrow);
}
else
{
ui->offsetTreeWidget->show();
ui->offsetToolButton->setArrowType(Qt::DownArrow);
}
}
/*
* Show widgets
*/
void MemoryWidget::cycleViews()
{
switch (ui->memTabWidget->currentIndex())
{
case 0:
// Show hexdump
ui->hexButton->setChecked(true);
on_hexButton_clicked();
break;
case 1:
// Show disasm
ui->disasButton->setChecked(true);
on_disasButton_clicked();
break;
}
}
/* /*
* Actions callback functions * Actions callback functions
*/ */
void MemoryWidget::on_actionSettings_menu_1_triggered() void HexdumpWidget::on_actionSettings_menu_1_triggered()
{ {
bool ok = true; bool ok = true;
@ -746,7 +580,7 @@ void MemoryWidget::on_actionSettings_menu_1_triggered()
} }
} }
void MemoryWidget::setFonts(QFont font) void HexdumpWidget::setFonts(QFont font)
{ {
//ui->disasTextEdit_2->setFont(font); //ui->disasTextEdit_2->setFont(font);
// the user clicked OK and font is set to the font the user selected // the user clicked OK and font is set to the font the user selected
@ -754,23 +588,9 @@ void MemoryWidget::setFonts(QFont font)
ui->hexOffsetText_2->setFont(font); ui->hexOffsetText_2->setFont(font);
ui->hexHexText_2->setFont(font); ui->hexHexText_2->setFont(font);
ui->hexASCIIText_2->setFont(font); ui->hexASCIIText_2->setFont(font);
ui->previewTextEdit->setFont(font);
ui->decoTextEdit->setFont(font);
} }
void MemoryWidget::on_actionHideDisasm_side_panel_triggered() void HexdumpWidget::on_actionHideHexdump_side_panel_triggered()
{
if (ui->memSideTabWidget_2->isVisible())
{
ui->memSideTabWidget_2->hide();
}
else
{
ui->memSideTabWidget_2->show();
}
}
void MemoryWidget::on_actionHideHexdump_side_panel_triggered()
{ {
if (ui->hexSideTab_2->isVisible()) if (ui->hexSideTab_2->isVisible())
{ {
@ -782,35 +602,8 @@ void MemoryWidget::on_actionHideHexdump_side_panel_triggered()
} }
} }
void MemoryWidget::on_actionHideGraph_side_panel_triggered()
{
if (ui->graphTreeWidget_2->isVisible())
{
ui->graphTreeWidget_2->hide();
}
else
{
ui->graphTreeWidget_2->show();
}
}
/* /*void HexdumpWidget::on_actionSend_to_Notepad_triggered()
* Buttons callback functions
*/
void MemoryWidget::on_disasButton_clicked()
{
ui->memTabWidget->setCurrentIndex(0);
ui->memSideTabWidget_2->setCurrentIndex(0);
}
void MemoryWidget::on_hexButton_clicked()
{
ui->memTabWidget->setCurrentIndex(1);
ui->memSideTabWidget_2->setCurrentIndex(1);
}
/*void MemoryWidget::on_actionSend_to_Notepad_triggered()
{ {
QTextCursor cursor = ui->disasTextEdit_2->textCursor(); QTextCursor cursor = ui->disasTextEdit_2->textCursor();
QString text = cursor.selectedText(); QString text = cursor.selectedText();
@ -818,89 +611,49 @@ void MemoryWidget::on_hexButton_clicked()
// this->main->sendToNotepad(text); // this->main->sendToNotepad(text);
}*/ }*/
void MemoryWidget::on_action8columns_triggered() void HexdumpWidget::on_action8columns_triggered()
{ {
this->core->setConfig("hex.cols", 8); this->core->setConfig("hex.cols", 8);
this->refreshHexdump(); this->refresh();
} }
void MemoryWidget::on_action16columns_triggered() void HexdumpWidget::on_action16columns_triggered()
{ {
this->core->setConfig("hex.cols", 16); this->core->setConfig("hex.cols", 16);
this->refreshHexdump(); this->refresh();
} }
void MemoryWidget::on_action4columns_triggered() void HexdumpWidget::on_action4columns_triggered()
{ {
this->core->setConfig("hex.cols", 4); this->core->setConfig("hex.cols", 4);
this->refreshHexdump(); this->refresh();
} }
void MemoryWidget::on_action32columns_triggered() void HexdumpWidget::on_action32columns_triggered()
{ {
this->core->setConfig("hex.cols", 32); this->core->setConfig("hex.cols", 32);
this->refreshHexdump(); this->refresh();
} }
void MemoryWidget::on_action64columns_triggered() void HexdumpWidget::on_action64columns_triggered()
{ {
this->core->setConfig("hex.cols", 64); this->core->setConfig("hex.cols", 64);
this->refreshHexdump(); this->refresh();
} }
void MemoryWidget::on_action2columns_triggered() void HexdumpWidget::on_action2columns_triggered()
{ {
this->core->setConfig("hex.cols", 2); this->core->setConfig("hex.cols", 2);
this->refreshHexdump(); this->refresh();
} }
void MemoryWidget::on_action1column_triggered() void HexdumpWidget::on_action1column_triggered()
{ {
this->core->setConfig("hex.cols", 1); this->core->setConfig("hex.cols", 1);
this->refreshHexdump(); this->refresh();
} }
void MemoryWidget::on_xreFromTreeWidget_2_itemDoubleClicked(QTreeWidgetItem *item, int /*column*/) void HexdumpWidget::on_codeCombo_2_currentTextChanged(const QString &arg1)
{
XrefDescription xref = item->data(0, Qt::UserRole).value<XrefDescription>();
this->core->seek(xref.to);
}
void MemoryWidget::on_xrefToTreeWidget_2_itemDoubleClicked(QTreeWidgetItem *item, int /*column*/)
{
XrefDescription xref = item->data(0, Qt::UserRole).value<XrefDescription>();
this->core->seek(xref.from);
}
void MemoryWidget::on_xrefFromToolButton_2_clicked()
{
if (ui->xrefFromToolButton_2->isChecked())
{
ui->xreFromTreeWidget_2->hide();
ui->xrefFromToolButton_2->setArrowType(Qt::RightArrow);
}
else
{
ui->xreFromTreeWidget_2->show();
ui->xrefFromToolButton_2->setArrowType(Qt::DownArrow);
}
}
void MemoryWidget::on_xrefToToolButton_2_clicked()
{
if (ui->xrefToToolButton_2->isChecked())
{
ui->xrefToTreeWidget_2->hide();
ui->xrefToToolButton_2->setArrowType(Qt::RightArrow);
}
else
{
ui->xrefToTreeWidget_2->show();
ui->xrefToToolButton_2->setArrowType(Qt::DownArrow);
}
}
void MemoryWidget::on_codeCombo_2_currentTextChanged(const QString &arg1)
{ {
if (arg1 == "Dissasembly") if (arg1 == "Dissasembly")
{ {
@ -914,132 +667,7 @@ void MemoryWidget::on_codeCombo_2_currentTextChanged(const QString &arg1)
} }
} }
void MemoryWidget::get_refs_data(RVA addr) QString HexdumpWidget::normalize_addr(QString addr)
{
// refs = calls q hace esa funcion
QList<XrefDescription> refs = core->getXRefs(addr, false, false);
// xrefs = calls a esa funcion
QList<XrefDescription> xrefs = core->getXRefs(addr, true, false);
// Data for the disasm side graph
QList<int> data;
//qDebug() << "Refs:" << refs.size();
data << refs.size();
//qDebug() << "XRefs:" << xrefs.size();
data << xrefs.size();
//qDebug() << "CC: " << this->core->fcnCyclomaticComplexity(offset.toLong(&ok, 16));
//data << this->core->fcnCyclomaticComplexity(offset.toLong(&ok, 16));
data << this->core->getCycloComplex(addr);
//qDebug() << "BB: " << this->core->fcnBasicBlockCount(offset.toLong(&ok, 16));
data << this->core->fcnBasicBlockCount(addr);
data << this->core->fcnEndBbs(addr);
//qDebug() << "MEOW: " + this->core->fcnEndBbs(offset);
// Update disasm side bar
this->fill_refs(refs, xrefs, data);
}
void MemoryWidget::fill_refs(QList<XrefDescription> refs, QList<XrefDescription> xrefs, QList<int> graph_data)
{
this->xreFromTreeWidget_2->clear();
for (int i = 0; i < refs.size(); ++i)
{
XrefDescription xref = refs[i];
QTreeWidgetItem *tempItem = new QTreeWidgetItem();
tempItem->setText(0, RAddressString(xref.to));
tempItem->setText(1, core->disassembleSingleInstruction(xref.from));
tempItem->setData(0, Qt::UserRole, QVariant::fromValue(xref));
QString tooltip = this->core->cmd("pdi 10 @ " + QString::number(xref.to)).trimmed();
tempItem->setToolTip(0, tooltip);
tempItem->setToolTip(1, tooltip);
this->xreFromTreeWidget_2->insertTopLevelItem(0, tempItem);
}
// Adjust columns to content
int count = this->xreFromTreeWidget_2->columnCount();
for (int i = 0; i != count; ++i)
{
this->xreFromTreeWidget_2->resizeColumnToContents(i);
}
this->xrefToTreeWidget_2->clear();
for (int i = 0; i < xrefs.size(); ++i)
{
XrefDescription xref = xrefs[i];
QTreeWidgetItem *tempItem = new QTreeWidgetItem();
tempItem->setText(0, RAddressString(xref.from));
tempItem->setText(1, core->disassembleSingleInstruction(xref.from));
tempItem->setData(0, Qt::UserRole, QVariant::fromValue(xref));
QString tooltip = this->core->cmd("pdi 10 @ " + QString::number(xref.from)).trimmed();
tempItem->setToolTip(0, this->core->cmd("pdi 10 @ " + tooltip).trimmed());
tempItem->setToolTip(1, this->core->cmd("pdi 10 @ " + tooltip).trimmed());
this->xrefToTreeWidget_2->insertTopLevelItem(0, tempItem);
}
// Adjust columns to content
int count2 = this->xrefToTreeWidget_2->columnCount();
for (int i = 0; i != count2; ++i)
{
this->xrefToTreeWidget_2->resizeColumnToContents(i);
}
// Add data to HTML Polar functions graph
QFile html(":/html/fcn_graph.html");
if (!html.open(QIODevice::ReadOnly))
{
QMessageBox::information(this, "error", html.errorString());
}
QString code = html.readAll();
html.close();
QString data = QString("\"%1\", \"%2\", \"%3\", \"%4\", \"%5\"").arg(graph_data.at(2)).arg(graph_data.at(0)).arg(graph_data.at(3)).arg(graph_data.at(1)).arg(graph_data.at(4));
code.replace("MEOW", data);
ui->fcnWebView->setHtml(code);
// Add data to HTML Radar functions graph
QFile html2(":/html/fcn_radar.html");
if (!html2.open(QIODevice::ReadOnly))
{
QMessageBox::information(this, "error", html.errorString());
}
QString code2 = html2.readAll();
html2.close();
QString data2 = QString("%1, %2, %3, %4, %5").arg(graph_data.at(2)).arg(graph_data.at(0)).arg(graph_data.at(3)).arg(graph_data.at(1)).arg(graph_data.at(4));
code2.replace("MEOW", data2);
ui->radarGraphWebView->setHtml(code2);
}
void MemoryWidget::fillOffsetInfo(QString off)
{
ui->offsetTreeWidget->clear();
QString raw = this->core->getOffsetInfo(off);
QList<QString> lines = raw.split("\n", QString::SkipEmptyParts);
foreach (QString line, lines)
{
QList<QString> eles = line.split(":", QString::SkipEmptyParts);
QTreeWidgetItem *tempItem = new QTreeWidgetItem();
tempItem->setText(0, eles.at(0).toUpper());
tempItem->setText(1, eles.at(1));
ui->offsetTreeWidget->insertTopLevelItem(0, tempItem);
}
// Adjust column to contents
int count = ui->offsetTreeWidget->columnCount();
for (int i = 0; i != count; ++i)
{
ui->offsetTreeWidget->resizeColumnToContents(i);
}
// Add opcode description
QStringList description = this->core->cmd("?d. @ " + off).split(": ");
if (description.length() >= 2)
{
ui->opcodeDescText->setPlainText("# " + description[0] + ":\n" + description[1]);
}
}
QString MemoryWidget::normalize_addr(QString addr)
{ {
QString base = this->core->cmd("s").split("0x")[1].trimmed(); QString base = this->core->cmd("s").split("0x")[1].trimmed();
int len = base.length(); int len = base.length();
@ -1057,26 +685,7 @@ QString MemoryWidget::normalize_addr(QString addr)
} }
} }
void MemoryWidget::setFcnName(RVA addr) QString HexdumpWidget::normalizeAddr(QString addr)
{
RAnalFunction *fcn;
QString addr_string;
fcn = this->core->functionAt(addr);
if (fcn)
{
QString segment = this->core->cmd("S. @ " + QString::number(addr)).split(" ").last();
addr_string = segment.trimmed() + ":" + fcn->name;
}
else
{
addr_string = core->cmdFunctionAt(addr);
}
ui->fcnNameEdit->setText(addr_string);
}
QString MemoryWidget::normalizeAddr(QString addr)
{ {
QString base = addr.split("0x")[1].trimmed(); QString base = addr.split("0x")[1].trimmed();
int len = base.length(); int len = base.length();
@ -1094,38 +703,7 @@ QString MemoryWidget::normalizeAddr(QString addr)
} }
} }
void MemoryWidget::setMiniGraph(QString at) void HexdumpWidget::on_hexSideTab_2_currentChanged(int /*index*/)
{
QString dot = this->core->getSimpleGraph(at);
//QString dot = this->core->cmd("agc " + at);
// Add data to HTML Polar functions graph
QFile html(":/html/graph.html");
if (!html.open(QIODevice::ReadOnly))
{
QMessageBox::information(this, "error", html.errorString());
}
QString code = html.readAll();
html.close();
code.replace("MEOW", dot);
ui->webSimpleGraph->setHtml(code);
}
void MemoryWidget::on_polarToolButton_clicked()
{
ui->radarToolButton->setChecked(false);
ui->fcnGraphTabWidget->setCurrentIndex(0);
}
void MemoryWidget::on_radarToolButton_clicked()
{
ui->polarToolButton->setChecked(false);
ui->fcnGraphTabWidget->setCurrentIndex(1);
}
void MemoryWidget::on_hexSideTab_2_currentChanged(int /*index*/)
{ {
/* /*
if (index == 2) { if (index == 2) {
@ -1144,50 +722,21 @@ void MemoryWidget::on_hexSideTab_2_currentChanged(int /*index*/)
*/ */
} }
void MemoryWidget::on_memSideToolButton_clicked() void HexdumpWidget::on_memSideToolButton_clicked()
{ {
if (ui->memSideToolButton->isChecked()) if (ui->memSideToolButton->isChecked())
{ {
ui->memSideTabWidget_2->hide();
ui->hexSideTab_2->hide(); ui->hexSideTab_2->hide();
ui->memSideToolButton->setIcon(QIcon(":/img/icons/left_light.svg")); ui->memSideToolButton->setIcon(QIcon(":/img/icons/left_light.svg"));
} }
else else
{ {
ui->memSideTabWidget_2->show();
ui->hexSideTab_2->show(); ui->hexSideTab_2->show();
ui->memSideToolButton->setIcon(QIcon(":/img/icons/right_light.svg")); ui->memSideToolButton->setIcon(QIcon(":/img/icons/right_light.svg"));
} }
} }
void MemoryWidget::on_previewToolButton_clicked() void HexdumpWidget::resizeEvent(QResizeEvent *event)
{
ui->memPreviewTab->setCurrentIndex(0);
}
void MemoryWidget::on_decoToolButton_clicked()
{
ui->memPreviewTab->setCurrentIndex(1);
}
void MemoryWidget::on_simpleGrapgToolButton_clicked()
{
ui->memPreviewTab->setCurrentIndex(2);
}
void MemoryWidget::on_previewToolButton_2_clicked()
{
if (ui->previewToolButton_2->isChecked())
{
ui->frame_3->setVisible(true);
}
else
{
ui->frame_3->setVisible(false);
}
}
void MemoryWidget::resizeEvent(QResizeEvent *event)
{ {
// FIXME // FIXME
/* /*
@ -1222,13 +771,7 @@ void MemoryWidget::resizeEvent(QResizeEvent *event)
QDockWidget::resizeEvent(event); QDockWidget::resizeEvent(event);
} }
void MemoryWidget::setScrollMode() void HexdumpWidget::on_copyMD5_clicked()
{
qhelpers::setVerticalScrollMode(ui->xreFromTreeWidget_2);
qhelpers::setVerticalScrollMode(ui->xrefToTreeWidget_2);
}
void MemoryWidget::on_copyMD5_clicked()
{ {
QString md5 = ui->bytesMD5->text(); QString md5 = ui->bytesMD5->text();
QClipboard *clipboard = QApplication::clipboard(); QClipboard *clipboard = QApplication::clipboard();
@ -1237,7 +780,7 @@ void MemoryWidget::on_copyMD5_clicked()
// this->main->addOutput("MD5 copied to clipboard: " + md5); // this->main->addOutput("MD5 copied to clipboard: " + md5);
} }
void MemoryWidget::on_copySHA1_clicked() void HexdumpWidget::on_copySHA1_clicked()
{ {
QString sha1 = ui->bytesSHA1->text(); QString sha1 = ui->bytesSHA1->text();
QClipboard *clipboard = QApplication::clipboard(); QClipboard *clipboard = QApplication::clipboard();
@ -1246,19 +789,7 @@ void MemoryWidget::on_copySHA1_clicked()
// this->main->addOutput("SHA1 copied to clipboard: " + sha1); // this->main->addOutput("SHA1 copied to clipboard: " + sha1);
} }
void MemoryWidget::switchTheme(bool dark) void HexdumpWidget::selectHexPreview()
{
if (dark)
{
ui->webSimpleGraph->page()->setBackgroundColor(QColor(64, 64, 64));
}
else
{
ui->webSimpleGraph->page()->setBackgroundColor(QColor(255, 255, 255));
}
}
void MemoryWidget::selectHexPreview()
{ {
// Pre-select arch and bits in the hexdump sidebar // Pre-select arch and bits in the hexdump sidebar
QString arch = this->core->cmd("e asm.arch").trimmed(); QString arch = this->core->cmd("e asm.arch").trimmed();
@ -1277,51 +808,7 @@ void MemoryWidget::selectHexPreview()
} }
} }
void MemoryWidget::seek_back() void HexdumpWidget::showOffsets(bool show)
{
//this->main->add_debug_output("Back!");
// FIXME
// this->main->backButton_clicked();
}
void MemoryWidget::on_memTabWidget_currentChanged(int /*index*/)
{
/*this->main->add_debug_output("Update index: " + QString::number(index) + " to function: " + RAddressString(main->getCursorAddress()));
this->main->add_debug_output("Last disasm: " + RAddressString(this->last_disasm_fcn));
this->main->add_debug_output("Last graph: " + RAddressString(this->last_graph_fcn));
this->main->add_debug_output("Last hexdump: " + RAddressString(this->last_hexdump_fcn));*/
this->updateViews(RVA_INVALID);
}
void MemoryWidget::updateViews(RVA offset)
{
// Update only the selected view to improve performance
int index = ui->memTabWidget->tabBar()->currentIndex();
// Anyway updateViews will die after break this widget.
// FIXME? One cursor per widget ? (if not synced)
// RVA cursor_addr = main->getCursorAddress();
// QString cursor_addr_string = RAddressString(cursor_addr);
QString cursor_addr_string = core->cmd("s");
RVA cursor_addr = cursor_addr_string.toULongLong();
if (offset != RVA_INVALID)
next_disasm_top_offset = offset;
if (index == 1)
{
// Hex
if (this->last_hexdump_fcn != cursor_addr)
{
this->refreshHexdump(cursor_addr_string);
this->last_hexdump_fcn = cursor_addr;
}
}
// TODO WTF
}
void MemoryWidget::showOffsets(bool show)
{ {
if (show) if (show)
{ {

106
src/widgets/HexdumpWidget.h Normal file
View File

@ -0,0 +1,106 @@
#ifndef HEXDUMPWIDGET_H
#define HEXDUMPWIDGET_H
#include <QDebug>
#include <QTextEdit>
#include <QDockWidget>
#include <QTreeWidget>
#include <QTabWidget>
#include <QWebEngineView>
#include <QUrl>
#include <QPlainTextEdit>
#include <QMouseEvent>
#include <memory>
#include "cutter.h"
#include "utils/Highlighter.h"
#include "utils/HexAsciiHighlighter.h"
#include "utils/HexHighlighter.h"
#include "Dashboard.h"
namespace Ui
{
class HexdumpWidget;
}
class HexdumpWidget : public QDockWidget
{
Q_OBJECT
public:
explicit HexdumpWidget(const QString &title, QWidget *parent = nullptr, Qt::WindowFlags flags = 0);
explicit HexdumpWidget(QWidget *parent = nullptr, Qt::WindowFlags flags = 0);
~HexdumpWidget();
QTextEdit *hexOffsetText;
QTextEdit *hexASCIIText;
QTextEdit *hexHexText;
QPlainTextEdit *hexDisasTextEdit;
Highlighter *highlighter;
signals:
void fontChanged(QFont font);
public slots:
void fillPlugins();
QString normalize_addr(QString addr);
QString normalizeAddr(QString addr);
void selectHexPreview();
void showOffsets(bool show);
protected:
void resizeEvent(QResizeEvent *event) override;
private:
std::unique_ptr<Ui::HexdumpWidget> ui;
CutterCore *core;
ut64 hexdumpBottomOffset;
void refresh(RVA addr = RVA_INVALID);
private slots:
void on_seekChanged(RVA addr);
void highlightHexCurrentLine();
void setFonts(QFont font);
void highlightHexWords(const QString &str);
void on_actionSettings_menu_1_triggered();
void on_actionHideHexdump_side_panel_triggered();
void showHexdumpContextMenu(const QPoint &pt);
void showHexASCIIContextMenu(const QPoint &pt);
void on_hexHexText_2_selectionChanged();
void on_hexArchComboBox_2_currentTextChanged(const QString &arg1);
void on_hexBitsComboBox_2_currentTextChanged(const QString &arg1);
void on_action1column_triggered();
void on_action2columns_triggered();
void on_action4columns_triggered();
void on_action8columns_triggered();
void on_action16columns_triggered();
void on_action32columns_triggered();
void on_action64columns_triggered();
void resizeHexdump();
void hexScrolled();
QList<QString> get_hexdump(const QString &offset);
void on_codeCombo_2_currentTextChanged(const QString &arg1);
void on_hexSideTab_2_currentChanged(int index);
void on_memSideToolButton_clicked();
void on_copyMD5_clicked();
void on_copySHA1_clicked();
};
#endif // HEXDUMPWIDGET_H

1154
src/widgets/HexdumpWidget.ui Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,161 +0,0 @@
#ifndef MEMORYWIDGET_H
#define MEMORYWIDGET_H
#include <QDebug>
#include <QTextEdit>
#include <QDockWidget>
#include <QTreeWidget>
#include <QTabWidget>
#include <QWebEngineView>
#include <QUrl>
#include <QPlainTextEdit>
#include <QMouseEvent>
#include <memory>
#include "cutter.h"
#include "utils/Highlighter.h"
#include "utils/HexAsciiHighlighter.h"
#include "utils/HexHighlighter.h"
#include "Dashboard.h"
namespace Ui
{
class MemoryWidget;
}
class MemoryWidget : public DockWidget
{
Q_OBJECT
public:
explicit MemoryWidget();
~MemoryWidget();
void setup() override;
void refresh() override;
QTextEdit *hexOffsetText;
QPlainTextEdit *hexDisasTextEdit;
QTextEdit *hexASCIIText;
QTextEdit *hexHexText;
QTreeWidget *xrefToTreeWidget_2;
QTreeWidget *xreFromTreeWidget_2;
QTabWidget *memTabWidget;
QWebEngineView *histoWebView;
Highlighter *highlighter;
Highlighter *highlighter_5;
AsciiHighlighter *ascii_highlighter;
HexHighlighter *hex_highlighter;
Highlighter *preview_highlighter;
Highlighter *deco_highlighter;
signals:
void fontChanged(QFont font);
public slots:
void fillPlugins();
void refreshHexdump(const QString &where = QString());
void fill_refs(QList<XrefDescription> refs, QList<XrefDescription> xrefs, QList<int> graph_data);
void fillOffsetInfo(QString off);
QString normalize_addr(QString addr);
QString normalizeAddr(QString addr);
void setMiniGraph(QString at);
void switchTheme(bool dark);
void selectHexPreview();
void showOffsets(bool show);
protected:
void resizeEvent(QResizeEvent *event) override;
private:
std::unique_ptr<Ui::MemoryWidget> ui;
CutterCore *core;
ut64 hexdumpTopOffset;
ut64 hexdumpBottomOffset;
QString last_fcn;
RVA disasm_top_offset;
RVA next_disasm_top_offset;
RVA last_graph_fcn;
RVA last_hexdump_fcn;
void setFcnName(RVA addr);
void get_refs_data(RVA addr);
void setScrollMode();
bool loadMoreDisassembly();
private slots:
void on_cursorAddressChanged(RVA addr);
void on_seekChanged(RVA addr);
void highlightHexCurrentLine();
void highlightPreviewCurrentLine();
void highlightDecoCurrentLine();
void setFonts(QFont font);
void highlightHexWords(const QString &str);
void on_showInfoButton_2_clicked();
void on_actionSettings_menu_1_triggered();
void on_actionHideDisasm_side_panel_triggered();
void on_actionHideHexdump_side_panel_triggered();
void on_actionHideGraph_side_panel_triggered();
void on_disasButton_clicked();
void on_hexButton_clicked();
void showHexdumpContextMenu(const QPoint &pt);
void showHexASCIIContextMenu(const QPoint &pt);
void on_hexHexText_2_selectionChanged();
void on_hexArchComboBox_2_currentTextChanged(const QString &arg1);
void on_hexBitsComboBox_2_currentTextChanged(const QString &arg1);
void on_action1column_triggered();
void on_action2columns_triggered();
void on_action4columns_triggered();
void on_action8columns_triggered();
void on_action16columns_triggered();
void on_action32columns_triggered();
void on_action64columns_triggered();
void resizeHexdump();
void hexScrolled();
QList<QString> get_hexdump(const QString &offset);
void updateViews(RVA offset = RVA_INVALID);
void cycleViews();
void on_xreFromTreeWidget_2_itemDoubleClicked(QTreeWidgetItem *item, int column);
void on_xrefToTreeWidget_2_itemDoubleClicked(QTreeWidgetItem *item, int column);
void on_xrefFromToolButton_2_clicked();
void on_xrefToToolButton_2_clicked();
void on_codeCombo_2_currentTextChanged(const QString &arg1);
void on_offsetToolButton_clicked();
void on_polarToolButton_clicked();
void on_radarToolButton_clicked();
void on_hexSideTab_2_currentChanged(int index);
void on_memSideToolButton_clicked();
void on_previewToolButton_clicked();
void on_decoToolButton_clicked();
void on_previewToolButton_2_clicked();
void on_copyMD5_clicked();
void on_copySHA1_clicked();
void on_simpleGrapgToolButton_clicked();
void seek_back();
void on_memTabWidget_currentChanged(int index);
};
#endif // MEMORYWIDGET_H

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,175 @@
#include "PreviewWidget.h"
#include "ui_PreviewWidget.h"
#include "DisassemblerGraphView.h"
#include "utils/Helpers.h"
#include <QClipboard>
#include <QWebEngineSettings>
#include <QWebEngineProfile>
#include <QSettings>
PreviewWidget::PreviewWidget(QWidget *parent, Qt::WindowFlags flags) :
QDockWidget(parent, flags),
ui(new Ui::PreviewWidget),
core(CutterCore::getInstance())
{
ui->setupUi(this);
// Highlight current line on previews and decompiler
connect(ui->previewTextEdit, SIGNAL(cursorPositionChanged()), this, SLOT(highlightPreviewCurrentLine()));
connect(ui->decoTextEdit, SIGNAL(cursorPositionChanged()), this, SLOT(highlightDecoCurrentLine()));
// Hide tabs
QTabBar *preTab = ui->memPreviewTab->tabBar();
preTab->setVisible(false);
connect(core, SIGNAL(seekChanged(RVA)), this, SLOT(on_seekChanged(RVA)));
}
PreviewWidget::PreviewWidget(const QString &title, QWidget *parent, Qt::WindowFlags flags) :
PreviewWidget(parent, flags)
{
setWindowTitle(title);
}
void PreviewWidget::on_seekChanged(RVA addr)
{
refresh(addr);
}
void PreviewWidget::highlightPreviewCurrentLine()
{
QList<QTextEdit::ExtraSelection> extraSelections;
if (ui->previewTextEdit->toPlainText() != "")
{
if (ui->previewTextEdit->isReadOnly())
{
QTextEdit::ExtraSelection selection;
QColor lineColor = QColor(190, 144, 212);
selection.format.setBackground(lineColor);
selection.format.setProperty(QTextFormat::FullWidthSelection, true);
selection.cursor = ui->previewTextEdit->textCursor();
selection.cursor.clearSelection();
extraSelections.append(selection);
}
}
ui->previewTextEdit->setExtraSelections(extraSelections);
}
void PreviewWidget::highlightDecoCurrentLine()
{
QList<QTextEdit::ExtraSelection> extraSelections;
if (ui->decoTextEdit->toPlainText() != "")
{
if (ui->decoTextEdit->isReadOnly())
{
QTextEdit::ExtraSelection selection;
QColor lineColor = QColor(190, 144, 212);
selection.format.setBackground(lineColor);
selection.format.setProperty(QTextFormat::FullWidthSelection, true);
selection.cursor = ui->decoTextEdit->textCursor();
selection.cursor.clearSelection();
extraSelections.append(selection);
}
}
ui->decoTextEdit->setExtraSelections(extraSelections);
}
PreviewWidget::~PreviewWidget() {}
void PreviewWidget::refresh(RVA addr)
{
if (addr == RVA_INVALID)
{
addr = core->getSeekAddr();
}
setMiniGraph(RAddressString(addr));
// TODO: pseudo, ...
}
/*
* Actions callback functions
*/
void PreviewWidget::on_actionSettings_menu_1_triggered()
{
bool ok = true;
QFont font = QFont("Monospace", 8);
// TODO Use global configuration
//QFont font = QFontDialog::getFont(&ok, ui->disasTextEdit_2->font(), this);
if (ok)
{
setFonts(font);
emit fontChanged(font);
}
}
void PreviewWidget::setFonts(QFont font)
{
ui->previewTextEdit->setFont(font);
ui->decoTextEdit->setFont(font);
}
/*
* Buttons callback functions
*/
void PreviewWidget::setMiniGraph(QString at)
{
QString dot = this->core->getSimpleGraph(at);
//QString dot = this->core->cmd("agc " + at);
// Add data to HTML Polar functions graph
QFile html(":/html/graph.html");
if (!html.open(QIODevice::ReadOnly))
{
QMessageBox::information(this, "error", html.errorString());
}
QString code = html.readAll();
html.close();
code.replace("MEOW", dot);
ui->webSimpleGraph->setHtml(code);
}
void PreviewWidget::on_previewToolButton_clicked()
{
ui->memPreviewTab->setCurrentIndex(0);
}
void PreviewWidget::on_decoToolButton_clicked()
{
ui->memPreviewTab->setCurrentIndex(1);
}
void PreviewWidget::on_simpleGrapgToolButton_clicked()
{
ui->memPreviewTab->setCurrentIndex(2);
}
void PreviewWidget::switchTheme(bool dark)
{
if (dark)
{
ui->webSimpleGraph->page()->setBackgroundColor(QColor(64, 64, 64));
}
else
{
ui->webSimpleGraph->page()->setBackgroundColor(QColor(255, 255, 255));
}
}

View File

@ -0,0 +1,64 @@
#ifndef PREVIEWWIDGET_H
#define PREVIEWWIDGET_H
#include <QDebug>
#include <QTextEdit>
#include <QDockWidget>
#include <QTreeWidget>
#include <QTabWidget>
#include <QWebEngineView>
#include <QUrl>
#include <QPlainTextEdit>
#include <QMouseEvent>
#include <memory>
#include "cutter.h"
#include "utils/Highlighter.h"
#include "utils/HexAsciiHighlighter.h"
#include "utils/HexHighlighter.h"
#include "Dashboard.h"
namespace Ui
{
class PreviewWidget;
}
class PreviewWidget : public QDockWidget
{
Q_OBJECT
public:
explicit PreviewWidget(const QString &title, QWidget *parent = nullptr, Qt::WindowFlags flags = 0);
explicit PreviewWidget(QWidget *parent = nullptr, Qt::WindowFlags flags = 0);
~PreviewWidget();
Highlighter *highlighter;
signals:
void fontChanged(QFont font);
public slots:
void setMiniGraph(QString at);
void switchTheme(bool dark);
private:
std::unique_ptr<Ui::PreviewWidget> ui;
CutterCore *core;
void refresh(RVA addr = RVA_INVALID);
private slots:
void on_seekChanged(RVA addr);
void highlightPreviewCurrentLine();
void highlightDecoCurrentLine();
void setFonts(QFont font);
void on_actionSettings_menu_1_triggered();
void on_previewToolButton_clicked();
void on_decoToolButton_clicked();
void on_simpleGrapgToolButton_clicked();
};
#endif // MEMORYWIDGET_H

View File

@ -0,0 +1,661 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>PreviewWidget</class>
<widget class="QDockWidget" name="PreviewWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>867</width>
<height>730</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="windowTitle">
<string notr="true">Preview</string>
</property>
<widget class="QWidget" name="dockWidgetContents">
<layout class="QVBoxLayout" name="verticalLayout">
<property name="spacing">
<number>0</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QFrame" name="frame_3">
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Plain</enum>
</property>
<layout class="QVBoxLayout" name="verticalLayout_7">
<property name="spacing">
<number>0</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QFrame" name="frame_2">
<property name="styleSheet">
<string notr="true">background-color: rgb(255, 255, 255);</string>
</property>
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Plain</enum>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_7">
<property name="spacing">
<number>0</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>55</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QToolButton" name="previewToolButton">
<property name="styleSheet">
<string notr="true">QToolButton { /* all types of tool button */
border: 3px solid rgb(255, 255, 255);
border-left: 10px solid rgb(255, 255, 255);
border-right: 10px solid rgb(255, 255, 255);
border-radius: 0px;
background-color: rgb(255, 255, 255);
color: rgb(191, 191, 191);
}
QToolButton:hover {
border: 3px solid #2180a9;
border-left: 10px solid #2180a9;
border-right: 10px solid #2180a9;
border-radius: 0px;
background-color: #2180a9;
color: rgb(255, 255, 255);
}
QToolButton:checked {
border: 3px solid #999;
border-left: 10px solid #999;
border-right: 10px solid #999;
border-radius: 0px;
background-color: #999;
color: rgb(255, 255, 255);
}
QToolTip {
background-color: #444;
border: 3px solid #444;
color: rgb(232, 232, 232);
}</string>
</property>
<property name="text">
<string notr="true">Preview</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="checked">
<bool>false</bool>
</property>
<attribute name="buttonGroup">
<string notr="true">buttonGroup_3</string>
</attribute>
</widget>
</item>
<item>
<widget class="QToolButton" name="decoToolButton">
<property name="styleSheet">
<string notr="true">QToolButton { /* all types of tool button */
border: 3px solid rgb(255, 255, 255);
border-left: 10px solid rgb(255, 255, 255);
border-right: 10px solid rgb(255, 255, 255);
border-radius: 0px;
background-color: rgb(255, 255, 255);
color: rgb(191, 191, 191);
}
QToolButton:hover {
border: 3px solid #2180a9;
border-left: 10px solid #2180a9;
border-right: 10px solid #2180a9;
border-radius: 0px;
background-color: #2180a9;
color: rgb(255, 255, 255);
}
QToolButton:checked {
border: 3px solid #999;
border-left: 10px solid #999;
border-right: 10px solid #999;
border-radius: 0px;
background-color: #999;
color: rgb(255, 255, 255);
}
QToolTip {
background-color: #444;
border: 3px solid #444;
color: rgb(232, 232, 232);
}</string>
</property>
<property name="text">
<string notr="true">Pseudo</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="checked">
<bool>false</bool>
</property>
<attribute name="buttonGroup">
<string notr="true">buttonGroup_3</string>
</attribute>
</widget>
</item>
<item>
<widget class="QToolButton" name="simpleGrapgToolButton">
<property name="styleSheet">
<string notr="true">QToolButton { /* all types of tool button */
border: 3px solid rgb(255, 255, 255);
border-left: 10px solid rgb(255, 255, 255);
border-right: 10px solid rgb(255, 255, 255);
border-radius: 0px;
background-color: rgb(255, 255, 255);
color: rgb(191, 191, 191);
}
QToolButton:hover {
border: 3px solid #2180a9;
border-left: 10px solid #2180a9;
border-right: 10px solid #2180a9;
border-radius: 0px;
background-color: #2180a9;
color: rgb(255, 255, 255);
}
QToolButton:checked {
border: 3px solid #999;
border-left: 10px solid #999;
border-right: 10px solid #999;
border-radius: 0px;
background-color: #999;
color: rgb(255, 255, 255);
}
QToolTip {
background-color: #444;
border: 3px solid #444;
color: rgb(232, 232, 232);
}</string>
</property>
<property name="text">
<string notr="true">Graph</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="checked">
<bool>true</bool>
</property>
<attribute name="buttonGroup">
<string notr="true">buttonGroup_3</string>
</attribute>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>55</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QTabWidget" name="memPreviewTab">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="styleSheet">
<string notr="true"/>
</property>
<property name="tabPosition">
<enum>QTabWidget::South</enum>
</property>
<property name="currentIndex">
<number>0</number>
</property>
<widget class="QWidget" name="tab_4">
<attribute name="title">
<string notr="true">Preview</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_6">
<property name="spacing">
<number>0</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>5</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QTextEdit" name="previewTextEdit">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<family>Anonymous Pro</family>
<pointsize>13</pointsize>
</font>
</property>
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Plain</enum>
</property>
<property name="verticalScrollBarPolicy">
<enum>Qt::ScrollBarAlwaysOff</enum>
</property>
<property name="horizontalScrollBarPolicy">
<enum>Qt::ScrollBarAlwaysOff</enum>
</property>
<property name="lineWrapMode">
<enum>QTextEdit::NoWrap</enum>
</property>
<property name="textInteractionFlags">
<set>Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="tab_5">
<attribute name="title">
<string notr="true">Decomp</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_5">
<property name="spacing">
<number>0</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>5</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QPlainTextEdit" name="decoTextEdit">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<family>Anonymous Pro</family>
<pointsize>13</pointsize>
</font>
</property>
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Plain</enum>
</property>
<property name="verticalScrollBarPolicy">
<enum>Qt::ScrollBarAlwaysOff</enum>
</property>
<property name="horizontalScrollBarPolicy">
<enum>Qt::ScrollBarAlwaysOff</enum>
</property>
<property name="undoRedoEnabled">
<bool>false</bool>
</property>
<property name="lineWrapMode">
<enum>QPlainTextEdit::NoWrap</enum>
</property>
<property name="plainText">
<string notr="true"/>
</property>
<property name="textInteractionFlags">
<set>Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="tab_8">
<attribute name="title">
<string notr="true">Graph</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_3">
<property name="spacing">
<number>0</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>5</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QWebEngineView" name="webSimpleGraph">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<family>Anonymous Pro</family>
<pointsize>12</pointsize>
</font>
</property>
<property name="styleSheet">
<string notr="true">QToolTip {
background-color: #444;
border: 3px solid #444;
color: rgb(232, 232, 232);
font: 11pt &quot;Monaco&quot;;
}</string>
</property>
<property name="url">
<url>
<string>about:blank</string>
</url>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<action name="actionSettings_menu_1">
<property name="text">
<string>Change font</string>
</property>
<property name="toolTip">
<string>Change font</string>
</property>
</action>
<action name="actionHideDisasm_side_panel">
<property name="text">
<string>Disasm side panel</string>
</property>
<property name="toolTip">
<string>Disasm side panel</string>
</property>
</action>
<action name="actionHideHexdump_side_panel">
<property name="text">
<string>Hexdump side panel</string>
</property>
<property name="toolTip">
<string>Hexdump side panel</string>
</property>
</action>
<action name="actionHideGraph_side_panel">
<property name="text">
<string>Graph side panel</string>
</property>
<property name="toolTip">
<string>Graph side panel</string>
</property>
</action>
<action name="actionSend_to_Notepad">
<property name="text">
<string>Send to notepad</string>
</property>
<property name="toolTip">
<string>Send to notepad</string>
</property>
</action>
<action name="actionFunctionsUndefine">
<property name="text">
<string>Undefine</string>
</property>
<property name="toolTip">
<string>Undefine</string>
</property>
</action>
<action name="actionDisasCopy_All">
<property name="text">
<string>Copy all</string>
</property>
<property name="toolTip">
<string>Copy all</string>
</property>
</action>
<action name="actionDisasCopy_Bytes">
<property name="text">
<string>Copy bytes</string>
</property>
<property name="toolTip">
<string>Copy bytes</string>
</property>
</action>
<action name="actionDisasCopy_Disasm">
<property name="text">
<string>Copy disasm</string>
</property>
<property name="toolTip">
<string>Copy disasm</string>
</property>
</action>
<action name="actionHexCopy_Hexpair">
<property name="text">
<string>Copy Hexpair</string>
</property>
<property name="toolTip">
<string>Copy Hexpair</string>
</property>
</action>
<action name="actionHexCopy_ASCII">
<property name="text">
<string>Copy ASCII</string>
</property>
<property name="toolTip">
<string>Copy ASCII</string>
</property>
</action>
<action name="actionHexCopy_Text">
<property name="text">
<string>Copy Text</string>
</property>
<property name="toolTip">
<string>Copy Text</string>
</property>
</action>
<action name="action1column">
<property name="text">
<string>1</string>
</property>
<property name="toolTip">
<string>1</string>
</property>
</action>
<action name="action2columns">
<property name="text">
<string>2</string>
</property>
<property name="toolTip">
<string>2</string>
</property>
</action>
<action name="action4columns">
<property name="text">
<string>4</string>
</property>
<property name="toolTip">
<string>4</string>
</property>
</action>
<action name="action8columns">
<property name="text">
<string>8</string>
</property>
<property name="toolTip">
<string>8</string>
</property>
</action>
<action name="action16columns">
<property name="text">
<string>16</string>
</property>
<property name="toolTip">
<string>16</string>
</property>
</action>
<action name="action32columns">
<property name="text">
<string>32</string>
</property>
<property name="toolTip">
<string>32</string>
</property>
</action>
<action name="action64columns">
<property name="text">
<string>64</string>
</property>
<property name="toolTip">
<string>64</string>
</property>
</action>
<action name="actionHexEdit">
<property name="text">
<string>Edit</string>
</property>
<property name="toolTip">
<string>Edit</string>
</property>
</action>
<action name="actionHexPaste">
<property name="text">
<string>Paste</string>
</property>
<property name="toolTip">
<string>Paste</string>
</property>
</action>
<action name="actionHexInsert_Hex">
<property name="text">
<string>Insert Hex</string>
</property>
<property name="toolTip">
<string>Insert Hex</string>
</property>
</action>
<action name="actionHexInsert_String">
<property name="text">
<string>Insert String</string>
</property>
<property name="toolTip">
<string>Insert String</string>
</property>
</action>
</widget>
<customwidgets>
<customwidget>
<class>QWebEngineView</class>
<extends>QWidget</extends>
<header location="global">QtWebEngineWidgets/QWebEngineView</header>
</customwidget>
</customwidgets>
<resources>
<include location="../resources.qrc"/>
</resources>
<connections/>
<buttongroups>
<buttongroup name="buttonGroup_3"/>
</buttongroups>
</ui>

View File

@ -0,0 +1,306 @@
#include "SidebarWidget.h"
#include "ui_SidebarWidget.h"
#include "DisassemblerGraphView.h"
#include "utils/Helpers.h"
#include <QTemporaryFile>
#include <QFontDialog>
#include <QScrollBar>
#include <QClipboard>
#include <QShortcut>
#include <QWebEnginePage>
#include <QMenu>
#include <QFont>
#include <QUrl>
#include <QWebEngineSettings>
#include <QWebEngineProfile>
#include <QSettings>
SidebarWidget::SidebarWidget(QWidget *parent, Qt::WindowFlags flags) :
QDockWidget(parent, flags),
ui(new Ui::SidebarWidget),
core(CutterCore::getInstance())
{
ui->setupUi(this);
this->xrefToTreeWidget_2 = ui->xrefToTreeWidget_2;
this->xreFromTreeWidget_2 = ui->xreFromTreeWidget_2;
// Add margin to function name line edit
ui->fcnNameEdit->setTextMargins(5, 0, 0, 0);
// Hide fcn graph notebooks tabs
QTabBar *graph_bar = ui->fcnGraphTabWidget->tabBar();
graph_bar->setVisible(false);
connect(core, SIGNAL(seekChanged(RVA)), this, SLOT(on_seekChanged(RVA)));
connect(core, SIGNAL(flagsChanged()), this, SLOT(refresh()));
connect(core, SIGNAL(commentsChanged()), this, SLOT(refresh()));
connect(core, SIGNAL(asmOptionsChanged()), this, SLOT(refresh()));
setScrollMode();
}
SidebarWidget::SidebarWidget(const QString &title, QWidget *parent, Qt::WindowFlags flags)
: SidebarWidget(parent, flags)
{
setWindowTitle(title);
}
SidebarWidget::~SidebarWidget()
{
}
void SidebarWidget::on_seekChanged(RVA addr)
{
refresh(addr);
}
void SidebarWidget::refresh(RVA addr)
{
if(addr == RVA_INVALID)
addr = core->getSeekAddr();
get_refs_data(addr);
setFcnName(addr);
fillOffsetInfo(RAddressString(addr));
}
/*
* Context menu functions
*/
void SidebarWidget::on_showInfoButton_2_clicked()
{
if (ui->showInfoButton_2->isChecked())
{
ui->fcnGraphTabWidget->hide();
ui->showInfoButton_2->setArrowType(Qt::RightArrow);
}
else
{
ui->fcnGraphTabWidget->show();
ui->showInfoButton_2->setArrowType(Qt::DownArrow);
}
}
void SidebarWidget::on_offsetToolButton_clicked()
{
if (ui->offsetToolButton->isChecked())
{
ui->offsetTreeWidget->hide();
ui->offsetToolButton->setArrowType(Qt::RightArrow);
}
else
{
ui->offsetTreeWidget->show();
ui->offsetToolButton->setArrowType(Qt::DownArrow);
}
}
void SidebarWidget::on_xreFromTreeWidget_2_itemDoubleClicked(QTreeWidgetItem *item, int /*column*/)
{
XrefDescription xref = item->data(0, Qt::UserRole).value<XrefDescription>();
this->core->seek(xref.to);
}
void SidebarWidget::on_xrefToTreeWidget_2_itemDoubleClicked(QTreeWidgetItem *item, int /*column*/)
{
XrefDescription xref = item->data(0, Qt::UserRole).value<XrefDescription>();
this->core->seek(xref.from);
}
void SidebarWidget::on_xrefFromToolButton_2_clicked()
{
if (ui->xrefFromToolButton_2->isChecked())
{
ui->xreFromTreeWidget_2->hide();
ui->xrefFromToolButton_2->setArrowType(Qt::RightArrow);
}
else
{
ui->xreFromTreeWidget_2->show();
ui->xrefFromToolButton_2->setArrowType(Qt::DownArrow);
}
}
void SidebarWidget::on_xrefToToolButton_2_clicked()
{
if (ui->xrefToToolButton_2->isChecked())
{
ui->xrefToTreeWidget_2->hide();
ui->xrefToToolButton_2->setArrowType(Qt::RightArrow);
}
else
{
ui->xrefToTreeWidget_2->show();
ui->xrefToToolButton_2->setArrowType(Qt::DownArrow);
}
}
void SidebarWidget::get_refs_data(RVA addr)
{
// refs = calls q hace esa funcion
QList<XrefDescription> refs = core->getXRefs(addr, false, false);
// xrefs = calls a esa funcion
QList<XrefDescription> xrefs = core->getXRefs(addr, true, false);
// Data for the disasm side graph
QList<int> data;
//qDebug() << "Refs:" << refs.size();
data << refs.size();
//qDebug() << "XRefs:" << xrefs.size();
data << xrefs.size();
//qDebug() << "CC: " << this->core->fcnCyclomaticComplexity(offset.toLong(&ok, 16));
//data << this->core->fcnCyclomaticComplexity(offset.toLong(&ok, 16));
data << this->core->getCycloComplex(addr);
//qDebug() << "BB: " << this->core->fcnBasicBlockCount(offset.toLong(&ok, 16));
data << this->core->fcnBasicBlockCount(addr);
data << this->core->fcnEndBbs(addr);
//qDebug() << "MEOW: " + this->core->fcnEndBbs(offset);
// Update disasm side bar
this->fill_refs(refs, xrefs, data);
}
void SidebarWidget::fill_refs(QList<XrefDescription> refs, QList<XrefDescription> xrefs, QList<int> graph_data)
{
this->xreFromTreeWidget_2->clear();
for (int i = 0; i < refs.size(); ++i)
{
XrefDescription xref = refs[i];
QTreeWidgetItem *tempItem = new QTreeWidgetItem();
tempItem->setText(0, RAddressString(xref.to));
tempItem->setText(1, core->disassembleSingleInstruction(xref.from));
tempItem->setData(0, Qt::UserRole, QVariant::fromValue(xref));
QString tooltip = this->core->cmd("pdi 10 @ " + QString::number(xref.to)).trimmed();
tempItem->setToolTip(0, tooltip);
tempItem->setToolTip(1, tooltip);
this->xreFromTreeWidget_2->insertTopLevelItem(0, tempItem);
}
// Adjust columns to content
int count = this->xreFromTreeWidget_2->columnCount();
for (int i = 0; i != count; ++i)
{
this->xreFromTreeWidget_2->resizeColumnToContents(i);
}
this->xrefToTreeWidget_2->clear();
for (int i = 0; i < xrefs.size(); ++i)
{
XrefDescription xref = xrefs[i];
QTreeWidgetItem *tempItem = new QTreeWidgetItem();
tempItem->setText(0, RAddressString(xref.from));
tempItem->setText(1, core->disassembleSingleInstruction(xref.from));
tempItem->setData(0, Qt::UserRole, QVariant::fromValue(xref));
QString tooltip = this->core->cmd("pdi 10 @ " + QString::number(xref.from)).trimmed();
// TODO wtf is this?
//tempItem->setToolTip(0, this->core->cmd("pdi 10 @ " + tooltip).trimmed());
//tempItem->setToolTip(1, this->core->cmd("pdi 10 @ " + tooltip).trimmed());
this->xrefToTreeWidget_2->insertTopLevelItem(0, tempItem);
}
// Adjust columns to content
int count2 = this->xrefToTreeWidget_2->columnCount();
for (int i = 0; i != count2; ++i)
{
this->xrefToTreeWidget_2->resizeColumnToContents(i);
}
// Add data to HTML Polar functions graph
QFile html(":/html/fcn_graph.html");
if (!html.open(QIODevice::ReadOnly))
{
QMessageBox::information(this, "error", html.errorString());
}
QString code = html.readAll();
html.close();
QString data = QString("\"%1\", \"%2\", \"%3\", \"%4\", \"%5\"").arg(graph_data.at(2)).arg(graph_data.at(0)).arg(graph_data.at(3)).arg(graph_data.at(1)).arg(graph_data.at(4));
code.replace("MEOW", data);
ui->fcnWebView->setHtml(code);
// Add data to HTML Radar functions graph
QFile html2(":/html/fcn_radar.html");
if (!html2.open(QIODevice::ReadOnly))
{
QMessageBox::information(this, "error", html.errorString());
}
QString code2 = html2.readAll();
html2.close();
QString data2 = QString("%1, %2, %3, %4, %5").arg(graph_data.at(2)).arg(graph_data.at(0)).arg(graph_data.at(3)).arg(graph_data.at(1)).arg(graph_data.at(4));
code2.replace("MEOW", data2);
ui->radarGraphWebView->setHtml(code2);
}
void SidebarWidget::fillOffsetInfo(QString off)
{
ui->offsetTreeWidget->clear();
QString raw = this->core->getOffsetInfo(off);
QList<QString> lines = raw.split("\n", QString::SkipEmptyParts);
foreach (QString line, lines)
{
QList<QString> eles = line.split(":", QString::SkipEmptyParts);
QTreeWidgetItem *tempItem = new QTreeWidgetItem();
tempItem->setText(0, eles.at(0).toUpper());
tempItem->setText(1, eles.at(1));
ui->offsetTreeWidget->insertTopLevelItem(0, tempItem);
}
// Adjust column to contents
int count = ui->offsetTreeWidget->columnCount();
for (int i = 0; i != count; ++i)
{
ui->offsetTreeWidget->resizeColumnToContents(i);
}
// Add opcode description
QStringList description = this->core->cmd("?d. @ " + off).split(": ");
if (description.length() >= 2)
{
ui->opcodeDescText->setPlainText("# " + description[0] + ":\n" + description[1]);
}
}
void SidebarWidget::setFcnName(RVA addr)
{
RAnalFunction *fcn;
QString addr_string;
fcn = this->core->functionAt(addr);
if (fcn)
{
QString segment = this->core->cmd("S. @ " + QString::number(addr)).split(" ").last();
addr_string = segment.trimmed() + ":" + fcn->name;
}
else
{
addr_string = core->cmdFunctionAt(addr);
}
ui->fcnNameEdit->setText(addr_string);
}
void SidebarWidget::on_polarToolButton_clicked()
{
ui->radarToolButton->setChecked(false);
ui->fcnGraphTabWidget->setCurrentIndex(0);
}
void SidebarWidget::on_radarToolButton_clicked()
{
ui->polarToolButton->setChecked(false);
ui->fcnGraphTabWidget->setCurrentIndex(1);
}
void SidebarWidget::setScrollMode()
{
qhelpers::setVerticalScrollMode(ui->xreFromTreeWidget_2);
qhelpers::setVerticalScrollMode(ui->xrefToTreeWidget_2);
}

View File

@ -0,0 +1,66 @@
#ifndef SIDEBARWIDGET_H
#define SIDEBARWIDGET_H
#include <QDebug>
#include <QTextEdit>
#include <QDockWidget>
#include <QTreeWidget>
#include <QTabWidget>
#include <QWebEngineView>
#include <QUrl>
#include <QPlainTextEdit>
#include <QMouseEvent>
#include <memory>
#include "cutter.h"
#include "utils/Highlighter.h"
#include "utils/HexAsciiHighlighter.h"
#include "utils/HexHighlighter.h"
#include "Dashboard.h"
namespace Ui
{
class SidebarWidget;
}
class SidebarWidget : public QDockWidget
{
Q_OBJECT
public:
explicit SidebarWidget(const QString &title, QWidget *parent = nullptr, Qt::WindowFlags flags = 0);
explicit SidebarWidget(QWidget *parent = nullptr, Qt::WindowFlags flags = 0);
~SidebarWidget();
QTreeWidget *xrefToTreeWidget_2;
QTreeWidget *xreFromTreeWidget_2;
private:
std::unique_ptr<Ui::SidebarWidget> ui;
CutterCore *core;
void setFcnName(RVA addr);
void get_refs_data(RVA addr);
void fill_refs(QList<XrefDescription> refs, QList<XrefDescription> xrefs, QList<int> graph_data);
void fillOffsetInfo(QString off);
void setScrollMode();
private slots:
void on_seekChanged(RVA addr);
void refresh(RVA addr = RVA_INVALID);
void on_showInfoButton_2_clicked();
void on_xreFromTreeWidget_2_itemDoubleClicked(QTreeWidgetItem *item, int column);
void on_xrefToTreeWidget_2_itemDoubleClicked(QTreeWidgetItem *item, int column);
void on_xrefFromToolButton_2_clicked();
void on_xrefToToolButton_2_clicked();
void on_offsetToolButton_clicked();
void on_polarToolButton_clicked();
void on_radarToolButton_clicked();
};
#endif // SIDEBARWIDGET_H

View File

@ -0,0 +1,877 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>SidebarWidget</class>
<widget class="QDockWidget" name="SidebarWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>333</width>
<height>835</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="windowTitle">
<string notr="true">Sidebar</string>
</property>
<widget class="QWidget" name="dockWidgetContents">
<layout class="QVBoxLayout" name="verticalLayout_3">
<property name="spacing">
<number>0</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QScrollArea" name="scrollArea_4">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Plain</enum>
</property>
<property name="lineWidth">
<number>0</number>
</property>
<property name="horizontalScrollBarPolicy">
<enum>Qt::ScrollBarAlwaysOff</enum>
</property>
<property name="sizeAdjustPolicy">
<enum>QAbstractScrollArea::AdjustToContents</enum>
</property>
<property name="widgetResizable">
<bool>true</bool>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
</property>
<widget class="QWidget" name="scrollAreaWidgetContents_4">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>319</width>
<height>882</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<layout class="QVBoxLayout" name="verticalLayout_11">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<layout class="QVBoxLayout" name="verticalLayout_12">
<property name="spacing">
<number>5</number>
</property>
<property name="leftMargin">
<number>2</number>
</property>
<property name="rightMargin">
<number>5</number>
</property>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="spacing">
<number>5</number>
</property>
<property name="topMargin">
<number>2</number>
</property>
<property name="bottomMargin">
<number>2</number>
</property>
<item>
<widget class="QLabel" name="label">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string> Function:</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="fcnNameEdit">
<property name="inputMask">
<string notr="true"/>
</property>
<property name="text">
<string notr="true"/>
</property>
<property name="frame">
<bool>false</bool>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_14">
<property name="spacing">
<number>5</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>5</number>
</property>
<item>
<widget class="QToolButton" name="showInfoButton_2">
<property name="text">
<string>...</string>
</property>
<property name="iconSize">
<size>
<width>8</width>
<height>8</height>
</size>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="autoRaise">
<bool>true</bool>
</property>
<property name="arrowType">
<enum>Qt::DownArrow</enum>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="infoTitleLabel_2">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Information&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_4">
<property name="spacing">
<number>0</number>
</property>
<item>
<widget class="QToolButton" name="radarToolButton">
<property name="toolTip">
<string>Radar graph</string>
</property>
<property name="styleSheet">
<string notr="true">QToolButton { /* all types of tool button */
border: 5px solid #333;
border-left: 10px solid #333;
border-right: 10px solid #333;
border-radius: 0px;
background-color: #333;
}
QToolButton:hover {
border: 5px solid #444;
border-left: 10px solid #444;
border-right: 10px solid #444;
border-radius: 0px;
background-color: #444;
}
QToolButton:checked {
border: 5px solid #2180a9;
border-left: 10px solid #2180a9;
border-right: 10px solid #2180a9;
border-radius: 0px;
background-color: #2180a9;
}
QToolTip {
background-color: #444;
border: 3px solid #444;
color: rgb(232, 232, 232);
}</string>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="../resources.qrc">
<normaloff>:/img/icons/radar_light.svg</normaloff>
<normalon>:/img/icons/radar_white.svg</normalon>
<activeon>:/img/icons/radar_white.svg</activeon>:/img/icons/radar_light.svg</iconset>
</property>
<property name="iconSize">
<size>
<width>8</width>
<height>8</height>
</size>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="checked">
<bool>true</bool>
</property>
<attribute name="buttonGroup">
<string notr="true">buttonGroup_2</string>
</attribute>
</widget>
</item>
<item>
<widget class="QToolButton" name="polarToolButton">
<property name="toolTip">
<string notr="true">Polar graph</string>
</property>
<property name="styleSheet">
<string notr="true">QToolButton { /* all types of tool button */
border: 5px solid #333;
border-left: 10px solid #333;
border-right: 10px solid #333;
border-radius: 0px;
background-color: #333;
}
QToolButton:hover {
border: 5px solid #444;
border-left: 10px solid #444;
border-right: 10px solid #444;
border-radius: 0px;
background-color: #444;
}
QToolButton:checked {
border: 5px solid #2180a9;
border-left: 10px solid #2180a9;
border-right: 10px solid #2180a9;
border-radius: 0px;
background-color: #2180a9;
}
QToolTip {
background-color: #444;
border: 3px solid #444;
color: rgb(232, 232, 232);
}</string>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="../resources.qrc">
<normaloff>:/img/icons/polar_light.svg</normaloff>
<normalon>:/img/icons/polar_white.svg</normalon>
<activeon>:/img/icons/polar_white.svg</activeon>:/img/icons/polar_light.svg</iconset>
</property>
<property name="iconSize">
<size>
<width>8</width>
<height>8</height>
</size>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="checked">
<bool>false</bool>
</property>
<attribute name="buttonGroup">
<string notr="true">buttonGroup_2</string>
</attribute>
</widget>
</item>
</layout>
</item>
</layout>
</item>
<item>
<widget class="QTabWidget" name="fcnGraphTabWidget">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>250</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>250</height>
</size>
</property>
<property name="currentIndex">
<number>0</number>
</property>
<widget class="QWidget" name="tab">
<attribute name="title">
<string>Tab 1</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="spacing">
<number>0</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QWebEngineView" name="fcnWebView">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>245</width>
<height>245</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>250</height>
</size>
</property>
<property name="url">
<url>
<string>qrc:/html/fcn_graph.html</string>
</url>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="tab_2">
<attribute name="title">
<string>Tab 2</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_2">
<property name="spacing">
<number>0</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QWebEngineView" name="radarGraphWebView">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>245</width>
<height>245</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>250</height>
</size>
</property>
<property name="url">
<url>
<string>qrc:/html/fcn_radar.html</string>
</url>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<property name="spacing">
<number>5</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<item>
<widget class="QToolButton" name="offsetToolButton">
<property name="text">
<string/>
</property>
<property name="iconSize">
<size>
<width>8</width>
<height>8</height>
</size>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="autoRaise">
<bool>true</bool>
</property>
<property name="arrowType">
<enum>Qt::DownArrow</enum>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_2">
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="mouseTracking">
<bool>true</bool>
</property>
<property name="text">
<string>Offset info:</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QTreeWidget" name="offsetTreeWidget">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>175</height>
</size>
</property>
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="horizontalScrollBarPolicy">
<enum>Qt::ScrollBarAlwaysOff</enum>
</property>
<property name="indentation">
<number>10</number>
</property>
<property name="headerHidden">
<bool>true</bool>
</property>
<column>
<property name="text">
<string>Info</string>
</property>
</column>
<column>
<property name="text">
<string>Value</string>
</property>
</column>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_5">
<item>
<widget class="QToolButton" name="opcodeDescButton">
<property name="text">
<string>...</string>
</property>
<property name="iconSize">
<size>
<width>8</width>
<height>8</height>
</size>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="autoRaise">
<bool>true</bool>
</property>
<property name="arrowType">
<enum>Qt::DownArrow</enum>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_3">
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="mouseTracking">
<bool>true</bool>
</property>
<property name="text">
<string>Opcode description:</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QPlainTextEdit" name="opcodeDescText">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="styleSheet">
<string notr="true">background-color: rgb(255, 255, 255);
color: rgb(0, 0, 0);</string>
</property>
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="verticalScrollBarPolicy">
<enum>Qt::ScrollBarAlwaysOff</enum>
</property>
<property name="horizontalScrollBarPolicy">
<enum>Qt::ScrollBarAlwaysOff</enum>
</property>
<property name="undoRedoEnabled">
<bool>false</bool>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_16">
<property name="spacing">
<number>5</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<item>
<widget class="QToolButton" name="xrefToToolButton_2">
<property name="text">
<string>...</string>
</property>
<property name="iconSize">
<size>
<width>8</width>
<height>8</height>
</size>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="autoRaise">
<bool>true</bool>
</property>
<property name="arrowType">
<enum>Qt::DownArrow</enum>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="xrefToLabel_2">
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>X-Refs to current address:</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QTreeWidget" name="xrefToTreeWidget_2">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>100</height>
</size>
</property>
<property name="styleSheet">
<string notr="true">QTreeWidget::item
{
padding-left:10px;
padding-top: 1px;
padding-bottom: 1px;
border-left: 10px;
}
QTreeWidget::item:hover
{
background: rgb(242, 246, 248);
color: black;
}
QTreeWidget::item:selected
{
background: gray;
color: white;
}
QToolTip {
background-color: #444;
border: 3px solid #444;
color: rgb(232, 232, 232);
font: 12pt &quot;Monaco&quot;;
}</string>
</property>
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="horizontalScrollBarPolicy">
<enum>Qt::ScrollBarAlwaysOff</enum>
</property>
<property name="verticalScrollMode">
<enum>QAbstractItemView::ScrollPerPixel</enum>
</property>
<property name="indentation">
<number>0</number>
</property>
<column>
<property name="text">
<string>Address</string>
</property>
</column>
<column>
<property name="text">
<string>Instruction</string>
</property>
</column>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_15">
<property name="spacing">
<number>5</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<item>
<widget class="QToolButton" name="xrefFromToolButton_2">
<property name="text">
<string/>
</property>
<property name="iconSize">
<size>
<width>8</width>
<height>8</height>
</size>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="autoRaise">
<bool>true</bool>
</property>
<property name="arrowType">
<enum>Qt::DownArrow</enum>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="xrefFromLabel_2">
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>X-Refs from current address:</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QTreeWidget" name="xreFromTreeWidget_2">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>100</height>
</size>
</property>
<property name="styleSheet">
<string notr="true">QTreeWidget::item
{
padding-left:10px;
padding-top: 1px;
padding-bottom: 1px;
border-left: 10px;
}
QTreeWidget::item:hover
{
background: rgb(242, 246, 248);
color: black;
}
QTreeWidget::item:selected
{
background: gray;
color: white;
}
QToolTip {
background-color: #444;
border: 3px solid #444;
color: rgb(232, 232, 232);
font: 12pt &quot;Monaco&quot;;
}</string>
</property>
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="horizontalScrollBarPolicy">
<enum>Qt::ScrollBarAlwaysOff</enum>
</property>
<property name="verticalScrollMode">
<enum>QAbstractItemView::ScrollPerPixel</enum>
</property>
<property name="indentation">
<number>0</number>
</property>
<column>
<property name="text">
<string>Address</string>
</property>
</column>
<column>
<property name="text">
<string>Instruction</string>
</property>
</column>
</widget>
</item>
<item>
<spacer name="verticalSpacer_4">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</widget>
</widget>
</item>
</layout>
</widget>
</widget>
<customwidgets>
<customwidget>
<class>QWebEngineView</class>
<extends>QWidget</extends>
<header location="global">QtWebEngineWidgets/QWebEngineView</header>
</customwidget>
</customwidgets>
<resources>
<include location="../resources.qrc"/>
</resources>
<connections/>
<buttongroups>
<buttongroup name="buttonGroup_2"/>
<buttongroup name="buttonGroup"/>
<buttongroup name="buttonGroup_3"/>
</buttongroups>
</ui>