Convert Rizin commands to the API calls

This commit is contained in:
billow 2022-05-22 16:51:54 +08:00 committed by GitHub
parent e43a31cc85
commit c9e8686ecb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 159 additions and 183 deletions

2
rizin

@ -1 +1 @@
Subproject commit cdc80202dd7eaf5bacf0e36a64f964c822e67dd4
Subproject commit f2a1e5e09087550e70122c3a2bedd4e2a02f77f1

View File

@ -37,9 +37,7 @@ ColorThemeWorker::ColorThemeWorker(QObject *parent) : QObject(parent)
QDir().mkpath(customRzThemesLocationPath);
}
QDir currDir {
QStringLiteral("%1%2%3").arg(rz_path_prefix(nullptr)).arg(RZ_SYS_DIR).arg(RZ_THEMES)
};
QDir currDir { QStringLiteral("%1%2%3").arg(rz_path_prefix(nullptr), RZ_SYS_DIR, RZ_THEMES) };
if (currDir.exists()) {
standardRzThemesLocationPath = currDir.absolutePath();
} else {
@ -78,27 +76,15 @@ QString ColorThemeWorker::copy(const QString &srcThemeName, const QString &copyT
return save(getTheme(srcThemeName), copyThemeName);
}
QString ColorThemeWorker::save(const QJsonDocument &theme, const QString &themeName) const
QString ColorThemeWorker::save(const Theme &theme, const QString &themeName) const
{
QFile fOut(QDir(customRzThemesLocationPath).filePath(themeName));
if (!fOut.open(QFile::WriteOnly | QFile::Truncate)) {
return tr("The file <b>%1</b> cannot be opened.").arg(QFileInfo(fOut).filePath());
}
QJsonObject obj = theme.object();
for (auto it = obj.constBegin(); it != obj.constEnd(); it++) {
QJsonArray arr = it.value().toArray();
QColor color;
if (arr.isEmpty()) {
color = it.value().toVariant().value<QColor>();
} else if (arr.size() == 4) {
color = QColor(arr[0].toInt(), arr[1].toInt(), arr[2].toInt(), arr[3].toInt());
} else if (arr.size() == 3) {
color = QColor(arr[0].toInt(), arr[1].toInt(), arr[2].toInt());
} else {
continue;
}
for (auto it = theme.constBegin(); it != theme.constEnd(); it++) {
const QColor &color = it.value();
if (cutterSpecificOptions.contains(it.key())) {
fOut.write(QString("#~%1 rgb:%2\n")
.arg(it.key(), color.name(QColor::HexArgb).remove('#'))
@ -125,37 +111,18 @@ bool ColorThemeWorker::isThemeExist(const QString &name) const
return themes.contains(name);
}
QJsonDocument ColorThemeWorker::getTheme(const QString &themeName) const
ColorThemeWorker::Theme ColorThemeWorker::getTheme(const QString &themeName) const
{
int r, g, b, a;
CutterJson rzTheme;
QVariantMap theme;
Theme theme;
QString curr = Config()->getColorTheme();
if (themeName != curr) {
RzCoreLocked core(Core());
rz_core_theme_load(core, themeName.toUtf8().constData());
rzTheme = Core()->cmdj("ecj");
theme = Core()->getTheme();
rz_core_theme_load(core, curr.toUtf8().constData());
} else {
rzTheme = Core()->cmdj("ecj");
}
for (CutterJson value : rzTheme) {
QJsonArray arr;
int count = 0;
for (CutterJson element : value) {
arr.append(element.toSt64());
count++;
if (count >= 3) {
break;
}
}
while (count < 3) {
arr.append(0);
}
arr.append(255);
theme[value.key()] = arr;
theme = Core()->getTheme();
}
ColorFlags colorFlags = ColorFlags::DarkFlag;
@ -164,14 +131,13 @@ QJsonDocument ColorThemeWorker::getTheme(const QString &themeName) const
}
for (auto &it : cutterSpecificOptions) {
Configuration::cutterOptionColors[it][colorFlags].getRgb(&r, &g, &b, &a);
theme.insert(it, QJsonArray { r, g, b, a });
theme.insert(it, QColor(Configuration::cutterOptionColors[it][colorFlags]));
}
if (isCustomTheme(themeName)) {
QFile src(QDir(customRzThemesLocationPath).filePath(themeName));
if (!src.open(QFile::ReadOnly)) {
return QJsonDocument();
return {};
}
QStringList sl;
for (auto &line : QString(src.readAll()).split('\n', CUTTER_QT_SKIP_EMPTY_PARTS)) {
@ -181,8 +147,7 @@ QJsonDocument ColorThemeWorker::getTheme(const QString &themeName) const
if (sl.size() != 3 || sl[0][0] == '#') {
continue;
}
QColor(sl[2]).getRgb(&r, &g, &b, &a);
theme.insert(sl[1], QJsonArray({ r, g, b, a }));
theme.insert(sl[1], QColor(sl[2]));
}
}
@ -190,21 +155,7 @@ QJsonDocument ColorThemeWorker::getTheme(const QString &themeName) const
theme.remove(key);
}
// manualy converting instead of using QJsonObject::fromVariantMap because
// Qt < 5.6 QJsonValue.fromVariant doesn't expect QVariant to already contain
// QJson values like QJsonArray.
// https://github.com/qt/qtbase/commit/26237f0a2d8db80024b601f676bbce54d483e672
QJsonObject obj;
for (auto it = theme.begin(); it != theme.end(); it++) {
auto &value = it.value();
if (value.canConvert<QJsonArray>()) {
obj[it.key()] = it.value().value<QJsonArray>();
} else {
obj[it.key()] = QJsonValue::fromVariant(value);
}
}
return QJsonDocument(obj);
return theme;
}
QString ColorThemeWorker::deleteTheme(const QString &themeName) const
@ -291,11 +242,10 @@ bool ColorThemeWorker::isFileTheme(const QString &filePath, bool *ok) const
const QString colors = "black|red|white|green|magenta|yellow|cyan|blue|gray|none";
QString options =
(Core()->cmdj("ecj").keys() << cutterSpecificOptions).join('|').replace(".", "\\.");
(Core()->getThemeKeys() << cutterSpecificOptions).join('|').replace(".", "\\.");
QString pattern = QString("((ec\\s+(%1)\\s+(((rgb:|#)[0-9a-fA-F]{3,8})|(%2))))\\s*")
.arg(options)
.arg(colors);
QString pattern =
QString("((ec\\s+(%1)\\s+(((rgb:|#)[0-9a-fA-F]{3,8})|(%2))))\\s*").arg(options, colors);
// The below construct mimics the behaviour of QRegexP::exactMatch(), which was here before
QRegularExpression regexp("\\A(?:" + pattern + ")\\z");
@ -326,7 +276,7 @@ QStringList ColorThemeWorker::customThemes() const
const QStringList &ColorThemeWorker::getRizinSpecificOptions()
{
if (rizinSpecificOptions.isEmpty()) {
rizinSpecificOptions = Core()->cmdj("ecj").keys();
rizinSpecificOptions << Core()->getThemeKeys();
}
return rizinSpecificOptions;
}

View File

@ -18,6 +18,8 @@ class ColorThemeWorker : public QObject
{
Q_OBJECT
public:
typedef QHash<QString, QColor> Theme;
/**
* @brief cutterSpecificOptions is list of all available Cutter-only color options.
*/
@ -54,7 +56,7 @@ public:
* Name of theme to save.
* @return "" on success or error message.
*/
QString save(const QJsonDocument &theme, const QString &themeName) const;
QString save(const Theme &theme, const QString &themeName) const;
/**
* @brief Returns whether or not @a themeName theme is custom (created by user or imported) or
@ -71,12 +73,11 @@ public:
bool isThemeExist(const QString &name) const;
/**
* @brief Returns theme as Json where key is option name and value is array of 3 Ints (Red,
* Green, Blue).
* @brief Returns theme as QHash where key is option name and value is QColor.
* @param themeName
* Theme to get.
*/
QJsonDocument getTheme(const QString &themeName) const;
Theme getTheme(const QString &themeName) const;
/**
* @brief Deletes theme named @a themeName.

View File

@ -534,13 +534,9 @@ void Configuration::setColorTheme(const QString &theme)
s.setValue("theme", theme);
}
QJsonObject colorTheme = ThemeWorker().getTheme(theme).object();
ColorThemeWorker::Theme colorTheme = ThemeWorker().getTheme(theme);
for (auto it = colorTheme.constBegin(); it != colorTheme.constEnd(); it++) {
QJsonArray rgb = it.value().toArray();
if (rgb.size() != 4) {
continue;
}
setColor(it.key(), QColor(rgb[0].toInt(), rgb[1].toInt(), rgb[2].toInt(), rgb[3].toInt()));
setColor(it.key(), it.value());
}
emit colorsUpdated();

View File

@ -181,26 +181,21 @@ void Cutter::initializeSettings()
static void removeObsoleteOptionsFromCustomThemes()
{
const QStringList options = Core()->cmdj("ecj").keys()
<< ColorThemeWorker::cutterSpecificOptions;
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)) {
const QStringList options = Core()->getThemeKeys() << ColorThemeWorker::cutterSpecificOptions;
QStringList themes = Core()->getColorThemes();
for (const auto &themeName : themes) {
if (!ThemeWorker().isCustomTheme(themeName)) {
continue;
}
QJsonObject updatedTheme;
auto sch = ThemeWorker().getTheme(theme).object();
for (const auto &key : sch.keys()) {
if (options.contains(key)) {
updatedTheme.insert(key, sch[key]);
ColorThemeWorker::Theme sch = ThemeWorker().getTheme(themeName);
ColorThemeWorker::Theme updatedTheme;
for (auto it = sch.constBegin(); it != sch.constEnd(); ++it) {
if (options.contains(it.key())) {
updatedTheme.insert(it.key(), it.value());
}
}
ThemeWorker().save(QJsonDocument(updatedTheme), theme);
ThemeWorker().save(updatedTheme, themeName);
}
rz_list_free(themes_list);
}
void Cutter::migrateThemes()

View File

@ -2157,26 +2157,9 @@ void CutterCore::stopDebug()
if (currentlyEmulating) {
cmdEsil("aeim-; aei-; wcr; .ar-; aets-");
currentlyEmulating = false;
} else if (currentlyAttachedToPID != -1) {
// Use cmd because cmdRaw would not work with command concatenation
cmd(QString("dp- %1; o %2; .ar-")
.arg(QString::number(currentlyAttachedToPID), currentlyOpenFile));
currentlyAttachedToPID = -1;
} else {
QString ptraceFiles = "";
// close ptrace file descriptors left open
RzCoreLocked core(Core());
RzList *descs = rz_id_storage_list(core->io->files);
RzListIter *it;
RzIODesc *desc;
CutterRzListForeach (descs, it, RzIODesc, desc) {
QString URI = QString(desc->uri);
if (URI.contains("ptrace")) {
ptraceFiles += "o-" + QString::number(desc->fd) + ";";
}
}
// Use cmd because cmdRaw would not work with command concatenation
cmd("doc" + ptraceFiles);
rz_core_debug_process_close(core());
currentlyAttachedToPID = -1;
}
syncAndSeekProgramCounter();
@ -2331,7 +2314,16 @@ void CutterCore::continueUntilSyscall()
return;
}
} else {
if (!asyncCmd("dcs", debugTask)) {
if (!asyncTask(
[](RzCore *core) {
rz_cons_break_push(reinterpret_cast<RzConsBreak>(rz_debug_stop), core->dbg);
rz_reg_arena_swap(core->dbg->reg, true);
rz_debug_continue_syscalls(core->dbg, NULL, 0);
rz_cons_break_pop();
rz_core_dbg_follow_seek_register(core);
return nullptr;
},
debugTask)) {
return;
}
}
@ -2390,7 +2382,15 @@ void CutterCore::stepOverDebug()
return;
}
} else {
if (!asyncCmd("dso", debugTask)) {
bool ret;
asyncTask(
[&](RzCore *core) {
ret = rz_core_debug_step_over(core, 1);
rz_core_dbg_follow_seek_register(core);
return nullptr;
},
debugTask);
if (!ret) {
return;
}
}
@ -2413,7 +2413,15 @@ void CutterCore::stepOutDebug()
}
emit debugTaskStateChanged();
if (!asyncCmd("dsf", debugTask)) {
bool ret;
asyncTask(
[&](RzCore *core) {
ret = rz_core_debug_step_until_frame(core);
rz_core_dbg_follow_seek_register(core);
return nullptr;
},
debugTask);
if (!ret) {
return;
}
@ -2438,7 +2446,15 @@ void CutterCore::stepBackDebug()
return;
}
} else {
if (!asyncCmd("dsb", debugTask)) {
bool ret;
asyncTask(
[&](RzCore *core) {
ret = rz_core_debug_step_back(core, 1);
rz_core_dbg_follow_seek_register(core);
return nullptr;
},
debugTask);
if (!ret) {
return;
}
}
@ -2457,11 +2473,11 @@ void CutterCore::stepBackDebug()
QStringList CutterCore::getDebugPlugins()
{
QStringList plugins;
for (CutterJson pluginObject : cmdj("dLj")) {
QString plugin = pluginObject[RJsonKey::name].toString();
plugins << plugin;
RzListIter *iter;
RzDebugPlugin *plugin;
CORE_LOCK();
CutterRzListForeach (core->dbg->plugins, iter, RzDebugPlugin, plugin) {
plugins << plugin->name;
}
return plugins;
}
@ -2661,11 +2677,9 @@ void CutterCore::disableBreakpoint(RVA addr)
void CutterCore::setBreakpointTrace(int index, bool enabled)
{
if (enabled) {
cmdRaw(QString("dbite %1").arg(index));
} else {
cmdRaw(QString("dbitd %1").arg(index));
}
CORE_LOCK();
RzBreakpointItem *bpi = rz_bp_get_index(core->dbg->bp, index);
bpi->trace = enabled;
}
static BreakpointDescription breakpointDescriptionFromRizin(int index, rz_bp_item_t *bpi)
@ -2746,11 +2760,6 @@ bool CutterCore::isBreakpoint(const QList<RVA> &breakpoints, RVA addr)
return breakpoints.contains(addr);
}
CutterJson CutterCore::getBacktrace()
{
return cmdj("dbtj");
}
QList<ProcessDescription> CutterCore::getProcessThreads(int pid = -1)
{
CORE_LOCK();
@ -4120,15 +4129,56 @@ QString CutterCore::getVersionInformation()
return versionInfo;
}
QList<QString> CutterCore::getColorThemes()
QStringList CutterCore::getColorThemes()
{
QList<QString> r;
for (CutterJson s : cmdj("ecoj")) {
r << s.toString();
QStringList r;
CORE_LOCK();
RzList *themes_list = rz_core_theme_list(core);
RzListIter *it;
const char *th;
CutterRzListForeach (themes_list, it, const char, th) {
r << fromOwnedCharPtr(rz_str_trim_dup(th));
}
rz_list_free(themes_list);
return r;
}
QHash<QString, QColor> CutterCore::getTheme()
{
QHash<QString, QColor> theme;
for (int i = 0;; ++i) {
const char *k = rz_cons_pal_get_name(i);
if (!k) {
break;
}
RzColor color = rz_cons_pal_get_i(i);
theme.insert(k, QColor(color.r, color.g, color.b));
}
return theme;
}
QStringList CutterCore::getThemeKeys()
{
QStringList stringList;
for (int i = 0;; ++i) {
const char *k = rz_cons_pal_get_name(i);
if (!k) {
break;
}
stringList << k;
}
return stringList;
}
bool CutterCore::setColor(const QString &key, const QString &color)
{
if (!rz_cons_pal_set(key.toUtf8().constData(), color.toUtf8().constData())) {
return false;
}
rz_cons_pal_update_event();
return true;
}
QString CutterCore::ansiEscapeToHtml(const QString &text)
{
int len;

View File

@ -393,7 +393,10 @@ public:
QString getConfig(const char *k);
QString getConfig(const QString &k) { return getConfig(k.toUtf8().constData()); }
QString getConfigDescription(const char *k);
QList<QString> getColorThemes();
QStringList getColorThemes();
QHash<QString, QColor> getTheme();
QStringList getThemeKeys();
bool setColor(const QString &key, const QString &color);
/* Assembly\Hexdump related methods */
QByteArray assemble(const QString &code);
@ -449,7 +452,6 @@ public:
* @return List of ProcessDescription
*/
QList<ProcessDescription> getProcessThreads(int pid);
CutterJson getBacktrace();
/**
* @brief Get a list of heap chunks
* Uses RZ_API rz_heap_chunks_list to get vector of chunks

View File

@ -72,7 +72,7 @@ ColorThemeEditDialog::~ColorThemeEditDialog()
void ColorThemeEditDialog::accept()
{
colorTheme = Config()->getColorTheme();
QJsonDocument sch = ui->colorThemeListView->colorSettingsModel()->getTheme();
ColorThemeWorker::Theme sch = ui->colorThemeListView->colorSettingsModel()->getTheme();
if (ThemeWorker().isCustomTheme(colorTheme)) {
QString err = ThemeWorker().save(sch, colorTheme);
if (!err.isEmpty()) {
@ -133,7 +133,7 @@ void ColorThemeEditDialog::colorOptionChanged(const QColor &newColor)
Config()->setColor(currOption.optionName, currOption.color);
if (!ColorThemeWorker::cutterSpecificOptions.contains(currOption.optionName)) {
Core()->cmdRaw(QString("ec %1 %2").arg(currOption.optionName).arg(currOption.color.name()));
Core()->setColor(currOption.optionName, currOption.color.name());
}
previewDisasmWidget->colorsUpdatedSlot();
}

View File

@ -44,27 +44,25 @@ void BacktraceWidget::updateContents()
void BacktraceWidget::setBacktraceGrid()
{
RzList *list = rz_core_debug_backtraces(Core()->core());
int i = 0;
for (CutterJson backtraceItem : Core()->getBacktrace()) {
QString progCounter = RzAddressString(backtraceItem["pc"].toRVA());
QString stackPointer = RzAddressString(backtraceItem["sp"].toRVA());
st64 frameSize = backtraceItem["frame_size"].toSt64();
QString funcName = backtraceItem["fname"].toString();
QString desc = backtraceItem["desc"].toString();
RzListIter *iter;
RzBacktrace *bt;
CutterRzListForeach (list, iter, RzBacktrace, bt) {
QString funcName = bt->fcn ? bt->fcn->name : "";
QString pc = RzAddressString(bt->frame ? bt->frame->addr : 0);
QString sp = RzAddressString(bt->frame ? bt->frame->sp : 0);
QString frameSize = QString::number(bt->frame ? bt->frame->size : 0);
QString desc = bt->desc;
QStandardItem *rowPC = new QStandardItem(progCounter);
QStandardItem *rowSP = new QStandardItem(stackPointer);
QStandardItem *rowFrameSize = new QStandardItem(QString::number(frameSize));
QStandardItem *rowFuncName = new QStandardItem(funcName);
QStandardItem *rowDesc = new QStandardItem(desc);
modelBacktrace->setItem(i, 0, rowFuncName);
modelBacktrace->setItem(i, 1, rowSP);
modelBacktrace->setItem(i, 2, rowPC);
modelBacktrace->setItem(i, 3, rowDesc);
modelBacktrace->setItem(i, 4, rowFrameSize);
i++;
modelBacktrace->setItem(i, 0, new QStandardItem(funcName));
modelBacktrace->setItem(i, 1, new QStandardItem(sp));
modelBacktrace->setItem(i, 2, new QStandardItem(pc));
modelBacktrace->setItem(i, 3, new QStandardItem(desc));
modelBacktrace->setItem(i, 4, new QStandardItem(frameSize));
++i;
}
rz_list_free(list);
// Remove irrelevant old rows
if (modelBacktrace->rowCount() > i) {

View File

@ -220,13 +220,7 @@ ColorThemeListView::ColorThemeListView(QWidget *parent) : QListView(parent)
setItemDelegate(new ColorOptionDelegate(this));
setResizeMode(ResizeMode::Adjust);
QJsonArray rgb =
colorSettingsModel()->getTheme().object().find("gui.background").value().toArray();
if (rgb.size() == 3) {
backgroundColor = QColor(rgb[0].toInt(), rgb[1].toInt(), rgb[2].toInt());
} else {
backgroundColor = palette().base().color();
}
backgroundColor = colorSettingsModel()->getTheme().find("gui.background").value();
connect(&blinkTimer, &QTimer::timeout, this, &ColorThemeListView::blinkTimeout);
@ -241,7 +235,7 @@ void ColorThemeListView::currentChanged(const QModelIndex &current, const QModel
ColorOption prev = previous.data(Qt::UserRole).value<ColorOption>();
Config()->setColor(prev.optionName, prev.color);
if (ThemeWorker().getRizinSpecificOptions().contains(prev.optionName)) {
Core()->cmdRaw(QString("ec %1 %2").arg(prev.optionName).arg(prev.color.name()));
Core()->setColor(prev.optionName, prev.color.name());
}
QListView::currentChanged(current, previous);
@ -267,9 +261,7 @@ void ColorThemeListView::mouseReleaseEvent(QMouseEvent *e)
.contains(e->pos())) {
ColorOption co = currentIndex().data(Qt::UserRole).value<ColorOption>();
co.changed = false;
QJsonArray rgb =
ThemeWorker().getTheme(Config()->getColorTheme()).object()[co.optionName].toArray();
co.color = QColor(rgb[0].toInt(), rgb[1].toInt(), rgb[2].toInt());
co.color = ThemeWorker().getTheme(Config()->getColorTheme())[co.optionName];
model()->setData(currentIndex(), QVariant::fromValue(co));
QCursor c;
c.setShape(Qt::CursorShape::ArrowCursor);
@ -307,7 +299,7 @@ void ColorThemeListView::blinkTimeout()
auto updateColor = [](const QString &name, const QColor &color) {
Config()->setColor(name, color);
if (ThemeWorker().getRizinSpecificOptions().contains(name)) {
Core()->cmdRaw(QString("ec %1 %2").arg(name).arg(color.name()));
Core()->setColor(name, color.name());
}
};
@ -374,16 +366,10 @@ void ColorSettingsModel::updateTheme()
{
beginResetModel();
theme.clear();
QJsonObject obj = ThemeWorker().getTheme(Config()->getColorTheme()).object();
ColorThemeWorker::Theme obj = ThemeWorker().getTheme(Config()->getColorTheme());
for (auto it = obj.constBegin(); it != obj.constEnd(); it++) {
QJsonArray rgb = it.value().toArray();
if (rgb.size() != 4) {
continue;
}
theme.push_back({ it.key(),
QColor(rgb[0].toInt(), rgb[1].toInt(), rgb[2].toInt(), rgb[3].toInt()),
false });
theme.push_back({ it.key(), it.value(), false });
}
std::sort(theme.begin(), theme.end(), [](const ColorOption &f, const ColorOption &s) {
@ -395,15 +381,13 @@ void ColorSettingsModel::updateTheme()
endResetModel();
}
QJsonDocument ColorSettingsModel::getTheme() const
ColorThemeWorker::Theme ColorSettingsModel::getTheme() const
{
QJsonObject obj;
int r, g, b, a;
ColorThemeWorker::Theme th;
for (auto &it : theme) {
it.color.getRgb(&r, &g, &b, &a);
obj.insert(it.optionName, QJsonArray({ r, g, b, a }));
th.insert(it.optionName, it.color);
}
return QJsonDocument(obj);
return th;
}
const QMap<QString, OptionInfo> optionInfoMap__ = {

View File

@ -73,7 +73,7 @@ public:
void updateTheme();
QJsonDocument getTheme() const;
QHash<QString, QColor> getTheme() const;
private:
QList<ColorOption> theme;