Using RetDec to Decompile a Simple C Program

Consider the following C source file:

#include <stdio.h>

void printff() {
    printf("this is called funtion printff");
}

int main(int argc, char *argv[]) {
    printff();
    printf("This is helo analysis");
    if (argc == 2) {
        printf("The argument supplied is %s\n", argv[1]);
    } else if (argc > 2) {
        printf("Too many arguments supplied.\n");
    } else {
        printf("One argument expected.\n");
    }
    return 0;
}

Compile it with GCC:

gcc hello.c -o a.exe

Running the binary yields expected output:

> a.exe hello
this is called funtion printffThis is helo analysisThe argument supplied is hello

To decompile a.exe, use RetDec:

retdec-decompiler.exe a.exe

This generates five output files:

  • a.exe.bc: LLVM bytecode
  • a.exe.ll: Human-readable LLVM IR
  • a.exe.dsm: Disassembled machine code
  • a.exe.config.json: Configuration metadata
  • a.exe.c: Reconstructed C source

The decompiled C file appears as follows:

#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>

int32_t ___do_global_ctors(void);
int32_t ___main(void);
int32_t _printff(void);

int32_t g1 = -1;
int32_t g2 = 0;

int32_t _printff(void) {
    return printf("this is called funtion printff");
}

int main(int argc, char **argv) {
    ___main();
    _printff();
    printf("This is helo analysis");
    if (argc == 2) {
        int32_t arg_ptr = *(int32_t *)((int32_t)argv + 4);
        printf("The argument supplied is %s\n", (char *)arg_ptr);
        return 0;
    }
    if (argc < 3) {
        puts("One argument expected.");
    } else {
        puts("Too many arguments supplied.");
    }
    return 0;
}

int32_t ___do_global_ctors(void) {
    int32_t i = 0;
    int32_t j = i + 1;
    while (*(int32_t *)(4 * j + (int32_t)&g1) != 0) {
        i = j;
        j = i + 1;
    }
    if (i == 0) {
        return atexit((void (*)())0x401990);
    }
    int32_t k = i;
    while (k != 1) {
        k--;
    }
    return atexit((void (*)())0x401990);
}

int32_t ___main(void) {
    int32_t result = g2;
    if (result != 0) {
        return result;
    }
    g2 = 1;
    return ___do_global_ctors();
}

Recompiling this decompiled source works for simple cases:

gcc a.exe.c -o a2.exe

Executing the recompiled binary reproduces the original behavior:

> a2.exe hello
this is called funtion printffThis is helo analysisThe argument supplied is hello

While straightforward programs like this can be cleanly reconstructed and recompiled, complex binaries often produce decompiled code that fails to compile directly. In such scenarios, manual analysis and rewriting—guided by reverse engineering expertise—are necsesary to recover functional equivalents.

Tags: reverse-engineering decompilation retdec binary-analysis C

Posted on Tue, 23 Jun 2026 18:01:09 +0000 by jpt62089