From 5c4ba4891d5fbca6cd1aa7cf4a27c065d179798f Mon Sep 17 00:00:00 2001 From: nirkog Date: Sat, 8 Jan 2022 15:53:27 +0200 Subject: [PATCH] Add double click to seek to global var in decompiler (#2871) --- src/widgets/DecompilerWidget.cpp | 32 +++++++++++++++++++++++++++++--- src/widgets/DecompilerWidget.h | 12 ++++++++++++ 2 files changed, 41 insertions(+), 3 deletions(-) diff --git a/src/widgets/DecompilerWidget.cpp b/src/widgets/DecompilerWidget.cpp index e45c8c8a..a6dd58af 100644 --- a/src/widgets/DecompilerWidget.cpp +++ b/src/widgets/DecompilerWidget.cpp @@ -115,6 +115,28 @@ Decompiler *DecompilerWidget::getCurrentDecompiler() return Core()->getDecompilerById(ui->decompilerComboBox->currentData().toString()); } +ut64 DecompilerWidget::findReference(size_t pos) +{ + size_t closestPos = SIZE_MAX; + ut64 closestOffset = RVA_INVALID; + void *iter; + rz_vector_foreach(&code->annotations, iter) + { + RzCodeAnnotation *annotation = (RzCodeAnnotation *)iter; + + if (!(annotation->type == RZ_CODE_ANNOTATION_TYPE_GLOBAL_VARIABLE) + || annotation->start > pos || annotation->end <= pos) { + continue; + } + if (closestPos != SIZE_MAX && closestPos >= annotation->start) { + continue; + } + closestPos = annotation->start; + closestOffset = annotation->reference.offset; + } + return closestOffset; +} + ut64 DecompilerWidget::offsetForPosition(size_t pos) { size_t closestPos = SIZE_MAX; @@ -123,7 +145,8 @@ ut64 DecompilerWidget::offsetForPosition(size_t pos) rz_vector_foreach(&code->annotations, iter) { RzCodeAnnotation *annotation = (RzCodeAnnotation *)iter; - if (annotation->type != RZ_CODE_ANNOTATION_TYPE_OFFSET || annotation->start > pos + + if (!(annotation->type == RZ_CODE_ANNOTATION_TYPE_OFFSET) || annotation->start > pos || annotation->end <= pos) { continue; } @@ -479,8 +502,11 @@ void DecompilerWidget::showDecompilerContextMenu(const QPoint &pt) void DecompilerWidget::seekToReference() { size_t pos = ui->textEdit->textCursor().position(); - RVA offset = offsetForPosition(pos); - seekable->seekToReference(offset); + RVA offset = findReference(pos); + if (offset != RVA_INVALID) { + seekable->seek(offset); + } + seekable->seekToReference(offsetForPosition(pos)); } bool DecompilerWidget::eventFilter(QObject *obj, QEvent *event) diff --git a/src/widgets/DecompilerWidget.h b/src/widgets/DecompilerWidget.h index 22d0abf7..015525af 100644 --- a/src/widgets/DecompilerWidget.h +++ b/src/widgets/DecompilerWidget.h @@ -198,6 +198,18 @@ private: * @param endPos - Position of the end of the range(inclusive). */ void gatherBreakpointInfo(RzAnnotatedCode &codeDecompiled, size_t startPos, size_t endPos); + /** + * @brief Finds the global variable reference that's closes to the specified position in the + * decompiled code. Same as offsetForPosition but for global references only + * + * @note If no global reference annotations are found at the given position, an RVA_INVALID is + * returned + * + * @param pos - Position in the decompiled code + * @return Address of the referenced global for the specified position, or RVA_INVALID if none + * is found + */ + ut64 findReference(size_t pos); /** * @brief Finds the offset that's closest to the specified position in the decompiled code. *