Added option to break esil execution on invalid instructions (#597)

* Added option to break esil execution on invalid instructions

* update r2
This commit is contained in:
fcasal 2018-07-27 13:00:23 +01:00 committed by xarkes
parent 4424c3c45d
commit 94f417c1ff
7 changed files with 34 additions and 7 deletions

@ -1 +1 @@
Subproject commit f260195ad5c3ac3e02768ff48670cd2e4780a4c9 Subproject commit 3e55b5f57d3d8eb2c38e681f125e7b9517191fde

View File

@ -645,6 +645,14 @@ QString CutterCore::cmdFunctionAt(RVA addr)
return cmdFunctionAt(QString::number(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) QString CutterCore::createFunctionAt(RVA addr, QString name)
{ {
name.remove(QRegExp("[^a-zA-Z0-9_]")); name.remove(QRegExp("[^a-zA-Z0-9_]"));
@ -905,7 +913,7 @@ void CutterCore::continueUntilDebug(QString offset)
if (!currentlyEmulating) { if (!currentlyEmulating) {
cmd("dcu " + offset); cmd("dcu " + offset);
} else { } else {
cmd("aecu " + offset); cmdEsil("aecu " + offset);
} }
emit registersChanged(); emit registersChanged();
emit refreshCodeViews(); emit refreshCodeViews();
@ -926,7 +934,7 @@ void CutterCore::continueUntilSyscall()
{ {
if (currentlyDebugging) { if (currentlyDebugging) {
if (currentlyEmulating) { if (currentlyEmulating) {
cmd("aecs"); cmdEsil("aecs");
} else { } else {
cmd("dcs"); cmd("dcs");
} }
@ -939,7 +947,7 @@ void CutterCore::continueUntilSyscall()
void CutterCore::stepDebug() void CutterCore::stepDebug()
{ {
if (currentlyDebugging) { if (currentlyDebugging) {
cmd("ds"); cmdEsil("ds");
QString programCounterValue = cmd("dr?`drn PC`").trimmed(); QString programCounterValue = cmd("dr?`drn PC`").trimmed();
seek(programCounterValue); seek(programCounterValue);
emit registersChanged(); emit registersChanged();
@ -949,7 +957,7 @@ void CutterCore::stepDebug()
void CutterCore::stepOverDebug() void CutterCore::stepOverDebug()
{ {
if (currentlyDebugging) { if (currentlyDebugging) {
cmd("dso"); cmdEsil("dso");
QString programCounterValue = cmd("dr?`drn PC`").trimmed(); QString programCounterValue = cmd("dr?`drn PC`").trimmed();
seek(programCounterValue); seek(programCounterValue);
emit registersChanged(); emit registersChanged();

View File

@ -15,6 +15,7 @@
#include <QStringList> #include <QStringList>
#include <QMessageBox> #include <QMessageBox>
#include <QJsonDocument> #include <QJsonDocument>
#include <QErrorMessage>
#define HAVE_LATEST_LIBR2 false #define HAVE_LATEST_LIBR2 false
@ -385,6 +386,7 @@ public:
} }
QString cmdTask(const QString &str); QString cmdTask(const QString &str);
QJsonDocument cmdjTask(const QString &str); QJsonDocument cmdjTask(const QString &str);
void cmdEsil(QString command);
QString getVersionInformation(); QString getVersionInformation();
QJsonDocument parseJson(const char *res, const QString &cmd = QString()); QJsonDocument parseJson(const char *res, const QString &cmd = QString());
@ -641,6 +643,7 @@ private:
RCore *core_; RCore *core_;
AsyncTaskManager *asyncTaskManager; AsyncTaskManager *asyncTaskManager;
RVA offsetPriorDebugging = RVA_INVALID; RVA offsetPriorDebugging = RVA_INVALID;
QErrorMessage msgBox;
QList<CutterPlugin*> plugins; QList<CutterPlugin*> plugins;
}; };

View File

@ -10,10 +10,11 @@
#include "utils/Helpers.h" #include "utils/Helpers.h"
#include "utils/Configuration.h" #include "utils/Configuration.h"
DebugOptionsWidget::DebugOptionsWidget(PreferencesDialog */*dialog*/, QWidget *parent) DebugOptionsWidget::DebugOptionsWidget(PreferencesDialog *dialog, QWidget *parent)
: QDialog(parent), : QDialog(parent),
ui(new Ui::DebugOptionsWidget) ui(new Ui::DebugOptionsWidget)
{ {
Q_UNUSED(dialog);
ui->setupUi(this); ui->setupUi(this);
updateDebugPlugin(); updateDebugPlugin();
@ -23,6 +24,7 @@ DebugOptionsWidget::~DebugOptionsWidget() {}
void DebugOptionsWidget::updateDebugPlugin() void DebugOptionsWidget::updateDebugPlugin()
{ {
ui->esilBreakOnInvalid->setChecked(Config()->getConfigBool("esil.breakoninvalid"));
disconnect(ui->pluginComboBox, SIGNAL(currentIndexChanged(const QString &)), this, disconnect(ui->pluginComboBox, SIGNAL(currentIndexChanged(const QString &)), this,
SLOT(on_pluginComboBox_currentIndexChanged(const QString &))); SLOT(on_pluginComboBox_currentIndexChanged(const QString &)));
@ -76,3 +78,8 @@ void DebugOptionsWidget::updateStackAddr()
Core()->setConfig("esil.stack.addr", newAddr); Core()->setConfig("esil.stack.addr", newAddr);
ui->stackAddr->setPlaceholderText(newAddr); ui->stackAddr->setPlaceholderText(newAddr);
} }
void DebugOptionsWidget::on_esilBreakOnInvalid_toggled(bool checked)
{
Config()->setConfig("esil.breakoninvalid", checked);
}

View File

@ -28,4 +28,5 @@ private slots:
void updateStackAddr(); void updateStackAddr();
void updateStackSize(); void updateStackSize();
void on_pluginComboBox_currentIndexChanged(const QString &index); void on_pluginComboBox_currentIndexChanged(const QString &index);
void on_esilBreakOnInvalid_toggled(bool checked);
}; };

View File

@ -103,6 +103,13 @@
</item> </item>
</layout> </layout>
</item> </item>
<item row="4" column="0">
<widget class="QCheckBox" name="esilBreakOnInvalid">
<property name="text">
<string>Break esil execution when instruction is invalid (esil.breakoninvalid)</string>
</property>
</widget>
</item>
</layout> </layout>
</item> </item>
</layout> </layout>

View File

@ -36,7 +36,8 @@ static const QHash<QString, QVariant> asmOptions = {
{ "asm.var.sub", true }, { "asm.var.sub", true },
{ "asm.var.subonly", true }, { "asm.var.subonly", true },
{ "asm.tabs", 5 }, { "asm.tabs", 5 },
{ "asm.tabs.off", 5 } { "asm.tabs.off", 5 },
{ "esil.breakoninvalid", true }
}; };