コンパイラ出力コードモデルの尤度に基づくアンパッキング手法
岩村誠 †‡伊藤光恭 †村岡洋一 ‡†NTT 情報流通プラットフォーム研究所
180-8585 東京都武蔵野市緑町 3-9-11{iwamura.makoto,itoh.mitsutaka}@lab.ntt.co.jp‡ 早稲田大学
169-8555 東京都新宿区大久保 3-4-1{iwamura@muraoka.info.waseda.ac.jp,muraoka@waseda.jp}
あらまし 本論文では，パッキングされた実行ファイルからオリジナルコードを抽出する新たなアンパッキング手法を提案する．従来のページフォールトハンドラを用いた手法では，メモリアクセス監視の際に TLB を利用していたためその実装が不十分な仮想マシン上で動作させることは不可能であった．これに対し提案手法では，TLB への依存を無くし仮想マシン上での動作を実現した．さらに，多重にパッキングされた実行ファイルであっても，確率モデルを用いてコンパイラが出力したバイナリとしての尤もらしさを算出することで，オリジナルコードを特定可能にした．研究用データセットCCC DATAset 2008 のマルウェア検体による実験では，複数のオリジナルコードの候補を抽出するとともに，その候補からオリジナルコードを特定可能なことを示した．

Unpacking based on the likelihood of the compiled code model
Makoto Iwamura†‡

Mitsutaka Itoh†Yoichi Muraoka‡†NTT Information Sharing Platform Laboratories
9-11, Midori-Cho 3-Chome Musashino-Shi, Tokyo 180-8585 Japan{iwamura.makoto,itoh.mitsutaka}@lab.ntt.co.jp‡Waseda University
3-4-1 Ohkubo, Shinjuku-ku, Tokyo, 169-8555 Japan{iwamura@muraoka.info.waseda.ac.jp,muraoka@waseda.jp}

Abstract In this paper, we propose a novel unpacking tool which can automatically extract
the original code of a packed malware. A conventional tool hooking page-fault handler cannot
run on the virtual machine which does not correctly implement TLB. Compared with it, ourtool can run on it by more sophisticated monitor, which do not need TLB, for memory access.
Additionally, even if the malware were multiple-packed i.e., two or more candidates of the originalcode were extracted by the previous process, our tool can specify the original code of a malware
by calculating the likelihood of the compiled code model from given candidates. Experimental
results with the malware sample of CCC DATAset 2008 show that our tool could extract somecode regions as the candidates and specify the original code from them.

1

研究の背景と動機

近年マルウェアの種類数が増加の一途を辿っており，国内でも一日当たり数千検体の新種が収集されているとの報告がある [1]．この要因としてはポリモーフィック型マルウェアや，対象プログラムを圧縮しオリジナルコードを隠蔽できるパッカーが多数存在することが挙げられる．
特にランタイムパッカーは，ソースコードや開発環境に手を入れることなく，容易にそのプログラムコードを隠蔽することができるため，解析を困難にすることを目的としてマルウェアに適用されるケースが多い．このようにマルウェアが氾濫している状況においては，それら全てに対策を打つことはおろか，対策の優先度を決めることさえ困難になっている．故に膨大な種類のマルウェアを，如何に効率的に管理するかが大きな課題となっており，その解決策のひとつとしてマルウェアの分類技術の研究が進んでいる．マルウェアの分類技術には大きく分けて二つのアプローチが存在する．ひとつはマルウェ
アの挙動によりそれらを分類する方法である．
しかしながら，マルウェアの昨今のトレンドが攻撃者からの指令無しには動かないボットであることを鑑みると，挙動によるマルウェアの分類は非常に難しい．こうした課題を解決するために，マルウェアのプログラムコードに基づく分類技術も研究されている．これはマルウェアのプログラムコードより抽出した N-perms やコールツリー，コントロールフローグラフなどからマルウェア間の類似度を算出し，クラスタリングする手法である [2][3]．ただし，これらの従来研究は何れもアンパッキングや逆アセンブ
ル等の解析が済んだマルウェアを対象としており，プログラムコードに基づくマルウェアの分類を全自動化するためには，以下のアンパッキングの工程を自動化することが必要となる．

• オリジナルエントリーポイントの特定• オリジナルコードの抽出• インポートテーブルの再構築• 実行ファイル用ヘッダの再構築
本論文では，この中でも特にプログラムコードに基づく分類の要となるオリジナルコードの抽出に焦点を当てる．

2

従来技術

実行ファイルがどのパッカーでパッキングされたかを識別し，隠蔽されたオリジナルコードを抽出するツールはいくつも存在する．例えば，PEiD[4] は単純なパターンマッチングによりパッカーを識別することができる．こうしてパッカーを特定することができれば，個別に開発されたアンパッカーを利用し隠蔽されたオリジナルコードを抽出することができる．このアプローチは非常に高速かつ正確にアンパッキングが可能であるが，パッカーを識別でき，尚且つ対応するアンパッカーが存在している必要があるため，新しいアルゴリズムを備えるパッカーが利用された場合には適用できない．
一方，パッカー毎のアルゴリズムに依存しない動的なアンパッキング手法も提案されている．
ランタイムパッカーでパッキングされたプログ
ラムは，実行されるとオリジナルコードがメモリ上に展開され，通常 OS に備わるローダが行う処理（動的ライブラリのリンク，リロケーションなど）を行った後に，オリジナルコードが実行される．ほとんどの動的なアンパッキング手法はこの事実を前提として開発されている．
OllyBonE[5] や Universal PE Unpacker[6] は事前にオリジナルコードのエントリポイントが含まれるであろう領域に対して，実行ブレークポイントを張り対象プログラムを実行することで，オリジナルコードのエントリポイントを発見する．ただしオリジナルコードのエントリポイン
トはマルウェアをリンクする際に任意に設定可能であるため，広大なアドレス空間に対してこれを事前に予測することは非常に難しい．この問題を解決するために Saﬀron[7] や Renovo[8]は，書き込みが生じた領域がその後実行された場合に，当該領域をオリジナルコードとして出力する．しかしながら，この手法にもふたつの課題が残っている．
一つ目は実装上の問題である．Renovo は TEMUと呼ばれる一種のエミュレーションエンジン上に構築されており，そのエミュレーション精度の問題からアンチデバッグ機構により解析できない状況も報告されている．またエミュレーションの性質上，解析速度の低下も免れない．一方，

Saﬀron は OS のページフォールトハンドラを独自のハンドラに置き換えることで，解析速度の向上を果たしている．具体的には解析対象プロセス空間内の全メモリページに関して PTE(Page Table Entry) 内のスーパーバイザービッ
トを設定することで，全メモリアクセスをフックし，メモリに対する書き込みおよび実行アクセスを監視している．メモリアクセスをフックした後に処理を続行させるためには，PTE の専用キャッシュである TLB (Translation LookasideBuﬀer) を用いることで解決している．IA-32 における TLB と PTE の同期処理は，通常システムプログラマに任されており，Saﬀron ではこの同期処理を敢えて省略することで PTE にはスーパーバイザービットを設定しつつも，TLBではスーパーバイザービットが設定されていない状態を作り出し，メモリアクセスをフックした後の処理を続行させている．ただしこれにも大きな問題が存在する．一般的に仮想マシンにおける TLB は実機のそれを忠実に再現しているとは限らない．実際，最も著名な仮想マシンである VMware[9] においても命令用 TLB が特権モードを跨ぐ際にフラッシュされるとの報告もある [10]．命令用 TLB が特権モードを跨ぐ際にフラッシュされてしまうと，Saﬀron の実装では常に PTE に設定したスーパーバイザービットが有効になってしまうため，ユーザプロセスとページフォールトハンドラを行き来する無限ループに陥ってしまう．そのため，マルウェア解析に非常に有効である仮想マシン上での解析が実質不可能となってしまう．
二つ目は多重にパッキングされたバイナリを解析するときに，各層のアンパッキングが完了するたびにオリジナルコード（の候補）が抽出されてしまうことにある．このため事前にタイムアウトを設定しておく等の対処も提案されているが，オリジナルコードを特定するための根本的な対処には至っていない．

3

提案手法

本章では，TLB の実装に依存せずに，ページフォールトハンドラを用いて高速にメモリアクセスを監視しつつ，さらに多重にパッキングされたバイナリであっても，オリジナルコードを特定可能なアンパッキング手法を提案する．提案手法は大きく分けて二つのモジュールから構成される．一つ目はメモリアクセス監視モジュールである．これは Saﬀron と同様，カーネルドライバとして実装され，独自のページフォールトハンドラを用いることで，「書き込まれた後に実行される」メモリページを，オリジナルコードの候補として出力する．二つ目はオリジナルコード特定モジュールであり，メモリアクセス監視モジュールから出力されたオリジナルコードの候補からオリジナルコードを特定するモジュールである．以下に各モジュールの詳細について述べる．

3.1

メモリアクセス監視モジュール

本モジュールは Saﬀron と同様の機能を持っている．まず対象プロセス空間内のすべてのメモリページに関して，書き込み監視状態とする．
その後，書き込みが発生したメモリページに関して，実行監視状態に遷移させる．そして実行監視状態であるメモリページが実行された際に，そのメモリページが含まれる領域をファイルへ出力し，当該領域を再び監視状態に戻す．メモ
リアクセス監視機構において提案手法と Saﬀronとが大きく異なる点は監視方法にある．まず書
き込み監視するべきメモリページに対しては，対応する PTE の writable-bit を 0 に設定する．
これにより書き込みが発生したときのみページフォルトを引き起こすことができる．一方，実行を監視するべきメモリページに対しては，対応する PTE の XDbit を 1 に設定することで実現する．これには PAE(Physical Address Extensions) が有効になっており，かつ MSR レジスタ内の 11 ビット目を設定する必要があることに注意する．一方，PTE を操作し該当する監視状態に移行させた後に，当該メモリページがページアウトしてしまうと，PTE へ書き込んだ情報が失われてしまう．さらに動的に確保されたメモリページに対しても，それを検出し書き込み監視のために writable-bit を 0 に設定する必要がある．これらの問題は，MiAddValidPageToWorkingSet(カーネル内部の関数) の呼び出しを監視しておくことで，物理メモリへのマッピングが行われる際に，PTE に該当する操作を行うようにすることで解決できる．また，仮想アドレスが動的に解放される場合は，MiRemoveVad(カーネル内部の関数) が呼び出されるため，この関数の呼び出しを契機に，監視状態を解除することができる．
こうした機能により TLB を用いることなく，監視する必要があるアクセスのみでページフォールトを発生させることができるようになったため，TLB の実装が実機のそれとは異なるVMware 等の仮想マシンであっても，問題なく動作可能となった．また，不要なページフォールトが発生しなくなったことにより速度面のパフォーマンス向上も見込むことができる．

度，つまりコンパイラ出力コードとしての尤もらしさと捉えることができる．こうして得られた P (X|Mθ ) と，事前の知見なしに求まるθ)
P (X)1 の比 P (X|M
P (X) （尤度比という）を算出し，その値が 1 以下であればコンパイラ出力コードらしくない，1 より大きければコンパイラ出力コードらしい，といった判断が可能となる．ただし，このモデルはあくまで命令の出現頻度および各状態間の遷移確率のみをモデル化しているに過ぎないため，アンパッキングの処理ルーチンであっても尤度が高くなる状況が考えられる．
アンパッキングの処理ルーチンには，コンパイラ出力コードには見られない特徴を持つものがある．そのひとつとして分岐命令の宛先が命
3.2 オリジナルコード特定モジュール
令の先頭からずれた場所を指すように見える，
ここでは，アンパッキングの処理ルーチンはといった状況（ブランチバイオレーションと呼コンパイラ出力コードとして尤もらしくなく，ぶ）が挙げられる．この意図は，先頭から順にオリジナルコードはコンパイラ出力コードとし逆アセンブルを行った際に本来の命令列を隠すて尤もらしいことを前提として，コンパイラ出（つまり解析を困難にする）ためであり，アン力コードを確率モデルにより表現することで，パッキングの処理ルーチンにはこういった分岐その尤度を算出しオリジナルコードを決定する命令が頻繁に出現する．一方，通常のコンパイことを目的とする．コンパイラ出力コードのモ
ラ出力コードには，宛先が命令の先頭ではない
デル化については逆アセンブルに関する研究に分岐命令は存在しない．したがって，コンパイおいて，隠れマルコフモデルを用いた確率モデ
ラ出力コードの尤もらしさを算出する際には，ルが提案されている [11]．提案手法ではこれをこのブランチバイオレーションが起こる逆アセ参考に命令およびデータを表す二つの状態を用ンブル結果を排除するべきである．
意し，各々において一命令または一バイトデー
ここで分岐命令の先頭と解釈できる入力バイタを出力するモデルを利用する．次にいくつかト値を xi ，その宛先を xj とした場合に，入力系の記号を定義する．
列 X に存在する {i, j} の集合を BX とすると，• N : 入力バイト数．
入力バイト列 X を出力し，ブランチバイオレー• X = xN
1 : 入力バイト系列．
ションを全く起こさない確率は• T = tN
1 : HMM の状態系列．
• S = {I, I 0 , D}: ti がとりうる値の集合 S． P (X, ∀{i, j} ∈ BX (ti 6= I or tj = I)|Mθ )= P (X|Mθ )P (∀{i, j} ∈ BX (ti 6= I or tj = I)|X, Mθ )I は命令の先頭，I 0 は命令の 2 バイト目以降，D はデータを表す．と表現できる．しかし，これを直接算出する• Mθ : パラメータ θ を持つ HMMには全ての分岐を展開する必要があり，その展逆アセンブルに関する研究では，Viterbi アル開数は分岐のオーバーラップ数に応じて指数関ゴリズムにより argmax P (X, T |Mθ ) を求める
数的に増加するため，計算量の観点から困難でTことで，最も尤もらしい逆アセンブル結果を得ていた．一方，Forward アルゴリズムを用いる∑ことで，P (X|Mθ ) = all T P (X, T |Mθ ) を効率的に求めることも可能である．これは Mθ を一般的なコンパイラで学習しておくことで，入力バイト系列 X が与えられたときの Mθ の尤ある．そこで，「ある分岐命令がブランチバイオレーションを起こさない確率は，その他の分岐命令がブランチバイオレーションを起こさない確率と独立であり，分岐元の状態確率と分岐先1ヌルモデルと呼ばれる．ここでは P (X) = 2561 N とする．

の状態確率もまた独立である」と仮定する．これにより前式は以下のように近似することができる．
P (X|Mθ )P (∀{i, j} ∈ BX (ti 6= I or tj = I)|X, Mθ )≈ P (X|Mθ )∏P (ti 6= I or tj = I|X, Mθ ){i,j}∈BX≈ P (X|Mθ )∏{i,j}∈BX(1 − P (ti = I|X, Mθ )P (tj 6= I|X, Mθ ))ホスト OS
ホスト CPU
ホストメモリ仮想マシン
ゲスト OS
ゲスト CPU 数
ゲストメモリ

Windows XP SP3
Intel Xeon 2.66GHz
3GB
VMware Server 1.0.4
Windows XP SP1
1512MB

表 2: 実験環境

図 1 は，オリジナルコードの候補を抽出した
ここで出てくる P (ti |X, Mθ ) は Forward / Back後に，各候補に関してコンパイラ出力コードモward アルゴリズムにより求められる行列を用
デルとヌルモデルの尤度比を算出した結果であいることで容易に算出することができる．また
尤度比を求める際に必要となるヌルモデルに関る．各点はオリジナルコードの候補であり，全しては，全てのバイト値をデータとして解釈す
部で 230 程度の候補が抽出された．横軸はそのることで，ブランチバイオレーションは全く起こらないことになるため，最終的には以下の尤候補が抽出された時間（秒），縦軸はその候補度比をコンパイラ出力コードの判断基準とする．の尤度比の対数をとった値となっている．当該∏P (X|Mθ ) {i,j}∈B (1 − P (ti = I|X, Mθ )P (tj 6= I|X, Mθ )) 検体は起動した後に三回の再起動を繰り返すたXP (X)め，オリジナルコードの候補を表すマーカーをプロセス毎に変えている．図 1 において対数尤
具体的には上式が 1 より大きい場合にはコン度比が 0 を超えた点は，コンパイラ出力コードパイラが出力したコードとし，1 以下の場合はとして尤もらしいことを表している．
コンパイラが出力したコードではない，と判断
当該検体において最初に対数尤度比が 0 を超する．
えた候補は図 1 における (*1) であり，その領域を逆アセンブルした結果，ボットとしてのプロ
4 実験
本章では，研究用データセットCCC DATA- グラムコードが確認された．またその他の対数
set 2008のマルウェア検体を提案手法でアンパッ 尤度比が 0 を超える領域は，全て (*1) と同じくボットとしてのプログラムコードを持ち，対数キングした結果について述べる．
尤度比が 0 以下の領域は，全てアンパッキング
アプリケーション Firefox 3.0.1
処理中のルーチンであることも確認された．
コンパイラ Microsoft C++ Compiler
図 1 からは他にもいくつかの興味深い結果をVer. 15.00.21022.08
読み取れる．まず一番目のプロセス（PID=364H）
表 1: 学習用プログラムとコンパイル環境には，全くオリジナルコードが出現していないことが分かる．このマルウェアに用いられたパッ提案手法におけるコンパイラ出力コードとしカーによりパッキングされた実行ファイルは，デての尤度を算出するために必要な HMM のモデバッガによる追跡等を困難にするため，アンパッルパラメータに関しては，表 1 によって生成さ2キング前に一度再起動を行うプログラムに変更れた xul.dll のアセンブリコードを学習データされると考えられる．また二番目のプロセスでとし，命令状態における出力確率および状態遷オリジナルコードが出現した後に，再びプロセ移確率を算出した．またデータ状態における出スが再起動しているが，これはマルウェア自身力確率は，プログラムによって大きく異なると1がシステムディレクトリへコピーされ，そこか考え全シンボルに関して等確率 256 とした．
ら再起動されているためである．つまり一度目実験環境は表 2 の通りであり，マルウェアのの再起動はパッカーによりもたらされたもので検体をゲスト OS 上でアンパッキングした．
あり，二度目の再起動はアンパッキングされたマルウェアによりもたらされたものであること
2Firefox において最も大きな実行バイナリ (約 8.5MB)が分かる．その後，システムディレクトリ内でであり，学習データとして十分なサイズである．

1.00E+05

(*1)

6.68

6.61

6.57

6.54

6.52

6.11

5.94

5.61

5.43

5.26

4.89

4.62

4.41

3.97

1.02

0.99

0.97

0.95

0.90

0.48

0.40

0.38

0.37

0.35

0.34

0.28

0.27

-5.00E+04

0.17

0.00E+00
0.14

Logarithm of Likelihood Ratio

5.00E+04-1.00E+05-1.50E+05-2.00E+05-2.50E+05-3.00E+05-3.50E+05-4.00E+05
Time (sec)
PID=364h

PID=5C0h

PID=4F0h

PID=400h

図 1: オリジナルコード候補の対数尤度比
三番目のプロセスが起動し，さらにパッカーのドに基づくマルウェア分類の全自動化に大きく機能により四番目のプロセスが起動している． 貢献できるものと期待している．
実際，この四番目のプロセスではじめてボット
参考文献としての本来の活動が開始されていることも別[1] Cyber Clean Center, https://www.ccc.go.jp /re途確認できた．
port /200807 /0807monthly.html.

5

まとめ

本論文ではパッキングされた実行ファイルからオリジナルコードを自動的に抽出可能なアンパッキング手法を提案した．従来の OS のペー
ジフォールトハンドラを用いたアンパッキング手法では，TLB の実装が不十分な仮想マシン上で動作させることはできなかった．これに対し，提案手法では PTE に存在する XDbit を利用することで TLB への依存をなくし，その結果，仮想マシン上での動作を可能にした．また，従来技術では「書き込まれた後に実行された」領域をオリジナルコードとして抽出していたが，多重パッキングされた実行ファイルの場合，オリジナルコードではないアンパッキング中のコードが抽出されてしまう問題があった．これに対して
本論文では，得られたオリジナルコードの候補に関して，確率モデルによってコンパイラ出力コードの尤もらしさを算出し，オリジナルコードを特定できる新たなアンパッキング手法を提案した．本手法を利用することで，マルウェア
解析作業の簡略化はもとより，プログラムコー[2] Md. Enamul Karim, Andrew Walenstein, Arun
Lakhotia, Laxmi Parida, Malware phylogeny generation using permutations of code. European Research Journal of Computer Virology 1, 1-2 (Nov.
2005) 13–23.
[3] E. Carrera and G. Erdelyi, Digital Genome Mapping - Advanced Binary Malware Analysis, InProc. Virus Bulletin Conf., 2004, pp. 187–197.
[4] PEiD, http://peid.has.it/.
[5] OllyBonE, http://www.joestewart.org/ollybone/.
[6] Using IDA to deal with packed executables,
http://www.hex-rays.com/idapro/unpack pe/.
[7] D. Quist, V. Smith, Covert Debugging: Circumventing Software Armoring, Blackhat USA 2007 /Defcon 15, Las Vegas, NV.
[8] Min Gyung Kang, Pongsin Poosankam, Heng Yin,Renovo: a hidden code extractor for packed executables, In Proc. WORM ’07: Proceedings of the2007 ACM workshop on Recurring malcode, 2007,
pp. 46–53.
[9] VMware: Virtualization via Hypervisor, Virtual Machine & Server Consolidation - VMware,
http://www.vmware.com/.
[10] Tron: He Fights for the User Alan Bradley,
http://www.openrce.org/repositories/users/AlanBradley /Tron-TC8.pdf.
[11] 岩村誠, 伊藤光恭, 村岡洋一, 隠れマルコフモデルに基づく新規逆アセンブル手法, In Proceedings of the2008 IEICE General Conference.