From 06c8f15ce08e5d9d4da02bdf6260aef24bd4a0a8 Mon Sep 17 00:00:00 2001 From: billow Date: Thu, 16 Jun 2022 07:28:43 +0800 Subject: [PATCH 1/6] Convert Rizin command calls to the API (#2968) * `es` * `il` * `wcr` * `.ar-` * `aets-` * `drp` * `ahts` * `e =?` * `fo` --- src/common/Decompiler.cpp | 2 +- src/core/Cutter.cpp | 55 +++++++++++++- src/core/Cutter.h | 2 + src/core/CutterCommon.h | 77 ++++++++++++++++++-- src/core/MainWindow.cpp | 6 +- src/dialogs/InitialOptionsDialog.cpp | 2 +- src/dialogs/preferences/AsmOptionsWidget.cpp | 2 +- src/menus/DisassemblyContextMenu.cpp | 18 +++-- src/widgets/CommentsWidget.cpp | 3 +- src/widgets/Dashboard.cpp | 21 +++--- 10 files changed, 151 insertions(+), 37 deletions(-) diff --git a/src/common/Decompiler.cpp b/src/common/Decompiler.cpp index 7653f1d2..1868e4e4 100644 --- a/src/common/Decompiler.cpp +++ b/src/common/Decompiler.cpp @@ -92,7 +92,7 @@ JSDecDecompiler::JSDecDecompiler(QObject *parent) : Decompiler("jsdec", "jsdec", bool JSDecDecompiler::isAvailable() { - return Core()->cmdList("es").contains("jsdec"); + return Core()->getConfigVariableSpaces().contains("jsdec"); } void JSDecDecompiler::decompileAt(RVA addr) diff --git a/src/core/Cutter.cpp b/src/core/Cutter.cpp index 59306d39..acd1e679 100644 --- a/src/core/Cutter.cpp +++ b/src/core/Cutter.cpp @@ -1199,7 +1199,21 @@ void CutterCore::message(const QString &msg, bool debug) QString CutterCore::getConfig(const char *k) { CORE_LOCK(); - return QString(rz_config_get(core->config, k)); + return { rz_config_get(core->config, k) }; +} + +QStringList CutterCore::getConfigOptions(const char *k) +{ + CORE_LOCK(); + RzConfigNode *node = rz_config_node_get(core->config, k); + if (!(node && node->options)) { + return {}; + } + QStringList list; + for (const auto &s : CutterRzList(node->options)) { + list << s; + } + return list; } void CutterCore::setConfig(const char *k, const QVariant &v) @@ -2146,11 +2160,15 @@ void CutterCore::stopDebug() currentlyRemoteDebugging = false; emit debugTaskStateChanged(); + CORE_LOCK(); if (currentlyEmulating) { - cmdEsil("aeim-; aei-; wcr; .ar-; aets-"); + cmdEsil("aeim- ; aei-"); + resetWriteCache(); + rz_core_debug_clear_register_flags(core); + rz_core_analysis_esil_trace_stop(core); currentlyEmulating = false; } else { - rz_core_debug_process_close(core()); + rz_core_debug_process_close(core); currentlyAttachedToPID = -1; } @@ -2870,8 +2888,17 @@ bool CutterCore::isGraphEmpty() void CutterCore::getOpcodes() { + CORE_LOCK(); this->opcodes = cmdList("?O"); - this->regs = cmdList("drp~[1]"); + + this->regs = {}; + const RzList *rs = rz_reg_get_list(core->dbg->reg, RZ_REG_TYPE_ANY); + if (!rs) { + return; + } + for (const auto &r : CutterRzList(rs)) { + this->regs.push_back(r->name); + } } void CutterCore::setSettings() @@ -4430,3 +4457,23 @@ QByteArray CutterCore::ioRead(RVA addr, int len) return array; } + +QStringList CutterCore::getConfigVariableSpaces(const QString &key) +{ + CORE_LOCK(); + QStringList stringList; + for (const auto &node : CutterRzList(core->config->nodes)) { + stringList.push_back(node->name); + } + + if (!key.isEmpty()) { + stringList = stringList.filter(QRegularExpression(QString("^%0\\..*").arg(key))); + std::transform(stringList.begin(), stringList.end(), stringList.begin(), + [](const QString &x) { return x.split('.').last(); }); + } else { + std::transform(stringList.begin(), stringList.end(), stringList.begin(), + [](const QString &x) { return x.split('.').first(); }); + } + stringList.removeDuplicates(); + return stringList; +} diff --git a/src/core/Cutter.h b/src/core/Cutter.h index 607fb7b2..9552fd82 100644 --- a/src/core/Cutter.h +++ b/src/core/Cutter.h @@ -393,10 +393,12 @@ public: QString getConfig(const char *k); QString getConfig(const QString &k) { return getConfig(k.toUtf8().constData()); } QString getConfigDescription(const char *k); + QStringList getConfigOptions(const char *k); QStringList getColorThemes(); QHash getTheme(); QStringList getThemeKeys(); bool setColor(const QString &key, const QString &color); + QStringList getConfigVariableSpaces(const QString &key = ""); /* Assembly\Hexdump related methods */ QByteArray assemble(const QString &code); diff --git a/src/core/CutterCommon.h b/src/core/CutterCommon.h index 6d6f7e7a..4adbf234 100644 --- a/src/core/CutterCommon.h +++ b/src/core/CutterCommon.h @@ -15,20 +15,21 @@ #endif // Q_OS_WIN // Rizin list iteration macros -#define CutterRzListForeach(list, it, type, x) \ +#define CutterRzListForeach(list, it, type, x) \ if (list) \ for (it = list->head; it && ((x = static_cast(it->data))); it = it->n) -#define CutterRzVectorForeach(vec, it, type) \ +#define CutterRzVectorForeach(vec, it, type) \ if ((vec) && (vec)->a) \ for (it = (type *)(vec)->a; \ (char *)it != (char *)(vec)->a + ((vec)->len * (vec)->elem_size); \ it = (type *)((char *)it + (vec)->elem_size)) -template class CutterPVector +template +class CutterPVector { private: - const RzPVector * const vec; + const RzPVector *const vec; public: class iterator : public std::iterator @@ -39,10 +40,19 @@ public: public: iterator(T **p) : p(p) {} iterator(const iterator &o) : p(o.p) {} - iterator &operator++() { p++; return *this; } - iterator operator++(int) { iterator tmp(*this); operator++(); return tmp; } - bool operator==(const iterator &rhs) const {return p == rhs.p;} - bool operator!=(const iterator &rhs) const {return p != rhs.p;} + iterator &operator++() + { + p++; + return *this; + } + iterator operator++(int) + { + iterator tmp(*this); + operator++(); + return tmp; + } + bool operator==(const iterator &rhs) const { return p == rhs.p; } + bool operator!=(const iterator &rhs) const { return p != rhs.p; } T *operator*() { return *p; } }; @@ -51,6 +61,57 @@ public: iterator end() const { return iterator(reinterpret_cast(vec->v.a) + vec->v.len); } }; +template +class CutterRzList +{ +private: + const RzList *const list; + +public: + class iterator : public std::iterator + { + private: + RzListIter *iter; + + public: + explicit iterator(RzListIter *iter) : iter(iter) {} + iterator(const iterator &o) : iter(o.iter) {} + iterator &operator++() + { + if (!iter) { + return *this; + } + iter = iter->n; + return *this; + } + iterator operator++(int) + { + iterator tmp(*this); + operator++(); + return tmp; + } + bool operator==(const iterator &rhs) const { return iter == rhs.iter; } + bool operator!=(const iterator &rhs) const { return iter != rhs.iter; } + T *operator*() + { + if (!iter) { + return nullptr; + } + return reinterpret_cast(iter->data); + } + }; + + explicit CutterRzList(const RzList *l) : list(l) {} + iterator begin() const + { + if (!list) { + return iterator(nullptr); + } + return iterator(list->head); + } + iterator end() const { return iterator(nullptr); } +}; + // Global information for Cutter #define APPNAME "Cutter" diff --git a/src/core/MainWindow.cpp b/src/core/MainWindow.cpp index 6e796a8c..e599809e 100644 --- a/src/core/MainWindow.cpp +++ b/src/core/MainWindow.cpp @@ -641,7 +641,11 @@ void MainWindow::finalizeOpen() core->updateSeek(); refreshAll(); // Add fortune message - core->message("\n" + core->cmdRaw("fo")); + char *fortune = rz_core_fortune_get_random(core->core()); + if (fortune) { + core->message("\n" + QString(fortune)); + free(fortune); + } // hide all docks before showing window to avoid false positive for refreshDeferrer for (auto dockWidget : dockWidgets) { diff --git a/src/dialogs/InitialOptionsDialog.cpp b/src/dialogs/InitialOptionsDialog.cpp index 437e290f..94e43f89 100644 --- a/src/dialogs/InitialOptionsDialog.cpp +++ b/src/dialogs/InitialOptionsDialog.cpp @@ -40,7 +40,7 @@ InitialOptionsDialog::InitialOptionsDialog(MainWindow *main) updateCPUComboBox(); // os combo box - for (const auto &plugin : core->cmdList("e asm.os=?")) { + for (const auto &plugin : Core()->getConfigOptions("asm.os")) { ui->kernelComboBox->addItem(plugin, plugin); } diff --git a/src/dialogs/preferences/AsmOptionsWidget.cpp b/src/dialogs/preferences/AsmOptionsWidget.cpp index 08abec50..dd5cb7a0 100644 --- a/src/dialogs/preferences/AsmOptionsWidget.cpp +++ b/src/dialogs/preferences/AsmOptionsWidget.cpp @@ -16,7 +16,7 @@ AsmOptionsWidget::AsmOptionsWidget(PreferencesDialog *dialog) ui->setupUi(this); ui->syntaxComboBox->blockSignals(true); - for (const auto &syntax : Core()->cmdList("e asm.syntax=?")) + for (const auto &syntax : Core()->getConfigOptions("asm.syntax")) ui->syntaxComboBox->addItem(syntax, syntax); ui->syntaxComboBox->blockSignals(false); diff --git a/src/menus/DisassemblyContextMenu.cpp b/src/menus/DisassemblyContextMenu.cpp index c0791493..873907d2 100644 --- a/src/menus/DisassemblyContextMenu.cpp +++ b/src/menus/DisassemblyContextMenu.cpp @@ -524,15 +524,19 @@ void DisassemblyContextMenu::aboutToShowSlot() structureOffsetMenu->menuAction()->setVisible(true); structureOffsetMenu->clear(); - // Get the possible offsets using the "ahts" command - // TODO: add ahtj command to Rizin and then use it here - QStringList ret = Core()->cmdList("ahts " + QString::number(memDisp)); - for (const QString &val : ret) { - if (val.isEmpty()) { - continue; + RzCoreLocked core(Core()); + RzList *typeoffs = rz_type_db_get_by_offset(core->analysis->typedb, memDisp); + if (typeoffs) { + for (const auto &ty : CutterRzList(typeoffs)) { + if (RZ_STR_ISEMPTY(ty->path)) { + continue; + } + structureOffsetMenu->addAction("[" + memBaseReg + " + " + ty->path + "]") + ->setData(ty->path); } - structureOffsetMenu->addAction("[" + memBaseReg + " + " + val + "]")->setData(val); + rz_list_free(typeoffs); } + if (structureOffsetMenu->isEmpty()) { // No possible offset was found so hide the menu structureOffsetMenu->menuAction()->setVisible(false); diff --git a/src/widgets/CommentsWidget.cpp b/src/widgets/CommentsWidget.cpp index cf7bea12..065548a3 100644 --- a/src/widgets/CommentsWidget.cpp +++ b/src/widgets/CommentsWidget.cpp @@ -220,8 +220,7 @@ bool CommentsProxyModel::lessThan(const QModelIndex &left, const QModelIndex &ri case CommentsModel::OffsetColumn: return leftComment.offset < rightComment.offset; case CommentsModel::FunctionColumn: - return Core()->flagAt(leftComment.offset) - < Core()->flagAt(rightComment.offset); + return Core()->flagAt(leftComment.offset) < Core()->flagAt(rightComment.offset); case CommentsModel::CommentColumn: return leftComment.name < rightComment.name; default: diff --git a/src/widgets/Dashboard.cpp b/src/widgets/Dashboard.cpp index 0d491009..7c37c26a 100644 --- a/src/widgets/Dashboard.cpp +++ b/src/widgets/Dashboard.cpp @@ -122,12 +122,6 @@ void Dashboard::updateContents() setPlainText(ui->codeSizeLineEdit, QString::number(analinfo["codesz"].toSt64()) + " bytes"); setPlainText(ui->percentageLineEdit, QString::number(analinfo["percent"].toSt64()) + "%"); - QStringList libs = Core()->cmdList("il"); - if (!libs.isEmpty()) { - libs.removeFirst(); - libs.removeLast(); - } - // dunno: why not label->setText(lines.join("\n")? while (ui->verticalLayout_2->count() > 0) { QLayoutItem *item = ui->verticalLayout_2->takeAt(0); @@ -141,12 +135,15 @@ void Dashboard::updateContents() } } - for (const QString &lib : libs) { - QLabel *label = new QLabel(this); - label->setText(lib); - label->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); - label->setTextInteractionFlags(Qt::TextSelectableByMouse); - ui->verticalLayout_2->addWidget(label); + const RzList *libs = rz_bin_object_get_libs(bf->o); + if (libs) { + for (const auto &lib : CutterRzList(libs)) { + auto *label = new QLabel(this); + label->setText(lib); + label->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); + label->setTextInteractionFlags(Qt::TextSelectableByMouse); + ui->verticalLayout_2->addWidget(label); + } } QSpacerItem *spacer = new QSpacerItem(1, 1, QSizePolicy::Fixed, QSizePolicy::Expanding); From cb26142398ebcd14e075161469c4f859608a75ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=A4rkl?= Date: Wed, 22 Jun 2022 20:26:54 +0200 Subject: [PATCH 2/6] Fix many null derefs when opening no file --- src/core/Cutter.cpp | 39 +++++++++++++++++++++++++-------------- src/widgets/Dashboard.cpp | 10 +++++----- 2 files changed, 30 insertions(+), 19 deletions(-) diff --git a/src/core/Cutter.cpp b/src/core/Cutter.cpp index acd1e679..fc9ad1bd 100644 --- a/src/core/Cutter.cpp +++ b/src/core/Cutter.cpp @@ -644,6 +644,10 @@ bool CutterCore::loadFile(QString path, ut64 baddr, ut64 mapaddr, int perms, int bool CutterCore::tryFile(QString path, bool rw) { + if (path.isEmpty()) { + // opening no file is always possible + return true; + } CORE_LOCK(); RzCoreFile *cf; int flags = RZ_PERM_R; @@ -3484,6 +3488,9 @@ QList CutterCore::getAllEntrypoint() { CORE_LOCK(); RzBinFile *bf = rz_bin_cur(core->bin); + if (!bf) { + return {}; + } bool va = core->io->va || core->bin->is_debugger; ut64 baddr = rz_bin_get_baddr(core->bin); ut64 laddr = rz_bin_get_laddr(core->bin); @@ -4321,14 +4328,15 @@ void CutterCore::commitWriteCache() // Temporarily disable cache mode TempConfig tempConfig; tempConfig.set("io.cache", false); - if (!isWriteModeEnabled()) { - rz_core_io_file_reopen(core, core->io->desc->fd, RZ_PERM_RW); - rz_io_cache_commit(core->io, 0, UT64_MAX); - rz_core_block_read(core); - rz_core_io_file_open(core, core->io->desc->fd); - } else { - rz_io_cache_commit(core->io, 0, UT64_MAX); - rz_core_block_read(core); + auto desc = core->io->desc; + bool reopen = !isWriteModeEnabled() && desc; + if (reopen) { + rz_core_io_file_reopen(core, desc->fd, RZ_PERM_RW); + } + rz_io_cache_commit(core->io, 0, UT64_MAX); + rz_core_block_read(core); + if (reopen) { + rz_core_io_file_open(core, desc->fd); } } @@ -4350,13 +4358,16 @@ void CutterCore::setWriteMode(bool enabled) CORE_LOCK(); // Change from read-only to write-mode - if (enabled) { - if (!writeModeState) { - rz_core_io_file_reopen(core, core->io->desc->fd, RZ_PERM_RW); + RzIODesc *desc = core->io->desc; + if (desc) { + if (enabled) { + if (!writeModeState) { + rz_core_io_file_reopen(core, desc->fd, RZ_PERM_RW); + } + } else { + // Change from write-mode to read-only + rz_core_io_file_open(core, desc->fd); } - } else { - // Change from write-mode to read-only - rz_core_io_file_open(core, core->io->desc->fd); } // Disable cache mode because we specifically set write or // read-only modes. diff --git a/src/widgets/Dashboard.cpp b/src/widgets/Dashboard.cpp index 7c37c26a..66265d43 100644 --- a/src/widgets/Dashboard.cpp +++ b/src/widgets/Dashboard.cpp @@ -63,9 +63,9 @@ void Dashboard::updateContents() setPlainText(ui->subsysEdit, binInfo ? binInfo->subsystem : ""); setPlainText(ui->compilerEdit, binInfo ? binInfo->compiler : ""); setPlainText(ui->bitsEdit, binInfo ? QString::number(binInfo->bits) : ""); - setPlainText(ui->baddrEdit, binInfo ? RzAddressString(rz_bin_file_get_baddr(bf)) : ""); - setPlainText(ui->sizeEdit, binInfo ? qhelpers::formatBytecount(bf->size) : ""); - setPlainText(ui->fdEdit, binInfo ? QString::number(bf->fd) : ""); + setPlainText(ui->baddrEdit, bf ? RzAddressString(rz_bin_file_get_baddr(bf)) : ""); + setPlainText(ui->sizeEdit, bf ? qhelpers::formatBytecount(bf->size) : ""); + setPlainText(ui->fdEdit, bf ? QString::number(bf->fd) : ""); // Setting the value of "Endianness" const char *endian = binInfo ? (binInfo->big_endian ? "BE" : "LE") : ""; @@ -78,7 +78,7 @@ void Dashboard::updateContents() int static_value = rz_bin_is_static(core->bin); setPlainText(ui->staticEdit, tr(setBoolText(static_value))); - RzList *hashes = rz_bin_file_compute_hashes(core->bin, bf, UT64_MAX); + RzList *hashes = bf ? rz_bin_file_compute_hashes(core->bin, bf, UT64_MAX) : nullptr; // Delete hashesWidget if it isn't null to avoid duplicate components if (hashesWidget) { @@ -135,7 +135,7 @@ void Dashboard::updateContents() } } - const RzList *libs = rz_bin_object_get_libs(bf->o); + const RzList *libs = bf ? rz_bin_object_get_libs(bf->o) : nullptr; if (libs) { for (const auto &lib : CutterRzList(libs)) { auto *label = new QLabel(this); From 5b777b820203f554338f387bc05c8c42e0763ee0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=A4rkl?= Date: Wed, 22 Jun 2022 20:36:20 +0200 Subject: [PATCH 3/6] Fix sections entropy display --- src/core/Cutter.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/core/Cutter.cpp b/src/core/Cutter.cpp index fc9ad1bd..1c19fc70 100644 --- a/src/core/Cutter.cpp +++ b/src/core/Cutter.cpp @@ -3420,7 +3420,6 @@ QList CutterCore::getAllSections() section.entropy = rz_str_get(entropy); ht_pp_free(digests); } - section.entropy = ""; sections << section; } From e60ba18e43362203ed643a2722992169fbdcef8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=A4rkl?= Date: Wed, 22 Jun 2022 20:36:30 +0200 Subject: [PATCH 4/6] Fix segments listing --- src/core/Cutter.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/core/Cutter.cpp b/src/core/Cutter.cpp index 1c19fc70..53e06fcf 100644 --- a/src/core/Cutter.cpp +++ b/src/core/Cutter.cpp @@ -3477,6 +3477,7 @@ QList CutterCore::getAllSegments() segDesc.size = segment->size; segDesc.vsize = segment->vsize; segDesc.perm = perms_str(segment->perm); + ret << segDesc; } rz_list_free(segments); From f99ffc3dbde8c437f45f04d1a3e57584b712234f Mon Sep 17 00:00:00 2001 From: Giovanni <561184+wargio@users.noreply.github.com> Date: Thu, 23 Jun 2022 01:44:25 +0200 Subject: [PATCH 5/6] Fix #2958 - Add checkbox to fill remaining bytes with nops. (#2974) --- src/core/Cutter.cpp | 8 ++++++-- src/core/Cutter.h | 2 +- src/dialogs/EditInstructionDialog.cpp | 17 +++++++++++++++++ src/dialogs/EditInstructionDialog.h | 6 +++--- src/dialogs/EditInstructionDialog.ui | 24 +++++++++++++++++++++++- src/menus/DisassemblyContextMenu.cpp | 3 ++- 6 files changed, 52 insertions(+), 8 deletions(-) diff --git a/src/core/Cutter.cpp b/src/core/Cutter.cpp index 53e06fcf..b1996b79 100644 --- a/src/core/Cutter.cpp +++ b/src/core/Cutter.cpp @@ -762,10 +762,14 @@ QString CutterCore::getInstructionOpcode(RVA addr) return fromOwnedCharPtr(ret); } -void CutterCore::editInstruction(RVA addr, const QString &inst) +void CutterCore::editInstruction(RVA addr, const QString &inst, bool fillWithNops) { CORE_LOCK(); - rz_core_write_assembly(core, addr, inst.trimmed().toStdString().c_str()); + if (fillWithNops) { + rz_core_write_assembly_fill(core, addr, inst.trimmed().toStdString().c_str()); + } else { + rz_core_write_assembly(core, addr, inst.trimmed().toStdString().c_str()); + } emit instructionChanged(addr); } diff --git a/src/core/Cutter.h b/src/core/Cutter.h index 9552fd82..4263a8a8 100644 --- a/src/core/Cutter.h +++ b/src/core/Cutter.h @@ -259,7 +259,7 @@ public: /* Edition functions */ QString getInstructionBytes(RVA addr); QString getInstructionOpcode(RVA addr); - void editInstruction(RVA addr, const QString &inst); + void editInstruction(RVA addr, const QString &inst, bool fillWithNops = false); void nopInstruction(RVA addr); void jmpReverse(RVA addr); void editBytes(RVA addr, const QString &inst); diff --git a/src/dialogs/EditInstructionDialog.cpp b/src/dialogs/EditInstructionDialog.cpp index d619bb51..041aea91 100644 --- a/src/dialogs/EditInstructionDialog.cpp +++ b/src/dialogs/EditInstructionDialog.cpp @@ -2,12 +2,20 @@ #include "ui_EditInstructionDialog.h" #include "core/Cutter.h" +#include + EditInstructionDialog::EditInstructionDialog(InstructionEditMode editMode, QWidget *parent) : QDialog(parent), ui(new Ui::EditInstructionDialog), editMode(editMode) { ui->setupUi(this); ui->lineEdit->setMinimumWidth(400); ui->instructionLabel->setWordWrap(true); + if (editMode == EDIT_TEXT) { + ui->fillWithNops->setVisible(true); + ui->fillWithNops->setCheckState(Qt::Checked); + } else { + ui->fillWithNops->setVisible(false); + } setWindowFlags(windowFlags() & (~Qt::WindowContextHelpButtonHint)); connect(ui->lineEdit, &QLineEdit::textEdited, this, &EditInstructionDialog::updatePreview); @@ -22,6 +30,15 @@ void EditInstructionDialog::on_buttonBox_rejected() close(); } +bool EditInstructionDialog::needsNops() const +{ + if (editMode != EDIT_TEXT) { + return false; + } + + return ui->fillWithNops->checkState() == Qt::Checked; +} + QString EditInstructionDialog::getInstruction() const { return ui->lineEdit->text(); diff --git a/src/dialogs/EditInstructionDialog.h b/src/dialogs/EditInstructionDialog.h index f343ed7d..1235a734 100644 --- a/src/dialogs/EditInstructionDialog.h +++ b/src/dialogs/EditInstructionDialog.h @@ -20,18 +20,18 @@ public: QString getInstruction() const; void setInstruction(const QString &instruction); + bool needsNops() const; private slots: void on_buttonBox_accepted(); - void on_buttonBox_rejected(); void updatePreview(const QString &input); private: std::unique_ptr ui; - InstructionEditMode - editMode; // true if editing intruction **bytes**; false if editing instruction **text** + // defines if the user is editing bytes or asm + InstructionEditMode editMode; }; #endif // EDITINSTRUCTIONDIALOG_H diff --git a/src/dialogs/EditInstructionDialog.ui b/src/dialogs/EditInstructionDialog.ui index 6ff8661b..98d53131 100644 --- a/src/dialogs/EditInstructionDialog.ui +++ b/src/dialogs/EditInstructionDialog.ui @@ -7,7 +7,7 @@ 0 0 400 - 118 + 151 @@ -37,6 +37,18 @@ + + 5 + + + 5 + + + 5 + + + 5 + @@ -82,6 +94,16 @@ + + + + Fill all remaining bytes with NOP opcodes + + + true + + + diff --git a/src/menus/DisassemblyContextMenu.cpp b/src/menus/DisassemblyContextMenu.cpp index 873907d2..f3f2dcfb 100644 --- a/src/menus/DisassemblyContextMenu.cpp +++ b/src/menus/DisassemblyContextMenu.cpp @@ -708,9 +708,10 @@ void DisassemblyContextMenu::on_actionEditInstruction_triggered() e.setInstruction(oldInstructionOpcode); if (e.exec()) { + bool fillWithNops = e.needsNops(); QString userInstructionOpcode = e.getInstruction(); if (userInstructionOpcode != oldInstructionOpcode) { - Core()->editInstruction(offset, userInstructionOpcode); + Core()->editInstruction(offset, userInstructionOpcode, fillWithNops); } } } From 8f7aebe7c72a893bec4fce47e02d608ac6b3fd65 Mon Sep 17 00:00:00 2001 From: Riccardo Schirone Date: Sat, 25 Jun 2022 09:51:17 +0200 Subject: [PATCH 6/6] CutterCore: select the right RzReg based on debug/emulation status (#2977) --- src/core/Cutter.cpp | 38 ++++++++++++++++++++++++++------------ src/core/Cutter.h | 4 ++++ 2 files changed, 30 insertions(+), 12 deletions(-) diff --git a/src/core/Cutter.cpp b/src/core/Cutter.cpp index b1996b79..abb86e4b 100644 --- a/src/core/Cutter.cpp +++ b/src/core/Cutter.cpp @@ -129,7 +129,10 @@ static QString fromOwnedCharPtr(char *str) static bool reg_sync(RzCore *core, RzRegisterType type, bool write) { - return rz_debug_reg_sync(core->dbg, type, write); + if (rz_core_is_debug(core)) { + return rz_debug_reg_sync(core->dbg, type, write); + } + return true; } RzCoreLocked::RzCoreLocked(CutterCore *core) : core(core) @@ -1514,6 +1517,17 @@ RefDescription CutterCore::formatRefDesc(const QSharedPointer &refItem return desc; } +RzReg *CutterCore::getReg() +{ + CORE_LOCK(); + if (currentlyDebugging && currentlyEmulating) { + return core->analysis->reg; + } else if (currentlyDebugging) { + return core->dbg->reg; + } + return core->analysis->reg; +} + QList CutterCore::getRegisterRefs(int depth) { QList ret; @@ -1522,7 +1536,7 @@ QList CutterCore::getRegisterRefs(int depth) } CORE_LOCK(); - RzList *ritems = rz_core_reg_filter_items_sync(core, core->dbg->reg, reg_sync, nullptr); + RzList *ritems = rz_core_reg_filter_items_sync(core, getReg(), reg_sync, nullptr); if (!ritems) { return ret; } @@ -1530,7 +1544,7 @@ QList CutterCore::getRegisterRefs(int depth) RzRegItem *ri; CutterRzListForeach (ritems, it, RzRegItem, ri) { RegisterRef reg; - reg.value = rz_reg_get_value(core->dbg->reg, ri); + reg.value = rz_reg_get_value(getReg(), ri); reg.ref = getAddrRefs(reg.value, depth); reg.name = ri->name; ret.append(reg); @@ -1547,7 +1561,7 @@ QList CutterCore::getStack(int size, int depth) } CORE_LOCK(); - RVA addr = rz_debug_reg_get(core->dbg, "SP"); + RVA addr = rz_core_reg_getv_by_role_or_name(core, "SP"); if (addr == RVA_INVALID) { return stack; } @@ -1596,7 +1610,7 @@ AddrRefs CutterCore::getAddrRefs(RVA addr, int depth) // Check if the address points to a register RzFlagItem *fi = rz_flag_get_i(core->flags, addr); if (fi) { - RzRegItem *r = rz_reg_get(core->dbg->reg, fi->name, -1); + RzRegItem *r = rz_reg_get(getReg(), fi->name, -1); if (r) { refs.reg = r->name; } @@ -1852,7 +1866,7 @@ QVector CutterCore::getRegisterRefValues() { QVector result; CORE_LOCK(); - RzList *ritems = rz_core_reg_filter_items_sync(core, core->dbg->reg, reg_sync, nullptr); + RzList *ritems = rz_core_reg_filter_items_sync(core, getReg(), reg_sync, nullptr); if (!ritems) { return result; } @@ -1861,8 +1875,8 @@ QVector CutterCore::getRegisterRefValues() CutterRzListForeach (ritems, it, RzRegItem, ri) { RegisterRefValueDescription desc; desc.name = ri->name; - ut64 value = rz_reg_get_value(core->dbg->reg, ri); - desc.value = QString::number(value); + ut64 value = rz_reg_get_value(getReg(), ri); + desc.value = "0x" + QString::number(value, 16); desc.ref = rz_core_analysis_hasrefs(core, value, true); result.push_back(desc); } @@ -1876,14 +1890,14 @@ QString CutterCore::getRegisterName(QString registerRole) return ""; } CORE_LOCK(); - return rz_reg_get_name_by_type(core->dbg->reg, registerRole.toUtf8().constData()); + return rz_reg_get_name_by_type(getReg(), registerRole.toUtf8().constData()); } RVA CutterCore::getProgramCounterValue() { if (currentlyDebugging) { CORE_LOCK(); - return rz_debug_reg_get(core->dbg, "PC"); + return rz_core_reg_getv_by_role_or_name(core, "PC"); } return RVA_INVALID; } @@ -1895,7 +1909,7 @@ void CutterCore::setRegister(QString regName, QString regValue) } CORE_LOCK(); ut64 val = rz_num_math(core->num, regValue.toUtf8().constData()); - rz_core_reg_assign_sync(core, core->dbg->reg, reg_sync, regName.toUtf8().constData(), val); + rz_core_reg_assign_sync(core, getReg(), reg_sync, regName.toUtf8().constData(), val); emit registersChanged(); emit refreshCodeViews(); } @@ -2900,7 +2914,7 @@ void CutterCore::getOpcodes() this->opcodes = cmdList("?O"); this->regs = {}; - const RzList *rs = rz_reg_get_list(core->dbg->reg, RZ_REG_TYPE_ANY); + const RzList *rs = rz_reg_get_list(getReg(), RZ_REG_TYPE_ANY); if (!rs) { return; } diff --git a/src/core/Cutter.h b/src/core/Cutter.h index 4263a8a8..b5be0ff8 100644 --- a/src/core/Cutter.h +++ b/src/core/Cutter.h @@ -662,6 +662,10 @@ public: QList getAllSearch(QString searchFor, QString space, QString in); QList getBreakpoints(); QList getAllProcesses(); + /** + * @brief Get the right RzReg object based on the cutter state (debugging vs emulating) + */ + RzReg *getReg(); /** * @brief returns a list of reg values and their telescoped references * @param depth telescoping depth