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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -5,12 +5,12 @@
#include <QTextEdit>
#include "cutter.h"
class DisassemblyView : public QDockWidget
class DisassemblyWidget : public QDockWidget
{
Q_OBJECT
public:
explicit DisassemblyView(QWidget *parent = nullptr);
explicit DisassemblyView(const QString &title, QWidget *parent = nullptr);
explicit DisassemblyWidget(QWidget *parent = nullptr);
explicit DisassemblyWidget(const QString &title, QWidget *parent = nullptr);
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 "MainWindow.h"
@ -20,25 +21,17 @@
#include <cassert>
MemoryWidget::MemoryWidget() :
ui(new Ui::MemoryWidget),
core(CutterCore::getInstance())
HexdumpWidget::HexdumpWidget(QWidget *parent, Qt::WindowFlags flags) :
QDockWidget(parent, flags),
ui(new Ui::HexdumpWidget),
core(CutterCore::getInstance())
{
ui->setupUi(this);
this->hexOffsetText = ui->hexOffsetText_2;
this->hexHexText = ui->hexHexText_2;
this->hexDisasTextEdit = ui->hexDisasTextEdit_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->last_graph_fcn = 0; //"";
this->last_hexdump_fcn = 0; //"";
disasm_top_offset = 0;
next_disasm_top_offset = 0;
this->hexDisasTextEdit = ui->hexDisasTextEdit_2;
//this->on_actionSettings_menu_1_triggered();
@ -46,29 +39,6 @@ MemoryWidget::MemoryWidget() :
//connect(ui->hexHexText, SIGNAL(cursorPositionChanged()), this, SLOT(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
qhelpers::normalizeEditFont(this->hexOffsetText);
qhelpers::normalizeEditFont(this->hexHexText);
@ -80,10 +50,6 @@ MemoryWidget::MemoryWidget() :
memMenu->addAction(ui->actionSettings_menu_1);
ui->memSettingsButton_2->setMenu(memMenu);
// Set Splitter stretch factor
ui->splitter->setStretchFactor(0, 10);
ui->splitter->setStretchFactor(1, 1);
// Set hexdump context menu
ui->hexHexText_2->setContextMenuPolicy(Qt::CustomContextMenu);
connect(ui->hexHexText_2, SIGNAL(customContextMenuRequested(const QPoint &)),
@ -108,39 +74,32 @@ MemoryWidget::MemoryWidget() :
connect(ui->hexASCIIText_2->verticalScrollBar(), SIGNAL(valueChanged(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
connect(this->hexASCIIText->verticalScrollBar(), SIGNAL(valueChanged(int)), this, SLOT(hexScrolled()));
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();
}
void MemoryWidget::on_seekChanged(RVA addr)
HexdumpWidget::HexdumpWidget(const QString &title, QWidget *parent, Qt::WindowFlags flags)
: HexdumpWidget(parent, flags)
{
updateViews(addr);
setWindowTitle(title);
}
void MemoryWidget::on_cursorAddressChanged(RVA addr)
void HexdumpWidget::on_seekChanged(RVA addr)
{
setFcnName(addr);
get_refs_data(addr);
refresh(addr);
}
HexdumpWidget::~HexdumpWidget() {}
/*
* Text highlight functions
*/
void MemoryWidget::highlightHexCurrentLine()
void HexdumpWidget::highlightHexCurrentLine()
{
QList<QTextEdit::ExtraSelection> extraSelections;
@ -173,7 +132,7 @@ void MemoryWidget::highlightHexCurrentLine()
highlightHexWords(cursor.selectedText());
}
void MemoryWidget::highlightHexWords(const QString &str)
void HexdumpWidget::highlightHexWords(const QString &str)
{
QString searchString = str;
QTextDocument *document = ui->hexHexText_2->document();
@ -204,89 +163,13 @@ void MemoryWidget::highlightHexWords(const QString &str)
cursor.endEditBlock();
}
void MemoryWidget::highlightPreviewCurrentLine()
void HexdumpWidget::refresh(RVA addr)
{
QList<QTextEdit::ExtraSelection> extraSelections;
if (ui->previewTextEdit->toPlainText() != "")
if (addr == RVA_INVALID)
{
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);
}
addr = core->getSeekAddr();
}
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();
// Prevent further scroll
disconnect(this->hexASCIIText->verticalScrollBar(), SIGNAL(valueChanged(int)), this, SLOT(hexScrolled()));
@ -314,15 +197,8 @@ void MemoryWidget::refreshHexdump(const QString &where)
QString s = "";
if (!where.isEmpty())
{
this->core->cmd("ss " + where);
}
// Add first the hexdump at block size --
this->core->cmd("ss-" + this->core->itoa(hexdumpLength));
//s = this->normalize_addr(this->core->cmd("s"));
QList<QString> ret = this->get_hexdump("");
QList<QString> ret = this->get_hexdump(RAddressString(addr - hexdumpLength));
hexdumpBottomOffset = lcore->offset;
this->hexOffsetText->setPlainText(ret[0]);
@ -330,12 +206,9 @@ void MemoryWidget::refreshHexdump(const QString &where)
this->hexASCIIText->setPlainText(ret[2]);
this->resizeHexdump();
// Add then the hexdump at block size ++
this->core->cmd("ss+" + this->core->itoa(hexdumpLength));
// 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"));
ret = this->get_hexdump("");
ret = this->get_hexdump(RAddressString(addr));
hexdumpBottomOffset = lcore->offset;
this->hexOffsetText->append(ret[0]);
@ -353,9 +226,20 @@ void MemoryWidget::refreshHexdump(const QString &where)
this->hexOffsetText->moveCursor(QTextCursor::EndOfLine, QTextCursor::MoveAnchor);
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();
QList<QString> ret;
@ -403,17 +287,17 @@ QList<QString> MemoryWidget::get_hexdump(const QString &offset)
{
switch (wc++)
{
case 0:
offsets += a + "\n";
break;
case 1:
{
hex += a.trimmed() + "\n";
}
break;
case 2:
ascii += a + "\n";
break;
case 0:
offsets += a + "\n";
break;
case 1:
{
hex += a.trimmed() + "\n";
}
break;
case 2:
ascii += a + "\n";
break;
}
}
}
@ -424,14 +308,14 @@ QList<QString> MemoryWidget::get_hexdump(const QString &offset)
return ret;
}
void MemoryWidget::resizeHexdump()
void HexdumpWidget::resizeHexdump()
{
this->hexOffsetText->setMinimumWidth(this->hexOffsetText->document()->size().width());
this->hexHexText->setMinimumWidth(this->hexHexText->document()->size().width());
this->hexASCIIText->setMinimumWidth(this->hexASCIIText->document()->size().width());
}
void MemoryWidget::hexScrolled()
void HexdumpWidget::hexScrolled()
{
RCoreLocked lcore = this->core->core();
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
QString parsing = ui->codeCombo_2->currentText();
@ -566,7 +450,7 @@ void MemoryWidget::on_hexHexText_2_selectionChanged()
//qDebug() << "Selected Bits: " << bits;
//qDebug() << "Selected Text: " << sel_text;
}
// TODO: update on selection changes.. use cmd("pc "+len+"@"+off)
// TODO: update on selection changes.. use cmd("pc "+len+"@"+off)
else if (parsing == "C byte array")
{
this->hexDisasTextEdit->setPlainText(this->core->cmd("pc@x:" + sel_text));
@ -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();
}
void MemoryWidget::on_hexBitsComboBox_2_currentTextChanged(const QString &/*arg1*/)
void HexdumpWidget::on_hexBitsComboBox_2_currentTextChanged(const QString &/*arg1*/)
{
on_hexHexText_2_selectionChanged();
}
@ -623,7 +507,7 @@ void MemoryWidget::on_hexBitsComboBox_2_currentTextChanged(const QString &/*arg1
* Context menu functions
*/
void MemoryWidget::showHexdumpContextMenu(const QPoint &pt)
void HexdumpWidget::showHexdumpContextMenu(const QPoint &pt)
{
// Set Hexdump popup menu
QMenu *menu = ui->hexHexText_2->createStandardContextMenu();
@ -650,7 +534,7 @@ void MemoryWidget::showHexdumpContextMenu(const QPoint &pt)
delete menu;
}
void MemoryWidget::showHexASCIIContextMenu(const QPoint &pt)
void HexdumpWidget::showHexASCIIContextMenu(const QPoint &pt)
{
// Set Hex ASCII popup menu
QMenu *menu = ui->hexASCIIText_2->createStandardContextMenu();
@ -676,61 +560,11 @@ void MemoryWidget::showHexASCIIContextMenu(const QPoint &pt)
menu->exec(ui->hexASCIIText_2->mapToGlobal(pt));
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
*/
void MemoryWidget::on_actionSettings_menu_1_triggered()
void HexdumpWidget::on_actionSettings_menu_1_triggered()
{
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);
// 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->hexHexText_2->setFont(font);
ui->hexASCIIText_2->setFont(font);
ui->previewTextEdit->setFont(font);
ui->decoTextEdit->setFont(font);
}
void MemoryWidget::on_actionHideDisasm_side_panel_triggered()
{
if (ui->memSideTabWidget_2->isVisible())
{
ui->memSideTabWidget_2->hide();
}
else
{
ui->memSideTabWidget_2->show();
}
}
void MemoryWidget::on_actionHideHexdump_side_panel_triggered()
void HexdumpWidget::on_actionHideHexdump_side_panel_triggered()
{
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();
}
}
/*
* 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()
/*void HexdumpWidget::on_actionSend_to_Notepad_triggered()
{
QTextCursor cursor = ui->disasTextEdit_2->textCursor();
QString text = cursor.selectedText();
@ -818,89 +611,49 @@ void MemoryWidget::on_hexButton_clicked()
// this->main->sendToNotepad(text);
}*/
void MemoryWidget::on_action8columns_triggered()
void HexdumpWidget::on_action8columns_triggered()
{
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->refreshHexdump();
this->refresh();
}
void MemoryWidget::on_action4columns_triggered()
void HexdumpWidget::on_action4columns_triggered()
{
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->refreshHexdump();
this->refresh();
}
void MemoryWidget::on_action64columns_triggered()
void HexdumpWidget::on_action64columns_triggered()
{
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->refreshHexdump();
this->refresh();
}
void MemoryWidget::on_action1column_triggered()
void HexdumpWidget::on_action1column_triggered()
{
this->core->setConfig("hex.cols", 1);
this->refreshHexdump();
this->refresh();
}
void MemoryWidget::on_xreFromTreeWidget_2_itemDoubleClicked(QTreeWidgetItem *item, int /*column*/)
{
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)
void HexdumpWidget::on_codeCombo_2_currentTextChanged(const QString &arg1)
{
if (arg1 == "Dissasembly")
{
@ -914,132 +667,7 @@ void MemoryWidget::on_codeCombo_2_currentTextChanged(const QString &arg1)
}
}
void MemoryWidget::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 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 HexdumpWidget::normalize_addr(QString addr)
{
QString base = this->core->cmd("s").split("0x")[1].trimmed();
int len = base.length();
@ -1057,26 +685,7 @@ QString MemoryWidget::normalize_addr(QString addr)
}
}
void MemoryWidget::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);
}
QString MemoryWidget::normalizeAddr(QString addr)
QString HexdumpWidget::normalizeAddr(QString addr)
{
QString base = addr.split("0x")[1].trimmed();
int len = base.length();
@ -1094,38 +703,7 @@ QString MemoryWidget::normalizeAddr(QString addr)
}
}
void MemoryWidget::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 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*/)
void HexdumpWidget::on_hexSideTab_2_currentChanged(int /*index*/)
{
/*
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())
{
ui->memSideTabWidget_2->hide();
ui->hexSideTab_2->hide();
ui->memSideToolButton->setIcon(QIcon(":/img/icons/left_light.svg"));
}
else
{
ui->memSideTabWidget_2->show();
ui->hexSideTab_2->show();
ui->memSideToolButton->setIcon(QIcon(":/img/icons/right_light.svg"));
}
}
void MemoryWidget::on_previewToolButton_clicked()
{
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)
void HexdumpWidget::resizeEvent(QResizeEvent *event)
{
// FIXME
/*
@ -1222,13 +771,7 @@ void MemoryWidget::resizeEvent(QResizeEvent *event)
QDockWidget::resizeEvent(event);
}
void MemoryWidget::setScrollMode()
{
qhelpers::setVerticalScrollMode(ui->xreFromTreeWidget_2);
qhelpers::setVerticalScrollMode(ui->xrefToTreeWidget_2);
}
void MemoryWidget::on_copyMD5_clicked()
void HexdumpWidget::on_copyMD5_clicked()
{
QString md5 = ui->bytesMD5->text();
QClipboard *clipboard = QApplication::clipboard();
@ -1237,7 +780,7 @@ void MemoryWidget::on_copyMD5_clicked()
// this->main->addOutput("MD5 copied to clipboard: " + md5);
}
void MemoryWidget::on_copySHA1_clicked()
void HexdumpWidget::on_copySHA1_clicked()
{
QString sha1 = ui->bytesSHA1->text();
QClipboard *clipboard = QApplication::clipboard();
@ -1246,19 +789,7 @@ void MemoryWidget::on_copySHA1_clicked()
// this->main->addOutput("SHA1 copied to clipboard: " + sha1);
}
void MemoryWidget::switchTheme(bool dark)
{
if (dark)
{
ui->webSimpleGraph->page()->setBackgroundColor(QColor(64, 64, 64));
}
else
{
ui->webSimpleGraph->page()->setBackgroundColor(QColor(255, 255, 255));
}
}
void MemoryWidget::selectHexPreview()
void HexdumpWidget::selectHexPreview()
{
// Pre-select arch and bits in the hexdump sidebar
QString arch = this->core->cmd("e asm.arch").trimmed();
@ -1277,51 +808,7 @@ void MemoryWidget::selectHexPreview()
}
}
void MemoryWidget::seek_back()
{
//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)
void HexdumpWidget::showOffsets(bool 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>