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"
This commit is contained in:
billow 2022-01-27 17:06:20 +08:00 committed by Anton Kochkov
parent cabe3ffb3e
commit 35408be46f
7 changed files with 95 additions and 70 deletions

View File

@ -527,7 +527,7 @@ const QColor Configuration::getColor(const QString &name) const
void Configuration::setColorTheme(const QString &theme) void Configuration::setColorTheme(const QString &theme)
{ {
if (theme == "default") { if (theme == "default") {
Core()->cmdRaw("ecd"); rz_cons_pal_init(Core()->core()->cons->context);
s.setValue("theme", "default"); s.setValue("theme", "default");
} else { } else {
rz_core_theme_load(Core()->core(), theme.toUtf8().constData()); rz_core_theme_load(Core()->core(), theme.toUtf8().constData());

View File

@ -183,8 +183,11 @@ static void removeObsoleteOptionsFromCustomThemes()
{ {
const QStringList options = Core()->cmdj("ecj").object().keys() const QStringList options = Core()->cmdj("ecj").object().keys()
<< ColorThemeWorker::cutterSpecificOptions; << ColorThemeWorker::cutterSpecificOptions;
for (auto theme : Core()->cmdList("eco*")) { RzList *themes_list = rz_core_theme_list(Core()->core());
theme = theme.trimmed(); RzListIter *th_iter;
const char *th;
CutterRzListForeach (themes_list, th_iter, const char, th) {
auto theme = QString(th).trimmed();
if (!ThemeWorker().isCustomTheme(theme)) { if (!ThemeWorker().isCustomTheme(theme)) {
continue; continue;
} }
@ -197,6 +200,7 @@ static void removeObsoleteOptionsFromCustomThemes()
} }
ThemeWorker().save(QJsonDocument(updatedTheme), theme); ThemeWorker().save(QJsonDocument(updatedTheme), theme);
} }
rz_list_free(themes_list);
} }
void Cutter::migrateThemes() void Cutter::migrateThemes()

View File

@ -687,19 +687,25 @@ bool CutterCore::mapFile(QString path, RVA mapaddr)
void CutterCore::renameFunction(const RVA offset, const QString &newName) 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); emit functionRenamed(offset, newName);
} }
void CutterCore::delFunction(RVA addr) void CutterCore::delFunction(RVA addr)
{ {
cmdRaw("af- " + RzAddressString(addr)); CORE_LOCK();
rz_core_analysis_undefine(core, addr);
emit functionsChanged(); emit functionsChanged();
} }
void CutterCore::renameFlag(QString old_name, QString new_name) 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(); emit flagsChanged();
} }
@ -717,13 +723,15 @@ void CutterCore::renameFunctionVariable(QString newName, QString oldName, RVA fu
void CutterCore::delFlag(RVA addr) void CutterCore::delFlag(RVA addr)
{ {
cmdRawAt("f-", addr); CORE_LOCK();
rz_flag_unset_off(core->flags, addr);
emit flagsChanged(); emit flagsChanged();
} }
void CutterCore::delFlag(const QString &name) void CutterCore::delFlag(const QString &name)
{ {
cmdRaw("f-" + name); CORE_LOCK();
rz_flag_unset_name(core->flags, name.toStdString().c_str());
emit flagsChanged(); emit flagsChanged();
} }
@ -797,34 +805,34 @@ void CutterCore::setAsString(RVA addr, int size, StringTypeFormats type)
return; return;
} }
QString command; RzStrEnc encoding;
switch (type) { switch (type) {
case StringTypeFormats::None: { case StringTypeFormats::None: {
command = "Cs"; encoding = RZ_STRING_ENC_GUESS;
break; break;
} }
case StringTypeFormats::ASCII_LATIN1: { case StringTypeFormats::ASCII_LATIN1: {
command = "Csa"; encoding = RZ_STRING_ENC_8BIT;
break; break;
} }
case StringTypeFormats::UTF8: { case StringTypeFormats::UTF8: {
command = "Cs8"; encoding = RZ_STRING_ENC_UTF8;
break; break;
} }
default: default:
return; return;
} }
CORE_LOCK();
seekAndShow(addr); seekAndShow(addr);
rz_core_meta_string_add(core, addr, size, encoding, nullptr);
cmdRawAt(QString("%1 %2").arg(command).arg(size), addr);
emit instructionChanged(addr); emit instructionChanged(addr);
} }
void CutterCore::removeString(RVA 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); emit instructionChanged(addr);
} }
@ -833,21 +841,33 @@ QString CutterCore::getString(RVA addr)
return cmdRawAt("ps", addr); return cmdRawAt("ps", addr);
} }
QString CutterCore::getMetaString(RVA addr)
{
return cmdRawAt("Cs.", addr);
}
void CutterCore::setToData(RVA addr, int size, int repeat) void CutterCore::setToData(RVA addr, int size, int repeat)
{ {
if (size <= 0 || repeat <= 0) { if (size <= 0 || repeat <= 0) {
return; 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); emit instructionChanged(addr);
} }
int CutterCore::sizeofDataMeta(RVA addr) int CutterCore::sizeofDataMeta(RVA addr)
{ {
bool ok; ut64 size;
int size = cmdRawAt("Cd.", addr).toInt(&ok); CORE_LOCK();
return (ok ? size : 0); rz_meta_get_at(core->analysis, addr, RZ_META_TYPE_DATA, &size);
return (int)size;
} }
void CutterCore::setComment(RVA addr, const QString &cmt) 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)); createFunctionAt(addr, "");
emit functionsChanged();
return ret;
} }
QString CutterCore::createFunctionAt(RVA addr, QString name) void CutterCore::createFunctionAt(RVA addr, QString name)
{ {
if (!name.isEmpty() && !name.isNull()) {
static const QRegularExpression regExp("[^a-zA-Z0-9_.]"); static const QRegularExpression regExp("[^a-zA-Z0-9_.]");
name.remove(regExp); name.remove(regExp);
QString ret = cmdRawAt(QString("af %1").arg(name), addr); }
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(); emit functionsChanged();
return ret;
} }
QJsonDocument CutterCore::getRegistersInfo() QJsonDocument CutterCore::getRegistersInfo()
@ -3118,45 +3140,37 @@ QList<StringDescription> CutterCore::parseStringsJson(const QJsonDocument &doc)
QList<FlagspaceDescription> CutterCore::getAllFlagspaces() QList<FlagspaceDescription> CutterCore::getAllFlagspaces()
{ {
CORE_LOCK(); CORE_LOCK();
QList<FlagspaceDescription> ret; QList<FlagspaceDescription> flagspaces;
RzSpaceIter it;
QJsonArray flagspacesArray = cmdj("fsj").array(); RzSpace *space;
for (const QJsonValue &value : flagspacesArray) { rz_flag_space_foreach(core->flags, it, space)
QJsonObject flagspaceObject = value.toObject(); {
FlagspaceDescription flagspace; FlagspaceDescription flagspace;
flagspace.name = space->name;
flagspace.name = flagspaceObject[RJsonKey::name].toString(); flagspaces << flagspace;
ret << flagspace;
} }
return ret; return flagspaces;
} }
QList<FlagDescription> CutterCore::getAllFlags(QString flagspace) QList<FlagDescription> CutterCore::getAllFlags(QString flagspace)
{ {
CORE_LOCK(); CORE_LOCK();
QList<FlagDescription> ret; QList<FlagDescription> flags;
std::string name = flagspace.isEmpty() || flagspace.isNull() ? "*" : flagspace.toStdString();
if (!flagspace.isEmpty()) RzSpace *space = rz_flag_space_get(core->flags, name.c_str());
cmdRaw("fs " + flagspace); rz_flag_foreach_space(
else core->flags, space,
cmdRaw("fs *"); [](RzFlagItem *item, void *user) {
QJsonArray flagsArray = cmdj("fj").array();
for (const QJsonValue &value : flagsArray) {
QJsonObject flagObject = value.toObject();
FlagDescription flag; FlagDescription flag;
flag.offset = item->offset;
flag.offset = flagObject[RJsonKey::offset].toVariant().toULongLong(); flag.size = item->size;
flag.size = flagObject[RJsonKey::size].toVariant().toULongLong(); flag.name = item->name;
flag.name = flagObject[RJsonKey::name].toString(); flag.realname = item->name;
flag.realname = flagObject[RJsonKey::realname].toString(); reinterpret_cast<QList<FlagDescription> *>(user)->append(flag);
return true;
ret << flag; },
} &flags);
return ret; return flags;
} }
QList<SectionDescription> CutterCore::getAllSections() QList<SectionDescription> CutterCore::getAllSections()
@ -3856,7 +3870,8 @@ QList<XrefDescription> CutterCore::getXRefs(RVA addr, bool to, bool whole_functi
void CutterCore::addFlag(RVA offset, QString name, RVA size) void CutterCore::addFlag(RVA offset, QString name, RVA size)
{ {
name = sanitizeStringForCommand(name); 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(); emit flagsChanged();
} }

View File

@ -198,8 +198,8 @@ public:
RVA getLastFunctionInstruction(RVA addr); RVA getLastFunctionInstruction(RVA addr);
QString cmdFunctionAt(QString addr); QString cmdFunctionAt(QString addr);
QString cmdFunctionAt(RVA addr); QString cmdFunctionAt(RVA addr);
QString createFunctionAt(RVA addr); void createFunctionAt(RVA addr);
QString createFunctionAt(RVA addr, QString name); void createFunctionAt(RVA addr, QString name);
QStringList getDisassemblyPreview(RVA address, int num_of_lines); QStringList getDisassemblyPreview(RVA address, int num_of_lines);
/* Flags */ /* Flags */
@ -242,6 +242,13 @@ public:
* \param addr The address of the array where the string will be applied * \param addr The address of the array where the string will be applied
*/ */
void removeString(RVA addr); 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 * @brief Gets string at address
* That function calls the 'ps' command * That function calls the 'ps' command

View File

@ -73,7 +73,7 @@ void EditVariablesDialog::applyFields()
if (!v_type || error_msg) { if (!v_type || error_msg) {
return; 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 // TODO Remove all those replace once rizin command parser is fixed
QString newName = ui->nameEdit->text() QString newName = ui->nameEdit->text()

View File

@ -533,7 +533,7 @@ void DisassemblyContextMenu::aboutToShowSlot()
actionAnalyzeFunction.setVisible(true); actionAnalyzeFunction.setVisible(true);
// Show the option to remove a defined string only if a string is defined in this address // 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()); actionSetAsStringRemove.setVisible(!stringDefinition.isEmpty());
QString comment = Core()->getCommentAt(offset); QString comment = Core()->getCommentAt(offset);

View File

@ -599,10 +599,9 @@ void FunctionsWidget::onActionFunctionsRenameTriggered()
void FunctionsWidget::onActionFunctionsUndefineTriggered() void FunctionsWidget::onActionFunctionsUndefineTriggered()
{ {
const auto selection = ui->treeView->selectionModel()->selection().indexes(); const auto selection = ui->treeView->selectionModel()->selection().indexes();
std::vector<RVA> offsets; QSet<RVA> offsets;
offsets.reserve(selection.size());
for (const auto &index : selection) { for (const auto &index : selection) {
offsets.push_back(functionProxyModel->address(index)); offsets.insert(functionProxyModel->address(index));
} }
for (RVA offset : offsets) { for (RVA offset : offsets) {
Core()->delFunction(offset); Core()->delFunction(offset);