← All Articles

DynamoRIOで始めるDBI

Posted on

DynamoRIOとは


DynamoRIOは、Dynamic Binary Instrumentation (DBI)ツールの1つです。DBIとは実行中のプログラムに対して任意の部分でのコード変換/挿入を行い、バイナリの挙動を分析する為の手法です。 DynamoRIO APIは、バイナリの動的分析をサポートするインターフェースを提供しています。

今回は、WinAFLにてFuzzingを行う際のCoverageを確認するためにDynamoRIOをソースからビルドしていきます。

DynamoRIOのロゴ


DynamoRIOビルド手順


DynamoRIOのレポジトリ上にあるHow To Buildに記載された以下のソフトウェアをインストールします。

  • Visual Studio 2017. Other versions are not officially supported as our automated tests use VS 2017.
  • CMake. 3.7+ is required. When prompted, we recommend adding it to your PATH.
  • Git. Any flavor should do, includingGit on Windowsor Cygwin git.
  • Perl. We recommend eitherStrawberry Perlor Cygwin perl.
  • (optional) Cygwin. Only needed for building documentation. Select the doxygen package if you do install it. (You can also select Cygwin’s perl and git as alternatives to the links above.)

上記のソフトウェアがインストール出来たら、32-bit DynamoRIOをビルドしていきます。


32-bit DynamoRIO

スタートメニュー > すべてのアプリケーション > Visual Studio 2017 > x86 Native Tools Command Promptを開きます。

x86 Native Tools Command Prompt画面


x86 Native Tools Command Prompt上で以下のコマンドを実行します。

DynamoRIOビルドコマンド
$ git clone https://github.com/DynamoRIO/dynamorio.git
$ cd dynamorio && mkdir build32 && cd build32
$ cmake -G"Visual Studio 15" ..
$ cmake --build . --config RelWithDebInfo
$ bin32\drrun.exe notepad.exe

最後のコマンド実行によりnotepad.exeが起動すればDynamoRIOが問題なくビルドできていることが分かります。

続いて64-bit DynamoRIOをビルドします。


64-bit DynamoRIO

スタートメニュー > すべてのアプリケーション > Visual Studio 2017 > x64 Native Tools Command Promptを開きます。


x64 Native Tools Command Prompt上で以下のコマンドを実行します。

DynamoRIOビルドコマンド
$ cd C:\dynamorio && mkdir build64 && cd build64
$ cmake -G"Visual Studio 15 Win64" ..
$ cmake --build . --config RelWithDebInfo
$ bin64\drrun.exe notepad.exe

32-bitビルドと同様、最後のコマンド実行によりnotepad.exeが起動すればDynamoRIOが問題なくビルドできていることが分かります。


お試し


DynamoRIOにはAPIを利用するサンプルプログラムが複数用意されています。

ここでは、その一つであるcountcalls.dllを使ってみたいと思います。

countcalls.dllは、対象プログラム内のnear callのdirect callおよびindirect call、そしてreturnの3種類のopcode数をカウントすることができます。

以下のコマンドでnotepad.exeに対してcountcalls.dllを実行します。

notepadにcountcalls.dllを実行
$ cd dynamorio\build
$ bin32\drrun.exe -c api\bin\countcalls.dll -- notepad

上記コマンドを実行すると以下のようなポップアップで結果が得られます。

countcalls結果画面


countcalls.dllのソースコードであるcountcalls.cを見てみると、以下の様にifおよびelse ifの分岐にて対象プログラム内のnear callのdirect callおよびindirect call、そしてreturnの3種類のopcode数をカウントしていることが分かります。

    /* instrument calls and returns -- ignore far calls/rets */
    if (instr_is_call_direct(instr)) {
        insert_counter_update(drcontext, bb, instr,
                              offsetof(per_thread_t, num_direct_calls));
    } else if (instr_is_call_indirect(instr)) {
        insert_counter_update(drcontext, bb, instr,
                              offsetof(per_thread_t, num_indirect_calls));
    } else if (instr_is_return(instr)) {
        insert_counter_update(drcontext, bb, instr, offsetof(per_thread_t, num_returns));
    }

さらにinstr_is_call_direct()をDynamoRIOのAPI documentで調べてみると引数instrのopcodeがOP_callまたはOP_call_farの場合にtrueを返すことが分かります。

このようにサンプルコードで使われているAPIを確認していくことでDynamoRIO APIで出来ることがつかめると思います。


reversingdbi