Java プログラミングにおける Obfuscator利用のすすめ
Javaのコンパイラは、Javaバイトコードと呼ばれる、プラットフォームに依存しない仮想
CPU を想定したコード(マシン語)を出力します。実際にバイトコードをみてみると、アセンブラコードに良く似ています。このコードを、それぞれのプラットフォーム(UNIX,
Windows, Mac, etc)上で動く Java VM (バーチャルマシン)が実行します。
また、Javaはオブジェクト指向言語です。この事がどういうことかというと、Java
VMが、メモリ管理やガベージコレクション、クラスの継承、メソッドの動的結合(Dynamic Binding)を正しく行なえるように、バイトコードがオブジェクト指向による一連の操作をサポートしなくてはなりません。つまり、メソッドの型や戻り値や名前などといったシンボル情報がバイトコード自身に含まれていなくてはなりません。
これらの事が何を意味するかというと、リバースエンジニアリングが容易であるということです。リバースエンジニアリングが容易ということは、苦労して作ったアプリケーションのソースコードが、配付した
Javaバイトコード(.class, .jar)から簡単に再現できてしまうということです。
Javaの移植性の良さ、オブジェクト指向プログラミング、ネットワーク・サポートなどといった優れた要素が、逆にリバース・エンジニアリングに対して非常に脆弱な要因になってしまいました。
では、どう対処すれば良いのでしょうか?
それが、Obfuscatorの利用です。
実際にリバースエンジニアリングがどの程度容易かということと、Obfuscatorがどのように働くかをサンプルで説明します。
ツールは
逆コンパイラ(Decompiler)として Jad (mirror)を
Obfuscatorとして Neil's Obfuscator を使っています。
Javaの例として以下のような文字がフェードするプログラム。(Browserによっては動作しないかもしれませんが、Javaのソースコードがどう生成されるか理解してもらう事が本題なので許してね!)
まず、オリジナルのソースです。コードが汚いのは気にせずに(汚いのにも理由があります)、コメントやクラス名、メソッド名に注意して下さい。このソースからコンパイルによって Fade.class, Thoughts.class が生成されます。
このJavaバイトコードを、逆コンパイラである Jed にかけます。方法はいたって簡単
c:> jad Fade.class c:> jad Thoughts.class
と実行するだけです。するとFade.jad, Thoughts.jadが生成されます。Javaバイトコードをもとに逆コンパイルされた二つのファイルを覗いてみて下さい。コメントはありませんが、かなり整理されたソースに逆コンパイルされているのがわかりますか?オリジナルと比べたとき逆コンパイルされた方が見やすいかも知れませんね。このようにいとも簡単にソースコードが復元できてしまうのです。
そこで、登場するのがObfuscatorです。Obfuscatorも使い方は簡単です。(Obfuscatorの種類によって多少異なりますが)
c:> java -classpath classes.zip;Obfuscate.cpz Obfuscate m Fade obfus
ちょっと説明すると、java インタプリタを使って javac(javaコンパイラ)によってコンパイルされた Fade.class, Thoughts.class を実行するようなイメージです。しかし、実行はせずにObfuscatorによってObfuscateします。
java インタプリタに、-classpathオプションで Javaのクラス(classes.zip)やアプリケーションに使用したクラスとObfuscator(Obfuscate.cpz)を指定し、メインである Fade クラスを指定します。Obfuscate m は、ミディアムレベルで
Obfuscateすることを表します。この他にハイレベル(h)があるのですが、ベリファイアが通らなくなるのでアプレットでは使用できません。最後に指定した obfus は、Obfuscateされた Fade.class, Thoughts.class を保存するディレクトリーです。Obfuscatorを通すと、メインのクラス Fade が存在する Fade.class はそのままの名前ですが、Fade から利用されるものは zzzgb.class と変更されています。
今度は、Obfuscateされた Java バイトコードを同じように逆コンパイラにかけてみます。生成されたものが Fade.jad, zzzgb.jadです。Obfuscatorを通す前に比べてクラス名やメソッド名(一部コード)が理解しにくいものになっているのが分ると思います。
Obfuscatorは、逆コンパイルを防ぐものではありませんが、ソースコードを解読しにくくするという効果があります。また、無意味なコードによって逆コンパイラを惑わす効果も得られます。
最後に
Javaの逆コンパイラは、非常に優秀で日々改良されています。逆コンパイラを騙すには、それこそバイトコードを手作業で変更していかなくてはなりません。しかし、Obfuscatorの利用によって、最初のソース・コードよりも読みにくいものや非常に長いソースとなります。普通の人が理解しにくいようなコードになるだけでも非常に注目すべきことだと思います。コードを Crackする人(例えば、アプリケーションなどのデモ版にパッチを当てて製品と同様にしてしまうような人達)はどんな状態でもリバースエンジニアリングを試みます。Obfuscatorを利用して、ある程度 Javaバイトコードを複雑化して自分のプログラムを保護してみてはいかがでしょうか?
Javaの Obfuscator や逆コンパイラについて以下のサイトも参考にしてください。