Remove JSDec as decompiler and use rizin C api

This commit is contained in:
wargio 2024-02-24 19:47:29 +08:00 committed by Giovanni
parent c20d2c61d6
commit 2106551d00
8 changed files with 21 additions and 156 deletions

View File

@ -120,10 +120,6 @@ CutterApplication::CutterApplication(int &argc, char **argv) : QApplication(argc
Config()->setOutputRedirectionEnabled(clOptions.outputRedirectionEnabled); Config()->setOutputRedirectionEnabled(clOptions.outputRedirectionEnabled);
if (JSDecDecompiler::isAvailable()) {
Core()->registerDecompiler(new JSDecDecompiler(Core()));
}
#if CUTTER_RZGHIDRA_STATIC #if CUTTER_RZGHIDRA_STATIC
Core()->registerDecompiler(new RzGhidraDecompiler(Core())); Core()->registerDecompiler(new RzGhidraDecompiler(Core()));
#endif #endif

View File

@ -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) RzAnnotatedCode *Decompiler::makeWarning(QString warningMessage)
{ {
std::string temporary = warningMessage.toStdString(); std::string temporary = warningMessage.toStdString();
return rz_annotated_code_new(strdup(temporary.c_str())); 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();
}

View File

@ -37,20 +37,4 @@ signals:
void finished(RzAnnotatedCode *codeDecompiled); 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 #endif // DECOMPILER_H

View File

@ -62,7 +62,7 @@ CutterJson RizinCmdTask::getResultJson()
} }
char *copy = static_cast<char *>(rz_mem_alloc(strlen(res) + 1)); char *copy = static_cast<char *>(rz_mem_alloc(strlen(res) + 1));
strcpy(copy, res); strcpy(copy, res);
return Core()->parseJson(copy, nullptr); return Core()->parseJson("task", copy, nullptr);
} }
const char *RizinCmdTask::getResultRaw() const char *RizinCmdTask::getResultRaw()

View File

@ -273,6 +273,7 @@ void CutterCore::loadCutterRC()
} }
qInfo() << tr("Loading initialization file from ") << cutterRCFilePath; qInfo() << tr("Loading initialization file from ") << cutterRCFilePath;
rz_core_cmd_file(core, cutterRCFilePath.toUtf8().constData()); 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; qInfo() << tr("Loading initialization file from ") << cutterRCFilePath;
rz_core_cmd_file(core, cutterRCFilePath.toUtf8().constData()); rz_core_cmd_file(core, cutterRCFilePath.toUtf8().constData());
rz_cons_flush();
} }
QList<QString> CutterCore::sdbList(QString path) QList<QString> CutterCore::sdbList(QString path)
@ -473,19 +475,7 @@ QString CutterCore::cmdRaw(const char *cmd)
{ {
QString res; QString res;
CORE_LOCK(); CORE_LOCK();
rz_cons_push(); return rz_core_cmd_str(core, cmd);
// 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;
} }
CutterJson CutterCore::cmdj(const char *str) CutterJson CutterCore::cmdj(const char *str)
@ -496,7 +486,7 @@ CutterJson CutterCore::cmdj(const char *str)
res = rz_core_cmd_str(core, str); res = rz_core_cmd_str(core, str);
} }
return parseJson(res, str); return parseJson("cmdj", res, str);
} }
QString CutterCore::cmdTask(const QString &str) QString CutterCore::cmdTask(const QString &str)
@ -507,9 +497,9 @@ QString CutterCore::cmdTask(const QString &str)
return task.getResult(); 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(); return CutterJson();
} }
@ -517,18 +507,11 @@ CutterJson CutterCore::parseJson(char *res, const char *cmd)
if (!doc) { if (!doc) {
if (cmd) { 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 { } else {
eprintf("Failed to parse JSON\n"); RZ_LOG_ERROR("%s: Failed to parse JSON %s\n", name, res);
}
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: %s\n", name, res);
} }
return CutterJson(doc, QSharedPointer<CutterJsonOwner>::create(doc, res)); return CutterJson(doc, QSharedPointer<CutterJsonOwner>::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); rz_bin_select_idx(core->bin, NULL, idx);
} }
#endif #endif
} else {
// Not loading RzBin info coz va = false
} }
auto iod = core->io ? core->io->desc : NULL; 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; core->file && iod && (core->file->fd == iod->fd) && iod->plugin && iod->plugin->isdbg;
if (!debug && rz_flag_get(core->flags, "entry0")) { 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) { 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); fflush(stdout);
return true; return true;
} }
@ -1390,7 +1373,7 @@ CutterJson CutterCore::getSignatureInfo()
if (!signature) { if (!signature) {
return {}; return {};
} }
return parseJson(signature, nullptr); return parseJson("signature", signature, nullptr);
} }
bool CutterCore::existsFileInfo() bool CutterCore::existsFileInfo()
@ -4333,6 +4316,7 @@ void CutterCore::loadScript(const QString &scriptname)
{ {
CORE_LOCK(); CORE_LOCK();
rz_core_cmd_file(core, scriptname.toUtf8().constData()); rz_core_cmd_file(core, scriptname.toUtf8().constData());
rz_cons_flush();
} }
triggerRefreshAll(); triggerRefreshAll();
} }

View File

@ -183,10 +183,10 @@ public:
QString getRizinVersionReadable(const char *program = nullptr); QString getRizinVersionReadable(const char *program = nullptr);
QString getVersionInformation(); QString getVersionInformation();
CutterJson parseJson(char *res, const char *cmd = nullptr); CutterJson parseJson(const char *name, char *res, const char *cmd = nullptr);
CutterJson parseJson(char *res, const QString &cmd = QString()) 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); QStringList autocomplete(const QString &cmd, RzLinePromptType promptType, size_t limit = 4096);

View File

@ -520,7 +520,7 @@ void DisassemblyContextMenu::aboutToShowSlot()
if (ab && ab->op) { if (ab && ab->op) {
const char *opexstr = RZ_STRBUF_SAFEGET(&ab->op->opex); 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 // Loop through both the operands of the instruction
for (const CutterJson operand : operands) { for (const CutterJson operand : operands) {

View File

@ -193,11 +193,11 @@ void GraphvizLayout::CalculateLayout(std::unordered_map<ut64, GraphBlock> &block
if (it != edges.end()) { if (it != edges.end()) {
auto e = it->second; auto e = it->second;
if (auto spl = ED_spl(e)) { 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]; auto bz = spl->list[i];
edge.polyline.clear(); edge.polyline.clear();
edge.polyline.reserve(bz.size + 1); 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)); edge.polyline.push_back(QPointF(bz.list[j].x, bz.list[j].y));
} }
QPointF last(0, 0); QPointF last(0, 0);