レビュー
2003/06/30 00:00:00 更新
.NETの知られざる脅威
「Dotfuscator」による難読化の威力を試してみる
エージーテックの難読化ツール「Dotfuscator」を使用してみよう。実際に画面を見ることで、難読化処理がどのようなものか理解できる。米PreEmptive Solutionsが特許を持つ Overload Inductionによって、クラス名、メソッド名、オブジェクト名などが、「a」や「b」といった単純な名前に置き換えられている。
GUIから「Dotfuscator」を使用してみよう
Dotfuscatorは、コマンドラインまたはGUIから使用するようになっている。細かいオプション指定などを行う際には、コマンドラインからの方が使いやすいが、Visual Studio .NET 2003(VS .NET)から使う場合は、[ツール]メニューからGUIを呼び出して使うことになる。GUIはWindowsの[スタート]メニューから呼び出して、VS .NETと独立させて使用することも可能だ。
DotfuscatorのGUI画面を立ち上げると、プロジェクトの新規作成または既存のプロジェクトを選ぶ画面となる(画面1)。ここで[プロジェクトを作成]または[開く]を選択しよう。
新規にプロジェクトを作成した場合、最低限設定しなければならないのは次の2つだ。まずは、「トリガ」タブに難読化をしたいexeファイルやdllファイルを「トリガファイル」として追加(画面2)。次に「ビルド」タブ内で「出力先ディレクトリ」を指定する(画面3)。この2つを指定したら、「ビルド」タブ内の「ビルド」ボタンをクリックするだけである。
Professional Editionを使用するに当たっては、「文字列の暗号化」タブや「除去」タブ内の設定はデフォルトで無効となっているので、必要に応じて設定する。「名前の変更」タブ(Overload Inductionを指定するところ)と「制御フロー」タブはデフォルトで有効になるようになっているうえ、クラスのツリー表示が「除外」するものを指定するようになっている。それに対し、「文字列の暗号化」と「除去」タブでは「対象」を選択するようになっており、逆の意味になっているので注意が必要だ。
難読化処理を行うと、どうなる?
では、実際に難読化を行うとどうなるかについて見てみよう。DotfuscatorのProfessional Editionに付属している「HelloWorld.cs」(リスト1)を難読化の前後で比較してみたい。
using System; namespace HelloWorld { public class Hello { public static void Main( string[] args ) { Converse( "Alice", "Bob" ); } private static void Converse( string name1, string name2 ) { Friendly friend1 = new Friendly( name1 ); Friendly friend2 = new Friendly( name2 ); friend1.SayHello(); friend2.SayHello(); friend1.SayGoodbye( friend2.Name ); friend2.SayGoodbye( friend1.Name ); } } class Friendly { private string myName; public Friendly( string name ) { myName = name; } public void SayHello() { Console.WriteLine( "Hello, my name is {0}", myName ); } public void SayGoodbye( string othername) { Console.WriteLine( "Goodbye {0}", othername ); } public string Name { get { return myName; } set { value = myName; } } } } |
まず、C#でコンパイルした直後のexeファイルをメモ帳で開いてみる(画面4)。クラス名の「Hello」や「Friendly」であるとか、メソッド名の「Converse」、「SayHello」、「SayGoodby」など、また「MyName」といったオブジェクト名がそのまま読み取れることが分かる。さらに、「Alice」や「Bob」、「Hello, my name is [0]」といった文字列の値そのものも、単純にexeの中に埋め込まれていることが分かるだろう。
では、難読化後はどうなるのだろうか。難読化後のexeファイルをメモ帳で開いてみると(画面5)、難読化前では丸見えであったクラス名、メソッド名、オブジェクト名が見事に消えている。
代わりに「a」や「b」、または「A_0」、「A_1」が増えている。これがオーバーロード誘導の結果だ。オーバーロード誘導は、クラス名やメソッド名、オブジェクト名などを、プログラマの命名した人間にとって分かりやすい名前から、aやbといった単純な名前に置き換えてしまう。特許にもなっているOverload Inductionが優れるのは、同じ「a」という名前をできるだけ使い回すというところにある。
例えばあるクラスFriendlyにSayHello()というメソッドがあった場合、「a.a()」というように置き換えられるのだ。こうなると、リバースエンジニアリングを行う側にとっては、なんのことか分からなくなる。Overload Inductionの副産物として、名前が短くなることで、exeファイルそのもののファイルサイズが小さくなるという利点もある。exeファイルの読み込みが高速化され、実行パフォーマンスの向上につながる。
また、文字列の値であった「Alice」や「Bob」、「Hello, my name is [0]」などがなくなっていることにも気づくだろう。これは「文字列の暗号化」の結果である。暗号化されたことで、プログラム中に書かれた文字列定数の値が判読できなくなっているのである。
多くのプログラムには、例えばSQL文などが文字列定数として書かれている。これら文字列定数はexeファイル中にそのまま現れてしまうため、どのようなデータベース処理をしているかが、そのまま分かってしまう。Dotfuscatorでは、これらを暗号化してしまうことでリバースエンジニアリングに対抗している。
Overload Inductionで、元の名前がどのように置き換わったかは、Dotfuscatorの「出力」タブ(画面6)で確認することができる。
このように、Dotfuscatorではリバースエンジニアリングの際に重要な手がかりとなる情報を隠蔽し、リバースエンジニアリングにかかるコストを大幅に増大させている。ご覧いただいたように、.NET Framework上で動作するプログラムは、メモ帳で見ただけで名前などがそのまま分かってしまう。それはつまりリバースエンジニアリングの敷居が低いということなのだ。
インタビューにも出てきたが、パッケージ製品を何の対処もしないまま出荷した場合、ノウハウの流出や著作権の侵害につながる重大な問題になる可能性が大きい。また、社内アプリケーションであっても、「Password」という変数名が丸見えで、さらに文字列定数で記述されているパスワードがあったとすると、システムのセキュリティを保つことが難しくなる。そうした意味で、Dotfuscatorを使えば、リバースエンジニアリングの敷居を高くし、安心して製品出荷ができ、安心してソフトウェアを使用できるようになるだろう。
関連記事あなたの開発した.NETソフトウェアは、リバースエンジニアリングの脅威が存在する
Interview:「難読化せずに.NET向けパッケージを出してはいけない」エージーテック鈴木氏
Windows.NETチャンネル
関連リンク
エージーテック
[宮内さとる,ITmedia]
Copyright © ITmedia, Inc. All Rights Reserved.