Right click edit instruction fix #312 (#328)

* Right click edit instruction fix #312
* added bytes editing
This commit is contained in:
0xcpy 2018-02-12 21:12:13 +01:00 committed by xarkes
parent 4f484eb1f4
commit 16ebe024a3
10 changed files with 269 additions and 2 deletions

View File

@ -46,7 +46,7 @@ void AnalThread::run()
core->setCPU(optionsDialog->getSelectedArch(), optionsDialog->getSelectedCPU(), optionsDialog->getSelectedBits()); core->setCPU(optionsDialog->getSelectedArch(), optionsDialog->getSelectedCPU(), optionsDialog->getSelectedBits());
bool rw = false; bool rw = ui->writeCheckBox->isChecked();
bool loadBinInfo = !ui->binCheckBox->isChecked(); bool loadBinInfo = !ui->binCheckBox->isChecked();
if (loadBinInfo) if (loadBinInfo)

View File

@ -219,7 +219,7 @@ bool CutterCore::loadFile(QString path, uint64_t loadaddr, uint64_t mapaddr, boo
if (va == 0 || va == 2) if (va == 0 || va == 2)
r_config_set_i(core_->config, "io.va", va); r_config_set_i(core_->config, "io.va", va);
f = r_core_file_open(core_, path.toUtf8().constData(), rw ? (R_IO_READ | R_IO_WRITE) : R_IO_READ, mapaddr); f = r_core_file_open(core_, path.toUtf8().constData(), rw ? R_IO_RW : R_IO_READ, mapaddr);
if (!f) if (!f)
{ {
eprintf("r_core_file_open failed\n"); eprintf("r_core_file_open failed\n");
@ -324,6 +324,18 @@ void CutterCore::delFlag(RVA addr)
emit flagsChanged(); emit flagsChanged();
} }
void CutterCore::editInstruction(RVA addr, const QString &inst)
{
cmd("wa " + inst);
emit instructionChanged(addr);
}
void CutterCore::editBytes(RVA addr, const QString &bytes)
{
cmd("wx " + bytes);
emit instructionChanged(addr);
}
void CutterCore::setComment(RVA addr, const QString &cmt) void CutterCore::setComment(RVA addr, const QString &cmt)
{ {
cmd("CCu base64:" + cmt.toLocal8Bit().toBase64() + " @ " + QString::number(addr)); cmd("CCu base64:" + cmt.toLocal8Bit().toBase64() + " @ " + QString::number(addr));

View File

@ -254,6 +254,9 @@ public:
void renameFlag(QString old_name, QString new_name); void renameFlag(QString old_name, QString new_name);
void delFlag(RVA addr); void delFlag(RVA addr);
void editInstruction(RVA addr, const QString &inst);
void editBytes(RVA addr, const QString &inst);
void setComment(RVA addr, const QString &cmt); void setComment(RVA addr, const QString &cmt);
void delComment(RVA addr); void delComment(RVA addr);

View File

@ -40,6 +40,7 @@ SOURCES += \
dialogs/OptionsDialog.cpp \ dialogs/OptionsDialog.cpp \
dialogs/AboutDialog.cpp \ dialogs/AboutDialog.cpp \
dialogs/CommentsDialog.cpp \ dialogs/CommentsDialog.cpp \
dialogs/EditInstructionDialog.cpp \
dialogs/FlagDialog.cpp \ dialogs/FlagDialog.cpp \
dialogs/RenameDialog.cpp \ dialogs/RenameDialog.cpp \
dialogs/XrefsDialog.cpp \ dialogs/XrefsDialog.cpp \
@ -99,6 +100,7 @@ HEADERS += \
dialogs/AboutDialog.h \ dialogs/AboutDialog.h \
dialogs/preferences/AsmOptionsWidget.h \ dialogs/preferences/AsmOptionsWidget.h \
dialogs/CommentsDialog.h \ dialogs/CommentsDialog.h \
dialogs/EditInstructionDialog.h \
dialogs/FlagDialog.h \ dialogs/FlagDialog.h \
dialogs/RenameDialog.h \ dialogs/RenameDialog.h \
dialogs/XrefsDialog.h \ dialogs/XrefsDialog.h \
@ -154,6 +156,7 @@ FORMS += \
dialogs/AboutDialog.ui \ dialogs/AboutDialog.ui \
dialogs/preferences/AsmOptionsWidget.ui \ dialogs/preferences/AsmOptionsWidget.ui \
dialogs/CommentsDialog.ui \ dialogs/CommentsDialog.ui \
dialogs/EditInstructionDialog.ui \
dialogs/FlagDialog.ui \ dialogs/FlagDialog.ui \
dialogs/RenameDialog.ui \ dialogs/RenameDialog.ui \
dialogs/XrefsDialog.ui \ dialogs/XrefsDialog.ui \

View File

@ -0,0 +1,56 @@
#include "EditInstructionDialog.h"
#include "ui_EditInstructionDialog.h"
EditInstructionDialog::EditInstructionDialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::EditInstructionDialog)
{
ui->setupUi(this);
setWindowFlags(windowFlags() & (~Qt::WindowContextHelpButtonHint));
// Event filter for capturing Ctrl/Cmd+Return
ui->lineEdit->installEventFilter(this);
}
EditInstructionDialog::~EditInstructionDialog() {}
void EditInstructionDialog::on_buttonBox_accepted()
{
}
void EditInstructionDialog::on_buttonBox_rejected()
{
close();
}
QString EditInstructionDialog::getInstruction()
{
QString ret = ui->lineEdit->text();
return ret;
}
void EditInstructionDialog::setInstruction(const QString &instruction)
{
ui->lineEdit->setText(instruction);
}
bool EditInstructionDialog::eventFilter(QObject *obj, QEvent *event)
{
Q_UNUSED(obj);
if (event -> type() == QEvent::KeyPress)
{
QKeyEvent *keyEvent = static_cast <QKeyEvent *>(event);
// Confirm comment by pressing Ctrl/Cmd+Return
if ((keyEvent -> modifiers() & Qt::ControlModifier) &&
((keyEvent -> key() == Qt::Key_Enter) || (keyEvent -> key() == Qt::Key_Return)))
{
this->accept();
return true;
}
}
return false;
}

View File

@ -0,0 +1,35 @@
#ifndef EDITINSTRUCTIONDIALOG_H
#define EDITINSTRUCTIONDIALOG_H
#include <QDialog>
#include <QKeyEvent>
#include <memory>
namespace Ui
{
class EditInstructionDialog;
}
class EditInstructionDialog : public QDialog
{
Q_OBJECT
public:
explicit EditInstructionDialog(QWidget *parent = 0);
~EditInstructionDialog();
QString getInstruction();
void setInstruction(const QString &instruction);
private slots:
void on_buttonBox_accepted();
void on_buttonBox_rejected();
private:
std::unique_ptr<Ui::EditInstructionDialog> ui;
bool eventFilter(QObject *obj, QEvent *event);
};
#endif // EDITINSTRUCTIONDIALOG_H

View File

@ -0,0 +1,89 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>EditInstructionDialog</class>
<widget class="QDialog" name="EditInstructionDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>118</height>
</rect>
</property>
<property name="windowTitle">
<string>Edit Instruction</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<property name="spacing">
<number>2</number>
</property>
<property name="leftMargin">
<number>2</number>
</property>
<property name="topMargin">
<number>5</number>
</property>
<property name="rightMargin">
<number>2</number>
</property>
<property name="bottomMargin">
<number>2</number>
</property>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="topMargin">
<number>0</number>
</property>
<item>
<widget class="QLineEdit" name="lineEdit"/>
</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>EditInstructionDialog</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>EditInstructionDialog</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>

View File

@ -435,6 +435,16 @@
<property name="sizeConstraint"> <property name="sizeConstraint">
<enum>QLayout::SetMinimumSize</enum> <enum>QLayout::SetMinimumSize</enum>
</property> </property>
<item>
<widget class="QCheckBox" name="writeCheckBox">
<property name="text">
<string>Load in write mode (-w)</string>
</property>
<property name="checked">
<bool>false</bool>
</property>
</widget>
</item>
<item> <item>
<widget class="QCheckBox" name="binCheckBox"> <widget class="QCheckBox" name="binCheckBox">
<property name="text"> <property name="text">

View File

@ -1,16 +1,20 @@
#include "DisassemblyContextMenu.h" #include "DisassemblyContextMenu.h"
#include "dialogs/preferences/PreferencesDialog.h" #include "dialogs/preferences/PreferencesDialog.h"
#include "dialogs/EditInstructionDialog.h"
#include "dialogs/CommentsDialog.h" #include "dialogs/CommentsDialog.h"
#include "dialogs/FlagDialog.h" #include "dialogs/FlagDialog.h"
#include "dialogs/RenameDialog.h" #include "dialogs/RenameDialog.h"
#include "dialogs/XrefsDialog.h" #include "dialogs/XrefsDialog.h"
#include <QtCore> #include <QtCore>
#include <QShortcut> #include <QShortcut>
#include <QJsonArray>
DisassemblyContextMenu::DisassemblyContextMenu(QWidget *parent) DisassemblyContextMenu::DisassemblyContextMenu(QWidget *parent)
: QMenu(parent), : QMenu(parent),
offset(0), offset(0),
canCopy(false), canCopy(false),
actionEditInstruction(this),
actionEditBytes(this),
actionCopy(this), actionCopy(this),
actionAddComment(this), actionAddComment(this),
actionAddFlag(this), actionAddFlag(this),
@ -78,6 +82,17 @@ DisassemblyContextMenu::DisassemblyContextMenu(QWidget *parent)
createAction(&actionXRefs, tr("Show X-Refs"), getXRefSequence(), SLOT(on_actionXRefs_triggered())); createAction(&actionXRefs, tr("Show X-Refs"), getXRefSequence(), SLOT(on_actionXRefs_triggered()));
createAction(&actionDisplayOptions, tr("Show Options"), getDisplayOptionsSequence(), SLOT(on_actionDisplayOptions_triggered())); createAction(&actionDisplayOptions, tr("Show Options"), getDisplayOptionsSequence(), SLOT(on_actionDisplayOptions_triggered()));
addSeparator();
editMenu = new QMenu(tr("Edit"), this);
editMenuAction = addMenu(editMenu);
actionEditInstruction.setText(tr("Instruction"));
editMenu->addAction(&actionEditInstruction);
actionEditBytes.setText(tr("Bytes"));
editMenu->addAction(&actionEditBytes);
connect(&actionEditInstruction, SIGNAL(triggered(bool)), this, SLOT(on_actionEditInstruction_triggered()));
connect(&actionEditBytes, SIGNAL(triggered(bool)), this, SLOT(on_actionEditBytes_triggered()));
connect(&actionSetBaseBinary, SIGNAL(triggered(bool)), this, SLOT(on_actionSetBaseBinary_triggered())); connect(&actionSetBaseBinary, SIGNAL(triggered(bool)), this, SLOT(on_actionSetBaseBinary_triggered()));
connect(&actionSetBaseOctal, SIGNAL(triggered(bool)), this, SLOT(on_actionSetBaseOctal_triggered())); connect(&actionSetBaseOctal, SIGNAL(triggered(bool)), this, SLOT(on_actionSetBaseOctal_triggered()));
connect(&actionSetBaseDecimal, SIGNAL(triggered(bool)), this, SLOT(on_actionSetBaseDecimal_triggered())); connect(&actionSetBaseDecimal, SIGNAL(triggered(bool)), this, SLOT(on_actionSetBaseDecimal_triggered()));
@ -220,6 +235,42 @@ QKeySequence DisassemblyContextMenu::getDisplayOptionsSequence() const
return {}; //TODO insert correct sequence return {}; //TODO insert correct sequence
} }
void DisassemblyContextMenu::on_actionEditInstruction_triggered()
{
EditInstructionDialog *e = new EditInstructionDialog(this);
e->setWindowTitle(tr("Edit Instruction at %1").arg(RAddressString(offset)));
QString oldInstruction = Core()->cmdj("aoj").array().first().toObject()["opcode"].toString();
e->setInstruction(oldInstruction);
if (e->exec()){}
{
QString instruction = e->getInstruction();
if (instruction != oldInstruction)
{
Core()->editInstruction(offset, instruction);
}
}
}
void DisassemblyContextMenu::on_actionEditBytes_triggered()
{
EditInstructionDialog *e = new EditInstructionDialog(this);
e->setWindowTitle(tr("Edit Bytes at %1").arg(RAddressString(offset)));
QString oldBytes = Core()->cmdj("aoj").array().first().toObject()["bytes"].toString();
e->setInstruction(oldBytes);
if (e->exec()){}
{
QString bytes = e->getInstruction();
if (bytes != oldBytes)
{
Core()->editBytes(offset, bytes);
}
}
}
void DisassemblyContextMenu::on_actionCopy_triggered() void DisassemblyContextMenu::on_actionCopy_triggered()
{ {
emit copy(); emit copy();

View File

@ -23,6 +23,9 @@ public slots:
private slots: private slots:
void aboutToShowSlot(); void aboutToShowSlot();
void on_actionEditInstruction_triggered();
void on_actionEditBytes_triggered();
void on_actionCopy_triggered(); void on_actionCopy_triggered();
void on_actionAddComment_triggered(); void on_actionAddComment_triggered();
@ -64,6 +67,11 @@ private:
QList<QAction*> anonymousActions; QList<QAction*> anonymousActions;
QMenu *editMenu;
QAction *editMenuAction;
QAction actionEditInstruction;
QAction actionEditBytes;
QAction actionCopy; QAction actionCopy;
QAction *copySeparator; QAction *copySeparator;