Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Emit RAnnotatedCode from decompileAt() #17

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions cutter-plugin/CMakeLists.txt
Expand Up @@ -16,6 +16,7 @@ find_package(Qt5 REQUIRED COMPONENTS Widgets)
add_library(r2retdec_cutter SHARED ${SOURCE})
target_link_libraries(r2retdec_cutter Qt5::Widgets)
target_link_libraries(r2retdec_cutter Radare2::libr)
target_link_libraries(r2retdec_cutter core_retdec)

#find_package(Cutter REQUIRED)
target_link_libraries(r2retdec_cutter Cutter::Cutter)
Expand Down
54 changes: 6 additions & 48 deletions cutter-plugin/R2RetDec.cpp
Expand Up @@ -7,7 +7,7 @@
*/

#include "R2RetDec.h"

#include "r2plugin/r2retdec.h"
#include <Cutter.h>

#include <QJsonDocument>
Expand All @@ -22,51 +22,9 @@ R2RetDec::R2RetDec(QObject *parent)

void R2RetDec::decompileAt(RVA addr)
{
if(task)
return;

AnnotatedCode code = {};

task = new R2Task ("pdzj @ " + QString::number(addr));

connect(task, &R2Task::finished, this, [this]() {
AnnotatedCode code = {};
QString s;

QJsonObject json = task->getResultJson().object();
delete task;
task = nullptr;
if(json.isEmpty())
{
code.code = tr("Failed to parse JSON from r2retdec");
emit finished(code);
return;
}

auto root = json;
code.code = root["code"].toString();

for(QJsonValueRef annotationValue : root["annotations"].toArray())
{
QJsonObject annotationObject = annotationValue.toObject();
CodeAnnotation annotation = {};
annotation.start = (size_t)annotationObject["start"].toVariant().toULongLong();
annotation.end = (size_t)annotationObject["end"].toVariant().toULongLong();
if(annotationObject["type"].toString() == "offset")
{
annotation.type = CodeAnnotation::Type::Offset;
annotation.offset.offset = annotationObject["offset"].toVariant().toULongLong();
}
else
continue;
code.annotations.push_back(annotation);
}

for(QJsonValueRef error : json["errors"].toArray())
code.code += "// " + error.toString() + "\n";

emit finished(code);
});
task->startTask();

RAnnotatedCode *code = r2retdec_decompile_annotated_code(Core()->core(), addr);
if(code == nullptr){
code = r_annotated_code_new(strdup("RetDec Decompiler Error: No function at this offset"));
}
emit finished(code);
}
2 changes: 1 addition & 1 deletion deps/cutter/CMakeLists.txt
Expand Up @@ -4,7 +4,7 @@ include(FetchContent)

FetchContent_Declare(cutter
GIT_REPOSITORY https://github.com/radareorg/cutter
GIT_TAG v1.10.3
GIT_TAG master
)

FetchContent_GetProperties(cutter)
Expand Down
2 changes: 1 addition & 1 deletion include/r2plugin/r2info.h
Expand Up @@ -29,7 +29,7 @@ class R2InfoProvider {
public:
std::string fetchFilePath() const;

common::Function fetchCurrentFunction() const;
common::Function fetchCurrentFunction(ut64 addr) const;

void fetchFunctionsAndGlobals(config::Config &rdconfig) const;

Expand Down
9 changes: 9 additions & 0 deletions include/r2plugin/r2retdec.h
@@ -0,0 +1,9 @@
#ifndef R2RETDEC_H
#define R2RETDEC_H

#include <r_util/r_annotated_code.h>
#include <r_core.h>

RAnnotatedCode* r2retdec_decompile_annotated_code(RCore *core, ut64 addr);

#endif //R2RETDEC_H
22 changes: 18 additions & 4 deletions src/core_plugin.cpp
Expand Up @@ -17,6 +17,7 @@
#include <r_util/r_annotated_code.h>

#include "r2plugin/cmd_exec.h"
#include "r2plugin/r2retdec.h"
#include "r2plugin/r2cgen.h"
#include "r2plugin/r2info.h"
#include "r2plugin/r2utils.h"
Expand Down Expand Up @@ -181,10 +182,12 @@ fs::path getOutDirPath()
* @brief Main decompilation method. Uses RetDec to decompile input binary.
*
* Decompiles binary on input by configuring and calling RetDec decompiler script.
*
* Decompiles the binary given by the offset passed addr.
*
* @param binInfo Provides informations gathered from r2 console.
* @param addr Decompiles the function at this offset.
*/
RAnnotatedCode* decompile(const R2InfoProvider &binInfo)
RAnnotatedCode* decompile(const R2InfoProvider &binInfo, ut64 addr)
{
try {
R2CGenerator outgen;
Expand All @@ -198,7 +201,7 @@ RAnnotatedCode* decompile(const R2InfoProvider &binInfo)
binInfo.fetchFunctionsAndGlobals(config);
config.generateJsonFile();

auto fnc = binInfo.fetchCurrentFunction();
auto fnc = binInfo.fetchCurrentFunction(addr);

auto decpath = outDir/"rd_dec.json";
auto outpath = outDir/"rd_out.log";
Expand Down Expand Up @@ -275,14 +278,25 @@ static void _cmd(RCore &core, const char &input)
std::lock_guard<std::mutex> lock (mutex);

R2InfoProvider binInfo(core);
auto code = decompile(binInfo);
auto code = decompile(binInfo, core.offset);
if (code == nullptr) {
return;
}

outputFunction(code);
}

/**
* This function is to get RAnnotatedCode to pass it to Cutter's decompiler widget.
*/
RAnnotatedCode* r2retdec_decompile_annotated_code(RCore *core, ut64 addr){
static std::mutex mutex;
std::lock_guard<std::mutex> lock (mutex);

R2InfoProvider binInfo(*core);
return decompile(binInfo, addr);
}

/**
* R2 console registration method. This method is called
* after each command typed into r2. If the function wants
Expand Down
10 changes: 6 additions & 4 deletions src/r2info.cpp
Expand Up @@ -51,14 +51,16 @@ std::string R2InfoProvider::fetchFilePath() const
}

/**
* @brief Fetches the currently seeked function in Radare2 console.
* @brief Fetches the function at the address passed as parameter.
*
* @param addr Analyzes the function at the given address.
*/
Function R2InfoProvider::fetchCurrentFunction() const
Function R2InfoProvider::fetchCurrentFunction(ut64 addr) const
{
RAnalFunction *cf = r_anal_get_fcn_in(_r2core.anal, _r2core.offset, R_ANAL_FCN_TYPE_NULL);
RAnalFunction *cf = r_anal_get_fcn_in(_r2core.anal, addr, R_ANAL_FCN_TYPE_NULL);
if (cf == nullptr) {
std::ostringstream errMsg;
errMsg << "no function at offset 0x" << std::hex << _r2core.offset;
errMsg << "no function at offset 0x" << std::hex << addr;
throw DecompilationError(errMsg.str());
}

Expand Down