mirror of
https://github.com/rizinorg/cutter.git
synced 2024-12-20 20:06:12 +00:00
Moved disassembly view to its own class
This commit is contained in:
parent
7b3d5ea7a7
commit
b4867cadef
@ -181,14 +181,7 @@ void MainWindow::initUI()
|
|||||||
/*
|
/*
|
||||||
* Dock Widgets
|
* Dock Widgets
|
||||||
*/
|
*/
|
||||||
dockWidgets.reserve(12);
|
dockWidgets.reserve(14);
|
||||||
|
|
||||||
// Add graph view as dockable
|
|
||||||
graphDock = new QDockWidget(tr("Graph"), this);
|
|
||||||
graphDock->setAllowedAreas(Qt::AllDockWidgetAreas);
|
|
||||||
DisassemblerGraphView *gv = new DisassemblerGraphView(graphDock);
|
|
||||||
graphDock->setWidget(gv);
|
|
||||||
dockWidgets.push_back(graphDock);
|
|
||||||
|
|
||||||
// Add Memory DockWidget
|
// Add Memory DockWidget
|
||||||
this->memoryDock = new MemoryWidget();
|
this->memoryDock = new MemoryWidget();
|
||||||
@ -197,6 +190,17 @@ void MainWindow::initUI()
|
|||||||
// this->memoryDock->setAttribute(Qt::WA_DeleteOnClose);
|
// this->memoryDock->setAttribute(Qt::WA_DeleteOnClose);
|
||||||
// this->add_debug_output( QString::number(this->dockList.length()) );
|
// this->add_debug_output( QString::number(this->dockList.length()) );
|
||||||
|
|
||||||
|
// Add disassembly view (dockable)
|
||||||
|
this->disassemblyDock = new DisassemblyView(tr("Disassembly"), this);
|
||||||
|
dockWidgets.push_back(disassemblyDock);
|
||||||
|
|
||||||
|
// Add graph view as dockable
|
||||||
|
graphDock = new QDockWidget(tr("Graph"), this);
|
||||||
|
graphDock->setAllowedAreas(Qt::AllDockWidgetAreas);
|
||||||
|
DisassemblerGraphView *gv = new DisassemblerGraphView(graphDock);
|
||||||
|
graphDock->setWidget(gv);
|
||||||
|
dockWidgets.push_back(graphDock);
|
||||||
|
|
||||||
// Add Sections dock panel
|
// Add Sections dock panel
|
||||||
this->sectionsDock = new SectionsDock(this);
|
this->sectionsDock = new SectionsDock(this);
|
||||||
dockWidgets.push_back(sectionsDock);
|
dockWidgets.push_back(sectionsDock);
|
||||||
@ -367,7 +371,6 @@ void MainWindow::finalizeOpen()
|
|||||||
start_web_server();
|
start_web_server();
|
||||||
showMaximized();
|
showMaximized();
|
||||||
// Initialize syntax highlighters
|
// Initialize syntax highlighters
|
||||||
memoryDock->highlightDisasms();
|
|
||||||
notepadDock->highlightPreview();
|
notepadDock->highlightPreview();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -510,6 +513,9 @@ void MainWindow::updateFrames()
|
|||||||
|
|
||||||
static bool first_time = true;
|
static bool first_time = true;
|
||||||
|
|
||||||
|
//TODO Send signal rather than that
|
||||||
|
disassemblyDock->refreshDisasm();
|
||||||
|
|
||||||
if (first_time)
|
if (first_time)
|
||||||
{
|
{
|
||||||
for (auto W : dockWidgets)
|
for (auto W : dockWidgets)
|
||||||
@ -619,7 +625,7 @@ void MainWindow::on_actionMem_triggered()
|
|||||||
this->dockWidgets << newMemDock;
|
this->dockWidgets << newMemDock;
|
||||||
newMemDock->setAttribute(Qt::WA_DeleteOnClose);
|
newMemDock->setAttribute(Qt::WA_DeleteOnClose);
|
||||||
this->tabifyDockWidget(this->memoryDock, newMemDock);
|
this->tabifyDockWidget(this->memoryDock, newMemDock);
|
||||||
newMemDock->refreshDisasm();
|
//newMemDock->refreshDisasm();
|
||||||
newMemDock->refreshHexdump();
|
newMemDock->refreshHexdump();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -752,13 +758,14 @@ void MainWindow::on_actionDisasAdd_comment_triggered()
|
|||||||
|
|
||||||
void MainWindow::restoreDocks()
|
void MainWindow::restoreDocks()
|
||||||
{
|
{
|
||||||
addDockWidget(Qt::RightDockWidgetArea, sectionsDock);
|
addDockWidget(Qt::LeftDockWidgetArea, this->functionsDock);
|
||||||
|
addDockWidget(Qt::RightDockWidgetArea, this->sectionsDock);
|
||||||
addDockWidget(Qt::TopDockWidgetArea, this->dashboardDock);
|
addDockWidget(Qt::TopDockWidgetArea, this->dashboardDock);
|
||||||
this->tabifyDockWidget(sectionsDock, this->commentsDock);
|
this->tabifyDockWidget(this->sectionsDock, this->commentsDock);
|
||||||
|
this->tabifyDockWidget(this->dashboardDock, this->disassemblyDock);
|
||||||
this->tabifyDockWidget(this->dashboardDock, this->graphDock);
|
this->tabifyDockWidget(this->dashboardDock, this->graphDock);
|
||||||
this->tabifyDockWidget(this->dashboardDock, this->memoryDock);
|
this->tabifyDockWidget(this->dashboardDock, this->memoryDock);
|
||||||
this->tabifyDockWidget(this->dashboardDock, this->entrypointDock);
|
this->tabifyDockWidget(this->dashboardDock, this->entrypointDock);
|
||||||
this->tabifyDockWidget(this->dashboardDock, this->functionsDock);
|
|
||||||
this->tabifyDockWidget(this->dashboardDock, this->flagsDock);
|
this->tabifyDockWidget(this->dashboardDock, this->flagsDock);
|
||||||
this->tabifyDockWidget(this->dashboardDock, this->stringsDock);
|
this->tabifyDockWidget(this->dashboardDock, this->stringsDock);
|
||||||
this->tabifyDockWidget(this->dashboardDock, this->relocsDock);
|
this->tabifyDockWidget(this->dashboardDock, this->relocsDock);
|
||||||
@ -767,7 +774,7 @@ void MainWindow::restoreDocks()
|
|||||||
this->tabifyDockWidget(this->dashboardDock, this->symbolsDock);
|
this->tabifyDockWidget(this->dashboardDock, this->symbolsDock);
|
||||||
this->tabifyDockWidget(this->dashboardDock, this->notepadDock);
|
this->tabifyDockWidget(this->dashboardDock, this->notepadDock);
|
||||||
this->dashboardDock->raise();
|
this->dashboardDock->raise();
|
||||||
sectionsDock->raise();
|
this->sectionsDock->raise();
|
||||||
this->functionsDock->raise();
|
this->functionsDock->raise();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -790,7 +797,6 @@ void MainWindow::hideAllDocks()
|
|||||||
void MainWindow::showDefaultDocks()
|
void MainWindow::showDefaultDocks()
|
||||||
{
|
{
|
||||||
const QList<QDockWidget *> defaultDocks = { sectionsDock,
|
const QList<QDockWidget *> defaultDocks = { sectionsDock,
|
||||||
graphDock,
|
|
||||||
entrypointDock,
|
entrypointDock,
|
||||||
functionsDock,
|
functionsDock,
|
||||||
memoryDock,
|
memoryDock,
|
||||||
@ -799,6 +805,8 @@ void MainWindow::showDefaultDocks()
|
|||||||
importsDock,
|
importsDock,
|
||||||
symbolsDock,
|
symbolsDock,
|
||||||
notepadDock,
|
notepadDock,
|
||||||
|
graphDock,
|
||||||
|
disassemblyDock,
|
||||||
dashboardDock
|
dashboardDock
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
#include <QList>
|
#include <QList>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include "RadareWebServer.h"
|
#include "RadareWebServer.h"
|
||||||
|
#include "widgets/DisassemblyView.h"
|
||||||
#include "cutter.h" // only needed for ut64
|
#include "cutter.h" // only needed for ut64
|
||||||
|
|
||||||
class CutterCore;
|
class CutterCore;
|
||||||
@ -169,6 +170,7 @@ private slots:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
CutterCore *core;
|
CutterCore *core;
|
||||||
|
DisassemblyView *disassemblyDock;
|
||||||
QDockWidget *graphDock;
|
QDockWidget *graphDock;
|
||||||
QDockWidget *asmDock;
|
QDockWidget *asmDock;
|
||||||
QDockWidget *calcDock;
|
QDockWidget *calcDock;
|
||||||
|
@ -73,7 +73,8 @@ SOURCES += \
|
|||||||
widgets/Sidebar.cpp \
|
widgets/Sidebar.cpp \
|
||||||
widgets/StringsWidget.cpp \
|
widgets/StringsWidget.cpp \
|
||||||
widgets/SymbolsWidget.cpp \
|
widgets/SymbolsWidget.cpp \
|
||||||
menus/DisassemblyContextMenu.cpp
|
menus/DisassemblyContextMenu.cpp \
|
||||||
|
widgets/DisassemblyView.cpp
|
||||||
|
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
cutter.h \
|
cutter.h \
|
||||||
@ -119,7 +120,8 @@ HEADERS += \
|
|||||||
widgets/Sidebar.h \
|
widgets/Sidebar.h \
|
||||||
widgets/StringsWidget.h \
|
widgets/StringsWidget.h \
|
||||||
widgets/SymbolsWidget.h \
|
widgets/SymbolsWidget.h \
|
||||||
menus/DisassemblyContextMenu.h
|
menus/DisassemblyContextMenu.h \
|
||||||
|
widgets/DisassemblyView.h
|
||||||
|
|
||||||
FORMS += \
|
FORMS += \
|
||||||
widgets/MemoryWidget.ui \
|
widgets/MemoryWidget.ui \
|
||||||
|
408
src/widgets/DisassemblyView.cpp
Normal file
408
src/widgets/DisassemblyView.cpp
Normal file
@ -0,0 +1,408 @@
|
|||||||
|
#include "DisassemblyView.h"
|
||||||
|
#include "menus/DisassemblyContextMenu.h"
|
||||||
|
#include "dialogs/XrefsDialog.h"
|
||||||
|
#include "utils/HexAsciiHighlighter.h"
|
||||||
|
#include "utils/HexHighlighter.h"
|
||||||
|
#include <QShortcut>
|
||||||
|
#include <QScrollBar>
|
||||||
|
|
||||||
|
DisassemblyView::DisassemblyView(QWidget *parent) :
|
||||||
|
QDockWidget(parent),
|
||||||
|
mDisasTextEdit(new QTextEdit(this))
|
||||||
|
{
|
||||||
|
// Configure Dock
|
||||||
|
this->setWidget(mDisasTextEdit);
|
||||||
|
this->setAllowedAreas(Qt::AllDockWidgetAreas);
|
||||||
|
|
||||||
|
// TODO Use Settings
|
||||||
|
mDisasTextEdit->setFont(QFont("Monospace", 10));
|
||||||
|
|
||||||
|
// Increase asm text edit margin
|
||||||
|
QTextDocument *asm_docu = mDisasTextEdit->document();
|
||||||
|
asm_docu->setDocumentMargin(10);
|
||||||
|
|
||||||
|
// Setup disasm highlight
|
||||||
|
connect(mDisasTextEdit, SIGNAL(cursorPositionChanged()), this, SLOT(highlightCurrentLine()));
|
||||||
|
highlightCurrentLine();
|
||||||
|
|
||||||
|
// Event filter to intercept double clicks in the textbox
|
||||||
|
mDisasTextEdit->viewport()->installEventFilter(this);
|
||||||
|
|
||||||
|
// Set Disas context menu
|
||||||
|
mDisasTextEdit->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||||
|
connect(mDisasTextEdit, SIGNAL(customContextMenuRequested(const QPoint &)),
|
||||||
|
this, SLOT(showDisasContextMenu(const QPoint &)));
|
||||||
|
|
||||||
|
// x or X to show XRefs
|
||||||
|
connect(new QShortcut(QKeySequence(Qt::Key_X), mDisasTextEdit),
|
||||||
|
SIGNAL(activated()), this, SLOT(showXrefsDialog()));
|
||||||
|
connect(new QShortcut(Qt::SHIFT + Qt::Key_X, mDisasTextEdit),
|
||||||
|
SIGNAL(activated()), this, SLOT(showXrefsDialog()));
|
||||||
|
|
||||||
|
// Scrollbar
|
||||||
|
connect(mDisasTextEdit->verticalScrollBar(), SIGNAL(valueChanged(int)), this, SLOT(disasmScrolled()));
|
||||||
|
|
||||||
|
// TODO Shortcuts
|
||||||
|
// Semicolon to add comment
|
||||||
|
//QShortcut *comment_shortcut = new QShortcut(QKeySequence(Qt::Key_Semicolon), mDisasTextEdit);
|
||||||
|
//connect(comment_shortcut, SIGNAL(activated()), this, SLOT(on_actionDisasAdd_comment_triggered()));
|
||||||
|
//comment_shortcut->setContext(Qt::WidgetShortcut);
|
||||||
|
|
||||||
|
// N to rename function
|
||||||
|
//QShortcut *rename_shortcut = new QShortcut(QKeySequence(Qt::Key_N), mDisasTextEdit);
|
||||||
|
//connect(rename_shortcut, SIGNAL(activated()), this, SLOT(on_actionFunctionsRename_triggered()));
|
||||||
|
//rename_shortcut->setContext(Qt::WidgetShortcut);
|
||||||
|
|
||||||
|
// Esc to seek back
|
||||||
|
//QShortcut *back_shortcut = new QShortcut(QKeySequence(Qt::Key_Escape), mDisasTextEdit);
|
||||||
|
//connect(back_shortcut, SIGNAL(activated()), this, SLOT(seek_back()));
|
||||||
|
//back_shortcut->setContext(Qt::WidgetShortcut);
|
||||||
|
|
||||||
|
// CTRL + R to refresh the disasm
|
||||||
|
//QShortcut *refresh_shortcut = new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_R), mDisasTextEdit);
|
||||||
|
//connect(refresh_shortcut, SIGNAL(activated()), this, SLOT(refreshDisasm()));
|
||||||
|
//refresh_shortcut->setContext(Qt::WidgetShortcut);
|
||||||
|
|
||||||
|
// Seek signal
|
||||||
|
connect(CutterCore::getInstance(), SIGNAL(seekChanged(RVA)), this, SLOT(on_seekChanged(RVA)));
|
||||||
|
}
|
||||||
|
|
||||||
|
DisassemblyView::DisassemblyView(const QString &title, QWidget *parent) :
|
||||||
|
DisassemblyView(parent)
|
||||||
|
{
|
||||||
|
this->setWindowTitle(title);
|
||||||
|
}
|
||||||
|
void DisassemblyView::highlightCurrentLine()
|
||||||
|
{
|
||||||
|
QList<QTextEdit::ExtraSelection> extraSelections;
|
||||||
|
|
||||||
|
// Highlight the current line in yellow
|
||||||
|
if (mDisasTextEdit->isReadOnly())
|
||||||
|
{
|
||||||
|
QTextEdit::ExtraSelection selection;
|
||||||
|
|
||||||
|
QColor lineColor = QColor(190, 144, 212);
|
||||||
|
|
||||||
|
selection.format.setBackground(lineColor);
|
||||||
|
selection.format.setProperty(QTextFormat::FullWidthSelection, true);
|
||||||
|
selection.cursor = mDisasTextEdit->textCursor();
|
||||||
|
selection.cursor.clearSelection();
|
||||||
|
extraSelections.append(selection);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Highlight the current word
|
||||||
|
QTextCursor cursor = mDisasTextEdit->textCursor();
|
||||||
|
cursor.select(QTextCursor::WordUnderCursor);
|
||||||
|
|
||||||
|
QTextEdit::ExtraSelection currentWord;
|
||||||
|
|
||||||
|
QColor blueColor = QColor(Qt::blue).lighter(160);
|
||||||
|
currentWord.format.setBackground(blueColor);
|
||||||
|
|
||||||
|
currentWord.cursor = cursor;
|
||||||
|
extraSelections.append(currentWord);
|
||||||
|
currentWord.cursor.clearSelection();
|
||||||
|
|
||||||
|
// Highlight all the words in the document same as the actual one
|
||||||
|
QString searchString = cursor.selectedText();
|
||||||
|
QTextDocument *document = mDisasTextEdit->document();
|
||||||
|
|
||||||
|
//QTextCursor highlightCursor(document);
|
||||||
|
QTextEdit::ExtraSelection highlightSelection;
|
||||||
|
highlightSelection.cursor = cursor;
|
||||||
|
highlightSelection.format.setBackground(blueColor);
|
||||||
|
QTextCursor cursor2(document);
|
||||||
|
|
||||||
|
cursor2.beginEditBlock();
|
||||||
|
|
||||||
|
highlightSelection.cursor.movePosition(QTextCursor::Start, QTextCursor::MoveAnchor);
|
||||||
|
while (!highlightSelection.cursor.isNull() && !highlightSelection.cursor.atEnd())
|
||||||
|
{
|
||||||
|
highlightSelection.cursor = document->find(searchString, highlightSelection.cursor, QTextDocument::FindWholeWords);
|
||||||
|
|
||||||
|
if (!highlightSelection.cursor.isNull())
|
||||||
|
{
|
||||||
|
highlightSelection.cursor.movePosition(QTextCursor::EndOfWord, QTextCursor::KeepAnchor);
|
||||||
|
extraSelections.append(highlightSelection);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cursor2.endEditBlock();
|
||||||
|
|
||||||
|
mDisasTextEdit->setExtraSelections(extraSelections);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DisassemblyView::showDisasContextMenu(const QPoint &pt)
|
||||||
|
{
|
||||||
|
DisassemblyContextMenu menu(this->readCurrentDisassemblyOffset(), mDisasTextEdit);
|
||||||
|
menu.exec(mDisasTextEdit->mapToGlobal(pt));
|
||||||
|
}
|
||||||
|
|
||||||
|
void DisassemblyView::showXrefsDialog()
|
||||||
|
{
|
||||||
|
// Get current offset
|
||||||
|
QTextCursor tc = mDisasTextEdit->textCursor();
|
||||||
|
tc.select(QTextCursor::LineUnderCursor);
|
||||||
|
QString lastline = tc.selectedText();
|
||||||
|
QString ele = lastline.split(" ", QString::SkipEmptyParts)[0];
|
||||||
|
if (ele.contains("0x"))
|
||||||
|
{
|
||||||
|
RVA addr = ele.toLongLong(0, 16);
|
||||||
|
XrefsDialog *dialog = new XrefsDialog(this);
|
||||||
|
dialog->fillRefsForAddress(addr, RAddressString(addr), false);
|
||||||
|
dialog->exec();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RVA DisassemblyView::readCurrentDisassemblyOffset()
|
||||||
|
{
|
||||||
|
// TODO: do this in a different way without parsing the disassembly text
|
||||||
|
QTextCursor tc = mDisasTextEdit->textCursor();
|
||||||
|
tc.select(QTextCursor::LineUnderCursor);
|
||||||
|
QString lastline = tc.selectedText();
|
||||||
|
QStringList parts = lastline.split(" ", QString::SkipEmptyParts);
|
||||||
|
|
||||||
|
if (parts.isEmpty())
|
||||||
|
return RVA_INVALID;
|
||||||
|
|
||||||
|
QString ele = parts[0];
|
||||||
|
if (!ele.contains("0x"))
|
||||||
|
return RVA_INVALID;
|
||||||
|
|
||||||
|
return ele.toULongLong(0, 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DisassemblyView::loadMoreDisassembly()
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Add more disasm as the user scrolls
|
||||||
|
* Not working properly when scrolling upwards
|
||||||
|
* r2 doesn't handle properly 'pd-' for archs with variable instruction size
|
||||||
|
*/
|
||||||
|
// Disconnect scroll signals to add more content
|
||||||
|
disconnect(mDisasTextEdit->verticalScrollBar(), SIGNAL(valueChanged(int)), this, SLOT(disasmScrolled()));
|
||||||
|
|
||||||
|
QScrollBar *sb = mDisasTextEdit->verticalScrollBar();
|
||||||
|
|
||||||
|
bool loaded = false;
|
||||||
|
|
||||||
|
if (sb->value() > sb->maximum() - 10)
|
||||||
|
{
|
||||||
|
//this->main->add_debug_output("End is coming");
|
||||||
|
|
||||||
|
QTextCursor tc = mDisasTextEdit->textCursor();
|
||||||
|
tc.movePosition(QTextCursor::End);
|
||||||
|
RVA offset = readCurrentDisassemblyOffset();
|
||||||
|
|
||||||
|
if (offset != RVA_INVALID)
|
||||||
|
{
|
||||||
|
CutterCore::getInstance()->seek(offset);
|
||||||
|
QString raw = CutterCore::getInstance()->cmd("pd 200");
|
||||||
|
QString txt = raw.section("\n", 1, -1);
|
||||||
|
//this->disasTextEdit->appendPlainText(" ;\n ; New content here\n ;\n " + txt.trimmed());
|
||||||
|
mDisasTextEdit->append(txt.trimmed());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
tc.movePosition(QTextCursor::End);
|
||||||
|
tc.select(QTextCursor::LineUnderCursor);
|
||||||
|
QString lastline = tc.selectedText();
|
||||||
|
//this->main->addDebugOutput("Last line: " + lastline);
|
||||||
|
}
|
||||||
|
|
||||||
|
loaded = true;
|
||||||
|
|
||||||
|
// Code below will be used to append more disasm upwards, one day
|
||||||
|
} /* else if (sb->value() < sb->minimum() + 10) {
|
||||||
|
//this->main->add_debug_output("Begining is coming");
|
||||||
|
|
||||||
|
QTextCursor tc = this->disasTextEdit->textCursor();
|
||||||
|
tc.movePosition( QTextCursor::Start );
|
||||||
|
tc.select( QTextCursor::LineUnderCursor );
|
||||||
|
QString firstline = tc.selectedText();
|
||||||
|
//this->main->add_debug_output("First Line: " + firstline);
|
||||||
|
QString ele = firstline.split(" ", QString::SkipEmptyParts)[0];
|
||||||
|
//this->main->add_debug_output("First Offset: " + ele);
|
||||||
|
if (ele.contains("0x")) {
|
||||||
|
int b = this->disasTextEdit->verticalScrollBar()->maximum();
|
||||||
|
this->core->cmd("ss " + ele);
|
||||||
|
this->core->cmd("so -50");
|
||||||
|
QString raw = this->core->cmd("pd 50");
|
||||||
|
//this->main->add_debug_output(raw);
|
||||||
|
//QString txt = raw.section("\n", 1, -1);
|
||||||
|
//this->main->add_debug_output(txt);
|
||||||
|
tc.movePosition(QTextCursor::Start, QTextCursor::MoveAnchor);
|
||||||
|
//tc.insertText(raw.trimmed() + "\n ;\n ; New content prepended here\n ;\n");
|
||||||
|
int c = this->disasTextEdit->verticalScrollBar()->maximum();
|
||||||
|
int z = c -b;
|
||||||
|
int a = this->disasTextEdit->verticalScrollBar()->sliderPosition();
|
||||||
|
this->disasTextEdit->verticalScrollBar()->setValue(a + z);
|
||||||
|
} else {
|
||||||
|
tc.movePosition( QTextCursor::Start );
|
||||||
|
tc.select( QTextCursor::LineUnderCursor );
|
||||||
|
QString lastline = tc.selectedText();
|
||||||
|
this->main->add_debug_output("Last line: " + lastline);
|
||||||
|
}
|
||||||
|
} */
|
||||||
|
|
||||||
|
// Reconnect scroll signals
|
||||||
|
connect(mDisasTextEdit->verticalScrollBar(), SIGNAL(valueChanged(int)), this, SLOT(disasmScrolled()));
|
||||||
|
|
||||||
|
return loaded;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DisassemblyView::disasmScrolled()
|
||||||
|
{
|
||||||
|
loadMoreDisassembly();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DisassemblyView::refreshDisasm()
|
||||||
|
{
|
||||||
|
// TODO Very slow mostly because of the highlight
|
||||||
|
// Prevent further scroll
|
||||||
|
disconnect(mDisasTextEdit->verticalScrollBar(), SIGNAL(valueChanged(int)), this, SLOT(disasmScrolled()));
|
||||||
|
disconnect(mDisasTextEdit, SIGNAL(cursorPositionChanged()), this, SLOT(on_mDisasTextEdit_cursorPositionChanged()));
|
||||||
|
|
||||||
|
QString disas = CutterCore::getInstance()->cmd("pd 200");
|
||||||
|
|
||||||
|
mDisasTextEdit->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
|
||||||
|
|
||||||
|
mDisasTextEdit->setPlainText(disas.trimmed());
|
||||||
|
|
||||||
|
auto cursor = mDisasTextEdit->textCursor();
|
||||||
|
cursor.setPosition(0);
|
||||||
|
mDisasTextEdit->setTextCursor(cursor);
|
||||||
|
mDisasTextEdit->verticalScrollBar()->setValue(0);
|
||||||
|
|
||||||
|
// load more disassembly if necessary
|
||||||
|
/*static const int load_more_limit = 10; // limit passes, so it can't take forever
|
||||||
|
for (int load_more_i = 0; load_more_i < load_more_limit; load_more_i++)
|
||||||
|
{
|
||||||
|
if (!loadMoreDisassembly())
|
||||||
|
break;
|
||||||
|
mDisasTextEdit->verticalScrollBar()->setValue(0);
|
||||||
|
}*/
|
||||||
|
|
||||||
|
connect(mDisasTextEdit->verticalScrollBar(), SIGNAL(valueChanged(int)), this, SLOT(disasmScrolled()));
|
||||||
|
connect(mDisasTextEdit, SIGNAL(cursorPositionChanged()), this, SLOT(on_mDisasTextEdit_cursorPositionChanged()));
|
||||||
|
//this->on_mDisasTextEdit_cursorPositionChanged();
|
||||||
|
this->highlightDisasms();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DisassemblyView::on_mDisasTextEdit_cursorPositionChanged()
|
||||||
|
{
|
||||||
|
// Get current offset
|
||||||
|
QTextCursor tc = mDisasTextEdit->textCursor();
|
||||||
|
tc.select(QTextCursor::LineUnderCursor);
|
||||||
|
QString lastline = tc.selectedText().trimmed();
|
||||||
|
QList<QString> words = lastline.split(" ", QString::SkipEmptyParts);
|
||||||
|
if (words.length() == 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
QString ele = words[0];
|
||||||
|
// TODO
|
||||||
|
/*if (ele.contains("0x"))
|
||||||
|
{
|
||||||
|
this->fillOffsetInfo(ele);
|
||||||
|
QString at = this->core->cmdFunctionAt(ele);
|
||||||
|
QString deco = this->core->getDecompiledCode(at);
|
||||||
|
|
||||||
|
|
||||||
|
RVA addr = ele.midRef(2).toULongLong(0, 16);
|
||||||
|
// FIXME per widget CursorAddress no?
|
||||||
|
// this->main->setCursorAddress(addr);
|
||||||
|
|
||||||
|
if (deco != "")
|
||||||
|
{
|
||||||
|
ui->decoTextEdit->setPlainText(deco);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ui->decoTextEdit->setPlainText("");
|
||||||
|
}
|
||||||
|
// Get jump information to fill the preview
|
||||||
|
QString jump = this->core->getOffsetJump(ele);
|
||||||
|
if (!jump.isEmpty())
|
||||||
|
{
|
||||||
|
// Fill the preview
|
||||||
|
QString jump_code = this->core->cmd("pdf @ " + jump);
|
||||||
|
ui->previewTextEdit->setPlainText(jump_code.trimmed());
|
||||||
|
ui->previewTextEdit->moveCursor(QTextCursor::End);
|
||||||
|
ui->previewTextEdit->find(jump.trimmed(), QTextDocument::FindBackward);
|
||||||
|
ui->previewTextEdit->moveCursor(QTextCursor::StartOfWord, QTextCursor::MoveAnchor);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ui->previewTextEdit->setPlainText("");
|
||||||
|
}
|
||||||
|
//this->main->add_debug_output("Fcn at: '" + at + "'");
|
||||||
|
if (this->last_fcn != at)
|
||||||
|
{
|
||||||
|
this->last_fcn = at;
|
||||||
|
//this->main->add_debug_output("New Fcn: '" + this->last_fcn + "'");
|
||||||
|
// Refresh function information at sidebar
|
||||||
|
ui->fcnNameEdit->setText(at);
|
||||||
|
// FIXME TITLE?
|
||||||
|
// this->main->memoryDock->setWindowTitle(at);
|
||||||
|
//this->main->memoryDock->create_graph(ele);
|
||||||
|
this->setMiniGraph(at);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DisassemblyView::eventFilter(QObject *obj, QEvent *event)
|
||||||
|
{
|
||||||
|
if ((obj == mDisasTextEdit || obj == mDisasTextEdit->viewport()) && event->type() == QEvent::MouseButtonDblClick)
|
||||||
|
{
|
||||||
|
QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event);
|
||||||
|
//qDebug()<<QString("Click location: (%1,%2)").arg(mouseEvent->x()).arg(mouseEvent->y());
|
||||||
|
QTextCursor cursor = mDisasTextEdit->cursorForPosition(QPoint(mouseEvent->x(), mouseEvent->y()));
|
||||||
|
cursor.select(QTextCursor::LineUnderCursor);
|
||||||
|
QString lastline = cursor.selectedText();
|
||||||
|
auto eles = lastline.split(" ", QString::SkipEmptyParts);
|
||||||
|
QString ele = eles.isEmpty() ? "" : eles[0];
|
||||||
|
if (ele.contains("0x"))
|
||||||
|
{
|
||||||
|
QString jump = CutterCore::getInstance()->getOffsetJump(ele);
|
||||||
|
if (!jump.isEmpty())
|
||||||
|
{
|
||||||
|
if (jump.contains("0x"))
|
||||||
|
{
|
||||||
|
QString fcn = CutterCore::getInstance()->cmdFunctionAt(jump);
|
||||||
|
if (!fcn.isEmpty())
|
||||||
|
{
|
||||||
|
RVA addr = jump.trimmed().toULongLong(0, 16);
|
||||||
|
CutterCore::getInstance()->seek(addr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
RVA addr = CutterCore::getInstance()->cmd("?v " + jump).toULongLong(0, 16);
|
||||||
|
CutterCore::getInstance()->seek(addr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return QDockWidget::eventFilter(obj, event);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DisassemblyView::on_seekChanged(RVA offset)
|
||||||
|
{
|
||||||
|
Q_UNUSED(offset);
|
||||||
|
refreshDisasm();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DisassemblyView::highlightDisasms()
|
||||||
|
{
|
||||||
|
// Syntax Highliting
|
||||||
|
// TODO doing new all the time
|
||||||
|
// TODO Seems very very heavy -- merge it with Graph one
|
||||||
|
Highlighter *highlighter = new Highlighter(mDisasTextEdit->document());
|
||||||
|
Highlighter *highlighter_5 = new Highlighter(mDisasTextEdit->document());
|
||||||
|
AsciiHighlighter *ascii_highlighter = new AsciiHighlighter(mDisasTextEdit->document());
|
||||||
|
HexHighlighter *hex_highlighter = new HexHighlighter(mDisasTextEdit->document());
|
||||||
|
Highlighter *preview_highlighter = new Highlighter(mDisasTextEdit->document());
|
||||||
|
Highlighter *deco_highlighter = new Highlighter(mDisasTextEdit->document());
|
||||||
|
}
|
35
src/widgets/DisassemblyView.h
Normal file
35
src/widgets/DisassemblyView.h
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
#ifndef DISASSEMBLYVIEW_H
|
||||||
|
#define DISASSEMBLYVIEW_H
|
||||||
|
|
||||||
|
#include <QDockWidget>
|
||||||
|
#include <QTextEdit>
|
||||||
|
#include "cutter.h"
|
||||||
|
|
||||||
|
class DisassemblyView : public QDockWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit DisassemblyView(QWidget *parent = nullptr);
|
||||||
|
explicit DisassemblyView(const QString &title, QWidget *parent = nullptr);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void highlightCurrentLine();
|
||||||
|
void disasmScrolled();
|
||||||
|
void showDisasContextMenu(const QPoint &pt);
|
||||||
|
void showXrefsDialog();
|
||||||
|
void on_mDisasTextEdit_cursorPositionChanged();
|
||||||
|
void on_seekChanged(RVA offset);
|
||||||
|
void refreshDisasm();
|
||||||
|
|
||||||
|
private:
|
||||||
|
QTextEdit *mDisasTextEdit;
|
||||||
|
|
||||||
|
RVA readCurrentDisassemblyOffset();
|
||||||
|
bool loadMoreDisassembly();
|
||||||
|
void highlightDisasms();
|
||||||
|
bool eventFilter(QObject *obj, QEvent *event);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // DISASSEMBLYVIEW_H
|
@ -4,8 +4,6 @@
|
|||||||
|
|
||||||
#include "MainWindow.h"
|
#include "MainWindow.h"
|
||||||
#include "utils/Helpers.h"
|
#include "utils/Helpers.h"
|
||||||
#include "dialogs/XrefsDialog.h"
|
|
||||||
#include "menus/DisassemblyContextMenu.h"
|
|
||||||
|
|
||||||
#include <QTemporaryFile>
|
#include <QTemporaryFile>
|
||||||
#include <QFontDialog>
|
#include <QFontDialog>
|
||||||
@ -27,8 +25,6 @@ MemoryWidget::MemoryWidget() :
|
|||||||
core(CutterCore::getInstance())
|
core(CutterCore::getInstance())
|
||||||
{
|
{
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
|
|
||||||
this->disasTextEdit = ui->disasTextEdit_2;
|
|
||||||
this->hexOffsetText = ui->hexOffsetText_2;
|
this->hexOffsetText = ui->hexOffsetText_2;
|
||||||
this->hexHexText = ui->hexHexText_2;
|
this->hexHexText = ui->hexHexText_2;
|
||||||
this->hexDisasTextEdit = ui->hexDisasTextEdit_2;
|
this->hexDisasTextEdit = ui->hexDisasTextEdit_2;
|
||||||
@ -44,13 +40,6 @@ MemoryWidget::MemoryWidget() :
|
|||||||
disasm_top_offset = 0;
|
disasm_top_offset = 0;
|
||||||
next_disasm_top_offset = 0;
|
next_disasm_top_offset = 0;
|
||||||
|
|
||||||
// Increase asm text edit margin
|
|
||||||
QTextDocument *asm_docu = this->disasTextEdit->document();
|
|
||||||
asm_docu->setDocumentMargin(10);
|
|
||||||
|
|
||||||
// Setup disasm highlight
|
|
||||||
connect(ui->disasTextEdit_2, SIGNAL(cursorPositionChanged()), this, SLOT(highlightCurrentLine()));
|
|
||||||
highlightCurrentLine();
|
|
||||||
//this->on_actionSettings_menu_1_triggered();
|
//this->on_actionSettings_menu_1_triggered();
|
||||||
|
|
||||||
// Setup hex highlight
|
// Setup hex highlight
|
||||||
@ -81,7 +70,6 @@ MemoryWidget::MemoryWidget() :
|
|||||||
ui->fcnNameEdit->setTextMargins(5, 0, 0, 0);
|
ui->fcnNameEdit->setTextMargins(5, 0, 0, 0);
|
||||||
|
|
||||||
// Normalize fonts for other OS
|
// Normalize fonts for other OS
|
||||||
qhelpers::normalizeFont(this->disasTextEdit);
|
|
||||||
qhelpers::normalizeEditFont(this->hexOffsetText);
|
qhelpers::normalizeEditFont(this->hexOffsetText);
|
||||||
qhelpers::normalizeEditFont(this->hexHexText);
|
qhelpers::normalizeEditFont(this->hexHexText);
|
||||||
qhelpers::normalizeEditFont(this->hexASCIIText);
|
qhelpers::normalizeEditFont(this->hexASCIIText);
|
||||||
@ -92,18 +80,10 @@ MemoryWidget::MemoryWidget() :
|
|||||||
memMenu->addAction(ui->actionSettings_menu_1);
|
memMenu->addAction(ui->actionSettings_menu_1);
|
||||||
ui->memSettingsButton_2->setMenu(memMenu);
|
ui->memSettingsButton_2->setMenu(memMenu);
|
||||||
|
|
||||||
// Event filter to intercept double clicks in the textbox
|
|
||||||
ui->disasTextEdit_2->viewport()->installEventFilter(this);
|
|
||||||
|
|
||||||
// Set Splitter stretch factor
|
// Set Splitter stretch factor
|
||||||
ui->splitter->setStretchFactor(0, 10);
|
ui->splitter->setStretchFactor(0, 10);
|
||||||
ui->splitter->setStretchFactor(1, 1);
|
ui->splitter->setStretchFactor(1, 1);
|
||||||
|
|
||||||
// Set Disas context menu
|
|
||||||
ui->disasTextEdit_2->setContextMenuPolicy(Qt::CustomContextMenu);
|
|
||||||
connect(ui->disasTextEdit_2, SIGNAL(customContextMenuRequested(const QPoint &)),
|
|
||||||
this, SLOT(showDisasContextMenu(const QPoint &)));
|
|
||||||
|
|
||||||
// Set hexdump context menu
|
// Set hexdump context menu
|
||||||
ui->hexHexText_2->setContextMenuPolicy(Qt::CustomContextMenu);
|
ui->hexHexText_2->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||||
connect(ui->hexHexText_2, SIGNAL(customContextMenuRequested(const QPoint &)),
|
connect(ui->hexHexText_2, SIGNAL(customContextMenuRequested(const QPoint &)),
|
||||||
@ -128,39 +108,12 @@ MemoryWidget::MemoryWidget() :
|
|||||||
connect(ui->hexASCIIText_2->verticalScrollBar(), SIGNAL(valueChanged(int)),
|
connect(ui->hexASCIIText_2->verticalScrollBar(), SIGNAL(valueChanged(int)),
|
||||||
ui->hexHexText_2->verticalScrollBar(), SLOT(setValue(int)));
|
ui->hexHexText_2->verticalScrollBar(), SLOT(setValue(int)));
|
||||||
|
|
||||||
// x or X to show XRefs
|
|
||||||
connect(new QShortcut(QKeySequence(Qt::Key_X), ui->disasTextEdit_2),
|
|
||||||
SIGNAL(activated()), this, SLOT(showXrefsDialog()));
|
|
||||||
connect(new QShortcut(Qt::SHIFT + Qt::Key_X, ui->disasTextEdit_2),
|
|
||||||
SIGNAL(activated()), this, SLOT(showXrefsDialog()));
|
|
||||||
|
|
||||||
// Space to switch between disassembly and graph
|
// Space to switch between disassembly and graph
|
||||||
QShortcut *graph_shortcut = new QShortcut(QKeySequence(Qt::Key_Space), this);
|
QShortcut *graph_shortcut = new QShortcut(QKeySequence(Qt::Key_Space), this);
|
||||||
connect(graph_shortcut, SIGNAL(activated()), this, SLOT(cycleViews()));
|
connect(graph_shortcut, SIGNAL(activated()), this, SLOT(cycleViews()));
|
||||||
//graph_shortcut->setContext(Qt::WidgetShortcut);
|
//graph_shortcut->setContext(Qt::WidgetShortcut);
|
||||||
|
|
||||||
// Semicolon to add comment
|
|
||||||
QShortcut *comment_shortcut = new QShortcut(QKeySequence(Qt::Key_Semicolon), ui->disasTextEdit_2);
|
|
||||||
connect(comment_shortcut, SIGNAL(activated()), this, SLOT(on_actionDisasAdd_comment_triggered()));
|
|
||||||
comment_shortcut->setContext(Qt::WidgetShortcut);
|
|
||||||
|
|
||||||
// N to rename function
|
|
||||||
QShortcut *rename_shortcut = new QShortcut(QKeySequence(Qt::Key_N), ui->disasTextEdit_2);
|
|
||||||
connect(rename_shortcut, SIGNAL(activated()), this, SLOT(on_actionFunctionsRename_triggered()));
|
|
||||||
rename_shortcut->setContext(Qt::WidgetShortcut);
|
|
||||||
|
|
||||||
// Esc to seek back
|
|
||||||
QShortcut *back_shortcut = new QShortcut(QKeySequence(Qt::Key_Escape), ui->disasTextEdit_2);
|
|
||||||
connect(back_shortcut, SIGNAL(activated()), this, SLOT(seek_back()));
|
|
||||||
back_shortcut->setContext(Qt::WidgetShortcut);
|
|
||||||
|
|
||||||
// CTRL + R to refresh the disasm
|
|
||||||
QShortcut *refresh_shortcut = new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_R), ui->disasTextEdit_2);
|
|
||||||
connect(refresh_shortcut, SIGNAL(activated()), this, SLOT(refreshDisasm()));
|
|
||||||
refresh_shortcut->setContext(Qt::WidgetShortcut);
|
|
||||||
|
|
||||||
// Control Disasm and Hex scroll to add more contents
|
// Control Disasm and Hex scroll to add more contents
|
||||||
connect(this->disasTextEdit->verticalScrollBar(), SIGNAL(valueChanged(int)), this, SLOT(disasmScrolled()));
|
|
||||||
connect(this->hexASCIIText->verticalScrollBar(), SIGNAL(valueChanged(int)), this, SLOT(hexScrolled()));
|
connect(this->hexASCIIText->verticalScrollBar(), SIGNAL(valueChanged(int)), this, SLOT(hexScrolled()));
|
||||||
|
|
||||||
connect(core, SIGNAL(seekChanged(RVA)), this, SLOT(on_seekChanged(RVA)));
|
connect(core, SIGNAL(seekChanged(RVA)), this, SLOT(on_seekChanged(RVA)));
|
||||||
@ -187,78 +140,6 @@ void MemoryWidget::on_cursorAddressChanged(RVA addr)
|
|||||||
/*
|
/*
|
||||||
* Text highlight functions
|
* Text highlight functions
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void MemoryWidget::highlightDisasms()
|
|
||||||
{
|
|
||||||
// Syntax Highliting
|
|
||||||
highlighter = new Highlighter(ui->disasTextEdit_2->document());
|
|
||||||
highlighter_5 = new Highlighter(ui->hexDisasTextEdit_2->document());
|
|
||||||
ascii_highlighter = new AsciiHighlighter(ui->hexASCIIText_2->document());
|
|
||||||
hex_highlighter = new HexHighlighter(ui->hexHexText_2->document());
|
|
||||||
preview_highlighter = new Highlighter(ui->previewTextEdit->document());
|
|
||||||
deco_highlighter = new Highlighter(ui->decoTextEdit->document());
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void MemoryWidget::highlightCurrentLine()
|
|
||||||
{
|
|
||||||
QList<QTextEdit::ExtraSelection> extraSelections;
|
|
||||||
|
|
||||||
// Highlight the current line in yellow
|
|
||||||
if (ui->disasTextEdit_2->isReadOnly())
|
|
||||||
{
|
|
||||||
QTextEdit::ExtraSelection selection;
|
|
||||||
|
|
||||||
QColor lineColor = QColor(190, 144, 212);
|
|
||||||
|
|
||||||
selection.format.setBackground(lineColor);
|
|
||||||
selection.format.setProperty(QTextFormat::FullWidthSelection, true);
|
|
||||||
selection.cursor = ui->disasTextEdit_2->textCursor();
|
|
||||||
selection.cursor.clearSelection();
|
|
||||||
extraSelections.append(selection);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Highlight the current word
|
|
||||||
QTextCursor cursor = ui->disasTextEdit_2->textCursor();
|
|
||||||
cursor.select(QTextCursor::WordUnderCursor);
|
|
||||||
|
|
||||||
QTextEdit::ExtraSelection currentWord;
|
|
||||||
|
|
||||||
QColor blueColor = QColor(Qt::blue).lighter(160);
|
|
||||||
currentWord.format.setBackground(blueColor);
|
|
||||||
|
|
||||||
currentWord.cursor = cursor;
|
|
||||||
extraSelections.append(currentWord);
|
|
||||||
currentWord.cursor.clearSelection();
|
|
||||||
|
|
||||||
// Highlight all the words in the document same as the actual one
|
|
||||||
QString searchString = cursor.selectedText();
|
|
||||||
QTextDocument *document = ui->disasTextEdit_2->document();
|
|
||||||
|
|
||||||
//QTextCursor highlightCursor(document);
|
|
||||||
QTextEdit::ExtraSelection highlightSelection;
|
|
||||||
highlightSelection.cursor = cursor;
|
|
||||||
highlightSelection.format.setBackground(blueColor);
|
|
||||||
QTextCursor cursor2(document);
|
|
||||||
|
|
||||||
cursor2.beginEditBlock();
|
|
||||||
|
|
||||||
highlightSelection.cursor.movePosition(QTextCursor::Start, QTextCursor::MoveAnchor);
|
|
||||||
while (!highlightSelection.cursor.isNull() && !highlightSelection.cursor.atEnd())
|
|
||||||
{
|
|
||||||
highlightSelection.cursor = document->find(searchString, highlightSelection.cursor, QTextDocument::FindWholeWords);
|
|
||||||
|
|
||||||
if (!highlightSelection.cursor.isNull())
|
|
||||||
{
|
|
||||||
highlightSelection.cursor.movePosition(QTextCursor::EndOfWord, QTextCursor::KeepAnchor);
|
|
||||||
extraSelections.append(highlightSelection);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
cursor2.endEditBlock();
|
|
||||||
|
|
||||||
ui->disasTextEdit_2->setExtraSelections(extraSelections);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MemoryWidget::highlightHexCurrentLine()
|
void MemoryWidget::highlightHexCurrentLine()
|
||||||
{
|
{
|
||||||
QList<QTextEdit::ExtraSelection> extraSelections;
|
QList<QTextEdit::ExtraSelection> extraSelections;
|
||||||
@ -369,24 +250,6 @@ void MemoryWidget::highlightDecoCurrentLine()
|
|||||||
ui->decoTextEdit->setExtraSelections(extraSelections);
|
ui->decoTextEdit->setExtraSelections(extraSelections);
|
||||||
}
|
}
|
||||||
|
|
||||||
RVA MemoryWidget::readCurrentDisassemblyOffset()
|
|
||||||
{
|
|
||||||
// TODO: do this in a different way without parsing the disassembly text
|
|
||||||
QTextCursor tc = this->disasTextEdit->textCursor();
|
|
||||||
tc.select(QTextCursor::LineUnderCursor);
|
|
||||||
QString lastline = tc.selectedText();
|
|
||||||
QStringList parts = lastline.split(" ", QString::SkipEmptyParts);
|
|
||||||
|
|
||||||
if (parts.isEmpty())
|
|
||||||
return RVA_INVALID;
|
|
||||||
|
|
||||||
QString ele = parts[0];
|
|
||||||
if (!ele.contains("0x"))
|
|
||||||
return RVA_INVALID;
|
|
||||||
|
|
||||||
return ele.toULongLong(0, 16);
|
|
||||||
}
|
|
||||||
|
|
||||||
MemoryWidget::~MemoryWidget() {}
|
MemoryWidget::~MemoryWidget() {}
|
||||||
|
|
||||||
void MemoryWidget::setup()
|
void MemoryWidget::setup()
|
||||||
@ -422,159 +285,6 @@ void MemoryWidget::fillPlugins()
|
|||||||
ui->hexArchComboBox_2->insertItems(0, core->getAsmPluginNames());
|
ui->hexArchComboBox_2->insertItems(0, core->getAsmPluginNames());
|
||||||
}
|
}
|
||||||
|
|
||||||
void MemoryWidget::addTextDisasm(QString txt)
|
|
||||||
{
|
|
||||||
//QTextDocument *document = ui->disasTextEdit_2->document();
|
|
||||||
//document->undo();
|
|
||||||
ui->disasTextEdit_2->appendPlainText(txt);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MemoryWidget::replaceTextDisasm(QString txt)
|
|
||||||
{
|
|
||||||
//QTextDocument *document = ui->disasTextEdit_2->document();
|
|
||||||
ui->disasTextEdit_2->clear();
|
|
||||||
//document->undo();
|
|
||||||
ui->disasTextEdit_2->setPlainText(txt);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool MemoryWidget::loadMoreDisassembly()
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* Add more disasm as the user scrolls
|
|
||||||
* Not working properly when scrolling upwards
|
|
||||||
* r2 doesn't handle properly 'pd-' for archs with variable instruction size
|
|
||||||
*/
|
|
||||||
// Disconnect scroll signals to add more content
|
|
||||||
disconnect(this->disasTextEdit->verticalScrollBar(), SIGNAL(valueChanged(int)), this, SLOT(disasmScrolled()));
|
|
||||||
|
|
||||||
QScrollBar *sb = this->disasTextEdit->verticalScrollBar();
|
|
||||||
|
|
||||||
bool loaded = false;
|
|
||||||
|
|
||||||
if (sb->value() > sb->maximum() - 10)
|
|
||||||
{
|
|
||||||
//this->main->add_debug_output("End is coming");
|
|
||||||
|
|
||||||
QTextCursor tc = this->disasTextEdit->textCursor();
|
|
||||||
tc.movePosition(QTextCursor::End);
|
|
||||||
RVA offset = readCurrentDisassemblyOffset();
|
|
||||||
|
|
||||||
if (offset != RVA_INVALID)
|
|
||||||
{
|
|
||||||
core->seek(offset);
|
|
||||||
QString raw = this->core->cmd("pd 200");
|
|
||||||
QString txt = raw.section("\n", 1, -1);
|
|
||||||
//this->disasTextEdit->appendPlainText(" ;\n ; New content here\n ;\n " + txt.trimmed());
|
|
||||||
this->disasTextEdit->appendPlainText(txt.trimmed());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
tc.movePosition(QTextCursor::End);
|
|
||||||
tc.select(QTextCursor::LineUnderCursor);
|
|
||||||
QString lastline = tc.selectedText();
|
|
||||||
//this->main->addDebugOutput("Last line: " + lastline);
|
|
||||||
}
|
|
||||||
|
|
||||||
loaded = true;
|
|
||||||
|
|
||||||
// Code below will be used to append more disasm upwards, one day
|
|
||||||
} /* else if (sb->value() < sb->minimum() + 10) {
|
|
||||||
//this->main->add_debug_output("Begining is coming");
|
|
||||||
|
|
||||||
QTextCursor tc = this->disasTextEdit->textCursor();
|
|
||||||
tc.movePosition( QTextCursor::Start );
|
|
||||||
tc.select( QTextCursor::LineUnderCursor );
|
|
||||||
QString firstline = tc.selectedText();
|
|
||||||
//this->main->add_debug_output("First Line: " + firstline);
|
|
||||||
QString ele = firstline.split(" ", QString::SkipEmptyParts)[0];
|
|
||||||
//this->main->add_debug_output("First Offset: " + ele);
|
|
||||||
if (ele.contains("0x")) {
|
|
||||||
int b = this->disasTextEdit->verticalScrollBar()->maximum();
|
|
||||||
this->core->cmd("ss " + ele);
|
|
||||||
this->core->cmd("so -50");
|
|
||||||
QString raw = this->core->cmd("pd 50");
|
|
||||||
//this->main->add_debug_output(raw);
|
|
||||||
//QString txt = raw.section("\n", 1, -1);
|
|
||||||
//this->main->add_debug_output(txt);
|
|
||||||
tc.movePosition(QTextCursor::Start, QTextCursor::MoveAnchor);
|
|
||||||
//tc.insertText(raw.trimmed() + "\n ;\n ; New content prepended here\n ;\n");
|
|
||||||
int c = this->disasTextEdit->verticalScrollBar()->maximum();
|
|
||||||
int z = c -b;
|
|
||||||
int a = this->disasTextEdit->verticalScrollBar()->sliderPosition();
|
|
||||||
this->disasTextEdit->verticalScrollBar()->setValue(a + z);
|
|
||||||
} else {
|
|
||||||
tc.movePosition( QTextCursor::Start );
|
|
||||||
tc.select( QTextCursor::LineUnderCursor );
|
|
||||||
QString lastline = tc.selectedText();
|
|
||||||
this->main->add_debug_output("Last line: " + lastline);
|
|
||||||
}
|
|
||||||
} */
|
|
||||||
|
|
||||||
// Reconnect scroll signals
|
|
||||||
connect(this->disasTextEdit->verticalScrollBar(), SIGNAL(valueChanged(int)), this, SLOT(disasmScrolled()));
|
|
||||||
|
|
||||||
return loaded;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void MemoryWidget::disasmScrolled()
|
|
||||||
{
|
|
||||||
loadMoreDisassembly();
|
|
||||||
}
|
|
||||||
|
|
||||||
void MemoryWidget::refreshDisasm()
|
|
||||||
{
|
|
||||||
RCoreLocked lcore = this->core->core();
|
|
||||||
|
|
||||||
// Prevent further scroll
|
|
||||||
disconnect(this->disasTextEdit->verticalScrollBar(), SIGNAL(valueChanged(int)), this, SLOT(disasmScrolled()));
|
|
||||||
disconnect(this->disasTextEdit, SIGNAL(cursorPositionChanged()), this, SLOT(on_disasTextEdit_2_cursorPositionChanged()));
|
|
||||||
|
|
||||||
RVA offset = next_disasm_top_offset;
|
|
||||||
next_disasm_top_offset = RVA_INVALID;
|
|
||||||
bool offset_changed = offset != RVA_INVALID;
|
|
||||||
|
|
||||||
if (offset_changed) // new offset (seek)
|
|
||||||
{
|
|
||||||
disasm_top_offset = offset;
|
|
||||||
this->core->cmd(QString("s %1").arg(offset));
|
|
||||||
}
|
|
||||||
else // simple refresh
|
|
||||||
{
|
|
||||||
core->cmd(QString("s %1").arg(disasm_top_offset));
|
|
||||||
}
|
|
||||||
|
|
||||||
QString txt2 = this->core->cmd("pd 200");
|
|
||||||
|
|
||||||
disasTextEdit->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
|
|
||||||
|
|
||||||
// if the offset changed, jump to the top
|
|
||||||
// otherwise try to retain the position
|
|
||||||
int cursor_pos = offset_changed ? 0 : disasTextEdit->textCursor().position();
|
|
||||||
int scroll_pos = offset_changed ? 0 : disasTextEdit->verticalScrollBar()->value();
|
|
||||||
|
|
||||||
this->disasTextEdit->setPlainText(txt2.trimmed());
|
|
||||||
|
|
||||||
auto cursor = disasTextEdit->textCursor();
|
|
||||||
cursor.setPosition(cursor_pos);
|
|
||||||
disasTextEdit->setTextCursor(cursor);
|
|
||||||
|
|
||||||
disasTextEdit->verticalScrollBar()->setValue(scroll_pos);
|
|
||||||
|
|
||||||
// load more disassembly if necessary
|
|
||||||
static const int load_more_limit = 10; // limit passes, so it can't take forever
|
|
||||||
for (int load_more_i = 0; load_more_i < load_more_limit; load_more_i++)
|
|
||||||
{
|
|
||||||
if (!loadMoreDisassembly())
|
|
||||||
break;
|
|
||||||
disasTextEdit->verticalScrollBar()->setValue(scroll_pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
connect(this->disasTextEdit->verticalScrollBar(), SIGNAL(valueChanged(int)), this, SLOT(disasmScrolled()));
|
|
||||||
connect(this->disasTextEdit, SIGNAL(cursorPositionChanged()), this, SLOT(on_disasTextEdit_2_cursorPositionChanged()));
|
|
||||||
this->on_disasTextEdit_2_cursorPositionChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
void MemoryWidget::refreshHexdump(const QString &where)
|
void MemoryWidget::refreshHexdump(const QString &where)
|
||||||
{
|
{
|
||||||
RCoreLocked lcore = this->core->core();
|
RCoreLocked lcore = this->core->core();
|
||||||
@ -714,14 +424,6 @@ QList<QString> MemoryWidget::get_hexdump(const QString &offset)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void MemoryWidget::seek_to(const QString &offset)
|
|
||||||
{
|
|
||||||
this->disasTextEdit->moveCursor(QTextCursor::End);
|
|
||||||
this->disasTextEdit->find(offset, QTextDocument::FindBackward);
|
|
||||||
this->disasTextEdit->moveCursor(QTextCursor::StartOfWord, QTextCursor::MoveAnchor);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MemoryWidget::resizeHexdump()
|
void MemoryWidget::resizeHexdump()
|
||||||
{
|
{
|
||||||
this->hexOffsetText->setMinimumWidth(this->hexOffsetText->document()->size().width());
|
this->hexOffsetText->setMinimumWidth(this->hexOffsetText->document()->size().width());
|
||||||
@ -975,12 +677,6 @@ void MemoryWidget::showHexASCIIContextMenu(const QPoint &pt)
|
|||||||
delete menu;
|
delete menu;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MemoryWidget::showDisasContextMenu(const QPoint &pt)
|
|
||||||
{
|
|
||||||
DisassemblyContextMenu menu(this->readCurrentDisassemblyOffset(), ui->disasTextEdit_2);
|
|
||||||
menu.exec(ui->disasTextEdit_2->mapToGlobal(pt));
|
|
||||||
}
|
|
||||||
|
|
||||||
void MemoryWidget::on_showInfoButton_2_clicked()
|
void MemoryWidget::on_showInfoButton_2_clicked()
|
||||||
{
|
{
|
||||||
if (ui->showInfoButton_2->isChecked())
|
if (ui->showInfoButton_2->isChecked())
|
||||||
@ -1009,23 +705,6 @@ void MemoryWidget::on_offsetToolButton_clicked()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void MemoryWidget::showXrefsDialog()
|
|
||||||
{
|
|
||||||
// Get current offset
|
|
||||||
QTextCursor tc = this->disasTextEdit->textCursor();
|
|
||||||
tc.select(QTextCursor::LineUnderCursor);
|
|
||||||
QString lastline = tc.selectedText();
|
|
||||||
QString ele = lastline.split(" ", QString::SkipEmptyParts)[0];
|
|
||||||
if (ele.contains("0x"))
|
|
||||||
{
|
|
||||||
RVA addr = ele.toLongLong(0, 16);
|
|
||||||
XrefsDialog *x = new XrefsDialog(this);
|
|
||||||
x->fillRefsForAddress(addr, RAddressString(addr), false);
|
|
||||||
x->exec();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Show widgets
|
* Show widgets
|
||||||
*/
|
*/
|
||||||
@ -1055,9 +734,9 @@ void MemoryWidget::on_actionSettings_menu_1_triggered()
|
|||||||
{
|
{
|
||||||
bool ok = true;
|
bool ok = true;
|
||||||
|
|
||||||
// QFont font = QFont("Monospace", 8);
|
QFont font = QFont("Monospace", 8);
|
||||||
// TODO Use global configuration
|
// TODO Use global configuration
|
||||||
QFont font = QFontDialog::getFont(&ok, ui->disasTextEdit_2->font(), this);
|
//QFont font = QFontDialog::getFont(&ok, ui->disasTextEdit_2->font(), this);
|
||||||
|
|
||||||
if (ok)
|
if (ok)
|
||||||
{
|
{
|
||||||
@ -1066,11 +745,12 @@ void MemoryWidget::on_actionSettings_menu_1_triggered()
|
|||||||
emit fontChanged(font);
|
emit fontChanged(font);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MemoryWidget::setFonts(QFont font)
|
void MemoryWidget::setFonts(QFont font)
|
||||||
{
|
{
|
||||||
ui->disasTextEdit_2->setFont(font);
|
//ui->disasTextEdit_2->setFont(font);
|
||||||
// the user clicked OK and font is set to the font the user selected
|
// the user clicked OK and font is set to the font the user selected
|
||||||
ui->disasTextEdit_2->setFont(font);
|
//ui->disasTextEdit_2->setFont(font);
|
||||||
ui->hexOffsetText_2->setFont(font);
|
ui->hexOffsetText_2->setFont(font);
|
||||||
ui->hexHexText_2->setFont(font);
|
ui->hexHexText_2->setFont(font);
|
||||||
ui->hexASCIIText_2->setFont(font);
|
ui->hexASCIIText_2->setFont(font);
|
||||||
@ -1130,13 +810,13 @@ void MemoryWidget::on_hexButton_clicked()
|
|||||||
ui->memSideTabWidget_2->setCurrentIndex(1);
|
ui->memSideTabWidget_2->setCurrentIndex(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MemoryWidget::on_actionSend_to_Notepad_triggered()
|
/*void MemoryWidget::on_actionSend_to_Notepad_triggered()
|
||||||
{
|
{
|
||||||
QTextCursor cursor = ui->disasTextEdit_2->textCursor();
|
QTextCursor cursor = ui->disasTextEdit_2->textCursor();
|
||||||
QString text = cursor.selectedText();
|
QString text = cursor.selectedText();
|
||||||
// TODO
|
// TODO
|
||||||
// this->main->sendToNotepad(text);
|
// this->main->sendToNotepad(text);
|
||||||
}
|
}*/
|
||||||
|
|
||||||
void MemoryWidget::on_action8columns_triggered()
|
void MemoryWidget::on_action8columns_triggered()
|
||||||
{
|
{
|
||||||
@ -1396,67 +1076,6 @@ void MemoryWidget::setFcnName(RVA addr)
|
|||||||
ui->fcnNameEdit->setText(addr_string);
|
ui->fcnNameEdit->setText(addr_string);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MemoryWidget::on_disasTextEdit_2_cursorPositionChanged()
|
|
||||||
{
|
|
||||||
// Get current offset
|
|
||||||
QTextCursor tc = this->disasTextEdit->textCursor();
|
|
||||||
tc.select(QTextCursor::LineUnderCursor);
|
|
||||||
QString lastline = tc.selectedText().trimmed();
|
|
||||||
QList<QString> words = lastline.split(" ", QString::SkipEmptyParts);
|
|
||||||
if (words.length() == 0)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
QString ele = words[0];
|
|
||||||
if (ele.contains("0x"))
|
|
||||||
{
|
|
||||||
this->fillOffsetInfo(ele);
|
|
||||||
QString at = this->core->cmdFunctionAt(ele);
|
|
||||||
QString deco = this->core->getDecompiledCode(at);
|
|
||||||
|
|
||||||
|
|
||||||
RVA addr = ele.midRef(2).toULongLong(0, 16);
|
|
||||||
// FIXME per widget CursorAddress no?
|
|
||||||
// this->main->setCursorAddress(addr);
|
|
||||||
|
|
||||||
if (deco != "")
|
|
||||||
{
|
|
||||||
ui->decoTextEdit->setPlainText(deco);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ui->decoTextEdit->setPlainText("");
|
|
||||||
}
|
|
||||||
// Get jump information to fill the preview
|
|
||||||
QString jump = this->core->getOffsetJump(ele);
|
|
||||||
if (!jump.isEmpty())
|
|
||||||
{
|
|
||||||
// Fill the preview
|
|
||||||
QString jump_code = this->core->cmd("pdf @ " + jump);
|
|
||||||
ui->previewTextEdit->setPlainText(jump_code.trimmed());
|
|
||||||
ui->previewTextEdit->moveCursor(QTextCursor::End);
|
|
||||||
ui->previewTextEdit->find(jump.trimmed(), QTextDocument::FindBackward);
|
|
||||||
ui->previewTextEdit->moveCursor(QTextCursor::StartOfWord, QTextCursor::MoveAnchor);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ui->previewTextEdit->setPlainText("");
|
|
||||||
}
|
|
||||||
//this->main->add_debug_output("Fcn at: '" + at + "'");
|
|
||||||
if (this->last_fcn != at)
|
|
||||||
{
|
|
||||||
this->last_fcn = at;
|
|
||||||
//this->main->add_debug_output("New Fcn: '" + this->last_fcn + "'");
|
|
||||||
// Refresh function information at sidebar
|
|
||||||
ui->fcnNameEdit->setText(at);
|
|
||||||
// FIXME TITLE?
|
|
||||||
// this->main->memoryDock->setWindowTitle(at);
|
|
||||||
//this->main->memoryDock->create_graph(ele);
|
|
||||||
this->setMiniGraph(at);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QString MemoryWidget::normalizeAddr(QString addr)
|
QString MemoryWidget::normalizeAddr(QString addr)
|
||||||
{
|
{
|
||||||
QString base = addr.split("0x")[1].trimmed();
|
QString base = addr.split("0x")[1].trimmed();
|
||||||
@ -1603,49 +1222,12 @@ void MemoryWidget::resizeEvent(QResizeEvent *event)
|
|||||||
QDockWidget::resizeEvent(event);
|
QDockWidget::resizeEvent(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MemoryWidget::eventFilter(QObject *obj, QEvent *event)
|
|
||||||
{
|
|
||||||
if ((obj == ui->disasTextEdit_2 || obj == ui->disasTextEdit_2->viewport()) && event->type() == QEvent::MouseButtonDblClick)
|
|
||||||
{
|
|
||||||
QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event);
|
|
||||||
//qDebug()<<QString("Click location: (%1,%2)").arg(mouseEvent->x()).arg(mouseEvent->y());
|
|
||||||
QTextCursor cursor = ui->disasTextEdit_2->cursorForPosition(QPoint(mouseEvent->x(), mouseEvent->y()));
|
|
||||||
cursor.select(QTextCursor::LineUnderCursor);
|
|
||||||
QString lastline = cursor.selectedText();
|
|
||||||
auto eles = lastline.split(" ", QString::SkipEmptyParts);
|
|
||||||
QString ele = eles.isEmpty() ? "" : eles[0];
|
|
||||||
if (ele.contains("0x"))
|
|
||||||
{
|
|
||||||
QString jump = this->core->getOffsetJump(ele);
|
|
||||||
if (!jump.isEmpty())
|
|
||||||
{
|
|
||||||
if (jump.contains("0x"))
|
|
||||||
{
|
|
||||||
QString fcn = this->core->cmdFunctionAt(jump);
|
|
||||||
if (!fcn.isEmpty())
|
|
||||||
{
|
|
||||||
RVA addr = jump.trimmed().toULongLong(0, 16);
|
|
||||||
this->core->seek(addr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
RVA addr = this->core->cmd("?v " + jump).toULongLong(0, 16);
|
|
||||||
this->core->seek(addr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return QDockWidget::eventFilter(obj, event);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MemoryWidget::setScrollMode()
|
void MemoryWidget::setScrollMode()
|
||||||
{
|
{
|
||||||
qhelpers::setVerticalScrollMode(ui->xreFromTreeWidget_2);
|
qhelpers::setVerticalScrollMode(ui->xreFromTreeWidget_2);
|
||||||
qhelpers::setVerticalScrollMode(ui->xrefToTreeWidget_2);
|
qhelpers::setVerticalScrollMode(ui->xrefToTreeWidget_2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void MemoryWidget::on_copyMD5_clicked()
|
void MemoryWidget::on_copyMD5_clicked()
|
||||||
{
|
{
|
||||||
QString md5 = ui->bytesMD5->text();
|
QString md5 = ui->bytesMD5->text();
|
||||||
@ -1727,12 +1309,7 @@ void MemoryWidget::updateViews(RVA offset)
|
|||||||
if (offset != RVA_INVALID)
|
if (offset != RVA_INVALID)
|
||||||
next_disasm_top_offset = offset;
|
next_disasm_top_offset = offset;
|
||||||
|
|
||||||
if (index == 0)
|
if (index == 1)
|
||||||
{
|
|
||||||
// Disasm
|
|
||||||
this->refreshDisasm();
|
|
||||||
}
|
|
||||||
else if (index == 1)
|
|
||||||
{
|
{
|
||||||
// Hex
|
// Hex
|
||||||
if (this->last_hexdump_fcn != cursor_addr)
|
if (this->last_hexdump_fcn != cursor_addr)
|
||||||
|
@ -35,7 +35,6 @@ public:
|
|||||||
|
|
||||||
void refresh() override;
|
void refresh() override;
|
||||||
|
|
||||||
QPlainTextEdit *disasTextEdit;
|
|
||||||
QTextEdit *hexOffsetText;
|
QTextEdit *hexOffsetText;
|
||||||
QPlainTextEdit *hexDisasTextEdit;
|
QPlainTextEdit *hexDisasTextEdit;
|
||||||
QTextEdit *hexASCIIText;
|
QTextEdit *hexASCIIText;
|
||||||
@ -58,20 +57,12 @@ signals:
|
|||||||
public slots:
|
public slots:
|
||||||
void fillPlugins();
|
void fillPlugins();
|
||||||
|
|
||||||
void addTextDisasm(QString txt);
|
|
||||||
|
|
||||||
void replaceTextDisasm(QString txt);
|
|
||||||
|
|
||||||
void refreshDisasm();
|
|
||||||
|
|
||||||
void refreshHexdump(const QString &where = QString());
|
void refreshHexdump(const QString &where = QString());
|
||||||
|
|
||||||
void fill_refs(QList<XrefDescription> refs, QList<XrefDescription> xrefs, QList<int> graph_data);
|
void fill_refs(QList<XrefDescription> refs, QList<XrefDescription> xrefs, QList<int> graph_data);
|
||||||
|
|
||||||
void fillOffsetInfo(QString off);
|
void fillOffsetInfo(QString off);
|
||||||
|
|
||||||
void seek_to(const QString &offset);
|
|
||||||
|
|
||||||
QString normalize_addr(QString addr);
|
QString normalize_addr(QString addr);
|
||||||
|
|
||||||
QString normalizeAddr(QString addr);
|
QString normalizeAddr(QString addr);
|
||||||
@ -80,15 +71,12 @@ public slots:
|
|||||||
|
|
||||||
void switchTheme(bool dark);
|
void switchTheme(bool dark);
|
||||||
|
|
||||||
void highlightDisasms();
|
|
||||||
|
|
||||||
void selectHexPreview();
|
void selectHexPreview();
|
||||||
|
|
||||||
void showOffsets(bool show);
|
void showOffsets(bool show);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void resizeEvent(QResizeEvent *event) override;
|
void resizeEvent(QResizeEvent *event) override;
|
||||||
bool eventFilter(QObject *obj, QEvent *event) override;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::unique_ptr<Ui::MemoryWidget> ui;
|
std::unique_ptr<Ui::MemoryWidget> ui;
|
||||||
@ -115,12 +103,9 @@ private slots:
|
|||||||
void on_cursorAddressChanged(RVA addr);
|
void on_cursorAddressChanged(RVA addr);
|
||||||
void on_seekChanged(RVA addr);
|
void on_seekChanged(RVA addr);
|
||||||
|
|
||||||
void highlightCurrentLine();
|
|
||||||
|
|
||||||
void highlightHexCurrentLine();
|
void highlightHexCurrentLine();
|
||||||
void highlightPreviewCurrentLine();
|
void highlightPreviewCurrentLine();
|
||||||
void highlightDecoCurrentLine();
|
void highlightDecoCurrentLine();
|
||||||
RVA readCurrentDisassemblyOffset();
|
|
||||||
void setFonts(QFont font);
|
void setFonts(QFont font);
|
||||||
|
|
||||||
void highlightHexWords(const QString &str);
|
void highlightHexWords(const QString &str);
|
||||||
@ -132,10 +117,8 @@ private slots:
|
|||||||
|
|
||||||
void on_disasButton_clicked();
|
void on_disasButton_clicked();
|
||||||
void on_hexButton_clicked();
|
void on_hexButton_clicked();
|
||||||
void showDisasContextMenu(const QPoint &pt);
|
|
||||||
void showHexdumpContextMenu(const QPoint &pt);
|
void showHexdumpContextMenu(const QPoint &pt);
|
||||||
void showHexASCIIContextMenu(const QPoint &pt);
|
void showHexASCIIContextMenu(const QPoint &pt);
|
||||||
void on_actionSend_to_Notepad_triggered();
|
|
||||||
|
|
||||||
void on_hexHexText_2_selectionChanged();
|
void on_hexHexText_2_selectionChanged();
|
||||||
void on_hexArchComboBox_2_currentTextChanged(const QString &arg1);
|
void on_hexArchComboBox_2_currentTextChanged(const QString &arg1);
|
||||||
@ -149,12 +132,10 @@ private slots:
|
|||||||
void on_action32columns_triggered();
|
void on_action32columns_triggered();
|
||||||
void on_action64columns_triggered();
|
void on_action64columns_triggered();
|
||||||
|
|
||||||
void disasmScrolled();
|
|
||||||
void resizeHexdump();
|
void resizeHexdump();
|
||||||
void hexScrolled();
|
void hexScrolled();
|
||||||
QList<QString> get_hexdump(const QString &offset);
|
QList<QString> get_hexdump(const QString &offset);
|
||||||
|
|
||||||
void showXrefsDialog();
|
|
||||||
void updateViews(RVA offset = RVA_INVALID);
|
void updateViews(RVA offset = RVA_INVALID);
|
||||||
void cycleViews();
|
void cycleViews();
|
||||||
void on_xreFromTreeWidget_2_itemDoubleClicked(QTreeWidgetItem *item, int column);
|
void on_xreFromTreeWidget_2_itemDoubleClicked(QTreeWidgetItem *item, int column);
|
||||||
@ -162,7 +143,6 @@ private slots:
|
|||||||
void on_xrefFromToolButton_2_clicked();
|
void on_xrefFromToolButton_2_clicked();
|
||||||
void on_xrefToToolButton_2_clicked();
|
void on_xrefToToolButton_2_clicked();
|
||||||
void on_codeCombo_2_currentTextChanged(const QString &arg1);
|
void on_codeCombo_2_currentTextChanged(const QString &arg1);
|
||||||
void on_disasTextEdit_2_cursorPositionChanged();
|
|
||||||
void on_offsetToolButton_clicked();
|
void on_offsetToolButton_clicked();
|
||||||
void on_polarToolButton_clicked();
|
void on_polarToolButton_clicked();
|
||||||
void on_radarToolButton_clicked();
|
void on_radarToolButton_clicked();
|
||||||
|
@ -438,62 +438,6 @@ border-top: 0px;
|
|||||||
<property name="handleWidth">
|
<property name="handleWidth">
|
||||||
<number>2</number>
|
<number>2</number>
|
||||||
</property>
|
</property>
|
||||||
<widget class="QPlainTextEdit" name="disasTextEdit_2">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="minimumSize">
|
|
||||||
<size>
|
|
||||||
<width>0</width>
|
|
||||||
<height>0</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="font">
|
|
||||||
<font>
|
|
||||||
<family>Anonymous Pro</family>
|
|
||||||
<pointsize>13</pointsize>
|
|
||||||
</font>
|
|
||||||
</property>
|
|
||||||
<property name="styleSheet">
|
|
||||||
<string notr="true"/>
|
|
||||||
</property>
|
|
||||||
<property name="frameShape">
|
|
||||||
<enum>QFrame::NoFrame</enum>
|
|
||||||
</property>
|
|
||||||
<property name="lineWidth">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="verticalScrollBarPolicy">
|
|
||||||
<enum>Qt::ScrollBarAlwaysOff</enum>
|
|
||||||
</property>
|
|
||||||
<property name="horizontalScrollBarPolicy">
|
|
||||||
<enum>Qt::ScrollBarAlwaysOff</enum>
|
|
||||||
</property>
|
|
||||||
<property name="undoRedoEnabled">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
<property name="lineWrapMode">
|
|
||||||
<enum>QPlainTextEdit::NoWrap</enum>
|
|
||||||
</property>
|
|
||||||
<property name="readOnly">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
<property name="plainText">
|
|
||||||
<string notr="true"/>
|
|
||||||
</property>
|
|
||||||
<property name="overwriteMode">
|
|
||||||
<bool>false</bool>
|
|
||||||
</property>
|
|
||||||
<property name="tabStopWidth">
|
|
||||||
<number>80</number>
|
|
||||||
</property>
|
|
||||||
<property name="textInteractionFlags">
|
|
||||||
<set>Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
<widget class="QFrame" name="frame_3">
|
<widget class="QFrame" name="frame_3">
|
||||||
<property name="frameShape">
|
<property name="frameShape">
|
||||||
<enum>QFrame::NoFrame</enum>
|
<enum>QFrame::NoFrame</enum>
|
||||||
@ -2883,8 +2827,8 @@ QToolTip {
|
|||||||
</resources>
|
</resources>
|
||||||
<connections/>
|
<connections/>
|
||||||
<buttongroups>
|
<buttongroups>
|
||||||
|
<buttongroup name="buttonGroup_2"/>
|
||||||
<buttongroup name="buttonGroup_3"/>
|
<buttongroup name="buttonGroup_3"/>
|
||||||
<buttongroup name="buttonGroup"/>
|
<buttongroup name="buttonGroup"/>
|
||||||
<buttongroup name="buttonGroup_2"/>
|
|
||||||
</buttongroups>
|
</buttongroups>
|
||||||
</ui>
|
</ui>
|
||||||
|
Loading…
Reference in New Issue
Block a user