retdec-cpp
retdec-cpp Documentation

This is an automatically generated API documentation for the retdec-cpp library.

Naming Conventions

The library uses the following naming conventions.

Moreover, no name contains two or more successive uppercase letters, even if it corresponds to an abbreviation. That is, the library uses withApiUrl() instead of withAPIURL() and IoError instead of IOError.

When a class represents a structure-like object, getters are named directly after the property, e.g. Settings::mode() instead of Settings::getMode(). In other cases, getters are prefixed with get, e.g. Decompilation::getOutputHll() instead of Decompilation::outputHll().

Includes

The easiest way to use the library is to include the general header file retdec.h that includes all the necessary header files:

#include <retdec/retdec.h>

However, if you use only specific parts of the library, you can include just the used header files:

// ...

Furthermore, the library provides header file fwd_decls.h, containing forward declarations for the used classes. It may be used in your header files to increase compilation speed.

Namespaces

All the classes, functions, and constants the library provides are in the retdec namespace.

For simplicity, in this API documentation, this namespace is omitted, e.g. it uses Decompilation instead of retdec::Decompilation.

Available Services

The library currently provides basic support for the file-analyzing and decompilation services. For simplicity, in the rest of this page, we will solely focus on decompilations. The use of the file-analyzing service through Fileinfo is analogical.

Creating Library Settings

At the very beginning, you need to create settings for the library. They are represented by an instance of class Settings. You have to provide at least your API key:

Settings settings;
settings.apiKey("YOUR-SECRET-API-KEY");

The class provides also a fluent interface, which allows you to chain the setting of multiple options:

auto settings = Settings()
.apiKey("YOUR-SECRET-API-KEY")

See the description of Settings for a list of all the available options.

Creating a Decompiler

To create a decompiler, instantiate class Decompiler and provide the settings constructed in the previous step:

Decompiler decompiler(settings);

It is of course possible to build the settings inline:

Decompiler decompiler(
Settings()
.apiKey("YOUR-SECRET-API-KEY")
);

This is handy if you want to use the settings only in a single place.

Starting Decompilations

After you have created a decompiler, you can run decompilations. To start a decompilation, call Decompiler::runDecompilation() and provide its arguments, represented by an instance of class DecompilationArguments. This class also provides a fluent interface. Example:

auto decompilation = decompiler.runDecompilation(
DecompilationArguments()
.mode("c")
.inputFile(
File::fromContentWithName("int main() {}", "empty.c")
)
);

The above example starts a decompilation of a C file empty.c and returns a handle to the decompilation. The file is created from the given content. In this way, you do not need to create regular files just to pass them as arguments to the decompilation. If you want to pass a regular file, use File::fromFilesystem() instead, which takes a path to the file.

Querying Decompilations

After a decompilation is started, you can query its state. For example, to check if the decompilation has finished, call Decompilation::hasFinished():

if (decompilation->hasFinished()) {
// ...
}

To effectively wait until the decompilation is finished, call Decompilation::waitUntilFinished():

decompilation->waitUntilFinished();

It will return once the decompilation finishes. You can also pass a callback that will be called whenever a change in the decompilation status is detected:

decompilation->waitUntilFinished([](const Decompilation &d) {
std::cout << "Currently completed: " << d.getCompletion() << "%\n";
});

The above code prints the completion status (in percentages) everytime a change is detected. Since the decompilation is passed to the callback via a parameter, you can have a generic callback and pass it to waitUntilFinished() without a need to capture the current decompilation via lambda captures.

To check whether the decompilation finished successfuly, call Decompilation::hasSucceeded().

Obtaining Outputs From Decompilations

Once a decompilation has successfully finished, you can obtain the produced outputs. To get the contents of the generated high-level language (HLL) in a string, call Decompilation::getOutputHll():

std::cout << decompilation->getOutputHll();

To get the file with the HLL, call Decompilation::getOutputHllFile(), which returns a handle to a File. With it, you can, for example, store the file to the filesystem by calling File::saveCopyTo():

decompilation->getOutputHllFile()->saveCopyTo("/some/directory/");

The copied file is given a proper name based on the name of the input file to the decompilation.

Error Handling

Errors are reported via exceptions. The base class of all custom exceptions thrown by the library is Error, which itself inherits from std::runtime_error. If you simply want to catch all the custom exceptions thrown by the library, catch this base class:

try {
// Use the library.
} catch (const Error &ex) {
// Handle the error.
}

Its subclasses include:

For a complete list, see the inheritance diagram for Error. Catch these subclasses if you want to handle different types of errors separately.

Resource errors are special. The waiting functions (e.g. Decompilation::waitUntilFinished()) take an optional parameter onError that specifies whether e.g. DecompilationError should be thrown when a decompilation fails. By default, they throw an exception.

A Complete Example

The following example creates a decompiler, starts a decompilation of the given binary file, and prints the decompiled C code to the standard output.

#include <iostream>
#include <retdec/retdec.h>
using namespace retdec;
int main(int argc, char **argv) {
if (argc != 3) {
std::cerr << "usage: " << argv[0] << " API-KEY FILE\n";
return 1;
}
try {
Decompiler decompiler(
.apiKey(argv[1])
);
auto decompilation = decompiler.runDecompilation(
.mode("bin")
.inputFile(File::fromFilesystem(argv[2]))
);
decompilation->waitUntilFinished();
std::cout << decompilation->getOutputHll();
return 0;
} catch (const Error &ex) {
std::cerr << "error: " << ex.what() << "\n";
return 1;
}
}

Contact

If you have any remarks or questions concerning the library, feel free to contact me.