2011年12月18日日曜日

え、まさか難読化の為にわざわざproguard.cfgをいじってるんですか?

このエントリーをブックマークに追加 このエントリーを含むはてなブックマーク

photo by http://www.flickr.com/photos/jonnygoldstein/

Android Advent Calendar 2011 12/18(日)担当の@sys1yagiです。

いきなりですがproguard.cfgをいじるのってクソめんどくせーわけですよ。何が悲しくてあんな意味不明なオプションの文法を毎回ググりながらsitと言いながら書かないといけないのか。ていうか複数人でやってたらproguard.cfgをいじるタイミングがさー色々面倒でもう最後にぱっと追加するかーとか皆思っちゃってて最後にカオスになったりして\(^o^)/とかさ、もっと簡単な方法はねーのかよ!?例えばアノテーションでさー、クラスのとこに書いたらさー、難読化されないとかさ。

あるでー


はい、ProguardがそもそもAnnotation用のライブラリを提供しています。これを使えば難読化の対象外にしたいクラスに所定のアノテーションを書くだけで難読化から逃れられます。普通にProguardが提供している機能なので、全くトリッキーな事なしでいけます。ちょっと副作用がありますが


導入の準備


ProguardはオープンソースでSoruceForgeで公開されています。
アノテーションによる難読化の回避はこのSourceForgeで配布されているアーカイブに含まれているライブラリを利用します。ダウンロードページからproguard4.6.zipをダウンロードして下さい(多分4.6じゃなくてもいけると思いますが)。
http://sourceforge.net/projects/proguard/files/



導入


proguard4.6.zipを展開し、proguard4.6/examples/annotations/lib/に入っているannotations.jarannotations.proをAndroidプロジェクトにコピーして下さい。annotations.jarはビルドバスを通しておきます。今回はproject/libsに置きました。


するとアノテーションで@Keepとか書けるようになります。


次にプロジェクト直下あたりのproguard.cfgの先頭辺りに以下の二行を記述します
-dontshrink
-include libs/annotations.pro
annotations.proはproguard.cfgと拡張子は異なりますが中身は大体同じです難読化についてのオプションが記述されています。-dontshrinkは書かないと何故かアノテーションが消えるので書きます。すかさず-keepattributes **を思いついたあなたはやっぱり凄い!ですがこのオプション書いてもダメでした。四の五の言わずに書いて下さいませね。

これだけでおk


実行


あとはProguardにかけるだけ。そういやAntで直接Proguardやれば-dontshrinkはいらないかもしれません。ここではEclipseのAndroid Toolsで"Export Signed Application Package ..."とかやっています。
難読化実施後のクラス構成


見事@KeepをつけたDonotObfuscationクラスが難読化されていません。
メソッドはどうでしょう。javapしてみます。


@KeepNameのついたnotObfuscation()は難読化されていませんね。obfuscation()の方は難読化されている事がわかります。
Keep以外にも色々なアノテーションがあります。色々使えそうですね。


副作用


良い事ばかりじゃもちろんありません。ちょっと副作用がありますんで注意して下さい。


不要クラスが残る


-dontshrinkは利用していないクラスなどの削除を行なってバイナリサイズを小さくしてくれる処理を禁止します。つまりProguardにかけた対象となるクラスが難読化後全て残ります。物によってはapkサイズがでかくなってしまいます。ただ、ほぼ気にしなくてもいいレベルだと思います。精々数KBの違いでしょう。これなら他のリソースの容量削った方が効率的だと思います。


何を難読化したくないかが一覧できない


proguard.cfgにKeepオプションなどを書く場合は全部書かれているので一覧性がありますが、アノテーションの場合はソースに個別に書くのでどのクラスが難読化したくないかについて分かりにくくなります。まーKeepとかでソース検索すりゃいいしどーでもいい気もしますがー


そういえば


annotations.proの中身を見てみるとこんな感じです。

-keep @proguard.annotation.Keep class *

-keepclassmembers class * {
    @proguard.annotation.Keep *;
}

つまりふつーにProguardのKeepの条件に「指定のアノテーションがある場合難読化しねーぜ」、と設定してるだけです、つまり別にProguardの提供しているannotations.jarを使わなくても自分で適当にアノテーションを定義して、annotation.proみたいなのを書いてincludeするかProguard.cfgに書くだけでいけるわけです。つまりそういう事です。


結論


皆楽になるといいですねー。
メリークリスマスー
明日は@patorash@Nkznさんです。わーい。

2 件のコメント:

  1. 検索でたどり着きました。こちらの情報には大変お世話になりました。
    ありがとうございます。

    自分もdontshrinkの件でかなり苦労したのですが、
    どうやら、annotations.jar自身が難読化されてしまい、変な動きになっているようです。
    proguard.cfgにannotations.jarの中身をkeepするように記述したところ、dontshrink無しで期待する動作になりました。

    返信削除
    返信
    1. ↑の匿名さん。こんにちわ。

      ちなみに、proguard.cfgにannotations.jarの中身をkeepするよる記述は、どのように記述すればよいのでしょうか?

      以上よろしくお願いいたします。

      削除