diff --git a/src/common/Decompiler.cpp b/src/common/Decompiler.cpp index 94892075..7653f1d2 100644 --- a/src/common/Decompiler.cpp +++ b/src/common/Decompiler.cpp @@ -10,6 +10,75 @@ 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_new(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(); @@ -31,7 +100,7 @@ void JSDecDecompiler::decompileAt(RVA addr) if (task) { return; } - task = new RizinCmdTask("pddj @ " + QString::number(addr)); + task = new RizinCmdTask("pddA @ " + QString::number(addr)); connect(task, &RizinCmdTask::finished, this, [this]() { CutterJson json = task->getResultJson(); delete task; @@ -40,36 +109,7 @@ void JSDecDecompiler::decompileAt(RVA addr) emit finished(Decompiler::makeWarning(tr("Failed to parse JSON from jsdec"))); return; } - RzAnnotatedCode *code = rz_annotated_code_new(nullptr); - QString codeString = ""; - for (auto line : json["log"]) { - if (line.type() != RZ_JSON_STRING) { - continue; - } - codeString.append(line.toString() + "\n"); - } - - for (auto lineObject : json["lines"]) { - if (!lineObject.size()) { - continue; - } - RzCodeAnnotation annotationi = {}; - annotationi.start = codeString.length(); - codeString.append(lineObject["str"].toString() + "\n"); - annotationi.end = codeString.length(); - annotationi.type = RZ_CODE_ANNOTATION_TYPE_OFFSET; - annotationi.offset.offset = lineObject["offset"].toUt64(); - rz_annotated_code_add_annotation(code, &annotationi); - } - - for (auto line : json["errors"]) { - if (line.type() != RZ_JSON_STRING) { - continue; - } - codeString.append(line.toString() + "\n"); - } - std::string tmp = codeString.toStdString(); - code->code = strdup(tmp.c_str()); + RzAnnotatedCode *code = parseJsonCode(json); emit finished(code); }); task->startTask(); diff --git a/src/core/CutterJson.h b/src/core/CutterJson.h index 042ca84b..e8dd9819 100644 --- a/src/core/CutterJson.h +++ b/src/core/CutterJson.h @@ -89,6 +89,7 @@ public: size_t size() const { return has_children() ? value->children.count : 0; } RzJsonType type() const { return value ? value->type : RZ_JSON_NULL; } bool valid() const { return value ? true : false; } + const RzJson *lowLevelValue() const { return value; } private: bool has_children() const