Use RzAnnotatedCode from JSDec (pddA)

This commit is contained in:
Nirmal Manoj 2021-10-04 18:07:49 +05:30 committed by Florian Märkl
parent 2c31d38d85
commit b92ad19148
2 changed files with 72 additions and 31 deletions

View File

@ -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) RzAnnotatedCode *Decompiler::makeWarning(QString warningMessage)
{ {
std::string temporary = warningMessage.toStdString(); std::string temporary = warningMessage.toStdString();
@ -31,7 +100,7 @@ void JSDecDecompiler::decompileAt(RVA addr)
if (task) { if (task) {
return; return;
} }
task = new RizinCmdTask("pddj @ " + QString::number(addr)); task = new RizinCmdTask("pddA @ " + QString::number(addr));
connect(task, &RizinCmdTask::finished, this, [this]() { connect(task, &RizinCmdTask::finished, this, [this]() {
CutterJson json = task->getResultJson(); CutterJson json = task->getResultJson();
delete task; delete task;
@ -40,36 +109,7 @@ void JSDecDecompiler::decompileAt(RVA addr)
emit finished(Decompiler::makeWarning(tr("Failed to parse JSON from jsdec"))); emit finished(Decompiler::makeWarning(tr("Failed to parse JSON from jsdec")));
return; return;
} }
RzAnnotatedCode *code = rz_annotated_code_new(nullptr); RzAnnotatedCode *code = parseJsonCode(json);
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());
emit finished(code); emit finished(code);
}); });
task->startTask(); task->startTask();

View File

@ -89,6 +89,7 @@ public:
size_t size() const { return has_children() ? value->children.count : 0; } size_t size() const { return has_children() ? value->children.count : 0; }
RzJsonType type() const { return value ? value->type : RZ_JSON_NULL; } RzJsonType type() const { return value ? value->type : RZ_JSON_NULL; }
bool valid() const { return value ? true : false; } bool valid() const { return value ? true : false; }
const RzJson *lowLevelValue() const { return value; }
private: private:
bool has_children() const bool has_children() const