From 2106551d00348dc4117a842aeb8d9f8428d626ee Mon Sep 17 00:00:00 2001 From: wargio Date: Sat, 24 Feb 2024 19:47:29 +0800 Subject: [PATCH] Remove JSDec as decompiler and use rizin C api --- src/CutterApplication.cpp | 4 -- src/common/Decompiler.cpp | 99 ---------------------------- src/common/Decompiler.h | 16 ----- src/common/RizinTask.cpp | 2 +- src/core/Cutter.cpp | 44 ++++--------- src/core/Cutter.h | 6 +- src/menus/DisassemblyContextMenu.cpp | 2 +- src/widgets/GraphvizLayout.cpp | 4 +- 8 files changed, 21 insertions(+), 156 deletions(-) diff --git a/src/CutterApplication.cpp b/src/CutterApplication.cpp index 79a48b59..fc71ba58 100644 --- a/src/CutterApplication.cpp +++ b/src/CutterApplication.cpp @@ -120,10 +120,6 @@ CutterApplication::CutterApplication(int &argc, char **argv) : QApplication(argc Config()->setOutputRedirectionEnabled(clOptions.outputRedirectionEnabled); - if (JSDecDecompiler::isAvailable()) { - Core()->registerDecompiler(new JSDecDecompiler(Core())); - } - #if CUTTER_RZGHIDRA_STATIC Core()->registerDecompiler(new RzGhidraDecompiler(Core())); #endif diff --git a/src/common/Decompiler.cpp b/src/common/Decompiler.cpp index 2d9478e5..2089a408 100644 --- a/src/common/Decompiler.cpp +++ b/src/common/Decompiler.cpp @@ -10,107 +10,8 @@ Decompiler::Decompiler(const QString &id, const QString &name, QObject *parent) { } -static char *jsonToStrdup(const CutterJson &str) -{ - const RzJson *j = str.lowLevelValue(); - if (!j || j->type != RZ_JSON_STRING) { - return NULL; - } - return rz_str_dup(j->str_value); -} - -static RzAnnotatedCode *parseJsonCode(CutterJson &json) -{ - char *raw_code = jsonToStrdup(json["code"]); - if (!raw_code) { - return NULL; - } - RzAnnotatedCode *code = rz_annotated_code_new(raw_code); - if (!code) { - return NULL; - } - for (const auto &jsonAnnotation : json["annotations"]) { - RzCodeAnnotation annotation = {}; - annotation.start = jsonAnnotation["start"].toUt64(); - annotation.end = jsonAnnotation["end"].toUt64(); - QString type = jsonAnnotation["type"].toString(); - if (type == "offset") { - annotation.type = RZ_CODE_ANNOTATION_TYPE_OFFSET; - annotation.offset.offset = jsonAnnotation["offset"].toString().toULongLong(); - } else if (type == "function_name") { - annotation.type = RZ_CODE_ANNOTATION_TYPE_FUNCTION_NAME; - annotation.reference.name = jsonToStrdup(jsonAnnotation["name"]); - annotation.reference.offset = jsonAnnotation["offset"].toString().toULongLong(); - } else if (type == "global_variable") { - annotation.type = RZ_CODE_ANNOTATION_TYPE_GLOBAL_VARIABLE; - annotation.reference.offset = jsonAnnotation["offset"].toString().toULongLong(); - } else if (type == "constant_variable") { - annotation.type = RZ_CODE_ANNOTATION_TYPE_CONSTANT_VARIABLE; - annotation.reference.offset = jsonAnnotation["offset"].toString().toULongLong(); - } else if (type == "local_variable") { - annotation.type = RZ_CODE_ANNOTATION_TYPE_LOCAL_VARIABLE; - annotation.variable.name = jsonToStrdup(jsonAnnotation["name"]); - } else if (type == "function_parameter") { - annotation.type = RZ_CODE_ANNOTATION_TYPE_FUNCTION_PARAMETER; - annotation.variable.name = jsonToStrdup(jsonAnnotation["name"]); - } else if (type == "syntax_highlight") { - annotation.type = RZ_CODE_ANNOTATION_TYPE_SYNTAX_HIGHLIGHT; - QString highlightType = jsonAnnotation["syntax_highlight"].toString(); - if (highlightType == "keyword") { - annotation.syntax_highlight.type = RZ_SYNTAX_HIGHLIGHT_TYPE_KEYWORD; - } else if (highlightType == "comment") { - annotation.syntax_highlight.type = RZ_SYNTAX_HIGHLIGHT_TYPE_COMMENT; - } else if (highlightType == "datatype") { - annotation.syntax_highlight.type = RZ_SYNTAX_HIGHLIGHT_TYPE_DATATYPE; - } else if (highlightType == "function_name") { - annotation.syntax_highlight.type = RZ_SYNTAX_HIGHLIGHT_TYPE_FUNCTION_NAME; - } else if (highlightType == "function_parameter") { - annotation.syntax_highlight.type = RZ_SYNTAX_HIGHLIGHT_TYPE_FUNCTION_PARAMETER; - } else if (highlightType == "local_variable") { - annotation.syntax_highlight.type = RZ_SYNTAX_HIGHLIGHT_TYPE_LOCAL_VARIABLE; - } else if (highlightType == "constant_variable") { - annotation.syntax_highlight.type = RZ_SYNTAX_HIGHLIGHT_TYPE_CONSTANT_VARIABLE; - } else if (highlightType == "global_variable") { - annotation.syntax_highlight.type = RZ_SYNTAX_HIGHLIGHT_TYPE_GLOBAL_VARIABLE; - } - } - rz_annotated_code_add_annotation(code, &annotation); - } - return code; -} - RzAnnotatedCode *Decompiler::makeWarning(QString warningMessage) { std::string temporary = warningMessage.toStdString(); return rz_annotated_code_new(strdup(temporary.c_str())); } - -JSDecDecompiler::JSDecDecompiler(QObject *parent) : Decompiler("jsdec", "jsdec", parent) -{ - task = nullptr; -} - -bool JSDecDecompiler::isAvailable() -{ - return Core()->getConfigVariableSpaces().contains("jsdec"); -} - -void JSDecDecompiler::decompileAt(RVA addr) -{ - if (task) { - return; - } - task = new RizinCmdTask("pddA @ " + QString::number(addr)); - connect(task, &RizinCmdTask::finished, this, [this]() { - CutterJson json = task->getResultJson(); - delete task; - task = nullptr; - if (!json.size()) { - emit finished(Decompiler::makeWarning(tr("Failed to parse JSON from jsdec"))); - return; - } - RzAnnotatedCode *code = parseJsonCode(json); - emit finished(code); - }); - task->startTask(); -} diff --git a/src/common/Decompiler.h b/src/common/Decompiler.h index c3468b1e..5cff67a8 100644 --- a/src/common/Decompiler.h +++ b/src/common/Decompiler.h @@ -37,20 +37,4 @@ signals: void finished(RzAnnotatedCode *codeDecompiled); }; -class JSDecDecompiler : public Decompiler -{ - Q_OBJECT - -private: - RizinCmdTask *task; - -public: - explicit JSDecDecompiler(QObject *parent = nullptr); - void decompileAt(RVA addr) override; - - bool isRunning() override { return task != nullptr; } - - static bool isAvailable(); -}; - #endif // DECOMPILER_H diff --git a/src/common/RizinTask.cpp b/src/common/RizinTask.cpp index 14433585..f3423ab9 100644 --- a/src/common/RizinTask.cpp +++ b/src/common/RizinTask.cpp @@ -62,7 +62,7 @@ CutterJson RizinCmdTask::getResultJson() } char *copy = static_cast(rz_mem_alloc(strlen(res) + 1)); strcpy(copy, res); - return Core()->parseJson(copy, nullptr); + return Core()->parseJson("task", copy, nullptr); } const char *RizinCmdTask::getResultRaw() diff --git a/src/core/Cutter.cpp b/src/core/Cutter.cpp index 2a0db993..3b2eaa48 100644 --- a/src/core/Cutter.cpp +++ b/src/core/Cutter.cpp @@ -273,6 +273,7 @@ void CutterCore::loadCutterRC() } qInfo() << tr("Loading initialization file from ") << cutterRCFilePath; rz_core_cmd_file(core, cutterRCFilePath.toUtf8().constData()); + rz_cons_flush(); } } @@ -286,6 +287,7 @@ void CutterCore::loadDefaultCutterRC() } qInfo() << tr("Loading initialization file from ") << cutterRCFilePath; rz_core_cmd_file(core, cutterRCFilePath.toUtf8().constData()); + rz_cons_flush(); } QList CutterCore::sdbList(QString path) @@ -473,19 +475,7 @@ QString CutterCore::cmdRaw(const char *cmd) { QString res; CORE_LOCK(); - rz_cons_push(); - - // rz_core_cmd does not return the output of the command - rz_core_cmd(core, cmd, 0); - - // we grab the output straight from rz_cons - res = rz_cons_get_buffer(); - - // cleaning up - rz_cons_pop(); - rz_cons_echo(NULL); - - return res; + return rz_core_cmd_str(core, cmd); } CutterJson CutterCore::cmdj(const char *str) @@ -496,7 +486,7 @@ CutterJson CutterCore::cmdj(const char *str) res = rz_core_cmd_str(core, str); } - return parseJson(res, str); + return parseJson("cmdj", res, str); } QString CutterCore::cmdTask(const QString &str) @@ -507,9 +497,9 @@ QString CutterCore::cmdTask(const QString &str) return task.getResult(); } -CutterJson CutterCore::parseJson(char *res, const char *cmd) +CutterJson CutterCore::parseJson(const char *name, char *res, const char *cmd) { - if (!res) { + if (RZ_STR_ISEMPTY(res)) { return CutterJson(); } @@ -517,18 +507,11 @@ CutterJson CutterCore::parseJson(char *res, const char *cmd) if (!doc) { if (cmd) { - eprintf("Failed to parse JSON for command \"%s\"\n", cmd); + RZ_LOG_ERROR("%s: Failed to parse JSON for command \"%s\"\n%s\n", name, cmd, res); } else { - eprintf("Failed to parse JSON\n"); - } - const int MAX_JSON_DUMP_SIZE = 8 * 1024; - size_t originalSize = strlen(res); - if (originalSize > MAX_JSON_DUMP_SIZE) { - res[MAX_JSON_DUMP_SIZE] = 0; - eprintf("%zu bytes total: %s ...\n", originalSize, res); - } else { - eprintf("%s\n", res); + RZ_LOG_ERROR("%s: Failed to parse JSON %s\n", name, res); } + RZ_LOG_ERROR("%s: %s\n", name, res); } return CutterJson(doc, QSharedPointer::create(doc, res)); @@ -602,8 +585,6 @@ bool CutterCore::loadFile(QString path, ut64 baddr, ut64 mapaddr, int perms, int rz_bin_select_idx(core->bin, NULL, idx); } #endif - } else { - // Not loading RzBin info coz va = false } auto iod = core->io ? core->io->desc : NULL; @@ -611,7 +592,8 @@ bool CutterCore::loadFile(QString path, ut64 baddr, ut64 mapaddr, int perms, int core->file && iod && (core->file->fd == iod->fd) && iod->plugin && iod->plugin->isdbg; if (!debug && rz_flag_get(core->flags, "entry0")) { - rz_core_cmd0(core, "s entry0"); + ut64 addr = rz_num_math(core->num, "entry0"); + rz_core_seek_and_save(core, addr, true); } if (perms & RZ_PERM_W) { @@ -621,6 +603,7 @@ bool CutterCore::loadFile(QString path, ut64 baddr, ut64 mapaddr, int perms, int } } + rz_cons_flush(); fflush(stdout); return true; } @@ -1390,7 +1373,7 @@ CutterJson CutterCore::getSignatureInfo() if (!signature) { return {}; } - return parseJson(signature, nullptr); + return parseJson("signature", signature, nullptr); } bool CutterCore::existsFileInfo() @@ -4333,6 +4316,7 @@ void CutterCore::loadScript(const QString &scriptname) { CORE_LOCK(); rz_core_cmd_file(core, scriptname.toUtf8().constData()); + rz_cons_flush(); } triggerRefreshAll(); } diff --git a/src/core/Cutter.h b/src/core/Cutter.h index ff2b4682..9634381b 100644 --- a/src/core/Cutter.h +++ b/src/core/Cutter.h @@ -183,10 +183,10 @@ public: QString getRizinVersionReadable(const char *program = nullptr); QString getVersionInformation(); - CutterJson parseJson(char *res, const char *cmd = nullptr); - CutterJson parseJson(char *res, const QString &cmd = QString()) + CutterJson parseJson(const char *name, char *res, const char *cmd = nullptr); + CutterJson parseJson(const char *name, char *res, const QString &cmd = QString()) { - return parseJson(res, cmd.isNull() ? nullptr : cmd.toLocal8Bit().constData()); + return parseJson(name, res, cmd.isNull() ? nullptr : cmd.toLocal8Bit().constData()); } QStringList autocomplete(const QString &cmd, RzLinePromptType promptType, size_t limit = 4096); diff --git a/src/menus/DisassemblyContextMenu.cpp b/src/menus/DisassemblyContextMenu.cpp index 9879a16e..fbadfeca 100644 --- a/src/menus/DisassemblyContextMenu.cpp +++ b/src/menus/DisassemblyContextMenu.cpp @@ -520,7 +520,7 @@ void DisassemblyContextMenu::aboutToShowSlot() if (ab && ab->op) { const char *opexstr = RZ_STRBUF_SAFEGET(&ab->op->opex); - CutterJson operands = Core()->parseJson(strdup(opexstr), nullptr); + CutterJson operands = Core()->parseJson("opex", strdup(opexstr), nullptr); // Loop through both the operands of the instruction for (const CutterJson operand : operands) { diff --git a/src/widgets/GraphvizLayout.cpp b/src/widgets/GraphvizLayout.cpp index eb1fe4e3..e7770dc1 100644 --- a/src/widgets/GraphvizLayout.cpp +++ b/src/widgets/GraphvizLayout.cpp @@ -193,11 +193,11 @@ void GraphvizLayout::CalculateLayout(std::unordered_map &block if (it != edges.end()) { auto e = it->second; if (auto spl = ED_spl(e)) { - for (int i = 0; i < 1 && i < spl->size; i++) { + for (size_t i = 0; i < 1 && i < spl->size; i++) { auto bz = spl->list[i]; edge.polyline.clear(); edge.polyline.reserve(bz.size + 1); - for (int j = 0; j < bz.size; j++) { + for (size_t j = 0; j < bz.size; j++) { edge.polyline.push_back(QPointF(bz.list[j].x, bz.list[j].y)); } QPointF last(0, 0);