1 
2 #include "Decompiler.h"
3 #include "Cutter.h"
4 
5 #include <QJsonObject>
6 #include <QJsonArray>
7 
Decompiler(const QString & id,const QString & name,QObject * parent)8 Decompiler::Decompiler(const QString &id, const QString &name, QObject *parent)
9     : QObject(parent),
10     id(id),
11     name(name)
12 {
13 }
14 
makeWarning(QString warningMessage)15 RAnnotatedCode *Decompiler::makeWarning(QString warningMessage){
16     std::string temporary = warningMessage.toStdString();
17     return r_annotated_code_new(strdup(temporary.c_str()));
18 }
19 
R2DecDecompiler(QObject * parent)20 R2DecDecompiler::R2DecDecompiler(QObject *parent)
21     : Decompiler("r2dec", "r2dec", parent)
22 {
23     task = nullptr;
24 }
25 
isAvailable()26 bool R2DecDecompiler::isAvailable()
27 {
28     return Core()->cmdList("e cmd.pdc=?").contains(QStringLiteral("pdd"));
29 }
30 
decompileAt(RVA addr)31 void R2DecDecompiler::decompileAt(RVA addr)
32 {
33     if (task) {
34         return;
35     }
36     task = new R2Task("pddj @ " + QString::number(addr));
37     connect(task, &R2Task::finished, this, [this]() {
38         QJsonObject json = task->getResultJson().object();
39         delete task;
40         task = nullptr;
41         if (json.isEmpty()) {
42             emit finished(Decompiler::makeWarning(tr("Failed to parse JSON from r2dec")));
43             return;
44         }
45         RAnnotatedCode *code = r_annotated_code_new(nullptr);
46         QString codeString = "";
47         for (const auto &line : json["log"].toArray()) {
48             if (!line.isString()) {
49                 continue;
50             }
51             codeString.append(line.toString() + "\n");
52         }
53 
54         auto linesArray = json["lines"].toArray();
55         for (const auto &line : linesArray) {
56             QJsonObject lineObject = line.toObject();
57             if (lineObject.isEmpty()) {
58                 continue;
59             }
60             RCodeAnnotation annotationi = { 0 };
61             annotationi.start = codeString.length();
62             codeString.append(lineObject["str"].toString() + "\n");
63             annotationi.end = codeString.length();
64             bool ok;
65             annotationi.type = R_CODE_ANNOTATION_TYPE_OFFSET;
66             annotationi.offset.offset = lineObject["offset"].toVariant().toULongLong(&ok);
67             r_annotated_code_add_annotation(code, &annotationi);
68         }
69 
70         for (const auto &line : json["errors"].toArray()) {
71             if (!line.isString()) {
72                 continue;
73             }
74             codeString.append(line.toString() + "\n");
75         }
76         std::string tmp = codeString.toStdString();
77         code->code = strdup(tmp.c_str());
78         emit finished(code);
79     });
80     task->startTask();
81 }
82