retdec とは

retdec とはセキュリティ企業のavast社が公開しているデコンパイラです。 詳細はavast社のブログを参照(アバストが自社のマシンコード逆コンパイラをオープンソース化) ちゃんとデコンパイルするのか気になったのでインストールから"Hello, world"をデコンパイルする所まで書きます。

実行環境

当記事は下記環境で実行した結果を書いています。

$ uname -a
Linux ubuntu 4.15.0-36-generic #39~16.04.1-Ubuntu SMP Tue Sep 25 08:59:23 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux
$ gcc --version
gcc (Ubuntu 5.4.0-6ubuntu1~16.04.10) 5.4.0 20160609
$ docker -v
Docker version 18.06.1-ce, build e68fc7a

retdec をインストール

dockerを使用してビルドする。 ビルドが終わるまでそこそこ時間がかかるのでコーヒーでも飲んで待っていましょう。

$ git clone https://github.com/avast-tl/retdec
$ cd retdec
$ docker build -t retdec .

デコンパイルしてみる

ビルドが終わったらデコンパイルできるか試してみます。 まずはサンプルとして"Hello, world"を書きます。

#include <stdio.h>

int main(int argc, char *argv[]){
    printf("Hello, world\n");
    return 0;
}

次にこのコードをコンパイルします。 一点、注意が必要でretdecはx86-64のコードには対応していません。 なので今回はx86でコンパイルします。

$ gcc -m32 hello.c -o hello

次にデコンパイルします。 retdecコンテナにバイナリが存在するディレクトリをマウントし、デコンパイル用のPythonスクリプトを実行します。 マウントに伴いディレクトリの実行権限も変更します。

$ chmod 0777 [バイナリの存在するディレクトリ]
$ docker run --rm -v [バイナリがあるディレクトリの絶対パス]:/destination retdec retdec-decompiler.py /destination/hello

成功するとディレクトリにいろいろと生成されている。 中身はretdecで使用しているllvmの中間コード。 それらのなかにhello.cというファイルがあるので確認する。

$ ls
hello  hello.c  hello.c.backend.bc  hello.c.backend.ll  hello.c.frontend.dsm  hello.c.json
$ cat hello.c
//
// This file was generated by the Retargetable Decompiler
// Website: https://retdec.com
// Copyright (c) 2018 Retargetable Decompiler <info@retdec.com>
//

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

// ------------------------ Functions -------------------------

// Address range: 0x804840b - 0x8048439
int main(int argc, char ** argv) {
    // 0x804840b
    puts("Hello, world");
    return 0;
}

// --------------- Dynamically Linked Functions ---------------

// int puts(const char * s);

// --------------------- Meta-Information ---------------------

// Detected compiler/packer: gcc (5.4.0)
// Detected functions: 1
// Decompilation date: 2018-10-19 13:00:23

コードがデコンパイルできている。 また、コードだけではなくバイナリに付随している情報も確認できた。