Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] Add Multiline Selections/Operations #3323

Draft
wants to merge 2 commits into
base: dev
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions src/core/Cutter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#include <QJsonObject>
#include <QRegularExpression>
#include <QDir>
#include <QDebug>
#include <QCoreApplication>
#include <QVector>
#include <QStringList>
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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;
}
Expand Down
112 changes: 102 additions & 10 deletions src/menus/DisassemblyContextMenu.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include "DisassemblyContextMenu.h"
#include "common/DisassemblyPreview.h"
#include "dialogs/preferences/PreferencesDialog.h"
#include "dialogs/EditInstructionDialog.h"
#include "dialogs/CommentsDialog.h"
Expand All @@ -15,6 +16,8 @@
#include <QtCore>
#include <QShortcut>
#include <QJsonArray>
#include <QDebug>
#include <QTextEdit>
#include <QClipboard>
#include <QApplication>
#include <QPushButton>
Expand Down Expand Up @@ -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);

Expand All @@ -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);
}

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));
}

auto switchAction = new QAction(this);
initAction(switchAction, "Switch Data", SLOT(on_actionSetToData_triggered()),
getSetToDataSequence());
// 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"));
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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());
Expand Down Expand Up @@ -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)
{
Expand Down
12 changes: 11 additions & 1 deletion src/menus/DisassemblyContextMenu.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
#include "core/Cutter.h"
#include "common/IOModesController.h"
#include <QMenu>
#include <QTextEdit>
#include <QSet>
#include <QKeySequence>

class MainWindow;
Expand All @@ -22,6 +24,8 @@ class CUTTER_EXPORT DisassemblyContextMenu : public QMenu
public slots:
void setOffset(RVA offset);
void setCanCopy(bool enabled);
void prepareMenu(const QList<QTextEdit::ExtraSelection>& selectedLines);


/**
* @brief Sets the value of curHighlightedWord
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -100,6 +108,7 @@ private slots:
bool canCopy;
QString curHighlightedWord; // The current highlighted word
MainWindow *mainWindow;
QList<QTextEdit::ExtraSelection> selectedLines;
IOModesController ioModesController;

QList<QAction *> anonymousActions;
Expand Down Expand Up @@ -189,12 +198,13 @@ private slots:

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();
Expand Down
Loading
Loading