"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "src/menus/DisassemblyContextMenu.cpp" between
cutter-1.8.3.tar.gz and cutter-1.9.0.tar.gz

About: cutter is a Qt and C++ GUI for radare2 reverse engineering framework.

DisassemblyContextMenu.cpp  (cutter-1.8.3):DisassemblyContextMenu.cpp  (cutter-1.9.0)
skipping to change at line 12 skipping to change at line 12
#include "dialogs/preferences/PreferencesDialog.h" #include "dialogs/preferences/PreferencesDialog.h"
#include "dialogs/EditInstructionDialog.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 "dialogs/EditVariablesDialog.h" #include "dialogs/EditVariablesDialog.h"
#include "dialogs/SetToDataDialog.h" #include "dialogs/SetToDataDialog.h"
#include "dialogs/EditFunctionDialog.h" #include "dialogs/EditFunctionDialog.h"
#include "dialogs/LinkTypeDialog.h" #include "dialogs/LinkTypeDialog.h"
#include "MainWindow.h"
#include <QtCore> #include <QtCore>
#include <QShortcut> #include <QShortcut>
#include <QJsonArray> #include <QJsonArray>
#include <QClipboard> #include <QClipboard>
#include <QApplication> #include <QApplication>
#include <QPushButton> #include <QPushButton>
DisassemblyContextMenu::DisassemblyContextMenu(QWidget *parent) DisassemblyContextMenu::DisassemblyContextMenu(QWidget *parent, MainWindow *main Window)
: QMenu(parent), : QMenu(parent),
offset(0), offset(0),
canCopy(false) canCopy(false),
mainWindow(mainWindow)
{ {
initAction(&actionCopy, tr("Copy"), SLOT(on_actionCopy_triggered()), getCopy Sequence()); initAction(&actionCopy, tr("Copy"), SLOT(on_actionCopy_triggered()), getCopy Sequence());
addAction(&actionCopy); addAction(&actionCopy);
initAction(&actionCopyAddr, tr("Copy address"), SLOT(on_actionCopyAddr_trigg initAction(&actionCopyAddr, tr("Copy address"), SLOT(on_actionCopyAddr_trigg
ered()), getCopyAddressSequence()); ered()),
getCopyAddressSequence());
addAction(&actionCopyAddr); addAction(&actionCopyAddr);
initAction(&showInSubmenu, tr("Show in"), nullptr);
addAction(&showInSubmenu);
copySeparator = addSeparator(); copySeparator = addSeparator();
initAction(&actionAddComment, tr("Add Comment"), initAction(&actionAddComment, tr("Add Comment"),
SLOT(on_actionAddComment_triggered()), getCommentSequence()); SLOT(on_actionAddComment_triggered()), getCommentSequence());
addAction(&actionAddComment); addAction(&actionAddComment);
initAction(&actionAddFlag, tr("Add Flag"), initAction(&actionAddFlag, tr("Add Flag"),
SLOT(on_actionAddFlag_triggered()), getAddFlagSequence()); SLOT(on_actionAddFlag_triggered()), getAddFlagSequence());
addAction(&actionAddFlag); addAction(&actionAddFlag);
skipping to change at line 110 skipping to change at line 116
addSeparator(); addSeparator();
addDebugMenu(); addDebugMenu();
connect(this, &DisassemblyContextMenu::aboutToShow, connect(this, &DisassemblyContextMenu::aboutToShow,
this, &DisassemblyContextMenu::aboutToShowSlot); this, &DisassemblyContextMenu::aboutToShowSlot);
} }
DisassemblyContextMenu::~DisassemblyContextMenu() DisassemblyContextMenu::~DisassemblyContextMenu()
{ {
for (QAction *action : anonymousActions) {
delete action;
}
} }
void DisassemblyContextMenu::addSetBaseMenu() void DisassemblyContextMenu::addSetBaseMenu()
{ {
setBaseMenu = addMenu(tr("Set Immediate Base to...")); setBaseMenu = addMenu(tr("Set Immediate Base to..."));
initAction(&actionSetBaseBinary, tr("Binary")); initAction(&actionSetBaseBinary, tr("Binary"));
setBaseMenu->addAction(&actionSetBaseBinary); setBaseMenu->addAction(&actionSetBaseBinary);
connect(&actionSetBaseBinary, &QAction::triggered, this, [this] { setBase("b "); }); connect(&actionSetBaseBinary, &QAction::triggered, this, [this] { setBase("b "); });
skipping to change at line 246 skipping to change at line 249
debugMenu->addAction(&actionAddBreakpoint); debugMenu->addAction(&actionAddBreakpoint);
initAction(&actionContinueUntil, tr("Continue until line"), initAction(&actionContinueUntil, tr("Continue until line"),
SLOT(on_actionContinueUntil_triggered())); SLOT(on_actionContinueUntil_triggered()));
debugMenu->addAction(&actionContinueUntil); debugMenu->addAction(&actionContinueUntil);
initAction(&actionSetPC, "Set PC", SLOT(on_actionSetPC_triggered())); initAction(&actionSetPC, "Set PC", SLOT(on_actionSetPC_triggered()));
debugMenu->addAction(&actionSetPC); debugMenu->addAction(&actionSetPC);
} }
QVector<DisassemblyContextMenu::ThingUsedHere> DisassemblyContextMenu::getThingU
sedHere(RVA offset)
{
QVector<ThingUsedHere> result;
const QJsonArray array = Core()->cmdj("anj @ " + QString::number(offset)).ar
ray();
result.reserve(array.size());
for (const auto &thing : array) {
auto obj = thing.toObject();
RVA offset = obj["offset"].toVariant().toULongLong();
QString name = obj["name"].toString();
QString typeString = obj["type"].toString();
ThingUsedHere::Type type = ThingUsedHere::Type::Address;
if (typeString == "var") {
type = ThingUsedHere::Type::Var;
} else if (typeString == "flag") {
type = ThingUsedHere::Type::Flag;
} else if (typeString == "function") {
type = ThingUsedHere::Type::Function;
} else if (typeString == "address") {
type = ThingUsedHere::Type::Address;
}
result.push_back(ThingUsedHere{name, offset, type});
}
return result;
}
void DisassemblyContextMenu::updateTargetMenuActions(const QVector<ThingUsedHere
> &targets)
{
for (auto action : showTargetMenuActions) {
removeAction(action);
auto menu = action->menu();
if (menu) {
menu->deleteLater();
}
action->deleteLater();
}
showTargetMenuActions.clear();
for (auto &target : targets) {
QString name;
if (target.name.isEmpty()) {
name = tr("%1 (used here)").arg(RAddressString(target.offset));
} else {
name = tr("%1 (%2)").arg(target.name, RAddressString(target.offset))
;
}
auto action = new QAction(name, this);
showTargetMenuActions.append(action);
auto menu = mainWindow->createShowInMenu(this, target.offset);
action->setMenu(menu);
QAction *copyAddress = new QAction(tr("Copy address"), menu);
RVA offset = target.offset;
connect(copyAddress, &QAction::triggered, copyAddress, [offset]() {
QClipboard *clipboard = QApplication::clipboard();
clipboard->setText(RAddressString(offset));
});
menu->addSeparator();
menu->addAction(copyAddress);
}
insertActions(copySeparator, showTargetMenuActions);
}
void DisassemblyContextMenu::setOffset(RVA offset) void DisassemblyContextMenu::setOffset(RVA offset)
{ {
this->offset = offset; this->offset = offset;
this->actionSetFunctionVarTypes.setVisible(true);
} }
void DisassemblyContextMenu::setCanCopy(bool enabled) void DisassemblyContextMenu::setCanCopy(bool enabled)
{ {
this->canCopy = enabled; this->canCopy = enabled;
} }
void DisassemblyContextMenu::setCurHighlightedWord(const QString &text) void DisassemblyContextMenu::setCurHighlightedWord(const QString &text)
{ {
this->curHighlightedWord = text; this->curHighlightedWord = text;
skipping to change at line 348 skipping to change at line 412
actionRename.setText(tr("Rename function \"%1\"").arg(fcn->name)); actionRename.setText(tr("Rename function \"%1\"").arg(fcn->name));
} else if (f) { } else if (f) {
actionRename.setVisible(true); actionRename.setVisible(true);
actionRename.setText(tr("Rename flag \"%1\"").arg(f->name)); actionRename.setText(tr("Rename flag \"%1\"").arg(f->name));
} else { } else {
actionRename.setVisible(false); actionRename.setVisible(false);
} }
// Only show retype for local vars if in a function // Only show retype for local vars if in a function
if (in_fcn) { if (in_fcn) {
actionSetFunctionVarTypes.setVisible(true); auto vars = Core()->getVariables(offset);
actionSetFunctionVarTypes.setVisible(!vars.empty());
actionEditFunction.setVisible(true); actionEditFunction.setVisible(true);
actionEditFunction.setText(tr("Edit function \"%1\"").arg(in_fcn->name)) ; actionEditFunction.setText(tr("Edit function \"%1\"").arg(in_fcn->name)) ;
} else { } else {
actionSetFunctionVarTypes.setVisible(false); actionSetFunctionVarTypes.setVisible(false);
actionEditFunction.setVisible(false); actionEditFunction.setVisible(false);
} }
// Only show "rename X used here" if there is something to rename // Only show "rename X used here" if there is something to rename
QJsonArray thingUsedHereArray = Core()->cmdj("anj @ " + QString::number(offs auto thingsUsedHere = getThingUsedHere(offset);
et)).array(); if (!thingsUsedHere.isEmpty()) {
if (!thingUsedHereArray.isEmpty()) {
actionRenameUsedHere.setVisible(true); actionRenameUsedHere.setVisible(true);
QJsonObject thingUsedHere = thingUsedHereArray.first().toObject(); auto &thingUsedHere = thingsUsedHere.first();
if (thingUsedHere["type"] == "address") { if (thingUsedHere.type == ThingUsedHere::Type::Address) {
RVA offset = thingUsedHere["offset"].toVariant().toULongLong(); RVA offset = thingUsedHere.offset;
actionRenameUsedHere.setText(tr("Add flag at %1 (used here)").arg(RA ddressString(offset))); actionRenameUsedHere.setText(tr("Add flag at %1 (used here)").arg(RA ddressString(offset)));
} else { } else if (thingUsedHere.type == ThingUsedHere::Type::Function) {
if (thingUsedHere["type"] == "function") { actionRenameUsedHere.setText(tr("Rename \"%1\"").arg(thingUsedHere.n
actionRenameUsedHere.setText(tr("Rename \"%1\"").arg(thingUsedHe ame));
re["name"].toString())); } else {
} actionRenameUsedHere.setText(tr("Rename \"%1\" (used here)").arg(thi
else { ngUsedHere.name));
actionRenameUsedHere.setText(tr("Rename \"%1\" (used here)").arg
(thingUsedHere["name"].toString()));
}
} }
} else { } else {
actionRenameUsedHere.setVisible(false); actionRenameUsedHere.setVisible(false);
} }
updateTargetMenuActions(thingsUsedHere);
// Decide to show Reverse jmp option // Decide to show Reverse jmp option
showReverseJmpQuery(); showReverseJmpQuery();
if (showInSubmenu.menu() != nullptr) {
showInSubmenu.menu()->deleteLater();
}
showInSubmenu.setMenu(mainWindow->createShowInMenu(this, offset));
// Only show debug options if we are currently debugging // Only show debug options if we are currently debugging
debugMenu->menuAction()->setVisible(Core()->currentlyDebugging); debugMenu->menuAction()->setVisible(Core()->currentlyDebugging);
QString progCounterName = Core()->getRegisterName("PC"); QString progCounterName = Core()->getRegisterName("PC");
actionSetPC.setText("Set " + progCounterName + " here"); actionSetPC.setText("Set " + progCounterName + " here");
} }
QKeySequence DisassemblyContextMenu::getCopySequence() const QKeySequence DisassemblyContextMenu::getCopySequence() const
{ {
return QKeySequence::Copy; return QKeySequence::Copy;
skipping to change at line 605 skipping to change at line 673
} }
void DisassemblyContextMenu::on_actionSetPC_triggered() void DisassemblyContextMenu::on_actionSetPC_triggered()
{ {
QString progCounterName = Core()->getRegisterName("PC"); QString progCounterName = Core()->getRegisterName("PC");
Core()->setRegister(progCounterName, RAddressString(offset)); Core()->setRegister(progCounterName, RAddressString(offset));
} }
void DisassemblyContextMenu::on_actionAddComment_triggered() void DisassemblyContextMenu::on_actionAddComment_triggered()
{ {
QString oldComment = Core()->cmd("CC." + RAddressString(offset)); CommentsDialog::addOrEditComment(offset, this);
// Remove newline at the end added by cmd
oldComment.remove(oldComment.length() - 1, 1);
CommentsDialog c(this);
if (oldComment.isNull() || oldComment.isEmpty()) {
c.setWindowTitle(tr("Add Comment at %1").arg(RAddressString(offset)));
} else {
c.setWindowTitle(tr("Edit Comment at %1").arg(RAddressString(offset)));
}
c.setComment(oldComment);
if (c.exec()) {
QString comment = c.getComment();
if (comment.isEmpty()) {
Core()->delComment(offset);
} else {
Core()->setComment(offset, comment);
}
}
} }
void DisassemblyContextMenu::on_actionAnalyzeFunction_triggered() void DisassemblyContextMenu::on_actionAnalyzeFunction_triggered()
{ {
RenameDialog dialog(this); RenameDialog dialog(mainWindow);
dialog.setWindowTitle(tr("Analyze function at %1").arg(RAddressString(offset ))); dialog.setWindowTitle(tr("Analyze function at %1").arg(RAddressString(offset )));
dialog.setPlaceholderText(tr("Function name")); dialog.setPlaceholderText(tr("Function name"));
if (dialog.exec()) { if (dialog.exec()) {
QString function_name = dialog.getName(); QString function_name = dialog.getName();
Core()->createFunctionAt(offset, function_name); Core()->createFunctionAt(offset, function_name);
} }
} }
void DisassemblyContextMenu::on_actionAddFlag_triggered() void DisassemblyContextMenu::on_actionAddFlag_triggered()
{ {
FlagDialog dialog(offset, this->parentWidget()); FlagDialog dialog(offset, this->parentWidget());
dialog.exec(); dialog.exec();
} }
void DisassemblyContextMenu::on_actionRename_triggered() void DisassemblyContextMenu::on_actionRename_triggered()
{ {
RCore *core = Core()->core(); RCore *core = Core()->core();
RenameDialog dialog(this); RenameDialog dialog(mainWindow);
RAnalFunction *fcn = r_anal_get_fcn_at (core->anal, offset, R_ANAL_FCN_TYPE_ NULL); RAnalFunction *fcn = r_anal_get_fcn_at (core->anal, offset, R_ANAL_FCN_TYPE_ NULL);
RFlagItem *f = r_flag_get_i (core->flags, offset); RFlagItem *f = r_flag_get_i (core->flags, offset);
if (fcn) { if (fcn) {
/* Rename function */ /* Rename function */
dialog.setWindowTitle(tr("Rename function %1").arg(fcn->name)); dialog.setWindowTitle(tr("Rename function %1").arg(fcn->name));
dialog.setName(fcn->name); dialog.setName(fcn->name);
if (dialog.exec()) { if (dialog.exec()) {
QString new_name = dialog.getName(); QString new_name = dialog.getName();
Core()->renameFunction(fcn->name, new_name); Core()->renameFunction(fcn->name, new_name);
skipping to change at line 675 skipping to change at line 724
QString new_name = dialog.getName(); QString new_name = dialog.getName();
Core()->renameFlag(f->name, new_name); Core()->renameFlag(f->name, new_name);
} }
} else { } else {
return; return;
} }
} }
void DisassemblyContextMenu::on_actionRenameUsedHere_triggered() void DisassemblyContextMenu::on_actionRenameUsedHere_triggered()
{ {
QJsonArray array = Core()->cmdj("anj @ " + QString::number(offset)).array(); auto array = getThingUsedHere(offset);
if (array.isEmpty()) { if (array.isEmpty()) {
return; return;
} }
QJsonObject thingUsedHere = array.first().toObject(); auto thingUsedHere = array.first();
QString type = thingUsedHere.value("type").toString();
RenameDialog dialog(this); RenameDialog dialog(mainWindow);
QString oldName; QString oldName;
auto type = thingUsedHere.type;
if (type == "address") { if (type == ThingUsedHere::Type::Address) {
RVA offset = thingUsedHere["offset"].toVariant().toULongLong(); RVA offset = thingUsedHere.offset;
dialog.setWindowTitle(tr("Add flag at %1").arg(RAddressString(offset))); dialog.setWindowTitle(tr("Add flag at %1").arg(RAddressString(offset)));
dialog.setName("label." + QString::number(offset, 16)); dialog.setName("label." + QString::number(offset, 16));
} else { } else {
oldName = thingUsedHere.value("name").toString(); oldName = thingUsedHere.name;
dialog.setWindowTitle(tr("Rename %1").arg(oldName)); dialog.setWindowTitle(tr("Rename %1").arg(oldName));
dialog.setName(oldName); dialog.setName(oldName);
} }
if (dialog.exec()) { if (dialog.exec()) {
QString newName = dialog.getName().trimmed(); QString newName = dialog.getName().trimmed();
if (!newName.isEmpty()) { if (!newName.isEmpty()) {
Core()->cmd("an " + newName + " @ " + QString::number(offset)); Core()->cmd("an " + newName + " @ " + QString::number(offset));
if (type == "address" || type == "flag") { if (type == ThingUsedHere::Type::Address || type == ThingUsedHere::T ype::Address) {
Core()->triggerFlagsChanged(); Core()->triggerFlagsChanged();
} else if (type == "var") { } else if (type == ThingUsedHere::Type::Var) {
Core()->triggerVarsChanged(); Core()->triggerVarsChanged();
} else if (type == "function") { } else if (type == ThingUsedHere::Type::Function) {
Core()->triggerFunctionRenamed(oldName, newName); Core()->triggerFunctionRenamed(oldName, newName);
} }
} }
} }
} }
void DisassemblyContextMenu::on_actionSetFunctionVarTypes_triggered() void DisassemblyContextMenu::on_actionSetFunctionVarTypes_triggered()
{ {
RAnalFunction *fcn = Core()->functionAt(offset); RAnalFunction *fcn = Core()->functionAt(offset);
if (!fcn) { if (!fcn) {
QMessageBox::critical(this, tr("Re-type function local vars"), tr("You m QMessageBox::critical(this, tr("Re-type function local vars"),
ust be in a function to define variable types.")); tr("You must be in a function to define variable t
ypes."));
return; return;
} }
EditVariablesDialog dialog(Core()->getOffset(), this); EditVariablesDialog dialog(Core()->getOffset(), curHighlightedWord, this);
if (dialog.empty()) { // don't show the dialog if there are no variables
return;
}
dialog.exec(); dialog.exec();
} }
void DisassemblyContextMenu::on_actionXRefs_triggered() void DisassemblyContextMenu::on_actionXRefs_triggered()
{ {
XrefsDialog dialog(nullptr); XrefsDialog dialog(mainWindow, nullptr);
dialog.fillRefsForAddress(offset, RAddressString(offset), false); dialog.fillRefsForAddress(offset, RAddressString(offset), false);
dialog.exec(); dialog.exec();
} }
void DisassemblyContextMenu::on_actionDisplayOptions_triggered() void DisassemblyContextMenu::on_actionDisplayOptions_triggered()
{ {
PreferencesDialog dialog(this->window()); PreferencesDialog dialog(this->window());
dialog.showSection(PreferencesDialog::Section::Disassembly); dialog.showSection(PreferencesDialog::Section::Disassembly);
dialog.exec(); dialog.exec();
} }
skipping to change at line 780 skipping to change at line 833
setToData(dialog.getItemSize(), dialog.getItemCount()); setToData(dialog.getItemSize(), dialog.getItemCount());
} }
void DisassemblyContextMenu::on_actionStructureOffsetMenu_triggered(QAction *act ion) void DisassemblyContextMenu::on_actionStructureOffsetMenu_triggered(QAction *act ion)
{ {
Core()->applyStructureOffset(action->data().toString(), offset); Core()->applyStructureOffset(action->data().toString(), offset);
} }
void DisassemblyContextMenu::on_actionLinkType_triggered() void DisassemblyContextMenu::on_actionLinkType_triggered()
{ {
LinkTypeDialog dialog(this); LinkTypeDialog dialog(mainWindow);
if (!dialog.setDefaultAddress(curHighlightedWord)) { if (!dialog.setDefaultAddress(curHighlightedWord)) {
dialog.setDefaultAddress(RAddressString(offset)); dialog.setDefaultAddress(RAddressString(offset));
} }
dialog.exec(); dialog.exec();
} }
void DisassemblyContextMenu::on_actionDeleteComment_triggered() void DisassemblyContextMenu::on_actionDeleteComment_triggered()
{ {
Core()->delComment(offset); Core()->delComment(offset);
} }
skipping to change at line 805 skipping to change at line 858
} }
void DisassemblyContextMenu::on_actionDeleteFunction_triggered() void DisassemblyContextMenu::on_actionDeleteFunction_triggered()
{ {
Core()->delFunction(offset); Core()->delFunction(offset);
} }
void DisassemblyContextMenu::on_actionEditFunction_triggered() void DisassemblyContextMenu::on_actionEditFunction_triggered()
{ {
RCore *core = Core()->core(); RCore *core = Core()->core();
EditFunctionDialog dialog(this); EditFunctionDialog dialog(mainWindow);
RAnalFunction *fcn = r_anal_get_fcn_in(core->anal, offset, 0); RAnalFunction *fcn = r_anal_get_fcn_in(core->anal, offset, 0);
if (fcn) { if (fcn) {
dialog.setWindowTitle(tr("Edit function %1").arg(fcn->name)); dialog.setWindowTitle(tr("Edit function %1").arg(fcn->name));
dialog.setNameText(fcn->name); dialog.setNameText(fcn->name);
QString startAddrText = "0x" + QString::number(fcn->addr, 16); QString startAddrText = "0x" + QString::number(fcn->addr, 16);
dialog.setStartAddrText(startAddrText); dialog.setStartAddrText(startAddrText);
QString endAddrText = "0x" + QString::number(fcn->addr + fcn->_size, 16) ; QString endAddrText = "0x" + QString::number(fcn->addr + fcn->_size, 16) ;
skipping to change at line 860 skipping to change at line 913
} }
void DisassemblyContextMenu::setToData(int size, int repeat) void DisassemblyContextMenu::setToData(int size, int repeat)
{ {
Core()->setToData(offset, size, repeat); Core()->setToData(offset, size, repeat);
} }
QAction *DisassemblyContextMenu::addAnonymousAction(QString name, const char *sl ot, QAction *DisassemblyContextMenu::addAnonymousAction(QString name, const char *sl ot,
QKeySequence keySequence) QKeySequence keySequence)
{ {
auto action = new QAction(); auto action = new QAction(this);
addAction(action); addAction(action);
anonymousActions.append(action); anonymousActions.append(action);
initAction(action, name, slot, keySequence); initAction(action, name, slot, keySequence);
return action; return action;
} }
void DisassemblyContextMenu::initAction(QAction *action, QString name, const cha r *slot) void DisassemblyContextMenu::initAction(QAction *action, QString name, const cha r *slot)
{ {
action->setParent(this); action->setParent(this);
parentWidget()->addAction(action); parentWidget()->addAction(action);
 End of changes. 32 change blocks. 
62 lines changed or deleted 118 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)