From c141eb34cc063ea3249b1913a36cece389872c82 Mon Sep 17 00:00:00 2001 From: Itay Cohen Date: Thu, 30 May 2019 11:41:14 +0300 Subject: [PATCH] Implement Seek to start/end of function Shortcuts (#1589) * fix ctrl+'+' to zoom in` * Add '^' and '$' shortcuts --- src/core/Cutter.cpp | 41 +++++++++++++++++++++++++++++++ src/core/Cutter.h | 3 +++ src/core/MainWindow.cpp | 13 ++++++++++ src/core/MainWindow.h | 3 ++- src/widgets/DisassemblyWidget.cpp | 4 +++ 5 files changed, 63 insertions(+), 1 deletion(-) diff --git a/src/core/Cutter.cpp b/src/core/Cutter.cpp index e303f66c..db013ba5 100644 --- a/src/core/Cutter.cpp +++ b/src/core/Cutter.cpp @@ -826,6 +826,47 @@ RAnalFunction *CutterCore::functionAt(ut64 addr) return r_anal_get_fcn_in(core_->anal, addr, 0); } + +/** + * @brief finds the start address of a function in a given address + * @param addr - an address which belongs to a function + * @returns if function exists, return its start address. Otherwise return RVA_INVALID + */ +RVA CutterCore::getFunctionStart(RVA addr) +{ + CORE_LOCK(); + RAnalFunction *fcn = Core()->functionAt(addr); + return fcn ? fcn->addr : RVA_INVALID; +} + +/** + * @brief finds the end address of a function in a given address + * @param addr - an address which belongs to a function + * @returns if function exists, return its end address. Otherwise return RVA_INVALID + */ +RVA CutterCore::getFunctionEnd(RVA addr) +{ + CORE_LOCK(); + RAnalFunction *fcn = Core()->functionAt(addr); + return fcn ? fcn->addr : RVA_INVALID; +} + +/** + * @brief finds the last instruction of a function in a given address + * @param addr - an address which belongs to a function + * @returns if function exists, return the address of its last instruction. Otherwise return RVA_INVALID + */ +RVA CutterCore::getLastFunctionInstruction(RVA addr) +{ + CORE_LOCK(); + RAnalFunction *fcn = Core()->functionAt(addr); + if (!fcn) { + return RVA_INVALID; + } + RAnalBlock *lastBB = (RAnalBlock *)r_list_last(fcn->bbs); + return lastBB ? lastBB->addr + r_anal_bb_offset_inst(lastBB, lastBB->ninstr-1) : RVA_INVALID; +} + QString CutterCore::cmdFunctionAt(QString addr) { QString ret; diff --git a/src/core/Cutter.h b/src/core/Cutter.h index 58c6b73f..522fb898 100644 --- a/src/core/Cutter.h +++ b/src/core/Cutter.h @@ -77,6 +77,9 @@ public: void delFunction(RVA addr); void renameFlag(QString old_name, QString new_name); RAnalFunction *functionAt(ut64 addr); + RVA getFunctionStart(RVA addr); + RVA getFunctionEnd(RVA addr); + RVA getLastFunctionInstruction(RVA addr); QString cmdFunctionAt(QString addr); QString cmdFunctionAt(RVA addr); QString createFunctionAt(RVA addr, QString name); diff --git a/src/core/MainWindow.cpp b/src/core/MainWindow.cpp index 5239e432..44ba2167 100644 --- a/src/core/MainWindow.cpp +++ b/src/core/MainWindow.cpp @@ -140,6 +140,10 @@ void MainWindow::initUI() connect(goto_shortcut, SIGNAL(activated()), this->omnibar, SLOT(setFocus())); QShortcut *seek_shortcut = new QShortcut(QKeySequence(Qt::Key_S), this); connect(seek_shortcut, SIGNAL(activated()), this->omnibar, SLOT(setFocus())); + QShortcut *seek_to_func_end_shortcut = new QShortcut(QKeySequence(Qt::Key_Dollar), this); + connect(seek_to_func_end_shortcut, SIGNAL(activated()), SLOT(seekToFunctionLastInstruction())); + QShortcut *seek_to_func_start_shortcut = new QShortcut(QKeySequence(Qt::Key_AsciiCircum), this); + connect(seek_to_func_start_shortcut, SIGNAL(activated()), SLOT(seekToFunctionStart())); QShortcut *refresh_shortcut = new QShortcut(QKeySequence(QKeySequence::Refresh), this); connect(refresh_shortcut, SIGNAL(activated()), this, SLOT(refreshAll())); @@ -1141,6 +1145,15 @@ void MainWindow::on_actionGrouped_dock_dragging_triggered(bool checked) setDockOptions(options); } +void MainWindow::seekToFunctionLastInstruction() +{ + Core()->seek(Core()->getLastFunctionInstruction(Core()->getOffset())); +} + +void MainWindow::seekToFunctionStart() +{ + Core()->seek(Core()->getFunctionStart(Core()->getOffset())); +} void MainWindow::projectSaved(bool successfully, const QString &name) { diff --git a/src/core/MainWindow.h b/src/core/MainWindow.h index ba8de75a..6fa4c303 100644 --- a/src/core/MainWindow.h +++ b/src/core/MainWindow.h @@ -115,7 +115,8 @@ public slots: void finalizeOpen(); void refreshAll(); - + void seekToFunctionLastInstruction(); + void seekToFunctionStart(); void setPanelLock(); void setTabLocation(); diff --git a/src/widgets/DisassemblyWidget.cpp b/src/widgets/DisassemblyWidget.cpp index 8020d5c2..5fc4c9f9 100644 --- a/src/widgets/DisassemblyWidget.cpp +++ b/src/widgets/DisassemblyWidget.cpp @@ -182,7 +182,11 @@ DisassemblyWidget::DisassemblyWidget(MainWindow *main, QAction *action) ADD_ACTION(QKeySequence::MoveToPreviousPage, Qt::WidgetWithChildrenShortcut, [this]() { moveCursorRelative(true, true); }) + + // Plus sign in num-bar considered "Qt::Key_Equal" ADD_ACTION(QKeySequence(Qt::CTRL + Qt::Key_Equal), Qt::WidgetWithChildrenShortcut, &DisassemblyWidget::zoomIn) + // Plus sign in numpad + ADD_ACTION(QKeySequence(Qt::CTRL + Qt::Key_Plus), Qt::WidgetWithChildrenShortcut, &DisassemblyWidget::zoomIn) ADD_ACTION(QKeySequence(Qt::CTRL + Qt::Key_Minus), Qt::WidgetWithChildrenShortcut, &DisassemblyWidget::zoomOut) #undef ADD_ACTION }