From 3f8f904ebd94663d914a1951f05b506949c36c49 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Florian=20M=C3=A4rkl?= <info@florianmaerkl.de>
Date: Fri, 9 Jun 2017 00:40:43 +0200
Subject: [PATCH] Some more X-Ref changes (#185)

X shortcut for X-Refs in MemoryWidget
---
 src/dialogs/xrefsdialog.cpp     |  8 ++--
 src/dialogs/xrefsdialog.h       |  2 +-
 src/qrcore.cpp                  |  5 ++-
 src/qrcore.h                    |  2 +-
 src/widgets/dashboard.cpp       |  1 +
 src/widgets/functionswidget.cpp |  2 +-
 src/widgets/memorywidget.cpp    | 75 ++++++++++++++++-----------------
 src/widgets/memorywidget.h      |  3 +-
 8 files changed, 50 insertions(+), 48 deletions(-)

diff --git a/src/dialogs/xrefsdialog.cpp b/src/dialogs/xrefsdialog.cpp
index 2bc3225d..3d68aa83 100644
--- a/src/dialogs/xrefsdialog.cpp
+++ b/src/dialogs/xrefsdialog.cpp
@@ -182,20 +182,20 @@ void XrefsDialog::updateLabels(QString name)
     ui->label_3->setText(tr("X-Refs from %1:").arg(name));
 }
 
-void XrefsDialog::fillRefsForFunction(RVA addr, QString name)
+void XrefsDialog::fillRefsForAddress(RVA addr, QString name, bool whole_function)
 {
     this->addr = addr;
     this->func_name = func_name;
 
-    setWindowTitle(tr("X-Refs for function %1").arg(name));
+    setWindowTitle(tr("X-Refs for %1").arg(name));
     updateLabels(name);
     // Get Refs and Xrefs
 
     // refs = calls q hace esa funcion
-    QList<XrefDescription> refs = main->core->getXRefs(addr, false, "C");
+    QList<XrefDescription> refs = main->core->getXRefs(addr, false, whole_function);
 
     // xrefs = calls a esa funcion
-    QList<XrefDescription> xrefs = main->core->getXRefs(addr, true);
+    QList<XrefDescription> xrefs = main->core->getXRefs(addr, true, whole_function);
 
     fillRefs(refs, xrefs);
 }
\ No newline at end of file
diff --git a/src/dialogs/xrefsdialog.h b/src/dialogs/xrefsdialog.h
index fe2b1854..cb6b907a 100644
--- a/src/dialogs/xrefsdialog.h
+++ b/src/dialogs/xrefsdialog.h
@@ -22,7 +22,7 @@ public:
     explicit XrefsDialog(MainWindow *main, QWidget *parent = 0);
     ~XrefsDialog();
 
-    void fillRefsForFunction(RVA addr, QString name);
+    void fillRefsForAddress(RVA addr, QString name, bool whole_function);
 
 private slots:
 
diff --git a/src/qrcore.cpp b/src/qrcore.cpp
index 9ddc02eb..7ed2d7a7 100644
--- a/src/qrcore.cpp
+++ b/src/qrcore.cpp
@@ -1090,7 +1090,7 @@ QList<SectionDescription> QRCore::getAllSections()
     return ret;
 }
 
-QList<XrefDescription> QRCore::getXRefs(RVA addr, bool to, const QString &filterType)
+QList<XrefDescription> QRCore::getXRefs(RVA addr, bool to, bool whole_function, const QString &filterType)
 {
     QList<XrefDescription> ret = QList<XrefDescription>();
 
@@ -1113,6 +1113,9 @@ QList<XrefDescription> QRCore::getXRefs(RVA addr, bool to, const QString &filter
 
         xref.from = xrefObject["from"].toVariant().toULongLong();
 
+        if (!whole_function && !to && xref.from != addr)
+            continue;
+
         if (to && !xrefObject.contains("to"))
             xref.to = addr;
         else
diff --git a/src/qrcore.h b/src/qrcore.h
index 417feef3..93c2e7ef 100644
--- a/src/qrcore.h
+++ b/src/qrcore.h
@@ -234,7 +234,7 @@ public:
     QList<FlagDescription> getAllFlags(QString flagspace = NULL);
     QList<SectionDescription> getAllSections();
 
-    QList<XrefDescription> getXRefs(RVA addr, bool to, const QString &filterType = QString::null);
+    QList<XrefDescription> getXRefs(RVA addr, bool to, bool whole_function, const QString &filterType = QString::null);
 
     RCoreLocked core() const;
 
diff --git a/src/widgets/dashboard.cpp b/src/widgets/dashboard.cpp
index b8356803..791e6188 100644
--- a/src/widgets/dashboard.cpp
+++ b/src/widgets/dashboard.cpp
@@ -71,6 +71,7 @@ void Dashboard::updateContents()
     this->ui->endianEdit->setText(item2["endian"].toString());
     this->ui->compiledEdit->setText(item2["compiled"].toString());
     this->ui->bitsEdit->setText(QString::number(item2["bits"].toDouble()));
+
     if (item2["relro"].isUndefined()) {
         QString relro=item2["relro"].toString().split(" ").at(0);
         relro[0]=relro[0].toUpper();
diff --git a/src/widgets/functionswidget.cpp b/src/widgets/functionswidget.cpp
index 72a23844..8676d48a 100644
--- a/src/widgets/functionswidget.cpp
+++ b/src/widgets/functionswidget.cpp
@@ -509,7 +509,7 @@ void FunctionsWidget::on_action_References_triggered()
     QTreeView *treeView = getCurrentTreeView();
     FunctionDescription function = treeView->selectionModel()->currentIndex().data(FunctionModel::FunctionDescriptionRole).value<FunctionDescription>();
     XrefsDialog *x = new XrefsDialog(this->main, this);
-    x->fillRefsForFunction(function.offset, function.name);
+    x->fillRefsForAddress(function.offset, function.name, true);
     x->exec();
 }
 
diff --git a/src/widgets/memorywidget.cpp b/src/widgets/memorywidget.cpp
index f79cbdb2..18ba88c3 100644
--- a/src/widgets/memorywidget.cpp
+++ b/src/widgets/memorywidget.cpp
@@ -151,10 +151,11 @@ MemoryWidget::MemoryWidget(MainWindow *main) :
     connect(ui->hexASCIIText_2->verticalScrollBar(), SIGNAL(valueChanged(int)),
             ui->hexHexText_2->verticalScrollBar(), SLOT(setValue(int)));
 
-    // X to show hexdump
-    QShortcut *hexdump_shortcut = new QShortcut(QKeySequence(Qt::Key_X), this->main);
-    connect(hexdump_shortcut, SIGNAL(activated()), this, SLOT(showHexdump()));
-    //hexdump_shortcut->setContext(Qt::WidgetShortcut);
+    // x or X to show XRefs
+    connect(new QShortcut(QKeySequence(Qt::Key_X), ui->disasTextEdit_2),
+            SIGNAL(activated()), this, SLOT(showXrefsDialog()));
+    connect(new QShortcut(Qt::SHIFT + Qt::Key_X, ui->disasTextEdit_2),
+            SIGNAL(activated()), this, SLOT(showXrefsDialog()));
 
     // Space to switch between disassembly and graph
     QShortcut *graph_shortcut = new QShortcut(QKeySequence(Qt::Key_Space), this->main);
@@ -171,11 +172,6 @@ MemoryWidget::MemoryWidget(MainWindow *main) :
     connect(rename_shortcut, SIGNAL(activated()), this, SLOT(on_actionFunctionsRename_triggered()));
     rename_shortcut->setContext(Qt::WidgetShortcut);
 
-    // R to show XRefs
-    QShortcut *xrefs_shortcut = new QShortcut(QKeySequence(Qt::Key_R), ui->disasTextEdit_2);
-    connect(xrefs_shortcut, SIGNAL(activated()), this, SLOT(on_actionXRefs_triggered()));
-    xrefs_shortcut->setContext(Qt::WidgetShortcut);
-
     // Esc to seek back
     QShortcut *back_shortcut = new QShortcut(QKeySequence(Qt::Key_Escape), ui->disasTextEdit_2);
     connect(back_shortcut, SIGNAL(activated()), this, SLOT(seek_back()));
@@ -1055,32 +1051,49 @@ void MemoryWidget::on_offsetToolButton_clicked()
     }
 }
 
+
+void MemoryWidget::showXrefsDialog()
+{
+    // Get current offset
+    QTextCursor tc = this->disasTextEdit->textCursor();
+    tc.select(QTextCursor::LineUnderCursor);
+    QString lastline = tc.selectedText();
+    QString ele = lastline.split(" ", QString::SkipEmptyParts)[0];
+    if (ele.contains("0x"))
+    {
+        RVA addr = ele.toLongLong(0, 16);
+        XrefsDialog *x = new XrefsDialog(this->main, this);
+        x->fillRefsForAddress(addr, RAddressString(addr), false);
+        x->exec();
+    }
+}
+
 /*
  * Show widgets
  */
 
-void MemoryWidget::showHexdump()
-{
-    ui->hexButton_2->setChecked(true);
-    ui->memTabWidget->setCurrentIndex(1);
-    ui->memSideTabWidget_2->setCurrentIndex(1);
-}
-
 void MemoryWidget::cycleViews()
 {
-    if (ui->memTabWidget->currentIndex() == 0)
+    switch (ui->memTabWidget->currentIndex())
     {
+    case 0:
         // Show graph
         ui->graphButton_2->setChecked(true);
         ui->memTabWidget->setCurrentIndex(2);
         ui->memSideTabWidget_2->setCurrentIndex(0);
-    }
-    else
-    {
+        break;
+    case 2:
+        // Show hexdump
+        ui->hexButton_2->setChecked(true);
+        ui->memTabWidget->setCurrentIndex(1);
+        ui->memSideTabWidget_2->setCurrentIndex(1);
+        break;
+    default:
         // Show disasm
         ui->disButton_2->setChecked(true);
         ui->memTabWidget->setCurrentIndex(0);
         ui->memSideTabWidget_2->setCurrentIndex(0);
+        break;
     }
 }
 
@@ -1403,10 +1416,10 @@ void MemoryWidget::on_codeCombo_2_currentTextChanged(const QString &arg1)
 void MemoryWidget::get_refs_data(RVA addr)
 {
     // refs = calls q hace esa funcion
-    QList<XrefDescription> refs = main->core->getXRefs(addr, false, "C");
+    QList<XrefDescription> refs = main->core->getXRefs(addr, false, false);
 
     // xrefs = calls a esa funcion
-    QList<XrefDescription> xrefs = main->core->getXRefs(addr, true);
+    QList<XrefDescription> xrefs = main->core->getXRefs(addr, true, false);
 
     // Data for the disasm side graph
     QList<int> data;
@@ -1830,23 +1843,7 @@ void MemoryWidget::setScrollMode()
 
 void MemoryWidget::on_actionXRefs_triggered()
 {
-    // Get current offset
-    QTextCursor tc = this->disasTextEdit->textCursor();
-    tc.select(QTextCursor::LineUnderCursor);
-    QString lastline = tc.selectedText();
-    QString ele = lastline.split(" ", QString::SkipEmptyParts)[0];
-    if (ele.contains("0x"))
-    {
-        // Get function for clicked offset
-        RAnalFunction *fcn = this->main->core->functionAt(ele.toLongLong(0, 16));
-        if (!fcn)
-        {
-            return;
-        }
-        XrefsDialog *x = new XrefsDialog(this->main, this);
-        x->fillRefsForFunction(fcn->addr, QString::fromUtf8(fcn->name));
-        x->exec();
-    }
+    showXrefsDialog();
 }
 
 
diff --git a/src/widgets/memorywidget.h b/src/widgets/memorywidget.h
index cd25fdbf..13a8b06c 100644
--- a/src/widgets/memorywidget.h
+++ b/src/widgets/memorywidget.h
@@ -158,8 +158,9 @@ private slots:
     void hexScrolled();
     QList<QString> get_hexdump(const QString &offset);
 
+    void showXrefsDialog();
     //void showDisas();
-    void showHexdump();
+    //void showHexdump();
     //void showGraph();
     void cycleViews();
     void on_xreFromTreeWidget_2_itemDoubleClicked(QTreeWidgetItem *item, int column);