From 35408be46f65f863607385b12efa7daf0699d931 Mon Sep 17 00:00:00 2001 From: billow Date: Thu, 27 Jan 2022 17:06:20 +0800 Subject: [PATCH] Convert rizin commands to C apis (#2861) * "fr" renameFlag * "f-" delFlag * "f" addFlag * "fsj" getAllFlagspaces * "fj" getAllFlags * "afn" renameFunction * "af-" delFunction * "af" createFunctionAt * "eco" * "ecd" --- src/common/Configuration.cpp | 2 +- src/common/SettingsUpgrade.cpp | 8 +- src/core/Cutter.cpp | 135 +++++++++++++++------------ src/core/Cutter.h | 11 ++- src/dialogs/EditVariablesDialog.cpp | 2 +- src/menus/DisassemblyContextMenu.cpp | 2 +- src/widgets/FunctionsWidget.cpp | 5 +- 7 files changed, 95 insertions(+), 70 deletions(-) diff --git a/src/common/Configuration.cpp b/src/common/Configuration.cpp index 5bb7a7ef..87a97b92 100644 --- a/src/common/Configuration.cpp +++ b/src/common/Configuration.cpp @@ -527,7 +527,7 @@ const QColor Configuration::getColor(const QString &name) const void Configuration::setColorTheme(const QString &theme) { if (theme == "default") { - Core()->cmdRaw("ecd"); + rz_cons_pal_init(Core()->core()->cons->context); s.setValue("theme", "default"); } else { rz_core_theme_load(Core()->core(), theme.toUtf8().constData()); diff --git a/src/common/SettingsUpgrade.cpp b/src/common/SettingsUpgrade.cpp index 33b5bff9..9ff48999 100644 --- a/src/common/SettingsUpgrade.cpp +++ b/src/common/SettingsUpgrade.cpp @@ -183,8 +183,11 @@ static void removeObsoleteOptionsFromCustomThemes() { const QStringList options = Core()->cmdj("ecj").object().keys() << ColorThemeWorker::cutterSpecificOptions; - for (auto theme : Core()->cmdList("eco*")) { - theme = theme.trimmed(); + RzList *themes_list = rz_core_theme_list(Core()->core()); + RzListIter *th_iter; + const char *th; + CutterRzListForeach (themes_list, th_iter, const char, th) { + auto theme = QString(th).trimmed(); if (!ThemeWorker().isCustomTheme(theme)) { continue; } @@ -197,6 +200,7 @@ static void removeObsoleteOptionsFromCustomThemes() } ThemeWorker().save(QJsonDocument(updatedTheme), theme); } + rz_list_free(themes_list); } void Cutter::migrateThemes() diff --git a/src/core/Cutter.cpp b/src/core/Cutter.cpp index 261ca99a..21a07c57 100644 --- a/src/core/Cutter.cpp +++ b/src/core/Cutter.cpp @@ -687,19 +687,25 @@ bool CutterCore::mapFile(QString path, RVA mapaddr) void CutterCore::renameFunction(const RVA offset, const QString &newName) { - cmdRaw("afn " + newName + " " + RzAddressString(offset)); + CORE_LOCK(); + rz_core_analysis_function_rename(core, offset, newName.toStdString().c_str()); emit functionRenamed(offset, newName); } void CutterCore::delFunction(RVA addr) { - cmdRaw("af- " + RzAddressString(addr)); + CORE_LOCK(); + rz_core_analysis_undefine(core, addr); emit functionsChanged(); } void CutterCore::renameFlag(QString old_name, QString new_name) { - cmdRaw("fr " + old_name + " " + new_name); + CORE_LOCK(); + RzFlagItem *flag = rz_flag_get(core->flags, old_name.toStdString().c_str()); + if (!flag) + return; + rz_flag_rename(core->flags, flag, new_name.toStdString().c_str()); emit flagsChanged(); } @@ -717,13 +723,15 @@ void CutterCore::renameFunctionVariable(QString newName, QString oldName, RVA fu void CutterCore::delFlag(RVA addr) { - cmdRawAt("f-", addr); + CORE_LOCK(); + rz_flag_unset_off(core->flags, addr); emit flagsChanged(); } void CutterCore::delFlag(const QString &name) { - cmdRaw("f-" + name); + CORE_LOCK(); + rz_flag_unset_name(core->flags, name.toStdString().c_str()); emit flagsChanged(); } @@ -797,34 +805,34 @@ void CutterCore::setAsString(RVA addr, int size, StringTypeFormats type) return; } - QString command; - + RzStrEnc encoding; switch (type) { case StringTypeFormats::None: { - command = "Cs"; + encoding = RZ_STRING_ENC_GUESS; break; } case StringTypeFormats::ASCII_LATIN1: { - command = "Csa"; + encoding = RZ_STRING_ENC_8BIT; break; } case StringTypeFormats::UTF8: { - command = "Cs8"; + encoding = RZ_STRING_ENC_UTF8; break; } default: return; } + CORE_LOCK(); seekAndShow(addr); - - cmdRawAt(QString("%1 %2").arg(command).arg(size), addr); + rz_core_meta_string_add(core, addr, size, encoding, nullptr); emit instructionChanged(addr); } void CutterCore::removeString(RVA addr) { - cmdRawAt("Cs-", addr); + CORE_LOCK(); + rz_meta_del(core->analysis, RZ_META_TYPE_STRING, addr, 1); emit instructionChanged(addr); } @@ -833,21 +841,33 @@ QString CutterCore::getString(RVA addr) return cmdRawAt("ps", addr); } +QString CutterCore::getMetaString(RVA addr) +{ + return cmdRawAt("Cs.", addr); +} + void CutterCore::setToData(RVA addr, int size, int repeat) { if (size <= 0 || repeat <= 0) { return; } - cmdRawAt("Cd-", addr); - cmdRawAt(QString("Cd %1 %2").arg(size).arg(repeat), addr); + + CORE_LOCK(); + rz_meta_del(core->analysis, RZ_META_TYPE_DATA, addr, 1); + RVA address = addr; + auto name = QString(size).toStdString(); + for (int i = 0; i < repeat; ++i, address += size) { + rz_meta_set(core->analysis, RZ_META_TYPE_DATA, address, size, name.c_str()); + } emit instructionChanged(addr); } int CutterCore::sizeofDataMeta(RVA addr) { - bool ok; - int size = cmdRawAt("Cd.", addr).toInt(&ok); - return (ok ? size : 0); + ut64 size; + CORE_LOCK(); + rz_meta_get_at(core->analysis, addr, RZ_META_TYPE_DATA, &size); + return (int)size; } void CutterCore::setComment(RVA addr, const QString &cmt) @@ -1302,20 +1322,22 @@ void CutterCore::cmdEsil(const char *command) } } -QString CutterCore::createFunctionAt(RVA addr) +void CutterCore::createFunctionAt(RVA addr) { - QString ret = cmdRaw(QString("af %1").arg(addr)); - emit functionsChanged(); - return ret; + createFunctionAt(addr, ""); } -QString CutterCore::createFunctionAt(RVA addr, QString name) +void CutterCore::createFunctionAt(RVA addr, QString name) { - static const QRegularExpression regExp("[^a-zA-Z0-9_.]"); - name.remove(regExp); - QString ret = cmdRawAt(QString("af %1").arg(name), addr); + if (!name.isEmpty() && !name.isNull()) { + static const QRegularExpression regExp("[^a-zA-Z0-9_.]"); + name.remove(regExp); + } + + CORE_LOCK(); + bool analyze_recursively = rz_config_get_i(core->config, "analysis.calls"); + rz_core_analysis_function_add(core, name.toStdString().c_str(), addr, analyze_recursively); emit functionsChanged(); - return ret; } QJsonDocument CutterCore::getRegistersInfo() @@ -3118,45 +3140,37 @@ QList CutterCore::parseStringsJson(const QJsonDocument &doc) QList CutterCore::getAllFlagspaces() { CORE_LOCK(); - QList ret; - - QJsonArray flagspacesArray = cmdj("fsj").array(); - for (const QJsonValue &value : flagspacesArray) { - QJsonObject flagspaceObject = value.toObject(); - + QList flagspaces; + RzSpaceIter it; + RzSpace *space; + rz_flag_space_foreach(core->flags, it, space) + { FlagspaceDescription flagspace; - - flagspace.name = flagspaceObject[RJsonKey::name].toString(); - - ret << flagspace; + flagspace.name = space->name; + flagspaces << flagspace; } - return ret; + return flagspaces; } QList CutterCore::getAllFlags(QString flagspace) { CORE_LOCK(); - QList ret; - - if (!flagspace.isEmpty()) - cmdRaw("fs " + flagspace); - else - cmdRaw("fs *"); - - QJsonArray flagsArray = cmdj("fj").array(); - for (const QJsonValue &value : flagsArray) { - QJsonObject flagObject = value.toObject(); - - FlagDescription flag; - - flag.offset = flagObject[RJsonKey::offset].toVariant().toULongLong(); - flag.size = flagObject[RJsonKey::size].toVariant().toULongLong(); - flag.name = flagObject[RJsonKey::name].toString(); - flag.realname = flagObject[RJsonKey::realname].toString(); - - ret << flag; - } - return ret; + QList flags; + std::string name = flagspace.isEmpty() || flagspace.isNull() ? "*" : flagspace.toStdString(); + RzSpace *space = rz_flag_space_get(core->flags, name.c_str()); + rz_flag_foreach_space( + core->flags, space, + [](RzFlagItem *item, void *user) { + FlagDescription flag; + flag.offset = item->offset; + flag.size = item->size; + flag.name = item->name; + flag.realname = item->name; + reinterpret_cast *>(user)->append(flag); + return true; + }, + &flags); + return flags; } QList CutterCore::getAllSections() @@ -3856,7 +3870,8 @@ QList CutterCore::getXRefs(RVA addr, bool to, bool whole_functi void CutterCore::addFlag(RVA offset, QString name, RVA size) { name = sanitizeStringForCommand(name); - cmdRawAt(QString("f %1 %2").arg(name).arg(size), offset); + CORE_LOCK(); + rz_flag_set(core->flags, name.toStdString().c_str(), offset, size); emit flagsChanged(); } diff --git a/src/core/Cutter.h b/src/core/Cutter.h index 8671b73a..d8b7a0a1 100644 --- a/src/core/Cutter.h +++ b/src/core/Cutter.h @@ -198,8 +198,8 @@ public: RVA getLastFunctionInstruction(RVA addr); QString cmdFunctionAt(QString addr); QString cmdFunctionAt(RVA addr); - QString createFunctionAt(RVA addr); - QString createFunctionAt(RVA addr, QString name); + void createFunctionAt(RVA addr); + void createFunctionAt(RVA addr, QString name); QStringList getDisassemblyPreview(RVA address, int num_of_lines); /* Flags */ @@ -242,6 +242,13 @@ public: * \param addr The address of the array where the string will be applied */ void removeString(RVA addr); + /** + * @brief Gets string at address + * That function correspond the 'Cs.' command + * \param addr The address of the string + * @return string at requested address + */ + QString getMetaString(RVA addr); /** * @brief Gets string at address * That function calls the 'ps' command diff --git a/src/dialogs/EditVariablesDialog.cpp b/src/dialogs/EditVariablesDialog.cpp index 5525048f..6954814a 100644 --- a/src/dialogs/EditVariablesDialog.cpp +++ b/src/dialogs/EditVariablesDialog.cpp @@ -73,7 +73,7 @@ void EditVariablesDialog::applyFields() if (!v_type || error_msg) { return; } - rz_analysis_var_set_type(v, v_type); + rz_analysis_var_set_type(v, v_type, true); // TODO Remove all those replace once rizin command parser is fixed QString newName = ui->nameEdit->text() diff --git a/src/menus/DisassemblyContextMenu.cpp b/src/menus/DisassemblyContextMenu.cpp index 420d15bc..2c7b8ba8 100644 --- a/src/menus/DisassemblyContextMenu.cpp +++ b/src/menus/DisassemblyContextMenu.cpp @@ -533,7 +533,7 @@ void DisassemblyContextMenu::aboutToShowSlot() actionAnalyzeFunction.setVisible(true); // Show the option to remove a defined string only if a string is defined in this address - QString stringDefinition = Core()->cmdRawAt("Cs.", offset); + QString stringDefinition = Core()->getMetaString(offset); actionSetAsStringRemove.setVisible(!stringDefinition.isEmpty()); QString comment = Core()->getCommentAt(offset); diff --git a/src/widgets/FunctionsWidget.cpp b/src/widgets/FunctionsWidget.cpp index 760a7487..c494e5a0 100644 --- a/src/widgets/FunctionsWidget.cpp +++ b/src/widgets/FunctionsWidget.cpp @@ -599,10 +599,9 @@ void FunctionsWidget::onActionFunctionsRenameTriggered() void FunctionsWidget::onActionFunctionsUndefineTriggered() { const auto selection = ui->treeView->selectionModel()->selection().indexes(); - std::vector offsets; - offsets.reserve(selection.size()); + QSet offsets; for (const auto &index : selection) { - offsets.push_back(functionProxyModel->address(index)); + offsets.insert(functionProxyModel->address(index)); } for (RVA offset : offsets) { Core()->delFunction(offset);