AndroidアプリにProGuardを使う
先日行われたGoogle Developer Day 2010 Japan (GDD)にてAndroidアプリのコードのセキュリティ対策として、ProGuardなどのオブファスケーターツールでコードを難読化させる事と、License Verification Library (LVL)を使って起動権限を確認させる事を挙げていました。
2011/07/31追記: 「Androidアプリの不正使用対策」のまとめはこちら!
コンテンツを守りたい方は必読です!
2012/08/23追記 Androidアプリの改造ツールの詳細と手口について(違法コピー天国の現状報告)
ProGuardだけでは違法コピーを防げない現実がわかります!
LVLは兎も角として、オブファスケーターツールとしてProGuardを使ってコードを難読化させると共にアプリファイルの軽量化を図ってみる事にします。
なお、以下に記載されている内容は備忘録としてのものなので間違いが含まれている場合がありますので注意して下さい。
また、細かい設定についてのご質問はご遠慮下さい。
EclipseのAndroid開発用Plug-InであるADT 8.0.0からリリースビルド時に少しの設定を行うだけで簡単にProGuard連携ができる様になりました。
詳しくは Googleの開発者サイト を参照して下さい。 (2010/12/08 追加)
前提条件として、既にEclipse上でAndroidプロジェクトを作成して開発しているものとします。
但し、Android SDK Toolsは最新のv7が必要です。
OSはWindowsを前提にしますので、他の環境の場合は特に文字コードの部分は注意して下さい。
なお、公式Android開発者サイトのブログ(Proguard, Android, and the Licensing Server)を参考にしていますので、必要ファイルである以下の2ファイルはこのブログの中央辺りにあるリンクからダウンロードしてプロジェクトのルートディレクトリに置いて下さい。
- add-proguard-release.xml
- procfg.txt
0. ツールを用意する
Eclipseに Ant は入っていますが、今回はダウンロードし、場所に解凍しました。
ProGuard もダウンロードして適当な場所に解凍しておきます。
1. Androidプロジェクトをアップデート
始めに[Android SDK]/tools下にある「android」ツールでAndroidプロジェクトをアップデートします。
※アップデートと言っても、ファイルとディレクトリが追加されるだけです。Eclipseだけの開発に戻したい場合は、「プロジェクト」メニューから該当プロジェクトを「クリーン」した後にビルドし直せばOKです。
コマンドライン(Windowsの場合はコマンドプロンプト)で以下のコマンドを実行します。
android update project –path ./MyAndroidAppProject –target 4
※「–path ./MyAndroidAppProject」と「–target 4」の部分は適宜修正して下さい。
※ここではAndroid 1.6向けに「–target 4」と指定しています。
上記コマンドが成功するとプロジェクトのルートに以下のファイルが作成されます。
- build.properties
- build.xml
- default.properties
- local.properties
2. 設定ファイルの修正
「local.properties」をエディタで開き、以下の値を追加します。
※各値は適宜修正して下さい。
key.store=/Path/to/my/keystore/MyKeystore.ks
key.alias=myalias
proguard.dir=C:/proguard/lib
次に「build.xml」をエディタで開き、先頭を以下の値に置き換えます。
<?xml version=”1.0″ encoding=”UTF-8″?>
<!DOCTYPE project [
<!ENTITY add-proguard-release SYSTEM “add-proguard-release.xml”>
]>
次に以下の値を追加します。
※「MyProjectName」の値はプロジェクト名に書き換えて下さい。
<project name=”MyProjectName” default=”help”>
&add-proguard-release;
次に「default.properties」を開き、以下の部分を適当な値に直して下さい。
※アップデートの時にtargetを指定してもNGでした。
target=android-8
今回はAndroid1.6を使うので以下の様に修正しました。
target=android-4
3. 試しにビルドしてみる
ここで一度ビルドしてみます。
コマンドラインでカレントディレクトリをプロジェクトのルートに移動させ、以下のコマンドを実行します。
ant release
この時点で以下の様なエラーが出ている場合は、JDKのパス指定が出来ていない可能性があります。
Unable to locate tools.jar. Expected to find it in C:\Program Files\Java\jre6\lib\tools.jar
JDKのパスを簡易的に通すには同じコマンドラインで以下の様に指定します。
※JDKのパスは適宜修正の事。
set JAVA_HOME=C:\Program Files\Java\jdk1.6
JDKのパスが通っている場合、多分、文字化けしたエラーメッセージが大量に出ると思います。
これはコンパイル時の文字コードがasciiになっているからです。
文字コードを直すには、以下のようなメッセージを探し、どの設定ファイルを読み込んでいるのかを判断します。
[setup] Importing rules file: tools\ant\ant_rules_r3.xml
今回は「[Android SDK]/tools/ant/ant_rules_r3.xml」ファイルを読み込んでいる様なので、エディタで開き、「javac」タグを検索します。
<javac encoding=”ascii” target=”1.5″
debug=”true” extdirs=””
(省略)
>
encodingがasciiになっているので、環境に合わせて変更します。
今回はWindowsなので「SJIS」を指定します。同時に「includeAntRuntime=”false”」を追加します。
「debug」属性が「true」になっているので、適宜false、-g:noneに変更して下さい。
※「SJIS」よりも「Windows-31J」の方が良いかも知れません。
<javac includeAntRuntime=”false” encoding=”SJIS” target=”1.5″ debug=”-g:none” extdirs=””
(省略)
>
2010/10/06追加
ここで文字コードを指定したとしても、各種XMLファイル内のコメントに全角文字が含まれると以下のようなビルドエラーが出る事があります。この場合はコメント内に全角文字を使わないようにするしか回避方法は無いかも知れません。
ちなみに、化けている元の文字は「保存」です。
[javac] C:\eclipse\workspace\[プロジェクト名]\gen\[プロジェクトのパッケージ]\R.java:176: 警告:この文字は、エンコーディング SJIS にマップできません。
[javac] <string name=”save”>菫晏ュ?/string>
4. ProGuardの設定を変更する
先にダウンロードしてプロジェクトのルートに置いたProGuardの設定ファイル「procfg.txt」をエディタで開き、publicな独自クラスを保持する様に以下の様に記述を追加します。
※「* [my classname]」の部分は適宜修正して下さい。
※設定の詳細はProGuardのサイトなどを参考にしてみて下さい。
-keep public class * [my classname]
「AndroidManifest.xml」に記載されているActivityクラスの名前が保持されていないと実行時にエラーになることがありますので、ここの設定は慎重に行って下さい。
以下の様にすると「com.skyarts.android」パッケージ以下のサブパッケージも含むpublicクラス名が保持されます。
-keep public class com.skyarts.android.*
[プロジェクト名]/obf 下にProGuardが処理したファイル一式が出力されます。
「mapping.txt」を見ればどのようにクラス名、メソッド名、変数名が変更されたかがわかると思います。
または処理後のJARファイルである「postobf.jar」を解凍して中身を見ればファイル名の状態がわかると思います。
5. ビルド
コマンドラインにて以下のコマンドを実行してビルドします。
ant release
ソースにエラーなどが無い場合はProGuardが実行され、最後にキーストアのパスワードとaliasのパスワードを聞かれるので入力します。
「BUILD SUCCESSFUL」が表示されてビルドが成功したならば、「プロジェクト/bin」下にアプリのファイル(apk)が3つ出来上がっているはずです。
- [プロジェクト名]-release.apk
- [プロジェクト名]-unaligned.apk
- [プロジェクト名]-unsigned.apk
Android Marketに置くには「[プロジェクト名]-release.apk」を「zipalign」ツールで処理すれば大丈夫だと思います。
実機にインストールするには、「adb install」コマンドを使用してインストールして下さい。
クリアしたい場合は以下のコマンドを使用します。
ant clean
6. 外部ライブラリの設定
2010/10/07追加
広告ライブラリなどのアプリファイルに含む必要のある外部ライブラリを使用する場合、各プロジェクトディレクトリ下にある「libs」ディレクトリに外部ライブラリのJARファイルなどを置くだけです。
勝手にJARファイルなどを一度解凍し、ビルドしてくれます。
注意点としては、Javaコード以外の設定ファイルなどで外部ライブラリ内のクラスを指定している場合はProGuardの設定に加えて名前を変更させられないようにしておく必要がある事です。
もし、「[プロジェクト名]/libs」ディレクトリに置くのは嫌だ!という場合は「[Android SDK]/tools/ant/ant_rules_r3.xml」ファイルなどに記載されている外部ライブラリの扱いに関する設定を変更して下さい。
7. 終わり
以上でAndroidアプリにProGuardを使う説明は終わりです。
サイズ削減の効果としては、300KB超のアプリが2割位削減できました!!
容量の多い端末が増えた現在では余り意味のないことかも知れませんが、簡単にアプリファイルを引き抜けるAndroid端末だからこそ、最低限の抵抗として難読化を検討してみては如何でしょうか?
今後、色々な配布サイトも出てくることも考えられ、ファイルの保護がされない場合にも知的所有物を守る上で難読化は有効かも知れません。
なお、ProGuardを使うと変数名、メソッド名などが1、2文字位に置き換わるため、エラーが発生した時に判断が難しくなりますので、最後のテストを行う位の時に使用するのが良いかも知れません。
間違いなどがありましたならば、ご連絡下さい。