From f35ce9949584995657450893971cf3208264162d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=A4rkl?= Date: Wed, 7 Jun 2017 21:35:38 +0200 Subject: [PATCH] Fix XrefsDialog, X-Refs in Sidebar from JSON --- src/dialogs/xrefsdialog.cpp | 71 ++++++++++++++++++--------- src/dialogs/xrefsdialog.h | 6 ++- src/mainwindow.cpp | 22 +-------- src/mainwindow.h | 2 - src/qrcore.cpp | 57 +++------------------- src/qrcore.h | 11 ++--- src/widgets/memorywidget.cpp | 94 ++++++++++++------------------------ src/widgets/memorywidget.h | 5 +- src/widgets/memorywidget.ui | 50 +++++++++++-------- 9 files changed, 127 insertions(+), 191 deletions(-) diff --git a/src/dialogs/xrefsdialog.cpp b/src/dialogs/xrefsdialog.cpp index af306c27..2bc3225d 100644 --- a/src/dialogs/xrefsdialog.cpp +++ b/src/dialogs/xrefsdialog.cpp @@ -3,10 +3,15 @@ #include "mainwindow.h" +#include + XrefsDialog::XrefsDialog(MainWindow *main, QWidget *parent) : QDialog(parent), ui(new Ui::XrefsDialog) { + addr = 0; + func_name = QString::null; + ui->setupUi(this); setWindowFlags(windowFlags() & (~Qt::WindowContextHelpButtonHint)); this->main = main; @@ -27,12 +32,12 @@ XrefsDialog::~XrefsDialog() delete ui; } -void XrefsDialog::fillRefs(QList refs, QList xrefs) +void XrefsDialog::fillRefs(QList refs, QList xrefs) { ui->fromTreeWidget->clear(); for (int i = 0; i < refs.size(); ++i) { - XRefDescription xref = refs[i]; + XrefDescription xref = refs[i]; QTreeWidgetItem *tempItem = new QTreeWidgetItem(); tempItem->setText(0, RAddressString(xref.to)); @@ -53,7 +58,7 @@ void XrefsDialog::fillRefs(QList refs, QList x ui->toTreeWidget->clear(); for (int i = 0; i < xrefs.size(); ++i) { - XRefDescription xref = xrefs[i]; + XrefDescription xref = xrefs[i]; QTreeWidgetItem *tempItem = new QTreeWidgetItem(); tempItem->setText(0, RAddressString(xref.from)); @@ -77,10 +82,10 @@ void XrefsDialog::on_fromTreeWidget_itemDoubleClicked(QTreeWidgetItem *item, int { QNOTUSED(column); - QString offset = item->text(0); - RAnalFunction *fcn = this->main->core->functionAt(offset.toLongLong(0, 16)); - //this->add_debug_output( fcn->name ); - this->main->seek(offset, fcn->name); + XrefDescription xref = item->data(0, Qt::UserRole).value(); + RAnalFunction *fcn = this->main->core->functionAt(xref.to); + this->main->seek(xref.to, fcn ? QString::fromUtf8(fcn->name) : QString::null, true); + this->close(); } @@ -88,10 +93,10 @@ void XrefsDialog::on_toTreeWidget_itemDoubleClicked(QTreeWidgetItem *item, int c { QNOTUSED(column); - QString offset = item->text(0); - RAnalFunction *fcn = this->main->core->functionAt(offset.toLongLong(0, 16)); - //this->add_debug_output( fcn->name ); - this->main->seek(offset, fcn->name); + XrefDescription xref = item->data(0, Qt::UserRole).value(); + RAnalFunction *fcn = this->main->core->functionAt(xref.from); + this->main->seek(xref.from, fcn ? QString::fromUtf8(fcn->name) : QString::null, true); + this->close(); } @@ -135,24 +140,39 @@ void XrefsDialog::highlightCurrentLine() void XrefsDialog::on_fromTreeWidget_itemSelectionChanged() { + if (ui->fromTreeWidget->selectedItems().isEmpty()) + return; + ui->toTreeWidget->clearSelection(); QTreeWidgetItem *item = ui->fromTreeWidget->currentItem(); - QString offset = item->text(0); - ui->previewTextEdit->setPlainText(this->main->core->cmd("pdf @ " + offset).trimmed()); - ui->previewTextEdit->moveCursor(QTextCursor::End); - // Does it make any sense? - ui->previewTextEdit->find(this->normalizeAddr(offset), QTextDocument::FindBackward); - ui->previewTextEdit->moveCursor(QTextCursor::StartOfWord, QTextCursor::MoveAnchor); + XrefDescription xref = item->data(0, Qt::UserRole).value(); + updatePreview(xref.to); } void XrefsDialog::on_toTreeWidget_itemSelectionChanged() { + if (ui->toTreeWidget->selectedItems().isEmpty()) + return; + ui->fromTreeWidget->clearSelection(); QTreeWidgetItem *item = ui->toTreeWidget->currentItem(); - QString offset = item->text(0); - ui->previewTextEdit->setPlainText(this->main->core->cmd("pdf @ " + offset).trimmed()); + XrefDescription xref = item->data(0, Qt::UserRole).value(); + updatePreview(xref.from); +} + +void XrefsDialog::updatePreview(RVA addr) +{ + QString disass; + + // is the address part of a function, so we can use pdf? + if (!main->core->cmdj("afij@" + QString::number(addr)).array().isEmpty()) + disass = main->core->cmd("pdf @ " + QString::number(addr)); + else + disass = main->core->cmd("pd 10 @ " + QString::number(addr)); + + ui->previewTextEdit->setPlainText(disass.trimmed()); + + // Does it make any sense? ui->previewTextEdit->moveCursor(QTextCursor::End); - // Again, does it make any sense? - // Also, this code should be refactored and shared instead of copied & pasted - ui->previewTextEdit->find(this->normalizeAddr(offset), QTextDocument::FindBackward); + ui->previewTextEdit->find(this->normalizeAddr(RAddressString(addr)), QTextDocument::FindBackward); ui->previewTextEdit->moveCursor(QTextCursor::StartOfWord, QTextCursor::MoveAnchor); } @@ -164,15 +184,18 @@ void XrefsDialog::updateLabels(QString name) void XrefsDialog::fillRefsForFunction(RVA addr, QString name) { + this->addr = addr; + this->func_name = func_name; + setWindowTitle(tr("X-Refs for function %1").arg(name)); updateLabels(name); // Get Refs and Xrefs // refs = calls q hace esa funcion - QList refs = main->core->getXRefs(addr, false, "C"); + QList refs = main->core->getXRefs(addr, false, "C"); // xrefs = calls a esa funcion - QList xrefs = main->core->getXRefs(addr, true); + QList xrefs = main->core->getXRefs(addr, true); fillRefs(refs, xrefs); } \ No newline at end of file diff --git a/src/dialogs/xrefsdialog.h b/src/dialogs/xrefsdialog.h index 7af77b2d..fe2b1854 100644 --- a/src/dialogs/xrefsdialog.h +++ b/src/dialogs/xrefsdialog.h @@ -38,13 +38,17 @@ private slots: void on_toTreeWidget_itemSelectionChanged(); private: + RVA addr; + QString func_name; + Ui::XrefsDialog *ui; MainWindow *main; Highlighter *highlighter; - void fillRefs(QList refs, QList xrefs); + void fillRefs(QList refs, QList xrefs); void updateLabels(QString name); + void updatePreview(RVA addr); }; diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index f999f682..c5b7cbaa 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -327,7 +327,6 @@ void MainWindow::finalizeOpen() core->cmd("fs sections"); updateFrames(); - get_refs(core->cmd("?v entry0")); memoryDock->selectHexPreview(); // Restore project notes @@ -770,7 +769,7 @@ void MainWindow::seek(const RVA offset, const QString &name, bool raise_memory_d core->seek(offset); setCursorAddress(offset); - refreshMem(offset); + refreshMem(); this->memoryDock->disasTextEdit->setFocus(); // Rise and shine baby! @@ -781,22 +780,8 @@ void MainWindow::seek(const RVA offset, const QString &name, bool raise_memory_d void MainWindow::refreshMem() { this->memoryDock->updateViews(); - } -void MainWindow::refreshMem(RVA offset) -{ - //add_debug_output("Refreshing to: " + off); - //graphicsBar->refreshColorBar(); - /* - this->memoryDock->refreshDisasm(off); - this->memoryDock->refreshHexdump(off); - this->memoryDock->create_graph(off); - */ - refreshMem(); - this->memoryDock->get_refs_data(RAddressString(offset)); - //this->memoryDock->setFcnName(offset); -} void MainWindow::on_backButton_clicked() { @@ -922,11 +907,6 @@ void MainWindow::on_actionFunctionsRename_triggered() r->open(); } -void MainWindow::get_refs(const QString &offset) -{ - this->memoryDock->get_refs_data(offset); -} - void MainWindow::addOutput(const QString &msg) { consoleWidget->addOutput(msg); diff --git a/src/mainwindow.h b/src/mainwindow.h index c6eaa5a0..f010759f 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -71,7 +71,6 @@ public: void updateFrames(); void refreshFunctions(); void refreshComments(); - void get_refs(const QString &offset); void addOutput(const QString &msg); void addDebugOutput(const QString &msg); void sendToNotepad(const QString &txt); @@ -180,7 +179,6 @@ private: bool doLock; void refreshMem(); - void refreshMem(RVA offset); ut64 hexdumpTopOffset; ut64 hexdumpBottomOffset; QString filename; diff --git a/src/qrcore.cpp b/src/qrcore.cpp index df58d83c..9ddc02eb 100644 --- a/src/qrcore.cpp +++ b/src/qrcore.cpp @@ -463,15 +463,13 @@ int QRCore::fcnBasicBlockCount(ut64 addr) return 0; } -int QRCore::fcnEndBbs(QString addr) +int QRCore::fcnEndBbs(RVA addr) { CORE_LOCK(); - bool ok; - int offset = addr.toLong(&ok, 16); - RAnalFunction *fcn = r_anal_get_fcn_in(core_->anal, offset, 0); + RAnalFunction *fcn = r_anal_get_fcn_in(core_->anal, addr, 0); if (fcn) { - QString tmp = this->cmd("afi @ " + addr + " ~end-bbs").split("\n")[0]; + QString tmp = this->cmd("afi @ " + QString::number(addr) + " ~end-bbs").split("\n")[0]; if (tmp.contains(":")) { QString endbbs = tmp.split(": ")[1]; @@ -1092,52 +1090,9 @@ QList QRCore::getAllSections() return ret; } - -QList QRCore::getFunctionXrefs(ut64 addr) +QList QRCore::getXRefs(RVA addr, bool to, const QString &filterType) { - CORE_LOCK(); - QList ret = QList(); - RList *list = r_anal_xrefs_get(core_->anal, addr); - RAnalRef *ref; - RListIter *it; - QRListForeach(list, it, RAnalRef, ref) - { - ret << QString("%1,0x%2,0x%3").arg( - QString(ref->type), - QString::number(ref->addr, 16), - QString::number(ref->at, 16)); - } - return ret; -} - -QList QRCore::getFunctionRefs(ut64 addr, char type) -{ - CORE_LOCK(); - QList ret = QList(); - //RAnalFunction *fcn = r_anal_get_fcn_at(core_->anal, addr, addr); - RAnalFunction *fcn = r_anal_get_fcn_in(core_->anal, addr, 0); - if (!fcn) - { - eprintf("qcore->getFunctionRefs: No function found\n"); - return ret; - } - //eprintf(fcn->name); - RAnalRef *ref; - RListIter *it; - QRListForeach(fcn->refs, it, RAnalRef, ref) - { - if (type == ref->type || type == 0) - ret << QString("%1,0x%2,0x%3").arg( - QString(ref->type), - QString::number(ref->addr, 16), - QString::number(ref->at, 16)); - } - return ret; -} - -QList QRCore::getXRefs(RVA addr, bool to, const QString &filterType) -{ - QList ret = QList(); + QList ret = QList(); QJsonArray xrefsArray; @@ -1150,7 +1105,7 @@ QList QRCore::getXRefs(RVA addr, bool to, const QString &filter { QJsonObject xrefObject = value.toObject(); - XRefDescription xref; + XrefDescription xref; xref.type = xrefObject["type"].toString(); if (!filterType.isNull() && filterType != xref.type) diff --git a/src/qrcore.h b/src/qrcore.h index 237882e0..417feef3 100644 --- a/src/qrcore.h +++ b/src/qrcore.h @@ -134,7 +134,7 @@ struct SectionDescription QString flags; }; -struct XRefDescription +struct XrefDescription { RVA from; RVA to; @@ -150,7 +150,7 @@ Q_DECLARE_METATYPE(RelocDescription) Q_DECLARE_METATYPE(StringDescription) Q_DECLARE_METATYPE(FlagspaceDescription) Q_DECLARE_METATYPE(FlagDescription) -Q_DECLARE_METATYPE(XRefDescription) +Q_DECLARE_METATYPE(XrefDescription) class QRCore : public QObject { @@ -167,7 +167,7 @@ public: int getFcnSize(ut64 addr); int fcnCyclomaticComplexity(ut64 addr); int fcnBasicBlockCount(ut64 addr); - int fcnEndBbs(QString addr); + int fcnEndBbs(RVA addr); QString cmd(const QString &str); QJsonDocument cmdj(const QString &str); void renameFunction(QString prev_name, QString new_name); @@ -234,10 +234,7 @@ public: QList getAllFlags(QString flagspace = NULL); QList getAllSections(); - - QList getFunctionXrefs(ut64 addr); - QList getFunctionRefs(ut64 addr, char type); - QList getXRefs(RVA addr, bool to, const QString &filterType = QString::null); + QList getXRefs(RVA addr, bool to, const QString &filterType = QString::null); RCoreLocked core() const; diff --git a/src/widgets/memorywidget.cpp b/src/widgets/memorywidget.cpp index 7872dcbf..f79cbdb2 100644 --- a/src/widgets/memorywidget.cpp +++ b/src/widgets/memorywidget.cpp @@ -202,6 +202,7 @@ MemoryWidget::MemoryWidget(MainWindow *main) : void MemoryWidget::on_cursorAddressChanged(RVA addr) { setFcnName(addr); + get_refs_data(addr); } /* @@ -404,7 +405,7 @@ void MemoryWidget::setup() refreshDisasm(off); refreshHexdump(off); create_graph(off); - get_refs_data(off); + get_refs_data(off.toLongLong(0, 16)); //setFcnName(off); } @@ -1296,7 +1297,6 @@ void MemoryWidget::on_actionFunctionsRename_triggered() this->main->core->renameFunction(fcn->name, new_name); // Seek to new renamed function this->main->seek(new_name); - // TODO: Refresh functions tree widget } } this->main->refreshFunctions(); @@ -1346,18 +1346,16 @@ void MemoryWidget::on_action1column_triggered() void MemoryWidget::on_xreFromTreeWidget_2_itemDoubleClicked(QTreeWidgetItem *item, int /*column*/) { - QString offset = item->text(0); - RAnalFunction *fcn = this->main->core->functionAt(offset.toLongLong(0, 16)); - //this->add_debug_output( fcn->name ); - this->main->seek(offset, fcn->name); + XrefDescription xref = item->data(0, Qt::UserRole).value(); + RAnalFunction *fcn = this->main->core->functionAt(xref.to); + this->main->seek(xref.to, fcn ? QString::fromUtf8(fcn->name) : QString::null, true); } void MemoryWidget::on_xrefToTreeWidget_2_itemDoubleClicked(QTreeWidgetItem *item, int /*column*/) { - QString offset = item->text(0); - RAnalFunction *fcn = this->main->core->functionAt(offset.toLongLong(0, 16)); - //this->add_debug_output( fcn->name ); - this->main->seek(offset, fcn->name); + XrefDescription xref = item->data(0, Qt::UserRole).value(); + RAnalFunction *fcn = this->main->core->functionAt(xref.from); + this->main->seek(xref.from, fcn ? QString::fromUtf8(fcn->name) : QString::null, true); } void MemoryWidget::on_xrefFromToolButton_2_clicked() @@ -1402,47 +1400,13 @@ void MemoryWidget::on_codeCombo_2_currentTextChanged(const QString &arg1) } } -void MemoryWidget::get_refs_data(const QString &offset) +void MemoryWidget::get_refs_data(RVA addr) { - // Get Refs and Xrefs - bool ok; - QList ret_refs; - QList ret_xrefs; - // refs = calls q hace esa funcion - QList refs = this->main->core->getFunctionRefs(offset.toLong(&ok, 16), 'C'); - if (refs.size() > 0) - { - for (int i = 0; i < refs.size(); ++i) - { - //this->add_debug_output(refs.at(i)); - QStringList retlist = refs.at(i).split(","); - QStringList temp; - QString addr = retlist.at(2); - temp << addr; - QString op = this->main->core->cmd("pi 1 @ " + addr); - temp << op.simplified(); - ret_refs << temp; - } - } + QList refs = main->core->getXRefs(addr, false, "C"); // xrefs = calls a esa funcion - //qDebug() << this->main->core->getFunctionXrefs(offset.toLong(&ok, 16)); - QList xrefs = this->main->core->getFunctionXrefs(offset.toLong(&ok, 16)); - if (xrefs.size() > 0) - { - for (int i = 0; i < xrefs.size(); ++i) - { - //this->add_debug_output(xrefs.at(i)); - QStringList retlist = xrefs.at(i).split(","); - QStringList temp; - QString addr = retlist.at(1); - temp << addr; - QString op = this->main->core->cmd("pi 1 @ " + addr); - temp << op.simplified(); - ret_xrefs << temp; - } - } + QList xrefs = main->core->getXRefs(addr, true); // Data for the disasm side graph QList data; @@ -1452,27 +1416,29 @@ void MemoryWidget::get_refs_data(const QString &offset) data << xrefs.size(); //qDebug() << "CC: " << this->main->core->fcnCyclomaticComplexity(offset.toLong(&ok, 16)); //data << this->main->core->fcnCyclomaticComplexity(offset.toLong(&ok, 16)); - data << this->main->core->getCycloComplex(offset.toLong(&ok, 16)); + data << this->main->core->getCycloComplex(addr); //qDebug() << "BB: " << this->main->core->fcnBasicBlockCount(offset.toLong(&ok, 16)); - data << this->main->core->fcnBasicBlockCount(offset.toLong(&ok, 16)); - data << this->main->core->fcnEndBbs(offset); + data << this->main->core->fcnBasicBlockCount(addr); + data << this->main->core->fcnEndBbs(addr); //qDebug() << "MEOW: " + this->main->core->fcnEndBbs(offset); // Update disasm side bar - this->fill_refs(ret_refs, ret_xrefs, data); + this->fill_refs(refs, xrefs, data); } -void MemoryWidget::fill_refs(QList refs, QList xrefs, QList graph_data) +void MemoryWidget::fill_refs(QList refs, QList xrefs, QList graph_data) { this->xreFromTreeWidget_2->clear(); for (int i = 0; i < refs.size(); ++i) { - //this->add_debug_output(refs.at(i).at(0) + " " + refs.at(i).at(1)); + XrefDescription xref = refs[i]; QTreeWidgetItem *tempItem = new QTreeWidgetItem(); - tempItem->setText(0, refs.at(i).at(0)); - tempItem->setText(1, refs.at(i).at(1)); - tempItem->setToolTip(0, this->main->core->cmd("pdi 10 @ " + refs.at(i).at(0)).trimmed()); - tempItem->setToolTip(1, this->main->core->cmd("pdi 10 @ " + refs.at(i).at(0)).trimmed()); + tempItem->setText(0, RAddressString(xref.to)); + tempItem->setText(1, main->core->disassembleSingleInstruction(xref.from)); + tempItem->setData(0, Qt::UserRole, QVariant::fromValue(xref)); + QString tooltip = this->main->core->cmd("pdi 10 @ " + QString::number(xref.to)).trimmed(); + tempItem->setToolTip(0, tooltip); + tempItem->setToolTip(1, tooltip); this->xreFromTreeWidget_2->insertTopLevelItem(0, tempItem); } // Adjust columns to content @@ -1485,12 +1451,15 @@ void MemoryWidget::fill_refs(QList refs, QList xrefs, this->xrefToTreeWidget_2->clear(); for (int i = 0; i < xrefs.size(); ++i) { - //this->add_debug_output(xrefs.at(i).at(0) + " " + xrefs.at(i).at(1)); + XrefDescription xref = xrefs[i]; + QTreeWidgetItem *tempItem = new QTreeWidgetItem(); - tempItem->setText(0, xrefs.at(i).at(0)); - tempItem->setText(1, xrefs.at(i).at(1)); - tempItem->setToolTip(0, this->main->core->cmd("pdi 10 @ " + xrefs.at(i).at(0)).trimmed()); - tempItem->setToolTip(1, this->main->core->cmd("pdi 10 @ " + xrefs.at(i).at(0)).trimmed()); + tempItem->setText(0, RAddressString(xref.from)); + tempItem->setText(1, main->core->disassembleSingleInstruction(xref.from)); + tempItem->setData(0, Qt::UserRole, QVariant::fromValue(xref)); + QString tooltip = this->main->core->cmd("pdi 10 @ " + QString::number(xref.from)).trimmed(); + tempItem->setToolTip(0, this->main->core->cmd("pdi 10 @ " + tooltip).trimmed()); + tempItem->setToolTip(1, this->main->core->cmd("pdi 10 @ " + tooltip).trimmed()); this->xrefToTreeWidget_2->insertTopLevelItem(0, tempItem); } // Adjust columns to content @@ -1670,7 +1639,6 @@ void MemoryWidget::on_disasTextEdit_2_cursorPositionChanged() // Refresh function information at sidebar ui->fcnNameEdit->setText(at); this->main->memoryDock->setWindowTitle(at); - this->main->memoryDock->get_refs_data(ele); //this->main->memoryDock->create_graph(ele); this->setMiniGraph(at); } diff --git a/src/widgets/memorywidget.h b/src/widgets/memorywidget.h index 77f6955c..cd25fdbf 100644 --- a/src/widgets/memorywidget.h +++ b/src/widgets/memorywidget.h @@ -70,12 +70,10 @@ public slots: void refreshHexdump(const QString &where = QString()); - void fill_refs(QList refs, QList xrefs, QList graph_data); + void fill_refs(QList refs, QList xrefs, QList graph_data); void fillOffsetInfo(QString off); - void get_refs_data(const QString &offset); - void seek_to(const QString &offset); void create_graph(QString off); @@ -112,6 +110,7 @@ private: RVA last_hexdump_fcn; void setFcnName(RVA addr); + void get_refs_data(RVA addr); void setScrollMode(); diff --git a/src/widgets/memorywidget.ui b/src/widgets/memorywidget.ui index fd1aa04c..8c0990dc 100644 --- a/src/widgets/memorywidget.ui +++ b/src/widgets/memorywidget.ui @@ -6,8 +6,8 @@ 0 0 - 990 - 767 + 1078 + 815 @@ -1325,7 +1325,7 @@ border-top: 0px; 0 - -175 + -127 256 887 @@ -1866,20 +1866,17 @@ color: rgb(0, 0, 0); - + 5 - - 0 - 0 - + - + ... @@ -1899,16 +1896,22 @@ color: rgb(0, 0, 0); - + + + + 75 + true + + - <b>Xrefs from:</b> + X-Refs to current address: - + 0 @@ -1974,17 +1977,20 @@ QToolTip { - + 5 + + 0 + 0 - + - ... + @@ -2004,16 +2010,22 @@ QToolTip { - + + + + 75 + true + + - <b>Xrefs To:</b> + X-Refs from current address: - + 0 @@ -3031,8 +3043,8 @@ QToolTip { + -