APKの難読化
Androidアプリはapkというファイル形式ですが、これはzipファイルの拡張子をapkに変えただけなので解凍して中身を見ればソースコード自体が簡単に手に入ってしまいます。
そこでAPKを作るときにeclipseのProGuard機能を使います。
難読化の準備
まず難読化したいプロジェクトのフォルダに次のようなproject.propertyファイルがあると思います。
そのファイルをクリックして中身を見ると次の行がコメントアウトされています。
#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
なので次のように#を外してプロガードが有効になるようにします。
proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
難読化の実行と効果
難読化を施したapkファイルを作るにはプロジェクト上で右クリックしてその中のメニューから「Android Tools」を選び、さらにその中の「Export Signed Application Package」を選択します。
もしapkに電子署名していなかったら先にapkに電子署名をする必要があります。電子署名済みなら画面の指示に従っていくと難読化されたapkが完成します。
難読化していないapkとしたapkの2つを比べると確かにプロガードしたほうが読みにくくなっていることが分かります。
注意
簡単に難読化できるProGuardですが難読化してはいけないクラスでメソッド名も存在します。以下は難読化しているとアプリが止まってエラーになってしまう代表的なクラスとメソッドの例です。
- AndroidManifest.xmlに直接名前が書かれたActivityやServiceやBroadcastReceiverクラス
- レイアウトファイルからonClickなどで呼ばれるメソッド名
- レイアウト上に設置したカスタムビュー
- WebViewなどでjavascriptから呼ばれるjavaのメソッド名
- JNI(Java Native Interface)
- リフレクションから呼ばれるメソッド
これらを難読化させたくない場合は次のようにproguard.txt(もしなければproguard.cfg)ファイルでkeepオプションの後に難読化しないクラスをパッケージ名で記述します。
proguard.txt(またはproguard.cfg)-keep class com.MyApp.myapp.MyClass { *; }
これでMyClassというクラス自身とその中のすべてのメソッド名は難読化されないようにすることができます。
もしクラス名だけを難読化の対象から外したい場合は次のように書きます。
-keep class com.MyApp.myapp.MyClass
また、クラス名にcom.MyApp.myapp.*のような名前を渡すとcom.MyApp.myappというパッケージに属する全てのクラス名が難読化されないことになります。
最後にこのブログなども参考にするとproguard-project.txtは最低でも次のように設定しておいた方が良いみたいです。
-keep public class * extends android.app.Activity{ public void *(android.view.View); } -keep public class * extends android.app.Service{ } -keep public class * extends android.content.BroadcastReceiver{ } -keep class * implements android.os.Parcelable { public static final android.os.Parcelable$Creator *; } -keep public class * extends android.view.View { public <init>(android.content.Context); public <init>(android.content.Context, android.util.AttributeSet); public <init>(android.content.Context, android.util.AttributeSet, int); public void set*(...); } -keep public class **.R
これは全ての場合に当てはまるわけではないので難読化するべきでないクラスを見つけたらすぐに難読化を解除してください。
keepオプションのさらに詳しい使い方についてはProGuardの公式マニュアルを参考にしてください。