ぼくのかんがえたcrackme パート2 [日記]
Java は、その性質上、逆コンパイルが優秀で、かなり精度の高いソースコードが復元できてしまいます。
そのため、シリアルキーを入力することで各種機能制限が解除されるタイプのソフトウェアを、シリアルキーなしで使用できるように改造する行為(クラック)も比較的簡単に出来てしまいます。
逆コンパイルしたソースコードを分かりづらくする難読化という処理もありますが、クラック対策としては、どの程度効力があるのか結構疑問です。
そんなわけで、別のアプローチを取ることにします。
とりあえず、こんなプログラムを作ってみました。
(実行には、Javaの実行環境(Java6 SE 以降)が必要です)
足し算と掛け算をするプログラムですが、シリアルキーを入力しないと掛け算が出来ません。
ちなみに、シリアルキーは 「AbC」です。
一応 crackme となっているので、逆コンパイルをするなりして、シリアルキーを見つけたり、シリアルキーなしで掛け算が出来るように改造するなりしてみても良いですが、徒労に終わることでしょう。
creckmeと言っておきながらクラックできない反則プログラムです。解けないパズルと同じですね。
仕組みですが、
シリアルキーを秘密鍵として掛け算部分のバイトコードを暗号化しています。
(暗号そのものがが解読されない限り)シリアルキー不要改造を行うことは不可能です。
シリアルキーについての情報もコード中には欠片も存在しない(シリアルキーが正しいかどうかは復号した結果がバイトコードとして正当かどうかで判断している)ので、シリアルキーをコード中から知ることを出来ません。
もっとも、この方法は、「固定のシリアルキー」を入力することで「制限されている機能」が使えるようになるタイプのものにしか適用できないので万能ではありませんし、シリアルキーさえ知っていれば復号は可能なので機密の秘匿(難読化の本来の目的)にも使えません。
自分のアプリにも適用してみたいと言う人のために、先のcrackmeのソースコードを含む開発環境一式を公開。
(ソースコードのビルドには、Antが必要です)
中身を見たら分かると思いますが、一応、解説。
-
暗号化したいクラス(サンプルでの
secret.XImp
クラス)を用意する。
暗号化はクラス単位で行うので、暗号化する機能としない機能は分離させる必要はある。中身は普通に実装する。
-
暗号化するクラスの public なメソッドを全て定義したインターフェース(サンプルでの
secret.X
インターフェース)を作り、暗号化するクラスに適用する。
暗号化するクラスの全ての public メソッドは、インターフェースの実装メソッドになる。 -
SecretClassLoader
クラスを使って、暗号化クラスをインスタンス化し、各種機能を呼び出す。(詳細はサンプルのgui.MainFrame
を参照) -
ビルド方法は、Ant の設定ファイル build.xml を参照。
大抵の場合、設定をちょっと変えて、そのままAntを実行すればOK。
クラス毎にファイルが出来るというJavaの性質のお蔭で、実現は物凄く簡単でした。
ただ、それでも、わざわざインターフェースを作らなければいけないとか、インスタンス化には new
演算子は使えず Class#newInstance()
を使わなければいけないとか、まだまだ面倒なところはあります。
インターフェースについては自動化できそうです。
後は new
演算子の方か……。
new
演算子を使ったときに使用されるクラスローダを自前のクラスローダ(この場合 SecretClassLoader
)に切り替えられれば良いんだけど……。(この話は続く)
コメント 0