
Drltrace は、Windows および Linux アプリケーション向けのライブラリコールトレーサーです。
Windows test build
Drltrace は、Windows および Linux アプリケーション向けの動的 API 呼び出しトレーサーです。Drltrace は DynamoRIO 動的バイナリ計装フレームワーク上に構築されています。Drltrace は当初 Derek Bruening によって実装され、DynamoRIO および DrMemory フレームワークとともに配布されていました。このリポジトリには、マルウェア解析に使用するための追加のスクリプトや資料とともに、drltrace のスタンドアロンバージョンが含まれています。リリースビルドは こちら からダウンロードできます。
drltrace の使用法は非常に簡単です。ユーザーは次のようにログディレクトリとターゲットプロセスの名前を指定する必要があります:
drltrace -logdir . -- calc.exe
これだけです。ツールは必要な DLL をターゲットプロセスに注入し、計測を開始し、並行してターゲットプロセスで実行されるすべてのライブラリ呼び出しに関する情報をログに記録します:
~~43600~~ msvcrt.dll!__wgetmainargs
arg 0: 0x010d2364
arg 1: 0x010d2368
and return to module id:0, offset:0x193a
~~43600~~ ntdll.dll!EtwEventRegister
arg 0: 0x002ff994
arg 1: 0x010d1490
and return to module id:0, offset:0x157e
~~43600~~ ntdll.dll!EtwEventSetInformation
arg 0: 0x007b4b40
arg 1: 0x00000033
and return to module id:0, offset:0x15a1
~~43600~~ SHELL32.dll!ShellExecuteW
arg 0: <null> (type=<unknown>, size=0x0)
arg 1: <null> (type=wchar_t*, size=0x0)
arg 2: calculator:// (type=wchar_t*, size=0x0)
arg 3: <null> (type=wchar_t*, size=0x0)
arg 4: <null> (type=wchar_t*, size=0x0)
arg 5: 0x1 (type=int, size=0x4)
and return to module id:0, offset:0x167d
出力の形式はシンプルで、外部スクリプトで簡単に解析できます:
~~[thread id]~~ [dll name]![api call name]
arg [arg #]: [value] (type=[Windows type name], size=[size of arg])
and return to module id:[module unique id], offset:[offset in memory]
解析は、-grepable 引数が使用されている場合に grep で行うことができます。これにより、関数名と引数がすべて 1 行に出力されます:
~~4824~~ KERNELBASE.dll!CreateFileW {0: C:\Windows\Fonts\staticcache.dat (type=wchar_t*, size=0x0)} {1: 0x80000000 (type=DWORD, size=0x4)} {2: 0x3 (type=DWORD, size=0x4)} {3: 0x005cde8c (type=<unknown>*, size=0x0)} {4: 0x3 (type=DWORD, size=0x4)} {5: 0x80 (type=DWORD, size=0x4)}
モジュールの一意の識別子テーブルは、ログファイルの最後に出力されます:
Module Table: version 3, count 70
Columns: id, containing_id, start, end, entry, checksum, timestamp, path
0, 0, 0x010d0000, 0x010da000, 0x010d1b80, 0x0000f752, 0xb5fe3575, C:\Windows\SysWOW64\calc.exe
1, 1, 0x6d4c0000, 0x6d621000, 0x6d563940, 0x00136d65, 0x59ce1b0b, C:\Users\Max\Downloads\drltrace\drltrace\dynamorio\lib32\release\dynamorio.dll
2, 2, 0x73800000, 0x73975000, 0x7380dbf7, 0x00000000, 0x59ce1b0f, C:\Users\Max\Downloads\drltrace\drltrace\bin\release/drltracelib.dll
3, 3, 0x742f0000, 0x742fa000, 0x742f2a00, 0x0000c877, 0x0adc52c1, C:\Windows\System32\CRYPTBASE.dll
4, 4, 0x74300000, 0x74320000, 0x7430c9b0, 0x0002c617, 0x245970b4, C:\Windows\System32\SspiCli.dll
5, 5, 0x74410000, 0x74431000, 0x74416900, 0x0002a940, 0x88a53c1d, C:\Windows\System32\GDI32.dll
6, 6, 0x74440000, 0x74500000, 0x7446fb20, 0x000cc410, 0xd343d532, C:\Windows\System32\RPCRT4.dll
7, 7, 0x74500000, 0x74525000, 0x745047d0, 0x00026737, 0xa39c8991, C:\Windows\System32\IMM32.DLL
8, 8, 0x74550000, 0x745c7000, 0x7456e8a0, 0x00081857, 0x73b971e1, C:\Windows\System32\advapi32.dll
9, 9, 0x748f0000, 0x74929000, 0x748febd0, 0x00045303, 0xa58be652, C:\Windows\System32\cfgmgr32.dll
10, 10, 0x74930000, 0x75c78000, 0x74aa09d0, 0x01377aa6, 0x4b39926b, C:\Windows\System32\SHELL32.dll
Drltrace は、-only_from_app オプションを指定することで、ライブラリ間の呼び出しを簡単にフィルタリングし、ターゲットアプリケーションのメインモジュール(またはヒープ)から実行された API 呼び出しのみを出力できます。これは、巨大なログを生成するアプリケーションの場合に非常に便利です。より細かい制御のために、-filter オプションを使用すると、ユーザーは特定のホワイトリスト関数をフィルタリングしたり、ブラックリスト関数を無視するためのフィルタ設定ファイルを指定できます(例については filter.config ファイルを参照)。Drltrace には、特定のライブラリの API 呼び出しをフィルタリングしたり、潜在的に興味深い API 呼び出しや文字列のみを出力するための便利な外部スクリプトもいくつか含まれています。
Drltrace のメインモジュールは BSD ライセンスの下で配布されています。
drltrace に必要な一部のファイルは LGPL の下で配布されています。詳細についてはソースファイルを参照してください。
マルウェア解析は簡単な作業ではありません。Themida や Armadillo のような高度なソフトウェアパッカー、そしてもちろんマルウェア作者によって書かれた無数の無名パッカーに加え、コードとデータの暗号化は、そのようなサンプルの静的リバースエンジニアリングを著しく困難にし(場合によっては完全に不可能にし)、マルウェア解析者の生活を複雑にしています。そのような場合、API 呼び出しのトレースは、実際の悪意のある意図を理解するために必要な時間を大幅に短縮し、保護された悪意のあるコードに関する多くの技術的詳細を明らかにすることができます。
従来の API フック手法はいくつかのソリューションでうまく実装されてきましたが、このアプローチはマルウェア作者によってよく研究されており、容易に検出および/または回避される可能性があります。さらに、これらのツールはスタンドアロンの重量級 GUI アプリケーション(プロプライエタリ製品として)として配布されており、既存のマルウェア解析ワークフローに統合するのが容易ではないことがよくあります。
Linux の世界を見ると、ltrace という素晴らしいツールがあります。単一の bash コマンドを使用して、特定の実行可能ファイルの API 呼び出しの完全なトレースを簡単に取得できます。
なぜ Windows にも、現代のマルウェアが使用するアンチリサーチトリックに対して透過的であり、Linux の ltrace のようなツールがないのでしょうか?
実際、Windows 向けにそのようなツールを持ち、実行中のプログラムに対して透過的に API 呼び出しをトレースするのに役立つ技術があります。この技術は動的バイナリ計装(DBI)と呼ばれます。DBI は、計装コードを注入することによって、実行時にバイナリアプリケーションの動作を解析する技術です。
しかし、マルウェア解析への DBI の応用は、アンパックの自動化や、命令、基本ブロック、関数呼び出しのトレースに関するいくつかの概念実証によって不当に制限されています。私たちの知る限り、drltrace は、実際にマルウェア解析に使用できる DBI ベースの API 呼び出しトレースのための最初のツールです。私たちは wiki でいくつかのマルウェア解析の例を提供しており、そこで drltrace がどのようにして、IDA やデバッガを起動することなく、複雑な悪意のあるサンプルに関する多くの内部技術的詳細を数分で明らかにできるかを説明しています。
-logdir [ .] Log directory to print library call data
-only_from_app [ false] Reports only library calls from the app
-follow_children [ true] Trace child processes
-print_ret_addr [ false] Print library call's return address
-num_unknown_args [ 2] Number of unknown libcall args to print
-num_max_args [ 6] Maximum number of arguments to print
-default_config [ true] Use default config file.
-config [ ""] The path to custom config file.
-filter [filter.config] The path of the whitelist/blacklist file.
-ignore_underscore [ false] Ignores library routine names starting with "_".
-help [ false] Print this message.
-version [ false] Print version number.
-verbose [ 1] Change verbosity.
-use_config [ true] Use config file
-grepable [ false] Grepable output
Drltrace は、ユーザーが特定の API 呼び出しの引数を drltrace がどのように出力すべきかを記述できる外部設定ファイルをサポートしています。
HANDLE|CreateRemoteThread|HANDLE|SECURITY_ATTRIBUTES*|size_t|THREAD_START_ROUTINE*|VOID*|DWORD|__out DWORD*
各関数引数は | で区切る必要があります。最初の引数は戻り値の型、2 番目の引数は関数名自体、残りは関数の引数です。トークン __out は出力引数をマークするために使用され、___inout は入力+出力引数をマークするために使用されます。
複雑なマルウェアの解析に drltrace を使用する方法の例は、Wiki ページ で見つけることができます。
ログファイルの作業を容易にするために、api_calls_viz.py というスクリプトを実装しました。このスクリプトは、各ピクセルの色が個別の API 呼び出しを表す RGB 画像を生成するために使用できます。例えば、以下の画像は WannaCry マルウェアのログファイルを表しています。

画像上の大きな緑色の領域は、暗号化するための興味深い拡張子(例:docx、xls、py)を持つファイルを選択するために使用される API 呼び出し(wcscmp/wcsicmp)を表しています。紫色の領域は、ディスク上のファイルやフォルダを列挙して暗号化するために使用される API 呼び出し(FindFirstFile/FindNextFile/CryptEncrypt)を表しています。
このスクリプトは、生成された RGB 画像の HTML 表現も生成でき、各要素を選択して API 呼び出しの名前を表示できます。

詳細については、api_calls_viz ディレクトリ を参照してください。
詳細なマニュアルは、この Wiki ページ にあります。
Windows、Linux(将来は macOS)。
x86、x64(ARM はリストに含まれています)。
C および C++ 標準ライブラリ(および Python で書かれたログ処理スクリプト)。
私たちは、動的バイナリ計装フレームワーク DynamoRIO 上に API 呼び出しトレーサーを実装することにしました。Drltrace は、ターゲットプロセスによってロードされる新しいライブラリを処理できるように、LoadLibrary 呼び出しの計測を DynamoRIO に依頼します。プロセスが新しいライブラリをロードしようとすると、DynamoRIO は制御フローを drltracelib.dll にリダイレクトします。次に、drltrace は新しくロードされた DLL のエクスポート関数を列挙し、それぞれに特別なコールバックを登録します。したがって、エクスポートされた関数がマルウェアによって呼び出されると、その関数の前に drltrace のコールバックが実行され、ツールは関数名や引数などの必要な情報をすべてログに記録できます。関数の後に別のコールバックを登録して、実行結果を保存することもできます。
なぜ Intel Pin ではないのか?以下の理由から DynamoRIO を使用することにしました:
drrun.exe の -syswide_on オプション)。ただし、将来は、そのような状況に対して drltrace に特別なサポートを実装する必要があります。問題トラッカーには drltrace の将来に関する詳細が含まれています。
Maksim Shudrak https://github.com/mxmssh
Derek Bruening https://github.com/derekbruening
Joe Testa https://github.com/jtesta