2017-10-10 10:17:05 +00:00
|
|
|
#include "DisassemblyContextMenu.h"
|
|
|
|
#include "dialogs/AsmOptionsDialog.h"
|
|
|
|
#include "dialogs/CommentsDialog.h"
|
|
|
|
#include "dialogs/FlagDialog.h"
|
|
|
|
#include "dialogs/RenameDialog.h"
|
|
|
|
#include "dialogs/XrefsDialog.h"
|
|
|
|
#include <QtCore>
|
2017-11-03 11:31:20 +00:00
|
|
|
#include <QShortcut>
|
2017-10-10 10:17:05 +00:00
|
|
|
|
2017-11-19 17:49:29 +00:00
|
|
|
DisassemblyContextMenu::DisassemblyContextMenu(QWidget *parent)
|
|
|
|
: QMenu(parent),
|
|
|
|
offset(0),
|
|
|
|
actionAddComment(this),
|
|
|
|
actionAddFlag(this),
|
|
|
|
actionRename(this),
|
|
|
|
actionXRefs(this),
|
2017-11-28 13:13:22 +00:00
|
|
|
actionDisplayOptions(this),
|
|
|
|
actionSetBaseBinary(this),
|
|
|
|
actionSetBaseOctal(this),
|
|
|
|
actionSetBaseDecimal(this),
|
|
|
|
actionSetBaseHexadecimal(this),
|
|
|
|
actionSetBasePort(this),
|
|
|
|
actionSetBaseIPAddr(this),
|
|
|
|
actionSetBaseSyscall(this),
|
|
|
|
actionSetBaseString(this)
|
2017-10-10 10:17:05 +00:00
|
|
|
{
|
2017-11-28 13:13:22 +00:00
|
|
|
actionAddComment.setText(tr("Add Comment"));
|
2017-10-10 10:17:05 +00:00
|
|
|
this->addAction(&actionAddComment);
|
2017-11-03 11:31:20 +00:00
|
|
|
actionAddComment.setShortcut(getCommentSequence());
|
|
|
|
|
2017-11-28 13:13:22 +00:00
|
|
|
actionAddFlag.setText(tr("Add Flag"));
|
2017-10-10 10:17:05 +00:00
|
|
|
this->addAction(&actionAddFlag);
|
2017-11-03 11:31:20 +00:00
|
|
|
actionAddComment.setShortcut(getAddFlagSequence());
|
|
|
|
|
2017-11-28 13:13:22 +00:00
|
|
|
actionRename.setText(tr("Rename"));
|
2017-10-10 10:17:05 +00:00
|
|
|
this->addAction(&actionRename);
|
2017-11-03 11:31:20 +00:00
|
|
|
actionAddComment.setShortcut(getRenameSequence());
|
|
|
|
|
2017-11-28 13:50:41 +00:00
|
|
|
setBaseMenu = new QMenu(tr("Set Immediate Base to..."), this);
|
|
|
|
setBaseMenuAction = addMenu(setBaseMenu);
|
2017-11-28 13:13:22 +00:00
|
|
|
actionSetBaseBinary.setText(tr("Binary"));
|
2017-11-28 13:50:41 +00:00
|
|
|
setBaseMenu->addAction(&actionSetBaseBinary);
|
2017-11-28 13:13:22 +00:00
|
|
|
actionSetBaseOctal.setText(tr("Octal"));
|
2017-11-28 13:50:41 +00:00
|
|
|
setBaseMenu->addAction(&actionSetBaseOctal);
|
2017-11-28 13:13:22 +00:00
|
|
|
actionSetBaseDecimal.setText(tr("Decimal"));
|
2017-11-28 13:50:41 +00:00
|
|
|
setBaseMenu->addAction(&actionSetBaseDecimal);
|
2017-11-28 13:13:22 +00:00
|
|
|
actionSetBaseHexadecimal.setText(tr("Hexadecimal"));
|
2017-11-28 13:50:41 +00:00
|
|
|
setBaseMenu->addAction(&actionSetBaseHexadecimal);
|
2017-11-28 13:13:22 +00:00
|
|
|
actionSetBasePort.setText(tr("Network Port"));
|
2017-11-28 13:50:41 +00:00
|
|
|
setBaseMenu->addAction(&actionSetBasePort);
|
2017-11-28 13:13:22 +00:00
|
|
|
actionSetBaseIPAddr.setText(tr("IP Address"));
|
2017-11-28 13:50:41 +00:00
|
|
|
setBaseMenu->addAction(&actionSetBaseIPAddr);
|
2017-11-28 13:13:22 +00:00
|
|
|
actionSetBaseSyscall.setText(tr("Syscall"));
|
2017-11-28 13:50:41 +00:00
|
|
|
setBaseMenu->addAction(&actionSetBaseSyscall);
|
2017-11-28 13:13:22 +00:00
|
|
|
actionSetBaseString.setText(tr("String"));
|
2017-11-28 13:50:41 +00:00
|
|
|
setBaseMenu->addAction(&actionSetBaseString);
|
2017-11-28 13:13:22 +00:00
|
|
|
|
|
|
|
this->addSeparator();
|
|
|
|
actionXRefs.setText(tr("Show X-Refs"));
|
2017-10-10 10:17:05 +00:00
|
|
|
this->addAction(&actionXRefs);
|
2017-11-03 11:31:20 +00:00
|
|
|
actionAddComment.setShortcut(getXRefSequence());
|
|
|
|
|
2017-10-10 10:17:05 +00:00
|
|
|
this->addSeparator();
|
2017-11-28 13:13:22 +00:00
|
|
|
actionDisplayOptions.setText(tr("Show Options"));
|
2017-11-03 11:31:20 +00:00
|
|
|
actionAddComment.setShortcut(getDisplayOptionsSequence());
|
2017-10-10 10:17:05 +00:00
|
|
|
this->addAction(&actionDisplayOptions);
|
|
|
|
|
2017-11-03 11:31:20 +00:00
|
|
|
auto pWidget = parentWidget();
|
|
|
|
|
|
|
|
QShortcut *shortcut_dispOptions = new QShortcut(getDisplayOptionsSequence(), pWidget);
|
|
|
|
shortcut_dispOptions->setContext(Qt::WidgetWithChildrenShortcut);
|
|
|
|
connect(shortcut_dispOptions, &QShortcut::activated,
|
|
|
|
this, &DisassemblyContextMenu::on_actionDisplayOptions_triggered);
|
|
|
|
|
|
|
|
QShortcut *shortcut_x = new QShortcut(getXRefSequence(), pWidget);
|
|
|
|
shortcut_x->setContext(Qt::WidgetWithChildrenShortcut);
|
|
|
|
connect(shortcut_x, &QShortcut::activated,
|
|
|
|
this, &DisassemblyContextMenu::on_actionXRefs_triggered);
|
|
|
|
|
|
|
|
QShortcut *shortcut_comment = new QShortcut(getCommentSequence(), pWidget);
|
|
|
|
shortcut_comment->setContext(Qt::WidgetWithChildrenShortcut);
|
|
|
|
connect(shortcut_comment, &QShortcut::activated,
|
|
|
|
this, &DisassemblyContextMenu::on_actionAddComment_triggered);
|
|
|
|
|
|
|
|
QShortcut *shortcut_addFlag = new QShortcut(getAddFlagSequence(), pWidget);
|
|
|
|
shortcut_addFlag->setContext(Qt::WidgetWithChildrenShortcut);
|
|
|
|
connect(shortcut_addFlag, &QShortcut::activated,
|
|
|
|
this, &DisassemblyContextMenu::on_actionAddFlag_triggered);
|
|
|
|
|
|
|
|
QShortcut *shortcut_renameSequence = new QShortcut(getRenameSequence(), pWidget);
|
|
|
|
shortcut_renameSequence->setContext(Qt::WidgetWithChildrenShortcut);
|
|
|
|
connect(shortcut_renameSequence, &QShortcut::activated,
|
|
|
|
this, &DisassemblyContextMenu::on_actionRename_triggered);
|
|
|
|
|
2017-10-10 10:17:05 +00:00
|
|
|
connect(&actionAddComment, SIGNAL(triggered(bool)), this, SLOT(on_actionAddComment_triggered()));
|
|
|
|
connect(&actionAddFlag, SIGNAL(triggered(bool)), this, SLOT(on_actionAddFlag_triggered()));
|
|
|
|
connect(&actionRename, SIGNAL(triggered(bool)), this, SLOT(on_actionRename_triggered()));
|
|
|
|
connect(&actionXRefs, SIGNAL(triggered(bool)), this, SLOT(on_actionXRefs_triggered()));
|
|
|
|
connect(&actionDisplayOptions, SIGNAL(triggered()), this, SLOT(on_actionDisplayOptions_triggered()));
|
2017-11-28 13:13:22 +00:00
|
|
|
|
|
|
|
connect(&actionSetBaseBinary, SIGNAL(triggered(bool)), this, SLOT(on_actionSetBaseBinary_triggered()));
|
|
|
|
connect(&actionSetBaseOctal, SIGNAL(triggered(bool)), this, SLOT(on_actionSetBaseOctal_triggered()));
|
|
|
|
connect(&actionSetBaseDecimal, SIGNAL(triggered(bool)), this, SLOT(on_actionSetBaseDecimal_triggered()));
|
|
|
|
connect(&actionSetBaseHexadecimal, SIGNAL(triggered(bool)), this, SLOT(on_actionSetBaseHexadecimal_triggered()));
|
|
|
|
connect(&actionSetBasePort, SIGNAL(triggered(bool)), this, SLOT(on_actionSetBasePort_triggered()));
|
|
|
|
connect(&actionSetBaseIPAddr, SIGNAL(triggered(bool)), this, SLOT(on_actionSetBaseIPAddr_triggered()));
|
|
|
|
connect(&actionSetBaseSyscall, SIGNAL(triggered(bool)), this, SLOT(on_actionSetBaseSyscall_triggered()));
|
|
|
|
connect(&actionSetBaseString, SIGNAL(triggered(bool)), this, SLOT(on_actionSetBaseString_triggered()));
|
2017-11-28 13:50:41 +00:00
|
|
|
|
|
|
|
connect(this, SIGNAL(aboutToShow()), this, SLOT(aboutToShowSlot()));
|
|
|
|
}
|
|
|
|
|
|
|
|
void DisassemblyContextMenu::setOffset(RVA offset)
|
|
|
|
{
|
|
|
|
this->offset = offset;
|
|
|
|
}
|
|
|
|
|
|
|
|
void DisassemblyContextMenu::aboutToShowSlot()
|
|
|
|
{
|
|
|
|
// check if set immediate base menu makes sense
|
|
|
|
QJsonObject instObject = Core()->cmdj("aoj @ " + QString::number(offset)).array().first().toObject();
|
|
|
|
auto keys = instObject.keys();
|
|
|
|
bool immBase = keys.contains("val") || keys.contains("ptr");
|
|
|
|
setBaseMenuAction->setVisible(immBase);
|
|
|
|
}
|
|
|
|
|
|
|
|
QKeySequence DisassemblyContextMenu::getCommentSequence() const
|
|
|
|
{
|
|
|
|
return {";"};
|
|
|
|
}
|
|
|
|
|
|
|
|
QKeySequence DisassemblyContextMenu::getAddFlagSequence() const
|
|
|
|
{
|
|
|
|
return {}; //TODO insert correct sequence
|
|
|
|
}
|
|
|
|
|
|
|
|
QKeySequence DisassemblyContextMenu::getRenameSequence() const
|
|
|
|
{
|
|
|
|
return {Qt::Key_N};
|
|
|
|
}
|
|
|
|
|
|
|
|
QKeySequence DisassemblyContextMenu::getXRefSequence() const
|
|
|
|
{
|
|
|
|
return {Qt::Key_X};
|
|
|
|
}
|
|
|
|
|
|
|
|
QKeySequence DisassemblyContextMenu::getDisplayOptionsSequence() const
|
|
|
|
{
|
|
|
|
return {}; //TODO insert correct sequence
|
2017-10-10 10:17:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void DisassemblyContextMenu::on_actionAddComment_triggered()
|
|
|
|
{
|
|
|
|
CommentsDialog *c = new CommentsDialog(this);
|
|
|
|
if (c->exec())
|
|
|
|
{
|
|
|
|
QString comment = c->getComment();
|
2017-11-08 09:18:07 +00:00
|
|
|
Core()->setComment(offset, comment);
|
2017-10-10 10:17:05 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void DisassemblyContextMenu::on_actionAddFlag_triggered()
|
|
|
|
{
|
|
|
|
FlagDialog *dialog = new FlagDialog(offset, this->parentWidget());
|
|
|
|
dialog->exec();
|
|
|
|
}
|
|
|
|
|
|
|
|
void DisassemblyContextMenu::on_actionRename_triggered()
|
|
|
|
{
|
2017-11-26 16:53:05 +00:00
|
|
|
ut64 tgt_addr = UT64_MAX;
|
|
|
|
RAnalOp op;
|
|
|
|
RCore *core = Core()->core();
|
2017-11-08 09:02:39 +00:00
|
|
|
|
2017-10-10 10:17:05 +00:00
|
|
|
RenameDialog *dialog = new RenameDialog(this);
|
2017-11-26 16:53:05 +00:00
|
|
|
|
2017-11-27 09:24:31 +00:00
|
|
|
r_anal_op(core->anal, &op, offset, core->block + offset - core->offset, 32);
|
2017-11-26 16:53:05 +00:00
|
|
|
tgt_addr = op.jump != UT64_MAX ? op.jump : op.ptr;
|
|
|
|
if (op.var) {
|
|
|
|
RAnalFunction *fcn = r_anal_get_fcn_in (core->anal, offset, 0);
|
|
|
|
if (fcn) {
|
|
|
|
RAnalVar *bar = r_anal_var_get_byname (core->anal, fcn, op.var->name);
|
|
|
|
if (!bar) {
|
|
|
|
bar = r_anal_var_get_byname (core->anal, fcn, op.var->name);
|
|
|
|
if (!bar) {
|
|
|
|
|
|
|
|
bar = r_anal_var_get_byname (core->anal, fcn, op.var->name);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (bar) {
|
|
|
|
dialog->setName(bar->name);
|
|
|
|
if (dialog->exec()) {
|
|
|
|
QString new_name = dialog->getName();
|
|
|
|
r_anal_var_rename (core->anal, fcn->addr, bar->scope,
|
|
|
|
bar->kind, bar->name, new_name.toStdString().c_str());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else if (tgt_addr != UT64_MAX) {
|
|
|
|
RAnalFunction *fcn = r_anal_get_fcn_at (core->anal, tgt_addr, R_ANAL_FCN_TYPE_NULL);
|
|
|
|
RFlagItem *f = r_flag_get_i (core->flags, tgt_addr);
|
|
|
|
if (fcn) {
|
|
|
|
/* Rename function */
|
|
|
|
dialog->setName(fcn->name);
|
|
|
|
if (dialog->exec()) {
|
|
|
|
QString new_name = dialog->getName();
|
|
|
|
Core()->renameFunction(fcn->name, new_name);
|
|
|
|
}
|
|
|
|
} else if (f) {
|
|
|
|
/* Rename current flag */
|
|
|
|
dialog->setName(f->name);
|
|
|
|
if (dialog->exec()) {
|
|
|
|
QString new_name = dialog->getName();
|
2017-11-27 08:22:52 +00:00
|
|
|
Core()->renameFlag(f->name, new_name);
|
2017-11-26 16:53:05 +00:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
/* Create new flag */
|
|
|
|
dialog->setName("");
|
|
|
|
if (dialog->exec()) {
|
|
|
|
QString new_name = dialog->getName();
|
|
|
|
Core()->addFlag(tgt_addr, new_name, 1);
|
|
|
|
}
|
|
|
|
}
|
2017-10-10 10:17:05 +00:00
|
|
|
}
|
2017-11-26 16:53:05 +00:00
|
|
|
r_anal_op_fini (&op);
|
|
|
|
emit Core()->commentsChanged();
|
2017-10-10 10:17:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void DisassemblyContextMenu::on_actionXRefs_triggered()
|
|
|
|
{
|
|
|
|
XrefsDialog *dialog = new XrefsDialog(this);
|
|
|
|
dialog->fillRefsForAddress(offset, RAddressString(offset), false);
|
|
|
|
dialog->exec();
|
|
|
|
}
|
|
|
|
|
|
|
|
void DisassemblyContextMenu::on_actionDisplayOptions_triggered()
|
|
|
|
{
|
|
|
|
AsmOptionsDialog *dialog = new AsmOptionsDialog(this->parentWidget());
|
|
|
|
dialog->show();
|
|
|
|
}
|
2017-11-28 13:13:22 +00:00
|
|
|
|
|
|
|
void DisassemblyContextMenu::on_actionSetBaseBinary_triggered()
|
|
|
|
{
|
|
|
|
Core()->setImmediateBase("b", offset);
|
|
|
|
}
|
|
|
|
|
|
|
|
void DisassemblyContextMenu::on_actionSetBaseOctal_triggered()
|
|
|
|
{
|
|
|
|
Core()->setImmediateBase("o", offset);
|
|
|
|
}
|
|
|
|
|
|
|
|
void DisassemblyContextMenu::on_actionSetBaseDecimal_triggered()
|
|
|
|
{
|
|
|
|
Core()->setImmediateBase("d", offset);
|
|
|
|
}
|
|
|
|
|
|
|
|
void DisassemblyContextMenu::on_actionSetBaseHexadecimal_triggered()
|
|
|
|
{
|
|
|
|
Core()->setImmediateBase("h", offset);
|
|
|
|
}
|
|
|
|
|
|
|
|
void DisassemblyContextMenu::on_actionSetBasePort_triggered()
|
|
|
|
{
|
|
|
|
Core()->setImmediateBase("p", offset);
|
|
|
|
}
|
|
|
|
|
|
|
|
void DisassemblyContextMenu::on_actionSetBaseIPAddr_triggered()
|
|
|
|
{
|
|
|
|
Core()->setImmediateBase("i", offset);
|
|
|
|
}
|
|
|
|
|
|
|
|
void DisassemblyContextMenu::on_actionSetBaseSyscall_triggered()
|
|
|
|
{
|
|
|
|
Core()->setImmediateBase("S", offset);
|
|
|
|
}
|
|
|
|
|
|
|
|
void DisassemblyContextMenu::on_actionSetBaseString_triggered()
|
|
|
|
{
|
|
|
|
Core()->setImmediateBase("s", offset);
|
|
|
|
}
|