Added context menu with Set as option

This commit is contained in:
Rohan-Sagar 2024-05-03 20:56:50 -04:00
parent f8a258f98c
commit 13d2c5ef02
4 changed files with 127 additions and 13 deletions

View File

@ -2,6 +2,7 @@
#include <QJsonObject>
#include <QRegularExpression>
#include <QDir>
#include <QDebug>
#include <QCoreApplication>
#include <QVector>
#include <QStringList>
@ -772,6 +773,7 @@ void CutterCore::editBytesEndian(RVA addr, const QString &bytes)
void CutterCore::setToCode(RVA addr)
{
qDebug() << "setToCode" << addr << "\n";
CORE_LOCK();
rz_meta_del(core->analysis, RZ_META_TYPE_STRING, core->offset, 1);
rz_meta_del(core->analysis, RZ_META_TYPE_DATA, core->offset, 1);
@ -842,6 +844,7 @@ QString CutterCore::getMetaString(RVA addr)
void CutterCore::setToData(RVA addr, int size, int repeat)
{
qDebug() << "setToData" << addr << size << repeat << "\n";
if (size <= 0 || repeat <= 0) {
return;
}

View File

@ -1,4 +1,5 @@
#include "DisassemblyContextMenu.h"
#include "common/DisassemblyPreview.h"
#include "dialogs/preferences/PreferencesDialog.h"
#include "dialogs/EditInstructionDialog.h"
#include "dialogs/CommentsDialog.h"
@ -15,6 +16,8 @@
#include <QtCore>
#include <QShortcut>
#include <QJsonArray>
#include <QDebug>
#include <QTextEdit>
#include <QClipboard>
#include <QApplication>
#include <QPushButton>
@ -242,7 +245,7 @@ void DisassemblyContextMenu::addSetAsMenu()
{
setAsMenu = addMenu(tr("Set as..."));
initAction(&actionSetToCode, tr("Code"), SLOT(on_actionSetToCode_triggered()),
initAction(&actionSetToCode, tr("Code"), SLOT(applySetToCode()),
getSetToCodeSequence());
setAsMenu->addAction(&actionSetToCode);
@ -262,35 +265,83 @@ void DisassemblyContextMenu::addSetAsMenu()
addSetToDataMenu();
}
void DisassemblyContextMenu::applySetToCode() {
qDebug() << "Applying set to code" << "\n";
if (selectedLines.size() > 1) {
QVector<QPair<int, RVA>> offsets;
for (const auto &selection : selectedLines) {
int startPos = selection.cursor.selectionStart();
RVA lineOffset = DisassemblyPreview::readDisassemblyOffset(selection.cursor);
offsets.append(qMakePair(startPos, lineOffset));
}
// Sorting by start position in descending order
std::sort(offsets.begin(), offsets.end(),
[](const QPair<int, RVA> &a, const QPair<int, RVA> &b) {
return a.first > b.first;
});
for (const auto &offset : offsets) {
qDebug() << "Offset:" << offset.second;
on_actionSetToCode_triggered(offset.second);
}
} else if (selectedLines.size() <= 1) {
on_actionSetToCode_triggered();
}
selectedLines.clear();
}
void DisassemblyContextMenu::addSetToDataMenu()
{
setToDataMenu = setAsMenu->addMenu(tr("Data..."));
initAction(&actionSetToDataByte, tr("Byte"));
setToDataMenu->addAction(&actionSetToDataByte);
connect(&actionSetToDataByte, &QAction::triggered, this, [this] { setToData(1); });
connect(&actionSetToDataByte, &QAction::triggered, this, [this] { applySetToData(1); });
initAction(&actionSetToDataWord, tr("Word"));
setToDataMenu->addAction(&actionSetToDataWord);
connect(&actionSetToDataWord, &QAction::triggered, this, [this] { setToData(2); });
connect(&actionSetToDataWord, &QAction::triggered, this, [this] { applySetToData(2); });
initAction(&actionSetToDataDword, tr("Dword"));
setToDataMenu->addAction(&actionSetToDataDword);
connect(&actionSetToDataDword, &QAction::triggered, this, [this] { setToData(4); });
connect(&actionSetToDataDword, &QAction::triggered, this, [this] { applySetToData(4); });
initAction(&actionSetToDataQword, tr("Qword"));
setToDataMenu->addAction(&actionSetToDataQword);
connect(&actionSetToDataQword, &QAction::triggered, this, [this] { setToData(8); });
connect(&actionSetToDataQword, &QAction::triggered, this, [this] { applySetToData(8); });
initAction(&actionSetToDataEx, "...", SLOT(on_actionSetToDataEx_triggered()),
getSetToDataExSequence());
initAction(&actionSetToDataEx, "...", SLOT(on_actionSetToDataEx_triggered()), getSetToDataExSequence());
setToDataMenu->addAction(&actionSetToDataEx);
auto switchAction = new QAction(this);
initAction(switchAction, "Switch Data", SLOT(on_actionSetToData_triggered()),
getSetToDataSequence());
}
void DisassemblyContextMenu::applySetToData(int dataSize) {
qDebug() << "Applying set to data with size:" << dataSize << "\n";
if (selectedLines.size() > 1) {
QVector<QPair<int, RVA>> offsets;
for (const auto &selection : selectedLines) {
int startPos = selection.cursor.selectionStart();
RVA lineOffset = DisassemblyPreview::readDisassemblyOffset(selection.cursor);
offsets.append(qMakePair(startPos, lineOffset));
}
// Sorting by start position in descending order
std::sort(offsets.begin(), offsets.end(),
[](const QPair<int, RVA> &a, const QPair<int, RVA> &b) {
return a.first > b.first;
});
for (const auto &offset : offsets) {
qDebug() << "Offset:" << offset.second;
setToData(offset.second, dataSize);
}
} else if (selectedLines.size() <= 1) {
setToData(dataSize);
}
selectedLines.clear();
}
void DisassemblyContextMenu::addEditMenu()
{
editMenu = addMenu(tr("Edit"));
@ -365,6 +416,27 @@ QVector<DisassemblyContextMenu::ThingUsedHere> DisassemblyContextMenu::getThingU
return result;
}
void DisassemblyContextMenu::prepareMenu(const QList<QTextEdit::ExtraSelection>& selectedLines) {
this->clear();
this->selectedLines = selectedLines;
qDebug() << "Number of selected lines:" << selectedLines.size();
for (const auto& selection : selectedLines) {
int cursorPosition = selection.cursor.position();
int anchorPosition = selection.cursor.anchor();
auto offset = DisassemblyPreview::readDisassemblyOffset(selection.cursor);
qDebug() << "Cursor position:" << cursorPosition << "Anchor position:" << anchorPosition << "Offset:" << offset << "\n";
}
addAction(&actionCopy);
if (selectedLines.size() > 1) {
addSetAsMenu();
}
}
void DisassemblyContextMenu::setOffset(RVA offset)
{
this->offset = offset;
@ -964,16 +1036,31 @@ void DisassemblyContextMenu::on_actionSetToCode_triggered()
Core()->setToCode(offset);
}
void DisassemblyContextMenu::on_actionSetToCode_triggered(RVA offset)
{
Core()->setToCode(offset);
}
void DisassemblyContextMenu::on_actionSetAsString_triggered()
{
Core()->setAsString(offset);
}
void DisassemblyContextMenu::on_actionSetAsString_triggered(RVA offset)
{
Core()->setAsString(offset);
}
void DisassemblyContextMenu::on_actionSetAsStringRemove_triggered()
{
Core()->removeString(offset);
}
void DisassemblyContextMenu::on_actionSetAsStringRemove_triggered(RVA offset)
{
Core()->removeString(offset);
}
void DisassemblyContextMenu::on_actionSetAsStringAdvanced_triggered()
{
EditStringDialog dialog(parentForDialog());
@ -1116,6 +1203,11 @@ void DisassemblyContextMenu::setToData(int size, int repeat)
Core()->setToData(offset, size, repeat);
}
void DisassemblyContextMenu::setToData(RVA offset, int size, int repeat)
{
Core()->setToData(offset, size, repeat);
}
QAction *DisassemblyContextMenu::addAnonymousAction(QString name, const char *slot,
QKeySequence keySequence)
{

View File

@ -4,6 +4,8 @@
#include "core/Cutter.h"
#include "common/IOModesController.h"
#include <QMenu>
#include <QTextEdit>
#include <QSet>
#include <QKeySequence>
class MainWindow;
@ -22,6 +24,8 @@ signals:
public slots:
void setOffset(RVA offset);
void setCanCopy(bool enabled);
void prepareMenu(const QList<QTextEdit::ExtraSelection>& selectedLines);
/**
* @brief Sets the value of curHighlightedWord
@ -61,9 +65,13 @@ private slots:
void on_actionContinueUntil_triggered();
void on_actionSetPC_triggered();
void applySetToCode();
void on_actionSetToCode_triggered();
void on_actionSetToCode_triggered(RVA offset);
void on_actionSetAsString_triggered();
void on_actionSetAsString_triggered(RVA offset);
void on_actionSetAsStringRemove_triggered();
void on_actionSetAsStringRemove_triggered(RVA offset);
void on_actionSetAsStringAdvanced_triggered();
void on_actionSetToData_triggered();
void on_actionSetToDataEx_triggered();
@ -100,6 +108,7 @@ private:
bool canCopy;
QString curHighlightedWord; // The current highlighted word
MainWindow *mainWindow;
QList<QTextEdit::ExtraSelection> selectedLines;
IOModesController ioModesController;
QList<QAction *> anonymousActions;
@ -189,12 +198,13 @@ private:
void setBase(QString base);
void setToData(int size, int repeat = 1);
void setToData(RVA offset, int size, int repeat = 1);
void setBits(int bits);
void addSetBaseMenu();
void addSetBitsMenu();
void addSetAsMenu();
void addSetToDataMenu();
void applySetToData(int datasize);
void addEditMenu();
void addAddAtMenu();
void addBreakpointMenu();

View File

@ -464,6 +464,12 @@ void DisassemblyWidget::highlightMultiLineSelections()
void DisassemblyWidget::showDisasContextMenu(const QPoint &pt)
{
qDebug() << "showDisasContextMenu()" << "\n";
auto selectedLines = mDisasTextEdit->getMultiLineSelections();
if (selectedLines.size() > 1) {
mCtxMenu->prepareMenu(selectedLines);
}
mCtxMenu->exec(mDisasTextEdit->mapToGlobal(pt));
}
@ -843,7 +849,7 @@ void DisassemblyTextEdit::mousePressEvent(QMouseEvent *event)
// Format selection
QTextEdit::ExtraSelection selection;
selection.format.setBackground(QColor("green"));
selection.format.setBackground(QColor("darkBlue"));
selection.format.setProperty(QTextFormat::FullWidthSelection, true);
// Move cursor to start of the line
@ -881,6 +887,9 @@ void DisassemblyTextEdit::mousePressEvent(QMouseEvent *event)
for (const auto &selection : multilineSelections) {
qDebug() << "Start:" << selection.cursor.selectionStart()
<< "End:" << selection.cursor.selectionEnd();
qDebug() << selection.cursor.block().text();
auto offset = DisassemblyPreview::readDisassemblyOffset(selection.cursor);
qDebug() << "Offset:" << offset << "\n";
}
}