From 94f417c1ff5df3a4b63d99a00c678d9456d01333 Mon Sep 17 00:00:00 2001 From: fcasal Date: Fri, 27 Jul 2018 13:00:23 +0100 Subject: [PATCH] Added option to break esil execution on invalid instructions (#597) * Added option to break esil execution on invalid instructions * update r2 --- radare2 | 2 +- src/Cutter.cpp | 16 ++++++++++++---- src/Cutter.h | 3 +++ src/dialogs/preferences/DebugOptionsWidget.cpp | 9 ++++++++- src/dialogs/preferences/DebugOptionsWidget.h | 1 + src/dialogs/preferences/DebugOptionsWidget.ui | 7 +++++++ src/utils/Configuration.cpp | 3 ++- 7 files changed, 34 insertions(+), 7 deletions(-) diff --git a/radare2 b/radare2 index f260195a..3e55b5f5 160000 --- a/radare2 +++ b/radare2 @@ -1 +1 @@ -Subproject commit f260195ad5c3ac3e02768ff48670cd2e4780a4c9 +Subproject commit 3e55b5f57d3d8eb2c38e681f125e7b9517191fde diff --git a/src/Cutter.cpp b/src/Cutter.cpp index 5cbbe1a9..6bb9641c 100644 --- a/src/Cutter.cpp +++ b/src/Cutter.cpp @@ -645,6 +645,14 @@ QString CutterCore::cmdFunctionAt(RVA addr) return cmdFunctionAt(QString::number(addr)); } +void CutterCore::cmdEsil(QString command) +{ + QString res = cmd(command); + if (res.contains("[ESIL] Stopped execution in an invalid instruction")) { + msgBox.showMessage("Stopped when attempted to run an invalid instruction. You can disable this in Preferences"); + } +} + QString CutterCore::createFunctionAt(RVA addr, QString name) { name.remove(QRegExp("[^a-zA-Z0-9_]")); @@ -905,7 +913,7 @@ void CutterCore::continueUntilDebug(QString offset) if (!currentlyEmulating) { cmd("dcu " + offset); } else { - cmd("aecu " + offset); + cmdEsil("aecu " + offset); } emit registersChanged(); emit refreshCodeViews(); @@ -926,7 +934,7 @@ void CutterCore::continueUntilSyscall() { if (currentlyDebugging) { if (currentlyEmulating) { - cmd("aecs"); + cmdEsil("aecs"); } else { cmd("dcs"); } @@ -939,7 +947,7 @@ void CutterCore::continueUntilSyscall() void CutterCore::stepDebug() { if (currentlyDebugging) { - cmd("ds"); + cmdEsil("ds"); QString programCounterValue = cmd("dr?`drn PC`").trimmed(); seek(programCounterValue); emit registersChanged(); @@ -949,7 +957,7 @@ void CutterCore::stepDebug() void CutterCore::stepOverDebug() { if (currentlyDebugging) { - cmd("dso"); + cmdEsil("dso"); QString programCounterValue = cmd("dr?`drn PC`").trimmed(); seek(programCounterValue); emit registersChanged(); diff --git a/src/Cutter.h b/src/Cutter.h index 6b3eb41d..5c75a45c 100644 --- a/src/Cutter.h +++ b/src/Cutter.h @@ -15,6 +15,7 @@ #include #include #include +#include #define HAVE_LATEST_LIBR2 false @@ -385,6 +386,7 @@ public: } QString cmdTask(const QString &str); QJsonDocument cmdjTask(const QString &str); + void cmdEsil(QString command); QString getVersionInformation(); QJsonDocument parseJson(const char *res, const QString &cmd = QString()); @@ -641,6 +643,7 @@ private: RCore *core_; AsyncTaskManager *asyncTaskManager; RVA offsetPriorDebugging = RVA_INVALID; + QErrorMessage msgBox; QList plugins; }; diff --git a/src/dialogs/preferences/DebugOptionsWidget.cpp b/src/dialogs/preferences/DebugOptionsWidget.cpp index 0cbffbfa..549f256c 100644 --- a/src/dialogs/preferences/DebugOptionsWidget.cpp +++ b/src/dialogs/preferences/DebugOptionsWidget.cpp @@ -10,10 +10,11 @@ #include "utils/Helpers.h" #include "utils/Configuration.h" -DebugOptionsWidget::DebugOptionsWidget(PreferencesDialog */*dialog*/, QWidget *parent) +DebugOptionsWidget::DebugOptionsWidget(PreferencesDialog *dialog, QWidget *parent) : QDialog(parent), ui(new Ui::DebugOptionsWidget) { + Q_UNUSED(dialog); ui->setupUi(this); updateDebugPlugin(); @@ -23,6 +24,7 @@ DebugOptionsWidget::~DebugOptionsWidget() {} void DebugOptionsWidget::updateDebugPlugin() { + ui->esilBreakOnInvalid->setChecked(Config()->getConfigBool("esil.breakoninvalid")); disconnect(ui->pluginComboBox, SIGNAL(currentIndexChanged(const QString &)), this, SLOT(on_pluginComboBox_currentIndexChanged(const QString &))); @@ -76,3 +78,8 @@ void DebugOptionsWidget::updateStackAddr() Core()->setConfig("esil.stack.addr", newAddr); ui->stackAddr->setPlaceholderText(newAddr); } + +void DebugOptionsWidget::on_esilBreakOnInvalid_toggled(bool checked) +{ + Config()->setConfig("esil.breakoninvalid", checked); +} diff --git a/src/dialogs/preferences/DebugOptionsWidget.h b/src/dialogs/preferences/DebugOptionsWidget.h index 0db1315d..2c6aa514 100644 --- a/src/dialogs/preferences/DebugOptionsWidget.h +++ b/src/dialogs/preferences/DebugOptionsWidget.h @@ -28,4 +28,5 @@ private slots: void updateStackAddr(); void updateStackSize(); void on_pluginComboBox_currentIndexChanged(const QString &index); + void on_esilBreakOnInvalid_toggled(bool checked); }; diff --git a/src/dialogs/preferences/DebugOptionsWidget.ui b/src/dialogs/preferences/DebugOptionsWidget.ui index 64860208..91cab5b1 100644 --- a/src/dialogs/preferences/DebugOptionsWidget.ui +++ b/src/dialogs/preferences/DebugOptionsWidget.ui @@ -103,6 +103,13 @@ + + + + Break esil execution when instruction is invalid (esil.breakoninvalid) + + + diff --git a/src/utils/Configuration.cpp b/src/utils/Configuration.cpp index ecaa311d..07669f6e 100644 --- a/src/utils/Configuration.cpp +++ b/src/utils/Configuration.cpp @@ -36,7 +36,8 @@ static const QHash asmOptions = { { "asm.var.sub", true }, { "asm.var.subonly", true }, { "asm.tabs", 5 }, - { "asm.tabs.off", 5 } + { "asm.tabs.off", 5 }, + { "esil.breakoninvalid", true } };