というわけで、ロシア人にクラックされて頭にきたので、DexGuardを導入しました。
DexGuard
http://www.saikoa.com/dexguard
DexGuardというのは、Android開発者にはお馴染みのProGuardの有償版で、Androidに特化した上で色々と機能が拡充されているものです。350EUR=五万円とそれなりのお値段がするのですが、解説記事が少ないので、導入記を書いてみたいと思います。
まず、購入
先ほどのページの一番下に価格表があります。
私は日本人の個人開発者なので、「Private customer outside EU (tax-free), 1 developer license, 350 € 」を選んで、「Buy Now」を押します。決済はPayPalのみ。支払いが終わると、ダウンロードページへの案内とパスワードがメールで届きます。
ライセンスは、「一回支払えば永久に利用権有り、ただし、バージョンアップのダウンロードは購入から一年間のみ、それ以降は半額/年でバージョンアップのダウンロードが可能」というものです。現状でも完成度が低いわけではないので、妥当な線と思われます。
DexGuardは、Eclipse,Ant,Gradle,Maven,手動起動をサポートしています。なので、よほど特殊な環境でもなければ、普通のAndroid開発で導入に困ることはないと思います。
Eclipseの場合、jarファイル一個をdropinフォルダにコピーするだけで、インストールは終わりです。あとは、サンプルで入っているdexguard-project.txtという設定ファイルを各プロジェクトにコピーするだけ。んで、Eclipseを再起動します。(認識されない場合は、Eclipse -cleanで)
DexGuarが有効になると、Androidツールのメニューに、「Export Optimized and Obfuscated Application Package...(DexGuard)」という項目が加わります。「署名アプリケーション…」の代わりにこちらを使うと、リリースビルドが出来るようになります。
DexGuardは、ProGuardと違い「Convert to Dalvik」「Obfuscate」「Packaging」「signing」を一括で行います。(ProGuardはObfuscateのフェーズのみ)
次に機能
本家saikoaの比較ページ。
http://www.saikoa.com/comparison_proguard_dexguard
実質これだけしか解説がないというのは、正直考え物です。
ここでは、ProGuardにない機能を説明していきます。
String Excryption
Staticな文字列を難読化します。
こんなコードを
String s = "hogehoge";
↓
String s = Encrypt.decode(new byte[]{x,x,x,x,x,x...})";
みたいな感じに変換します。
これによって、プログラム中の可読文字列を不可読なデータに変換します。
Class Encryption
変換後のコードを読んだわけではないのですが、dexコード自体を難読化するようです。
ライセンスチェック等のセンシティブな処理を暗号化すると良いとのこと。
Reflection
指定したクラス・メソッドの呼出を、リフレクションを使って処理するように変換します。
こうすると、ぱっと見ではどのAPIを呼び出しているか判別できなくなります。
もちろんリフレクションでは呼出クラス名を文字列で埋め込む必要があるので、String Encryptionとの合わせ技が必要です。
Assets Encryption
Resource XML obfuscation
assets/res配下のファイル名・内容を難読化してくれるようです。
Tamper Detection
改変検知用のライブラリが提供されていて、パッケージに改変があった場合の検出が出来るようになっています。
難読化の辞書
dexのシンボルにはUnicode文字が使えるので、各種言語で「・」のような単純なシンボルをかき集めた難読化辞書が付いてきます。
ただし、機械的に一括変換かけて読みやすい文字シンボルに再変換することも出来るので、これ自体が解析の難易度を上げるわけではありません。
nul,aux,con,lptなどのWindowsのファイルシステムで使えない単語も入っています。
パッケージのフラット化
AndroidManifest.xmlでexportされているパッケージだけは、パッケージ構造に従ったクラス名が付けられますが、それ以外のファイルは全て、o.hogeのようなフラットなパッケージ名に変更されます。また、exportされていないクラス名も難読化の対象になります。
スタックトレースの難読化
ProGuardでは、デバッグ情報を残すために、ファイル名と行番号の情報を出す様にしていました。これがあるとクラッシュレポートを読むのが非常に容易になるのですが、反面、攻撃者に対してヒントを与えることになる、というのが悩みどころでした。
(ファイル名と行番号を消すと今度はどこで落ちたか分からなくなる)
DexGuardでは、埋め込むファイル名が全て「SourceFile」という固定ファイル名になります。これによって、行番号を残しながらソースファイル名を秘匿することが出来るようになりました。
スタックトレースとビルド時に生成されるマップファイルを付属のretraceツールにかければシンボル名が復元できるので、デバッグにも支障は出ません。
ネイティブライブラリの難読化
ネイティブライブラリのシンボル名も難読化してくれるとのこと。
ログの無効化
Logcatの呼出を全て削ってくれます。ログ表示文字列と一緒に。
サンプル
AdMob,AmazonIAP,Google PlayのIAP,ライセンス、などの実践的なサンプルが付いてきます。
導入する時は
まず、ProGuard用のアプリ個別設定のインポートが必要です。
次は、マニュアル/サンプルを読みつつ設定項目を追加→ビルド→実機で動作確認→マップファイルの内容を確認→apktoolでリバースして内容を確認→最初に戻る、のループを回しつつ設定を追い込んでいきましょう。
使ってみてどうよ
とりあえず、apktoolがデコード時にクラッシュします。
これだけでも、値段分の価値はあると思います。
いくつか盛り込んで欲しいネタもあるので、開発側にフィードバックかける予定です。
お薦めできない人
あえて書いておきます。以下に当てはまる人は手を出すのはやめましょう。
・マネタイズできてない人
・不正コピーされてない人
・ProGuardが分からない人
・英語が読めない人
ワンクリックでプロテクトをかけてくれるような銀の弾丸ではありません。
また、DexGuardだけでは防げない攻撃も多々ありますので、攻撃者の手口を良く研究し対処していく必要があります。
最後に
海賊行為をする輩にこの言葉を届けます。
「くたばれ」