mirror of
https://github.com/rizinorg/cutter.git
synced 2025-01-18 18:38:51 +00:00
Add flag in disassembly context menu, changes in disassembly refreshing (#197)
* Prepare Add Flag * Flag Dialog * MainWindow::globalSeekTo() signal * Load more disassembly in refresh if necessary
This commit is contained in:
parent
771eccc125
commit
6ed212a4ef
@ -7,11 +7,11 @@
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>400</width>
|
||||
<height>61</height>
|
||||
<height>75</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Dialog</string>
|
||||
<string>Comment</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<property name="spacing">
|
||||
|
35
src/dialogs/flagdialog.cpp
Normal file
35
src/dialogs/flagdialog.cpp
Normal file
@ -0,0 +1,35 @@
|
||||
|
||||
#include "ui_flagdialog.h"
|
||||
#include "flagdialog.h"
|
||||
|
||||
FlagDialog::FlagDialog(IaitoRCore *core, RVA offset, QWidget *parent) :
|
||||
QDialog(parent),
|
||||
ui(new Ui::FlagDialog)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
setWindowFlags(windowFlags() & (~Qt::WindowContextHelpButtonHint));
|
||||
|
||||
this->core = core;
|
||||
this->offset = offset;
|
||||
|
||||
auto size_validator = new QIntValidator(ui->sizeEdit);
|
||||
size_validator->setBottom(1);
|
||||
ui->sizeEdit->setValidator(size_validator);
|
||||
}
|
||||
|
||||
FlagDialog::~FlagDialog()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void FlagDialog::on_buttonBox_accepted()
|
||||
{
|
||||
QString name = ui->nameEdit->text();
|
||||
RVA size = ui->sizeEdit->text().toULongLong();
|
||||
core->addFlag(offset, name, size);
|
||||
}
|
||||
|
||||
void FlagDialog::on_buttonBox_rejected()
|
||||
{
|
||||
close();
|
||||
}
|
31
src/dialogs/flagdialog.h
Normal file
31
src/dialogs/flagdialog.h
Normal file
@ -0,0 +1,31 @@
|
||||
#ifndef FLAGDIALOG_H
|
||||
#define FLAGDIALOG_H
|
||||
|
||||
#include <QDialog>
|
||||
#include <iaitorcore.h>
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class FlagDialog;
|
||||
}
|
||||
|
||||
class FlagDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit FlagDialog(IaitoRCore *core, RVA offset, QWidget *parent = 0);
|
||||
~FlagDialog();
|
||||
|
||||
private slots:
|
||||
void on_buttonBox_accepted();
|
||||
void on_buttonBox_rejected();
|
||||
|
||||
private:
|
||||
Ui::FlagDialog *ui;
|
||||
|
||||
IaitoRCore *core;
|
||||
RVA offset;
|
||||
};
|
||||
|
||||
#endif // FLAGDIALOG_H
|
126
src/dialogs/flagdialog.ui
Normal file
126
src/dialogs/flagdialog.ui
Normal file
@ -0,0 +1,126 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>FlagDialog</class>
|
||||
<widget class="QDialog" name="FlagDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>452</width>
|
||||
<height>121</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Add Flag</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<layout class="QFormLayout" name="formLayout">
|
||||
<property name="horizontalSpacing">
|
||||
<number>12</number>
|
||||
</property>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Flag:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLineEdit" name="nameEdit">
|
||||
<property name="frame">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="placeholderText">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLineEdit" name="sizeEdit">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>100</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>1</string>
|
||||
</property>
|
||||
<property name="frame">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="placeholderText">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Size:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>accepted()</signal>
|
||||
<receiver>FlagDialog</receiver>
|
||||
<slot>accept()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>248</x>
|
||||
<y>254</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>157</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>rejected()</signal>
|
||||
<receiver>FlagDialog</receiver>
|
||||
<slot>reject()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>316</x>
|
||||
<y>260</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>286</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
@ -66,7 +66,8 @@ SOURCES += \
|
||||
hexhighlighter.cpp \
|
||||
widgets/sectionsdock.cpp \
|
||||
widgets/consolewidget.cpp \
|
||||
radarewebserver.cpp
|
||||
radarewebserver.cpp \
|
||||
dialogs/flagdialog.cpp
|
||||
|
||||
HEADERS += \
|
||||
mainwindow.h \
|
||||
@ -106,7 +107,8 @@ HEADERS += \
|
||||
radarewebserver.h \
|
||||
settings.h \
|
||||
iaitorcore.h \
|
||||
iaitordisasm.h
|
||||
iaitordisasm.h \
|
||||
dialogs/flagdialog.h
|
||||
|
||||
FORMS += \
|
||||
mainwindow.ui \
|
||||
@ -131,7 +133,8 @@ FORMS += \
|
||||
widgets/dashboard.ui \
|
||||
dialogs/xrefsdialog.ui \
|
||||
widgets/sectionsdock.ui \
|
||||
widgets/consolewidget.ui
|
||||
widgets/consolewidget.ui \
|
||||
dialogs/flagdialog.ui
|
||||
|
||||
RESOURCES += \
|
||||
resources.qrc
|
||||
|
@ -46,6 +46,8 @@ public:
|
||||
|
||||
typedef ut64 RVA;
|
||||
|
||||
#define RVA_INVALID UT64_MAX
|
||||
|
||||
inline QString RAddressString(RVA addr)
|
||||
{
|
||||
return QString::asprintf("%#010llx", addr);
|
||||
@ -163,6 +165,7 @@ public:
|
||||
~IaitoRCore();
|
||||
|
||||
RVA getOffset() const { return core_->offset; }
|
||||
static QString sanitizeStringForCommand(QString s);
|
||||
int getCycloComplex(ut64 addr);
|
||||
int getFcnSize(ut64 addr);
|
||||
int fcnCyclomaticComplexity(ut64 addr);
|
||||
@ -172,7 +175,6 @@ public:
|
||||
QJsonDocument cmdj(const QString &str);
|
||||
void renameFunction(QString prev_name, QString new_name);
|
||||
void setComment(RVA addr, QString cmt);
|
||||
void setComment(QString addr, QString cmt);
|
||||
void delComment(ut64 addr);
|
||||
QMap<QString, QList<QList<QString>>> getNestedComments();
|
||||
void setOptions(QString key);
|
||||
@ -236,6 +238,8 @@ public:
|
||||
|
||||
QList<XrefDescription> getXRefs(RVA addr, bool to, bool whole_function, const QString &filterType = QString::null);
|
||||
|
||||
void addFlag(RVA offset, QString name, RVA size);
|
||||
|
||||
RCoreLocked core() const;
|
||||
|
||||
/* fields */
|
||||
@ -243,7 +247,10 @@ public:
|
||||
Sdb *db;
|
||||
|
||||
signals:
|
||||
// TODO: create a more sophisticated update-event system
|
||||
void functionRenamed(QString prev_name, QString new_name);
|
||||
void flagsChanged();
|
||||
void commentsChanged();
|
||||
|
||||
public slots:
|
||||
|
||||
|
@ -767,9 +767,10 @@ void MainWindow::seek(const RVA offset, const QString &name, bool raise_memory_d
|
||||
this->hexdumpTopOffset = 0;
|
||||
this->hexdumpBottomOffset = 0;
|
||||
core->seek(offset);
|
||||
emit globalSeekTo(offset);
|
||||
setCursorAddress(offset);
|
||||
|
||||
refreshMem();
|
||||
//refreshMem();
|
||||
this->memoryDock->disasTextEdit->setFocus();
|
||||
|
||||
// Rise and shine baby!
|
||||
|
@ -80,6 +80,7 @@ public:
|
||||
void refreshOmniBar(const QStringList &flags);
|
||||
|
||||
signals:
|
||||
void globalSeekTo(RVA address);
|
||||
void cursorAddressChanged(RVA address);
|
||||
|
||||
public slots:
|
||||
|
@ -167,6 +167,12 @@ IaitoRCore::~IaitoRCore()
|
||||
r_cons_free();
|
||||
}
|
||||
|
||||
QString IaitoRCore::sanitizeStringForCommand(QString s)
|
||||
{
|
||||
static const QRegExp regexp(";|@");
|
||||
return s.replace(regexp, "_");
|
||||
}
|
||||
|
||||
QString IaitoRCore::cmd(const QString &str)
|
||||
{
|
||||
CORE_LOCK();
|
||||
@ -325,13 +331,9 @@ void IaitoRCore::setComment(RVA addr, QString cmt)
|
||||
{
|
||||
//r_meta_add (core->anal, 'C', addr, 1, cmt.toUtf8());
|
||||
cmd("CC " + cmt + " @ " + QString::number(addr));
|
||||
emit commentsChanged();
|
||||
}
|
||||
|
||||
void IaitoRCore::setComment(QString addr, QString cmt)
|
||||
{
|
||||
//r_meta_add (core->anal, 'C', addr, 1, cmt.toUtf8());
|
||||
cmd("CC " + cmt + " @ " + addr);
|
||||
}
|
||||
|
||||
void IaitoRCore::delComment(ut64 addr)
|
||||
{
|
||||
@ -1125,4 +1127,11 @@ QList<XrefDescription> IaitoRCore::getXRefs(RVA addr, bool to, bool whole_functi
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void IaitoRCore::addFlag(RVA offset, QString name, RVA size)
|
||||
{
|
||||
name = sanitizeStringForCommand(name);
|
||||
cmd(QString("f %1 %2 @ %3").arg(name).arg(size).arg(offset));
|
||||
emit flagsChanged();
|
||||
}
|
@ -28,6 +28,8 @@ CommentsWidget::CommentsWidget(MainWindow *main, QWidget *parent) :
|
||||
connect(this, SIGNAL(customContextMenuRequested(const QPoint &)),
|
||||
this, SLOT(showTitleContextMenu(const QPoint &)));
|
||||
|
||||
connect(main->core, SIGNAL(commentsChanged()), this, SLOT(refreshTree()));
|
||||
|
||||
// Hide the buttons frame
|
||||
ui->frame->hide();
|
||||
}
|
||||
|
@ -140,6 +140,8 @@ FlagsWidget::FlagsWidget(MainWindow *main, QWidget *parent) :
|
||||
connect(ui->filterLineEdit, SIGNAL(textChanged(const QString &)), flags_proxy_model, SLOT(setFilterWildcard(const QString &)));
|
||||
ui->flagsTreeView->setModel(flags_proxy_model);
|
||||
ui->flagsTreeView->sortByColumn(FlagsModel::OFFSET, Qt::AscendingOrder);
|
||||
|
||||
connect(main->core, SIGNAL(flagsChanged()), this, SLOT(flagsChanged()));
|
||||
}
|
||||
|
||||
FlagsWidget::~FlagsWidget()
|
||||
@ -172,6 +174,11 @@ void FlagsWidget::on_flagspaceCombo_currentTextChanged(const QString &arg1)
|
||||
refreshFlags();
|
||||
}
|
||||
|
||||
void FlagsWidget::flagsChanged()
|
||||
{
|
||||
refreshFlagspaces();
|
||||
}
|
||||
|
||||
void FlagsWidget::refreshFlagspaces()
|
||||
{
|
||||
int cur_idx = ui->flagspaceCombo->currentIndex();
|
||||
|
@ -70,6 +70,8 @@ private slots:
|
||||
void on_flagsTreeView_doubleClicked(const QModelIndex &index);
|
||||
void on_flagspaceCombo_currentTextChanged(const QString &arg1);
|
||||
|
||||
void flagsChanged();
|
||||
|
||||
private:
|
||||
Ui::FlagsWidget *ui;
|
||||
MainWindow *main;
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include "dialogs/xrefsdialog.h"
|
||||
#include "dialogs/renamedialog.h"
|
||||
#include "dialogs/commentsdialog.h"
|
||||
#include "dialogs/flagdialog.h"
|
||||
|
||||
#include <QTemporaryFile>
|
||||
#include <QFontDialog>
|
||||
@ -41,10 +42,12 @@ MemoryWidget::MemoryWidget(MainWindow *main) :
|
||||
this->memTabWidget = ui->memTabWidget;
|
||||
|
||||
this->last_fcn = "entry0";
|
||||
this->last_disasm_fcn = 0; //"";
|
||||
this->last_graph_fcn = 0; //"";
|
||||
this->last_hexdump_fcn = 0; //"";
|
||||
|
||||
disasm_top_offset = 0;
|
||||
next_disasm_top_offset = 0;
|
||||
|
||||
// Increase asm text edit margin
|
||||
QTextDocument *asm_docu = this->disasTextEdit->document();
|
||||
asm_docu->setDocumentMargin(10);
|
||||
@ -188,12 +191,19 @@ MemoryWidget::MemoryWidget(MainWindow *main) :
|
||||
|
||||
connect(ui->graphWebView->page(), SIGNAL(loadFinished(bool)), this, SLOT(frameLoadFinished(bool)));
|
||||
|
||||
connect(main, SIGNAL(globalSeekTo(RVA)), this, SLOT(on_globalSeekTo(RVA)));
|
||||
connect(main, SIGNAL(cursorAddressChanged(RVA)), this, SLOT(on_cursorAddressChanged(RVA)));
|
||||
connect(main->core, SIGNAL(flagsChanged()), this, SLOT(updateViews()));
|
||||
connect(main->core, SIGNAL(commentsChanged()), this, SLOT(updateViews()));
|
||||
|
||||
fillPlugins();
|
||||
}
|
||||
|
||||
|
||||
void MemoryWidget::on_globalSeekTo(RVA addr)
|
||||
{
|
||||
updateViews(addr);
|
||||
}
|
||||
|
||||
void MemoryWidget::on_cursorAddressChanged(RVA addr)
|
||||
{
|
||||
@ -386,6 +396,23 @@ void MemoryWidget::highlightDecoCurrentLine()
|
||||
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()
|
||||
{
|
||||
@ -397,11 +424,13 @@ void MemoryWidget::setup()
|
||||
setScrollMode();
|
||||
|
||||
const QString off = main->core->cmd("afo entry0").trimmed();
|
||||
RVA offset = off.toULongLong(0, 16);
|
||||
updateViews(offset);
|
||||
|
||||
refreshDisasm(off);
|
||||
refreshHexdump(off);
|
||||
create_graph(off);
|
||||
get_refs_data(off.toLongLong(0, 16));
|
||||
//refreshDisasm();
|
||||
//refreshHexdump(off);
|
||||
//create_graph(off);
|
||||
get_refs_data(offset);
|
||||
//setFcnName(off);
|
||||
}
|
||||
|
||||
@ -438,31 +467,32 @@ void MemoryWidget::replaceTextDisasm(QString txt)
|
||||
ui->disasTextEdit_2->setPlainText(txt);
|
||||
}
|
||||
|
||||
void MemoryWidget::disasmScrolled()
|
||||
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
|
||||
*/
|
||||
* 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);
|
||||
tc.select(QTextCursor::LineUnderCursor);
|
||||
QString lastline = tc.selectedText();
|
||||
QString ele = lastline.split(" ", QString::SkipEmptyParts)[0];
|
||||
if (ele.contains("0x"))
|
||||
RVA offset = readCurrentDisassemblyOffset();
|
||||
|
||||
if (offset != RVA_INVALID)
|
||||
{
|
||||
this->main->core->seek(ele);
|
||||
main->core->seek(offset);
|
||||
QString raw = this->main->core->cmd("pd 200");
|
||||
QString txt = raw.section("\n", 1, -1);
|
||||
//this->disasTextEdit->appendPlainText(" ;\n ; New content here\n ;\n " + txt.trimmed());
|
||||
@ -475,6 +505,9 @@ void MemoryWidget::disasmScrolled()
|
||||
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");
|
||||
@ -510,65 +543,63 @@ void MemoryWidget::disasmScrolled()
|
||||
|
||||
// Reconnect scroll signals
|
||||
connect(this->disasTextEdit->verticalScrollBar(), SIGNAL(valueChanged(int)), this, SLOT(disasmScrolled()));
|
||||
|
||||
return loaded;
|
||||
}
|
||||
|
||||
void MemoryWidget::refreshDisasm(const QString &offset)
|
||||
|
||||
void MemoryWidget::disasmScrolled()
|
||||
{
|
||||
loadMoreDisassembly();
|
||||
}
|
||||
|
||||
void MemoryWidget::refreshDisasm()
|
||||
{
|
||||
RCoreLocked lcore = this->main->core->core();
|
||||
// we must store those ranges somewhere, to handle scroll
|
||||
//ut64 addr = lcore->offset;
|
||||
//int length = lcore->num->value;
|
||||
|
||||
//printf("refreshDisasm %s\n", offset.toLocal8Bit().constData());
|
||||
|
||||
// Prevent further scroll
|
||||
disconnect(this->disasTextEdit->verticalScrollBar(), SIGNAL(valueChanged(int)), this, SLOT(disasmScrolled()));
|
||||
disconnect(this->disasTextEdit, SIGNAL(cursorPositionChanged()), this, SLOT(on_disasTextEdit_2_cursorPositionChanged()));
|
||||
|
||||
// Get disas at offset
|
||||
if (!offset.isEmpty())
|
||||
RVA offset = next_disasm_top_offset;
|
||||
next_disasm_top_offset = RVA_INVALID;
|
||||
bool offset_changed = offset != RVA_INVALID;
|
||||
|
||||
if (offset_changed) // new offset (seek)
|
||||
{
|
||||
this->main->core->cmd("s " + offset);
|
||||
disasm_top_offset = offset;
|
||||
this->main->core->cmd(QString("s %1").arg(offset));
|
||||
}
|
||||
else
|
||||
else // simple refresh
|
||||
{
|
||||
// Get current offset
|
||||
QTextCursor tc = this->disasTextEdit->textCursor();
|
||||
tc.select(QTextCursor::LineUnderCursor);
|
||||
QString lastline = tc.selectedText();
|
||||
QStringList elements = lastline.split(" ", QString::SkipEmptyParts);
|
||||
if (elements.length() > 0)
|
||||
{
|
||||
QString ele = elements[0];
|
||||
if (ele.contains("0x"))
|
||||
{
|
||||
QString fcn = this->main->core->cmdFunctionAt(ele);
|
||||
if (fcn != "")
|
||||
{
|
||||
this->main->core->cmd("s " + fcn);
|
||||
}
|
||||
else
|
||||
{
|
||||
this->main->core->cmd("s " + ele);
|
||||
}
|
||||
}
|
||||
}
|
||||
main->core->cmd(QString("s %1").arg(disasm_top_offset));
|
||||
}
|
||||
|
||||
QString txt2 = this->main->core->cmd("pd 100");
|
||||
QString txt2 = this->main->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());
|
||||
|
||||
// TODO: Fixx this ugly code
|
||||
//QString temp_seek = this->main->core->cmd("s").split("0x")[1].trimmed();
|
||||
QString s = this->normalize_addr(this->main->core->cmd("s"));
|
||||
//this->main->add_debug_output("Offset to search: " + s);
|
||||
this->disasTextEdit->ensureCursorVisible();
|
||||
/*this->disasTextEdit->moveCursor(QTextCursor::End);
|
||||
auto cursor = disasTextEdit->textCursor();
|
||||
cursor.setPosition(cursor_pos);
|
||||
disasTextEdit->setTextCursor(cursor);
|
||||
|
||||
while (this->disasTextEdit->find(QRegExp("^" + s), QTextDocument::FindBackward))
|
||||
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++)
|
||||
{
|
||||
this->disasTextEdit->moveCursor(QTextCursor::StartOfWord, QTextCursor::MoveAnchor);
|
||||
}*/
|
||||
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()));
|
||||
@ -998,6 +1029,7 @@ void MemoryWidget::showDisasContextMenu(const QPoint &pt)
|
||||
// Add menu actions
|
||||
menu->clear();
|
||||
menu->addAction(ui->actionDisasAdd_comment);
|
||||
menu->addAction(ui->actionAddFlag);
|
||||
menu->addAction(ui->actionFunctionsRename);
|
||||
menu->addAction(ui->actionFunctionsUndefine);
|
||||
menu->addSeparator();
|
||||
@ -1260,31 +1292,43 @@ void MemoryWidget::on_actionSend_to_Notepad_triggered()
|
||||
|
||||
void MemoryWidget::on_actionDisasAdd_comment_triggered()
|
||||
{
|
||||
// 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 offset = readCurrentDisassemblyOffset();
|
||||
|
||||
// Get function for clicked offset
|
||||
RAnalFunction *fcn = this->main->core->functionAt(offset);
|
||||
CommentsDialog *c = new CommentsDialog(this);
|
||||
if (c->exec())
|
||||
{
|
||||
// Get function for clicked offset
|
||||
RAnalFunction *fcn = this->main->core->functionAt(ele.toLongLong(0, 16));
|
||||
CommentsDialog *c = new CommentsDialog(this);
|
||||
if (c->exec())
|
||||
// Get new function name
|
||||
QString comment = c->getComment();
|
||||
//this->main->add_debug_output("Comment: " + comment + " at: " + ele);
|
||||
// Rename function in r2 core
|
||||
this->main->core->setComment(offset, comment);
|
||||
// Seek to new renamed function
|
||||
if (fcn)
|
||||
{
|
||||
// Get new function name
|
||||
QString comment = c->getComment();
|
||||
//this->main->add_debug_output("Comment: " + comment + " at: " + ele);
|
||||
// Rename function in r2 core
|
||||
this->main->core->setComment(ele, comment);
|
||||
// Seek to new renamed function
|
||||
if (fcn)
|
||||
{
|
||||
this->main->seek(fcn->name);
|
||||
}
|
||||
// TODO: Refresh functions tree widget
|
||||
this->main->seek(fcn->name);
|
||||
}
|
||||
// TODO: Refresh functions tree widget
|
||||
}
|
||||
|
||||
this->main->refreshComments();
|
||||
}
|
||||
|
||||
|
||||
void MemoryWidget::on_actionAddFlag_triggered()
|
||||
{
|
||||
RVA offset = readCurrentDisassemblyOffset();
|
||||
|
||||
FlagDialog *dialog = new FlagDialog(main->core, offset, this);
|
||||
if (dialog->exec())
|
||||
{
|
||||
//QString comment = dialog->getFlagName();
|
||||
// Rename function in r2 core
|
||||
|
||||
//this->main->core->setComment(offset, comment);
|
||||
}
|
||||
|
||||
this->main->refreshComments();
|
||||
}
|
||||
|
||||
@ -1939,7 +1983,7 @@ void MemoryWidget::on_memTabWidget_currentChanged(int /*index*/)
|
||||
this->updateViews();
|
||||
}
|
||||
|
||||
void MemoryWidget::updateViews()
|
||||
void MemoryWidget::updateViews(RVA offset)
|
||||
{
|
||||
// Update only the selected view to improve performance
|
||||
|
||||
@ -1949,14 +1993,13 @@ void MemoryWidget::updateViews()
|
||||
|
||||
QString cursor_addr_string = RAddressString(cursor_addr);
|
||||
|
||||
if (offset != RVA_INVALID)
|
||||
next_disasm_top_offset = offset;
|
||||
|
||||
if (index == 0)
|
||||
{
|
||||
// Disasm
|
||||
if (this->last_disasm_fcn != cursor_addr)
|
||||
{
|
||||
this->refreshDisasm(cursor_addr_string);
|
||||
this->last_disasm_fcn = cursor_addr;
|
||||
}
|
||||
this->refreshDisasm();
|
||||
}
|
||||
else if (index == 1)
|
||||
{
|
||||
|
@ -66,7 +66,7 @@ public slots:
|
||||
|
||||
void replaceTextDisasm(QString txt);
|
||||
|
||||
void refreshDisasm(const QString &offset = QString());
|
||||
void refreshDisasm();
|
||||
|
||||
void refreshHexdump(const QString &where = QString());
|
||||
|
||||
@ -92,7 +92,7 @@ public slots:
|
||||
|
||||
void frameLoadFinished(bool ok);
|
||||
|
||||
void updateViews();
|
||||
void updateViews(RVA offset = RVA_INVALID);
|
||||
|
||||
protected:
|
||||
void resizeEvent(QResizeEvent *event) override;
|
||||
@ -105,7 +105,9 @@ private:
|
||||
ut64 hexdumpBottomOffset;
|
||||
QString last_fcn;
|
||||
|
||||
RVA last_disasm_fcn;
|
||||
RVA disasm_top_offset;
|
||||
RVA next_disasm_top_offset;
|
||||
|
||||
RVA last_graph_fcn;
|
||||
RVA last_hexdump_fcn;
|
||||
|
||||
@ -114,7 +116,10 @@ private:
|
||||
|
||||
void setScrollMode();
|
||||
|
||||
bool loadMoreDisassembly();
|
||||
|
||||
private slots:
|
||||
void on_globalSeekTo(RVA addr);
|
||||
void on_cursorAddressChanged(RVA addr);
|
||||
|
||||
void highlightCurrentLine();
|
||||
@ -122,6 +127,7 @@ private slots:
|
||||
void highlightHexCurrentLine();
|
||||
void highlightPreviewCurrentLine();
|
||||
void highlightDecoCurrentLine();
|
||||
RVA readCurrentDisassemblyOffset();
|
||||
void setFonts(QFont font);
|
||||
|
||||
void highlightHexWords(const QString &str);
|
||||
@ -138,6 +144,7 @@ private slots:
|
||||
void showHexASCIIContextMenu(const QPoint &pt);
|
||||
void on_actionSend_to_Notepad_triggered();
|
||||
void on_actionDisasAdd_comment_triggered();
|
||||
void on_actionAddFlag_triggered();
|
||||
void on_actionFunctionsRename_triggered();
|
||||
void on_actionDisas_ShowHideBytes_triggered();
|
||||
|
||||
|
@ -3036,6 +3036,11 @@ QToolTip {
|
||||
<string>Show stack pointer</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionAddFlag">
|
||||
<property name="text">
|
||||
<string>Add flag</string>
|
||||
</property>
|
||||
</action>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
@ -3050,7 +3055,7 @@ QToolTip {
|
||||
<connections/>
|
||||
<buttongroups>
|
||||
<buttongroup name="buttonGroup_3"/>
|
||||
<buttongroup name="buttonGroup"/>
|
||||
<buttongroup name="buttonGroup_2"/>
|
||||
<buttongroup name="buttonGroup"/>
|
||||
</buttongroups>
|
||||
</ui>
|
||||
|
Loading…
Reference in New Issue
Block a user