Proguard, Android, and the Licensing Server

Proguard, Android と ライセンシングサーバについて

Posted by Tim Bray on 21 September 2010 at 4:05 PM

[This post is by Dan Galpin, an Android Developer Advocate specializing in games and comics. — Tim Bray]

Tim Brayより。この記事は自称ゲーム&コミック専門家のDan Galpinによるものです。

The Securing Android LVL Applications blog post makes it clear that an Android developer should use an obfuscation tool such as Proguard in order to help safeguard their applications when using License Server. Of course, this does present another question. How should one integrate such a tool with the Android build process? We’re specifically going to detail integrating Proguard in this post.

記事「LVLを使ったAndroidアプリをセキュアにしてみる」では、Androidアプリ開発者はライセンシングサーバを使う際にProguardなどの難読化ツールをアプリの保護手段の一助として使うべきだと書きました。もちろん、そういったツールをアプリのビルド手段にどうやって組み込むのかという問題が出てきます。この記事ではそれを明らかにしていきましょう。

Before you Begin

手を付ける前に

You must be running the latest version of the Android SDK Tools (at least v7). The new Ant build rules file included with v7 contains hooks to support user-created pre and post compile steps in order to make it easier to integrate tools such as Proguard into an Android build. It also integrates a single rules file for building against all versions of the Android SDK.

まず最新のAndroid SDK Toolsが必要です(v7以降)。v7に同梱されたAntビルド定義ファイルには、コンパイル前段階・後段階にProguardなどのユーザ定義ステップを挿入するためのフックが含まれています。これは今までの各バージョンのAndroid SDK向けのビルド定義ファイルも統合しています。

Adding an Optimization Step to build.xml

build.xmlに最適化用の定義を追記してみる

First, you’ll have to get Proguard if you don’t yet have it.

まだProguardを入手していないなら、手に入れておいてください。

If you’ve been using Eclipse to do your development, you’ll have to switch to using the command line. Android builds are done using Apache Ant. A version of Ant ships along with Eclipse, but I recommend installing your own version.

開発にEclipseを使用してきた方は、コマンドラインへの移行が必要です。AndroidアプリのビルドはAntを使用しますが、Eclipseに同梱されたものとは別口でAntをインストールしておいたほうがいいですよ。

The Android SDK can build you a starter build.xml file. Here is how it’s done:

Android SDKはbuild.xmlの雛形を生成できます。やってみましょう。

 android update project --path ./MyAndroidAppProject

If all works well, you’ll have a shiny new build.xml file sitting in your path. Let’s try doing a build.

うまくいったなら、新しいピカピカのbuild.xmlがあなたのアプリのプロジェクトフォルダに作成されているはずです。ではビルドに進んでみましょう。

ant release

antによるリリース

You should end up with an unsigned release build. The command-line tools can also sign your build for you. You’ll notice that the android tool created a local.properties file in your directory. It will contain the sdk.dir property. You can have it make you a signed build by adding the location of your keystore and alias to this file.

まず、署名なしのリリースビルドなapkを作成します。署名はコマンドラインツールでも可能です。先程実行したAndroid Toolがあなたのプロジェクトフォルダに、build.xmlと一緒にlocal.propertiesファイルを作成しているのにお気づきでしょうか。このファイルの内容にはsdk.dir値が含まれているはずです。このファイルにあなたのkeystoreファイルへのpathとkeystore内のエイリアス名を追記することで、証明済みビルドが作成できるようになります。

key.store=/Path/to/my/keystore/MyKeystore.ks

key.alias=myalias

So, now you have a signed build from the command line, but still no obfuscated build. To make things easy, you’re going to want to get two helper files: add-proguard-release.xml and procfg.txt.

これでコマンドラインから署名済みビルドが作成できるようになりましたが、このビルドは難読化がされていません。もっと簡単にするため、2つのヘルパファイルが必要となるでしょう。add-proguard-release.xml と procfg.txt です。

Copy these files into your root directory (where the build.xml file sits). To add Proguard to your build, you first need to edit your local properties file to add the location of the directory that Proguard is installed in:

このファイル達をあなたのプロジェクトフォルダのrootにコピーしてください(先程のbuild.xmlが存在しているフォルダです)。あなたのビルド手順にProguardを追加するには、local.propertiesファイルにproguardのインストール先を追記する必要があります。

proguard.dir=/Directory/Proguard/Is/Installed/In

Finally... you need to add our script to your build file and have it override a few targets. To do this, we use the XML “entity” construct. At the top of your build.xml file, add an entity that references our script file:

最後に、私たちが提供するスクリプトをbuild.xmlに追加して、いくつかのターゲットを上書きするようにします。XMLのentity構造体を使います。build.xmlの最初に、私たちが提供するスクリプトへの参照を記述したentityを追加します。

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE project [

       <!ENTITY add-proguard-release SYSTEM "add-proguard-release.xml">

]>

You’re not done yet. Somewhere within the project tag add the reference to our entity to include our script.

っと、まだ手順がありました。私たちが提供するスクリプトをインクルードするため、<project>タグ内に先程のentityへの参照を追加してください。

<project name="MyProjectName" default="help">

&add-proguard-release;

That’s it! In many cases, calling

これでOKです。殆どの場合では以下のコマンド

ant release

Will give you an obfuscated build. Now test and make sure that it hasn’t broken anything.

で難読化されたビルドが生成されます。実際に試して、この手順が何も壊していないことを確かめてください。

But Wait, My App is Crashing Now

でもまって、こっちのアプリじゃクラッシュしちゃうんだけど。

Most crashes happen because Proguard has obfuscated away something that your application needs, such as a class that is referenced in the AndroidManifest or within a layout, or perhaps something called from JNI or reflection. The Proguard configuration provided here tries to avoid obfuscating most of these cases, but it’s still possible that in edge cases you’ll end up seeing something like a ClassNotFoundException.

大抵の場合、あなたのアプリが要求している物(AndroidManifestやLayoutで参照しているclassや、JNIやリフレクションで参照しているものなど)を、Proguardが難読化してしまっていることが原因です。大体は以下の例のようなProguardの設定で難読化から除外を試みますが、複雑な使用例の場合にはClassNotFoundExceptionの発生が避けられない場合もあります

You can make edits to the procfg.txt file to keep classes that have been obfuscated away. Adding:

procfg.txtを編集することで難読化から除外するclassを指定できます。以下の追記が助けになるでしょう。

-keep public class * [my classname]

should help. For more information about how to prevent Proguard from obfuscating specific things, see the Proguard manual. Specifically, the keep section. In the interest of security, try to keep as little of your application unobfuscated as possible.

難読化の除外設定の詳細についてはProgardのマニュアルを参照してください。特に除外設定については参照したほうが良いでしょう。セキュリティが気になる場合は、除外設定の範囲をできるだけ小さくとどめてください。

The standard settings provided in procfg.txt will be good for many applications, and will catch many common cases, but they are by no means comprehensive. One of the things that we’ve done is had Proguard create a bunch of output files in the obf directory to help you debug these problems.

procfg.txtに記述された標準設定は大体の適用例にとって妥当かつ、想定される数多くの場面をカバーするものですが、以上が全てというわけではありません。ここまで試してきた物事のうち、例えばProguardがあなたのプロジェクトフォルダ内のobfフォルダに出力した、上記の問題をデバッグするためのファイル群があります。

The mapping.txt file explains how your classes have been obfuscated. You’ll want to make sure to keep this around once you have submitted your build to Market, as you’ll need this to decipher your stack traces.

このフォルダに難読化した際のログとしてmapping.txtが存在しています。アプリをマーケットに公開したあとも、クラッシュが報告された際のスタックトレースを解析するためにこのmapping.txtが必要になります。

Conclusion

結論

Tools such as Proguard make the binary of your application harder to understand, and make your application slightly smaller and more efficient at the same time, at the cost of making it slightly more challenging to debug problems in the field. For many applications, the tradeoff is more than worthwhile.

Proguardなどのツール群はあなたのアプリへの解析を難しくしたり、サイズのコンパクト化にわずかながら寄与したり、実行速度を向上させると共に、リリース後のデバッグが少し手間のかかる・興味深いものとなります。多くのアプリでは、このトレードオフは価値のあるものです。