全3191文字
PR

 マルウエアを解析する際、基本的に入手できるのはコンパイルされた後のバイナリーファイルだけである。そこで解析者は、解析ツールを使ってコードを逆アセンブルしてプログラムの処理の流れ(制御フロー)を調べたり、逆コンパイルしてソースコードの復元を試みたりする。逆に攻撃者は、解析を妨げるために様々な難読化を施す。

 難読化は、ソースコードのコンパイル前に施す手法と後に施す手法の2通りがある。後者は、パッカーなどの専用ツールを用いて、コンパイル後の実行ファイルを圧縮するなどして難読化する。しかしこの手法は、動的解析で対処できるケースが多い。実行ファイルを動作させて、プログラムがメモリーに展開されたところを解析すればよいからだ。

 このため最近では、コンパイル前に難読化を施すマルウエアが目立っている。今回は、その難読化の代表例として「Control Flow Flattening(CFF)」という手法を解説する。

処理の流れを「横並び」にする

 CFFは、順次実行するだけの単純な処理などを、条件分岐と繰り返し処理に置き換える手法である。制御フローで見ると縦に連なる処理が、分岐と繰り返しで横に並ぶようになる。制御フローが平らになることから、こうした書き換えを「平坦化」と呼ぶ。平坦化されたプログラムは処理の流れが分かりづらく、解析が難しくなる。

 「Hello World!」を繰り返し表示する簡単なプログラムにCFFを施してみよう(図1)。

図1●「CFF」を施してソースコードを難読化
図1●「CFF」を施してソースコードを難読化
CFFは、階層構造になっているプログラムの実行の流れ(制御フロー)が複雑になるように書き換える。この例では手作業でコードにCFFを施した。
[画像のクリックで拡大表示]

 CFFを施す前のコードをコンパイルして解析ツール「IDA Pro」で解析してみると、制御フローグラフは3個のブロックが縦に並ぶ単純な構造だった。実行ファイルを逆コンパイルすると、コンパイル前とほとんど同じ分かりやすいソースコードが復元された。

 次に、手動でCFFを施した。具体的には、switch文を使って元の処理を4つの分岐に分割した。得られる処理の結果はCFFを施す前と変わらない。こうして書き換えたコードをコンパイルして解析すると、制御フローグラフのブロックが12個に増えた。実行ファイルを逆コンパイルすると、コンパイル前と同じくどういう処理なのか分かりづらいソースコードが復元された。