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

Add a hotkey for toggling immediate base (#2420) #2429

Draft
wants to merge 8 commits into
base: dev
Choose a base branch
from
2 changes: 2 additions & 0 deletions docs/source/user-docs/shortcuts.rst
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@ Disassembly View Shortcuts
+-------------+----------------------------------+
| Ctrl/Cmd+= | Reset zoom |
+-------------+----------------------------------+
| H | Toggle immediate base |
+-------------+----------------------------------+

Graph View Shortcuts
--------------------
Expand Down
6 changes: 6 additions & 0 deletions src/core/Cutter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -842,6 +842,12 @@ void CutterCore::setImmediateBase(const QString &r2BaseName, RVA offset)
emit instructionChanged(offset);
}

int CutterCore::getImmediateBase(RVA offset)
{
QJsonValue result = this->cmdj(QString("ahj %1").arg(offset)).array().first();
return result.toObject()["immbase"].toInt();
}

void CutterCore::setCurrentBits(int bits, RVA offset)
{
if (offset == RVA_INVALID) {
Expand Down
1 change: 1 addition & 0 deletions src/core/Cutter.h
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,7 @@ class CUTTER_EXPORT CutterCore: public QObject
void delComment(RVA addr);
QString getCommentAt(RVA addr);
void setImmediateBase(const QString &r2BaseName, RVA offset = RVA_INVALID);
int getImmediateBase(RVA offset = RVA_INVALID);
void setCurrentBits(int bits, RVA offset = RVA_INVALID);

/**
Expand Down
41 changes: 35 additions & 6 deletions src/menus/DisassemblyContextMenu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,10 @@ DisassemblyContextMenu::DisassemblyContextMenu(QWidget *parent, MainWindow *main

addSetBaseMenu();

initAction(&actionToggleBase, tr("Toggle Immediate Base (Hex/Dec)"),
SLOT(on_actionToggleBase_triggered()), getToggleBaseSequence());
addAction(&actionToggleBase);

addSetBitsMenu();

structureOffsetMenu = addMenu(tr("Structure offset"));
Expand Down Expand Up @@ -400,6 +404,7 @@ void DisassemblyContextMenu::setOffset(RVA offset)
this->offset = offset;

this->actionSetFunctionVarTypes.setVisible(true);
actionToggleBase.setVisible(checkImmediateBaseMenu(getInstObject()));
}

void DisassemblyContextMenu::setCanCopy(bool enabled)
Expand All @@ -412,14 +417,22 @@ void DisassemblyContextMenu::setCurHighlightedWord(const QString &text)
this->curHighlightedWord = text;
}

void DisassemblyContextMenu::aboutToShowSlot()
{
// check if set immediate base menu makes sense
QJsonObject instObject = Core()->cmdj("aoj @ " + QString::number(
QJsonObject DisassemblyContextMenu::getInstObject() {
plaets marked this conversation as resolved.
Show resolved Hide resolved
return Core()->cmdj("aoj @ " + QString::number(
offset)).array().first().toObject();
}

// check if set immediate base menu makes sense
plaets marked this conversation as resolved.
Show resolved Hide resolved
bool DisassemblyContextMenu::checkImmediateBaseMenu(const QJsonObject& instObject) {
auto keys = instObject.keys();
bool immBase = keys.contains("val") || keys.contains("ptr");
setBaseMenu->menuAction()->setVisible(immBase);
return keys.contains("val") || keys.contains("ptr");
}

void DisassemblyContextMenu::aboutToShowSlot()
{
QJsonObject instObject = getInstObject();

setBaseMenu->menuAction()->setVisible(checkImmediateBaseMenu(instObject));
setBitsMenu->menuAction()->setVisible(true);

// Create structure offset menu if it makes sense
Expand Down Expand Up @@ -674,6 +687,11 @@ QKeySequence DisassemblyContextMenu::getUndefineFunctionSequence() const
return {Qt::Key_U};
}

QKeySequence DisassemblyContextMenu::getToggleBaseSequence() const
{
return {Qt::Key_H};
}


void DisassemblyContextMenu::on_actionEditInstruction_triggered()
{
Expand Down Expand Up @@ -803,6 +821,17 @@ void DisassemblyContextMenu::on_actionAnalyzeFunction_triggered()
}
}

// TODO: requires the user to trigger the action twice if the number is in decimals
void DisassemblyContextMenu::on_actionToggleBase_triggered()
{
int base = Core()->getImmediateBase(offset);
if (base == 10) {
setBase("h");
} else {
setBase("d");
}
}

void DisassemblyContextMenu::on_actionAddFlag_triggered()
{
FlagDialog dialog(offset, this->parentWidget());
Expand Down
18 changes: 18 additions & 0 deletions src/menus/DisassemblyContextMenu.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ private slots:
void on_actionSetToData_triggered();
void on_actionSetToDataEx_triggered();

void on_actionToggleBase_triggered();

/**
* @brief Executed on selecting an offset from the structureOffsetMenu
* Uses the applyStructureOffset() function of CutterCore to apply the
Expand Down Expand Up @@ -101,6 +103,7 @@ private slots:
QKeySequence getDefineNewFunctionSequence() const;
QKeySequence getUndefineFunctionSequence() const;
QKeySequence getEditFunctionSequence() const;
QKeySequence getToggleBaseSequence() const;
QList<QKeySequence> getAddBPSequence() const;

/**
Expand Down Expand Up @@ -156,6 +159,7 @@ private slots:
QAction actionSetBaseIPAddr;
QAction actionSetBaseSyscall;
QAction actionSetBaseString;
QAction actionToggleBase;

QMenu *setBitsMenu;
QAction actionSetBits16;
Expand Down Expand Up @@ -229,6 +233,20 @@ private slots:
};
QVector<ThingUsedHere> getThingUsedHere(RVA offset);

/**
* @brief Checks if it makes sense to display the immediate base menu
* @param instObject Object with instruction data
* @returns Return true if the it makes sense to display the set immediate base menu
* return false otherwise.
*/
bool checkImmediateBaseMenu(const QJsonObject& instObject);

/**
* @brief Returns json data of the current instruction
* @returns Instruction data
*/
QJsonObject getInstObject();
plaets marked this conversation as resolved.
Show resolved Hide resolved

void updateTargetMenuActions(const QVector<ThingUsedHere> &targets);
};
#endif // DISASSEMBLYCONTEXTMENU_H