fr33f0r4ll

自分用雑記

avastのretdec

avastがデコンパイラを公開したので使ってみた。 お題はちょっと前のsharif-ctf2018のvuln4で、試しにデコンパイルしてみる。

インストール

まずはretdecをインストールする。 githubリポジトリにインストールのやり方があるのでプラットフォームに合わせてインストール。 ubuntuだとaptで入るcmakeじゃバージョンが低くてコンパイルできないので、cmakeも別途入れる必要があった。 とりあえずコンパイルしてインストールすると様々なツールとスクリプトがインストールされる。 ぱっと見た感じだとマルウェア解析をやりやすくするための解析ツールとかLLVM IRのトランスレータとかも入るみたいなので使ってみたい。 他にも簡単に使えるようにするためのスクリプトも入る。 デコンパイルするにはretdec-decompiler.shを実行すればいい。

デコンパイル

vuln4をデコンパイルしてみる。

retdec-decompiler.sh vuln4

簡単過ぎてビックリする。

デコンパイルすると、いくつかのファイルが生成された。 + vuln4.c + vuln4.c.backend.bc + vuln4.c.backend.ll + vuln4.c.frontend.dsm + vuln4.c.json

vuln4.c以外は中間生成物っぽい? vuln4.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>
#include <stdlib.h>
#include <string.h>

// ------------------- Function Prototypes --------------------

int32_t __x86_get_pc_thunk_bx(int32_t a1);
int32_t _start(int32_t a1);
int32_t copy_it(int32_t a1);
int32_t function_8048360(int32_t a1);
int32_t function_8048370(int32_t a1);
int32_t function_8048380(int32_t a1, int32_t a2, int32_t a3);
int32_t function_8048390(int32_t a1, int32_t a2);
int32_t function_80483a0(int32_t a1);
int32_t function_80483b0(int32_t a1, int32_t a2, int32_t a3, int32_t a4, int32_t a5, int32_t a6, int32_t a7, int32_t a8);

// --------------------- Global Variables ---------------------

int32_t g1 = 0; // eax
int32_t g2 = 0;
int32_t (*g3)(int32_t) = NULL;

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

// Address range: 0x8048360 - 0x804836f
int32_t function_8048360(int32_t a1) {
    // entry
    return ((int32_t (*)(int32_t))&g3)(g2);
}

// Address range: 0x8048370 - 0x804837f
int32_t function_8048370(int32_t a1) {
    // 0x8048370
    g1 = fflush();
    return function_8048360(0);
}

// Address range: 0x8048380 - 0x804838f
int32_t function_8048380(int32_t a1, int32_t a2, int32_t a3) {
    // 0x8048380
    g1 = fgets();
    return function_8048360(8);
}

// Address range: 0x8048390 - 0x804839f
int32_t function_8048390(int32_t a1, int32_t a2) {
    // 0x8048390
    g1 = strcpy();
    return function_8048360(16);
}

// Address range: 0x80483a0 - 0x80483af
int32_t function_80483a0(int32_t a1) {
    // 0x80483a0
    g1 = puts();
    return function_8048360(24);
}

// Address range: 0x80483b0 - 0x80483bf
int32_t function_80483b0(int32_t a1, int32_t a2, int32_t a3, int32_t a4, int32_t a5, int32_t a6, int32_t a7, int32_t a8) {
    // 0x80483b0
    g1 = __libc_start_main();
    return function_8048360(32);
}

// Address range: 0x80483d0 - 0x80483ff
int32_t _start(int32_t a1) {
    int32_t v1 = g1; // 0x80483d8
    int32_t v2 = v1; // bp-4
    int32_t v3;
    int32_t result = function_80483b0(0x80484ea, a1, (int32_t)&v3, 0x8048580, 0x80485e0, 0, (int32_t)&v2, v1); // 0x80483ec
    return result;
}

// Address range: 0x8048400 - 0x8048403
int32_t __x86_get_pc_thunk_bx(int32_t a1) {
    // entry
    return g1;
}

// Address range: 0x80484cb - 0x80484e9
int32_t copy_it(int32_t a1) {
    // entry
    int32_t v1; // bp-22
    function_8048390((int32_t)&v1, a1);
    return 0;
}

// Address range: 0x80484ea - 0x8048571
int main(int argc, char ** argv) {
    // entry
    function_80483a0((int32_t)"This time it is randomized...");
    function_80483a0((int32_t)"You should find puts yourself");
    function_8048370(*(int32_t *)0x80498a4);
    int32_t v1; // bp-66
    int32_t v2 = &v1; // 0x804853a
    function_8048380(v2, 200, *(int32_t *)0x80498a0);
    copy_it(v2);
    function_80483a0((int32_t)"done!");
    return 0;
}

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

// int32_t __libc_start_main(void);
// int32_t fflush(void);
// int32_t fgets(void);
// int32_t puts(void);
// int32_t strcpy(void);

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

// Detected compiler/packer: gcc (4.7.2)
// Detected functions: 10
// Decompilation date: 2018-02-06 22:45:20

元のvuln4が分岐もループもほとんどない単純なプログラムだからどの程度できるのかよく分からない。 pltっぽいところも関数にしているのが少し分かりにくいが、結構リバーシングの手間が省けるんじゃないだろうか? どの程度使えるのかこれから試していきたい。