2010年11月29日月曜日



f:id:bs-android:20091024120512j:image


はじめに


このエントリでは、Androidアプリという知的財産を守る方法の一つとして、難読化ツールであるProGuardを紹介し、実際にAndroidアプリに組み込む方法を示します。





ソフトウェアの価値


ソフトウェアでは処理の流れ(アルゴリズム)を記述したソースコードが大きな価値を持つため、(特に商用のソフトウェアは)ソースコードを非公開とし、コンピュータで実行可能な必要最小限の中間コードやネイティブコードに限って配布することで、ソフトウェアビジネスを成立させています。つまり、処理の流れを「隠す」ことにより、その会社(あるいは人)にしか解決できないという「情報に対する付加価値」を与え、ソフトウェアビジネスを成立させていると言えます。一方で、何らかの形でこの「隠した部分」が明らかになり白日の下に晒されると、類似したソフトウェアが流通するなど、もはや処理の流れという情報としての「価値」は失われ、ビジネスとして成立しなくなります。


さて、Androidに限らず、最近のソフトウェアは高級言語(Javaなど)を用いて記述され、翻訳(コンパイル)を通じて最終的にはコンピュータが処理可能な「中間コード」や「ネイティブコード」に変換されます。この変換は言語ごとに定められた「文法」によって翻訳されるため、その翻訳ルールさえ判れば逆翻訳(デコンパイルやデアセンブルと言います)が可能です。つまり、「中間コード」や「ネイティブコード」から逆翻訳を行い、人間が理解可能なソースコードを生成することが可能ということです。


このままでは、ちょっとした知識があればソースコードが推測されてしまいます。その為、商用ソフトなどでは難読化を行い、逆翻訳された場合でもソースコードを読みにくくするなどして、簡単に処理の流れが明らかにならないように対策しています。





難読化とは


先に記した通り、難読化とは「ソースコードを読みにくくすること」です。難読化の手法は様々ありますが、下記のような方法によって、翻訳時にソースコードを可能な限り読みにくくします。




  • クラスやメソッド、変数名を省略・無意味化

  • コメントの削除

  • 空白(行)の削除


また、翻訳時に処理パフォーマンスが良くなるように処理の最適化(繰り返し処理の簡略化、関数・メソッドのインライン化等)が行われますが、その結果、人間にとって理解が困難なコードとなることもあります。





Androidの難読化ツール


Androidのビルドプロセスにも適用可能な難読化ツールが存在します。その名も「ProGuard」。


ProGuardは、Javaのクラスファイルの圧縮・難読化・最適化・前検証を行うツールです。使われていないクラス/メソッド/変数を検知・削除したり、バイトコードを最適化したり、クラスやメソッド名を無意味化したりします。ProGuardは一般的なAndroidアプリケーション開発に用いられるEclipseではなく、CUIベースのビルドツール「Ant」に統合される形で利用できます。Antによって、Androidアプリケーションの翻訳や難読化はもちろん、アプリケーションの署名や端末へのインストールも自動化することができます。





ProGuardの概要


f:id:bs-android:20101129144703j:image


引用:http://proguard.sourceforge.net/manual/introduction.html


ProGuardは、jar/war/zip/ディレクトリなどを入力として、次の4つのステップを経て、最終的にjar/war/zip/ディレクトリへ処理結果を出力します。




  • 圧縮ステップ(shrink)

  • 最適化ステップ(optimize)

  • 難読化ステップ(obfuscate)

  • 前検証ステップ(preverify)


圧縮ステップでは、プログラム中の利用されていないクラスやメソッド等を取り除きます。このステップは再帰的に処理されるので、全てのクラス・メソッドが対象となります。


最適化ステップでは、エントリポイントではないクラスやメソッドをprivate/static/final属性に変換、使われていないパラメータは削除され、一部のメソッドはインライン化されます。


難読化ステップでは、エントリポイントではないクラスやメソッドの名前を変更します。エントリポイントとなるクラスやメソッドは、オリジナルの名前でアクセスできるようにするために変更されません。


前検証ステップでは、実行時・ロード時のバイトコードの検証負荷を減らすために、あらかじめ型情報を調査し、その情報をクラスファイル内に添付します。Android(Java6)では使用しません。


開発したプログラムは外部から提供されるライブラリを使用することがありますが、これらはProGuardの処理の対象外となります。





ProGuardの適用


それでは、以下ではAndroidのプロジェクトにProGuardを適用し、難読化&最適化を行う方法について説明しましょう。





システム要件

AndroidのプロジェクトにProGuardを適用する場合、次の条件を満たしている必要があります:




  • Android SDKがインストールされていること

  • Android SDK Toolsがインストールされていて、少なくともリビジョン7以上であること

  • Apache Ant 1.6.5以上(Linux and Mac)/1.7以上(Windows) :Eclipse付属のものを使わず、最新のAntを別途インストールすることが望ましい。


Android SDK Tools Rev.7には、プリコンパイルまたはコンパイル時のユーザー定義処理をサポートするフックを含む、Antビルドルールファイルが同梱されています。





サンプルプロジェクト

今回のサンプルは下記のような比較的シンプルな処理を含みます。ソースコード中には無意味な処理が含まれますが、ProGuardの適用状態が判るようにするためのものです。ここでは処理の内容に注目する必要はありません。


プロジェクトのホームを /HelloAndroidとします。このホームは各自の環境に合わせて読み替えてください。


HelloAndroid/src/test/hello/HelloAndroid.java



package test.hello;

import android.app.Activity;
import android.os.Bundle;

public class HelloAndroid extends Activity
{
public static final class testClass {

testClass() {
methodA(1,"str");
}

private void methodA(int i, String j) {
return;
}
}

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
testMethod1();
new testClass();
}

private void testMethod1()
{
int i,sum;
for( i = 0, sum = 0; i < 10; i++ ) {
sum += i;
}
}
}


リソースファイル等はデフォルトのものをそのまま使用します。





署名キーの用意

ProGuardには直接的に関係無いが、今回はEclipseを使用してビルド・デプロイしないため、ビルド後に自動でデプロイするために予め署名キーを生成しておくと、後が便利です。既に署名キーを用意している場合は、読み飛ばしてもらって構いません。



$ keytool -genkey -v -keystore release.keystore -alias testhello -keyalg RSA -keysize 4096 -validity 10000
キーストアのパスワードを入力してください: <パスワードを入力>
新規パスワードを再入力してください: <もう一度パスワードを入力>
姓名を入力してください。
[Unknown]: Seto Naoki
組織単位名を入力してください。
[Unknown]:
組織名を入力してください。
[Unknown]: Brilliant Service co.,Ltd.
都市名または地域名を入力してください。
[Unknown]: Tokyo
州名または地方名を入力してください。
[Unknown]:
この単位に該当する 2 文字の国番号を入力してください。
[Unknown]: jp
CN=Seto Naoki, OU=Unknown, O=Brilliant Service co.,Ltd., L=Tokyo, ST=Unknown, C=jp でよろしいですか?
[no]: yes

10,000 日間有効な 4,096 ビットの RSA の鍵ペアと自己署名型証明書 (SHA1withRSA) を生成しています
ディレクトリ名: CN=Seto Naoki, OU=Unknown, O="Brilliant Service co.,Ltd.", L=Tokyo, ST=Unknown, C=jp
<testhello> の鍵パスワードを入力してください。
(キーストアのパスワードと同じ場合は RETURN を押してください): <リターンキーを押す>
[release.keystore を格納中]





プロジェクトの更新

下記のコマンドでAntビルドできるようにプロジェクトを更新します。



cd /HelloAndroid/.. (プロジェクトホームの一つ上)
android update project --path ./HelloAndroid


更新すると下記のファイルが作成されているはずです。




  • default.properties

  • local.properties

  • build.properties

  • build.xml





ProGuard用設定ファイルの配置

下記のファイルをプロジェクトのホームに配置します。これらのファイルはオフィシャルブログからもダウンロードできます。




  • add-proguard-release.xml

  • procfg.txt


/HelloAndroid/add-progurad-release.xml




<property name="obfuscate.dir" value="obf" />
<property name="obfuscate.absolute.dir" location="${obfuscate.dir}" />
<property name="android-jar-preobfuscate" value="${obfuscate.absolute.dir}/original.jar" />
<property name="android-jar-postobfuscate" value="${obfuscate.absolute.dir}/postobf.jar" />
<property name="out.dex.input.absolute.dir" value="${android-jar-postobfuscate}" />


<target name="-post-compile" depends="-dex-obfuscate,-dex-no-obfuscate">
</target>

<target name="-dex-no-obfuscate" unless="build.mode.release">
<mkdir dir="${obfuscate.absolute.dir}" />
<jar basedir="${out.classes.dir}" destfile="${android-jar-postobfuscate}" />
</target>


<target name="-dex-obfuscate" if="build.mode.release">
<property name="proguard-jar" value="${proguard.dir}/proguard.jar" />
<property name="proguard-conf.dir" value="" />
<property name="proguard-conf.absolute.dir" location="${proguard-conf.dir}" />
<property name="proguard-conf" value="${proguard-conf.absolute.dir}/procfg.txt" />
<path id="fullclasspath">
<path refid="android.target.classpath"/>
<pathelement path="${external.libs.dir}"/>
</path>
<property name="libraryjarpath" refid="fullclasspath"/>


<taskdef resource="proguard/ant/task.properties" classpath="${proguard-jar}" />

<mkdir dir="${obfuscate.absolute.dir}" />
<delete file="${android-jar-preobfuscate}"/>
<delete file="${android-jar-postobfuscate}"/>
<jar basedir="${out.classes.dir}" destfile="${android-jar-preobfuscate}" />
<proguard>
@${proguard-conf}
-injars ${android-jar-preobfuscate}
-outjars ${android-jar-postobfuscate}
-libraryjars ${libraryjarpath}
-dump ${obfuscate.absolute.dir}/dump.txt
-printseeds ${obfuscate.absolute.dir}/seeds.txt
-printusage ${obfuscate.absolute.dir}/usage.txt
-printmapping ${obfuscate.absolute.dir}/mapping.txt
</proguard>
</target>


このファイルでは、AntでProGuardを使用する際のパラメータ(出力先ディレクトリなど)の定義、ant_rules_r3で定義されるAntのプリコンパイルルールの書き換え、Ant用ProGuardタスクの追加の定義などを行います。


/HelloAndroid/procfg.txt



-optimizationpasses 5
-dontusemixedcaseclassnames
-dontskipnonpubliclibraryclasses
-dontpreverify
-verbose
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*

-keep public class * extends android.app.Activity
-keep public class * extends android.app.Application
-keep public class * extends android.app.Service
-keep public class * extends android.content.BroadcastReceiver
-keep public class * extends android.content.ContentProvider
-keep public class com.android.vending.licensing.ILicensingService

-keepclasseswithmembernames class * {
native <methods>;
}

-keepclasseswithmembernames class * {
public <init>(android.content.Context, android.util.AttributeSet);
}

-keepclasseswithmembernames class * {
public <init>(android.content.Context, android.util.AttributeSet, int);
}

-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}


ここでは最適化の設定や難読化をしない設定(-keep*)を行っています。ビルドエラーが発生する場合、設定を変更する必要があります。この辺りのテクニックは以下のサイトが参考になります。


http://d.hatena.ne.jp/hyoromo/20101120/1290216449





ビルド設定ファイルの修正

build.propertiesとbuild.xmlを改修してProGuardに対応させます。


/HelloAndroid/build.properties


標準の設定ファイルに、下記の設定を追加します。




  • 自動デプロイのオプション設定(12~16行目)

  • 自動署名の設定(18~26行目)

  • ProGuardの有効化(33行目)



01 : # This file is used to override default values used by the Ant build system.
02 : #
03 : # This file must be checked in Version Control Systems, as it is
04 : # integral to the build system of your project.
05 :
06 : # This file is only used by the Ant script.
07 :
08 : # You can use this to override default values such as
09 : # 'source.dir' for the location of your java source folder and
10 : # 'out.dir' for the location of your output folder.
11 :
12 : #-d:device/-e:emulator
13 : adb.device.arg=
14 :
15 : #adb install <option>
16 : adb.install.option=-r
17 :
18 : # You can also use it define how the release builds are signed by declaring
19 : # the following properties:
20 : # 'key.store' for the location of your keystore and
21 : # 'key.alias' for the name of the key to use.
22 : # The password will be asked during the build when you use the 'release' target.
23 : key.store=<キーストアのファイルパス(ファイル名含む)>
24 : key.store.password=<キーストアのパスワード>
25 : key.alias=<キー生成時に指定したエイリアス>
26 : key.alias.password=<エイリアスのパスワード>
27 :
28 : # The name of your application package as defined in the manifest.
29 : # Used by the 'uninstall' rule.
30 : application.package=test.hello
31 :
32 : # For ProGuard
33 : proguard.dir=<ProGuardのlibディレクトリまでのパス>


proguard.dirは<ProGuardのインストール先>\libを指定する必要があります。





/HelloAndroid/build.xml


標準の設定ファイルに、下記の設定を追加します。




  • ProGuard用設定XMLファイルの読み込み(2~6行目)

  • アプリケーションへの自動署名とデプロイタスクの定義(88~103行目)



01 : <?xml version="1.0" encoding="UTF-8"?>
02 : <!DOCTYPE project [
03 : <!ENTITY add-proguard-release SYSTEM "add-proguard-release.xml">
04 : ]>
05 : <project name="HelloAndroid" default="help">
06 : &add-proguard-release;
07 :
08 :
12 : <property file="local.properties" />
13 :
14 :
31 : <property file="build.properties" />
32 :
33 :
37 : <property file="default.properties" />
38 :
39 :
42 : <path id="android.antlibs">
43 : <pathelement path="${sdk.dir}/tools/lib/anttasks.jar" />
44 : <pathelement path="${sdk.dir}/tools/lib/sdklib.jar" />
45 : <pathelement path="${sdk.dir}/tools/lib/androidprefs.jar" />
46 : </path>
47 :
48 : <taskdef name="setup"
49 : classname="com.android.ant.SetupTask"
50 : classpathref="android.antlibs" />
51 :
52 :
54 :
66 :
67 :
68 :
86 : <setup />
87 :
88 :
89 : <macrodef name="install-release-helper">
90 : <sequential>
91 : <echo>Installing ${out.release.file}...</echo>
92 : <exec executable="${adb}" failonerror="true">
93 : <arg line="${adb.device.arg}" />
94 : <arg value="install" />
95 : <arg value="${adb.install.option}" />
96 : <arg path="${out.release.file}" />
97 : </exec>
98 : </sequential>
99 : </macrodef>
101:
101: <target name="deploy" depends="release">
102: <install-release-helper />
103: </target>
104:
105:</project>





ProGuardの適用(ビルド)とデプロイ

ビルドとデプロイは簡単です。アプリを配置したいデバイスを接続し(または、abdコマンドでシミュレータ上にデバイスを作成しておいて)、下記のコマンドを実行します。



$ ant deploy


これまでに示した定義ファイルの記述が正しければ、ProGuardが適用された状態でビルドされ、アプリへの自動署名が行われて端末にアプリがインストールされます。



Buildfile: C:\Users\brilliantservice.brilliant_vaio\anttest\HelloAndroid\build.xml
[setup] Android SDK Tools Revision 7
[setup] Project Target: Google APIs
[setup] Vendor: Google Inc.
[setup] Platform Version: 1.5
[setup] API level: 3
[setup]
[setup] ------------------
[setup] Resolving library dependencies:
[setup] ------------------
[setup] Ordered libraries:
[setup] ------------------
[setup]
[setup] WARNING: No minSdkVersion value set. Application will install on all Android versions.
[setup]
[setup] Importing rules file: tools\ant\ant_rules_r3.xml

-set-release-mode:

-dirs:
[echo] Creating output directories if needed...
[mkdir] Created dir: C:\Users\brilliantservice.brilliant_vaio\anttest\HelloAndroid\bin
[mkdir] Created dir: C:\Users\brilliantservice.brilliant_vaio\anttest\HelloAndroid\gen
[mkdir] Created dir: C:\Users\brilliantservice.brilliant_vaio\anttest\HelloAndroid\bin\classes

-pre-build:

-resource-src:
[echo] Generating R.java / Manifest.java from the resources...

-aidl:
[echo] Compiling aidl files into Java classes...

-pre-compile:

compile:
[javac] C:\android-sdk-windows\tools\ant\ant_rules_r3.xml:336: warning: 'includeantruntime' was not set, defaulting to build.sysclasspath=last; set to false for repeatable builds
[javac] Compiling 2 source files to C:\Users\brilliantservice.brilliant_vaio\anttest\HelloAndroid\bin\classes

-dex-obfuscate:
[mkdir] Created dir: C:\Users\brilliantservice.brilliant_vaio\anttest\HelloAndroid\obf
[jar] Building jar: C:\Users\brilliantservice.brilliant_vaio\anttest\HelloAndroid\obf\original.jar
[proguard] ProGuard, version 4.5.1
[proguard] Reading input...
[proguard] Reading program jar [C:\Users\brilliantservice.brilliant_vaio\anttest\HelloAndroid\obf\original.jar]
[proguard] Reading library jar [C:\android-sdk-windows\platforms\android-3\android.jar]
[proguard] Reading library jar [C:\android-sdk-windows\add-ons\addon_google_apis_google_inc_3\libs\maps.jar]
[proguard] Reading library directory [C:\Users\brilliantservice.brilliant_vaio\anttest\HelloAndroid\libs]
[proguard] Initializing...
[proguard] Note: the configuration refers to the unknown class 'com.android.vending.licensing.ILicensingService'
[proguard] Note: there were 1 references to unknown classes.
[proguard] You should check your configuration for typos.
[proguard] Ignoring unused library classes...
[proguard] Original number of library classes: 2398
[proguard] Final number of library classes: 92
[proguard] Printing kept classes, fields, and methods...
[proguard] Shrinking...
[proguard] Printing usage to [C:\Users\brilliantservice.brilliant_vaio\anttest\HelloAndroid\obf\usage.txt]...
[proguard] Removing unused program classes and class elements...
[proguard] Original number of program classes: 6
[proguard] Final number of program classes: 2
[proguard] Optimizing...
[proguard] Number of finalized classes: 0
[proguard] Number of vertically merged classes: 0 (disabled)
[proguard] Number of horizontally merged classes: 0 (disabled)
[proguard] Number of removed write-only fields: 0 (disabled)
[proguard] Number of privatized fields: 0 (disabled)
[proguard] Number of inlined constant fields: 0 (disabled)
[proguard] Number of privatized methods: 0
[proguard] Number of staticized methods: 2
[proguard] Number of finalized methods: 0
[proguard] Number of removed method parameters: 2
[proguard] Number of inlined constant parameters: 1
[proguard] Number of inlined constant return values: 0
[proguard] Number of inlined short method calls: 0
[proguard] Number of inlined unique method calls: 0
[proguard] Number of inlined tail recursion calls: 0
[proguard] Number of merged code blocks: 0
[proguard] Number of variable peephole optimizations: 0
[proguard] Number of arithmetic peephole optimizations: 0 (disabled)
[proguard] Number of cast peephole optimizations: 0
[proguard] Number of field peephole optimizations: 0
[proguard] Number of branch peephole optimizations: 0
[proguard] Number of simplified instructions: 0
[proguard] Number of removed instructions: 21
[proguard] Number of removed local variables: 0
[proguard] Number of removed exception blocks: 0
[proguard] Number of optimized local variable frames: 0
[proguard] Shrinking...
[proguard] Removing unused program classes and class elements...
[proguard] Original number of program classes: 2
[proguard] Final number of program classes: 2
[proguard] Optimizing...
[proguard] Number of finalized classes: 0
[proguard] Number of vertically merged classes: 0 (disabled)
[proguard] Number of horizontally merged classes: 0 (disabled)
[proguard] Number of removed write-only fields: 0 (disabled)
[proguard] Number of privatized fields: 0 (disabled)
[proguard] Number of inlined constant fields: 0 (disabled)
[proguard] Number of privatized methods: 0
[proguard] Number of staticized methods: 0
[proguard] Number of finalized methods: 0
[proguard] Number of removed method parameters: 0
[proguard] Number of inlined constant parameters: 0
[proguard] Number of inlined constant return values: 0
[proguard] Number of inlined short method calls: 0
[proguard] Number of inlined unique method calls: 0
[proguard] Number of inlined tail recursion calls: 0
[proguard] Number of merged code blocks: 0
[proguard] Number of variable peephole optimizations: 0
[proguard] Number of arithmetic peephole optimizations: 0 (disabled)
[proguard] Number of cast peephole optimizations: 0
[proguard] Number of field peephole optimizations: 0
[proguard] Number of branch peephole optimizations: 0
[proguard] Number of simplified instructions: 0
[proguard] Number of removed instructions: 0
[proguard] Number of removed local variables: 0
[proguard] Number of removed exception blocks: 0
[proguard] Number of optimized local variable frames: 0
[proguard] Obfuscating...
[proguard] Printing mapping to [C:\Users\brilliantservice.brilliant_vaio\anttest\HelloAndroid\obf\mapping.txt]...
[proguard] Writing output...
[proguard] Preparing output jar [C:\Users\brilliantservice.brilliant_vaio\anttest\HelloAndroid\obf\postobf.jar]
[proguard] Copying resources from program jar [C:\Users\brilliantservice.brilliant_vaio\anttest\HelloAndroid\obf\original.jar]
[proguard] Printing classes to [C:\Users\brilliantservice.brilliant_vaio\anttest\HelloAndroid\obf\dump.txt]...

-dex-no-obfuscate:

-post-compile:

-dex:
[echo] Converting compiled files and external libraries into C:\Users\brilliantservice.brilliant_vaio\anttest\HelloAndroid\bin\classes.dex...

-package-resources:
[echo] Packaging resources
[aapt] Creating full resource package...

-package-release:
[apkbuilder] Creating HelloAndroid-unsigned.apk for release...

-release-prompt-for-password:

-release-nosign:

release:
[echo] Signing final apk...
[signjar] Signing JAR: C:\Users\brilliantservice.brilliant_vaio\anttest\HelloAndroid\bin\HelloAndroid-unsigned.apk to C:\Users\brilliantservice.brilliant_vaio\anttest\HelloAndroid\bin\HelloAndroid-unaligned.apk as ky
[signjar] キーストアのパスワードを入力してください:
[echo] Running zip align on final apk...
[echo] Release Package: C:\Users\brilliantservice.brilliant_vaio\anttest\HelloAndroid\bin\HelloAndroid-release.apk

deploy:
[echo] Installing C:\Users\brilliantservice.brilliant_vaio\anttest\HelloAndroid\bin\HelloAndroid-release.apk...
[exec] pkg: /data/local/tmp/HelloAndroid-release.apk
[exec] Success
[exec] 72 KB/s (4211 bytes in 0.057s)

BUILD SUCCESSFUL
Total time: 8 seconds


-dex-obfuscate:のフェーズで[proguard]のログが出力されていれば、ProGuardが適用されています。ログを詳しく見ると、下記のように圧縮、最適化、難読化が行われていることが分かります。




  • [proguard] Shrinking...

  • [proguard] Optimizing...

  • [proguard] Obfuscating...





ProGuard適用前と適用後を比較してみる


実際にProGuardの処理結果を比較して確認してみましょう。





apktoolによるデコンパイル

リエンジニアリングツールであるandroid-apktoolを使って、.apkファイルをデコンパイルし、アプリ内のクラス構成や処理内容を可視化します。





apktoolのシステム要件



  • JRE 1.6 (Java Runtime Environment)

  • 実行パスにaaptコマンドが設定されていること





apktoolのダウンロード

apktoolのダウンロードページから、OSに対応したファイルをダウンロードして下さい。





apktoolのインストール



  1. apktool-install-windows-* ファイルのダウンロード(Windowsの場合)

  2. apktool-* ファイルのダウンロード

  3. 以上の2つのファイルを適当なディレクトリに展開します。





デコンパイルの実行


$ cd <プロジェクトディレクトリ>/bin/
$ apktool d HelloAndroid-release.apk


デコンパイルの結果、HelloAndroid-release.apkのディレクトリ以下に、HelloAndroid-releaseディレクトリが生成され、下記のようなファイルが生成されます。




  • AndroidManifest.xml:アプリのマニフェストファイル

  • apktool.yml:apktoolの処理結果

  • resディレクトリ:アプリに含まれるリソースファイル

  • smaliディレクトリ:アプリの処理手順の解析結果





smaliファイルの比較

最適化や難読化がなされているかどうかは、smaliディレクトリをProGuardを適用しない場合と適用した場合とで見比べてみることで判ります。


ProGuard適用前


ファイル構成:




  • HelloAndroid.smali

  • HelloAndroid$testClass.smali

  • R.smali

  • R$attr.smali

  • R$layout.smali

  • R$string.smali


HelloAndroid.smaliの内容:



.class public Ltest/hello/HelloAndroid;
.super Landroid/app/Activity;
.source "HelloAndroid.java"

# annotations
.annotation system Ldalvik/annotation/MemberClasses;
value = {
Ltest/hello/HelloAndroid$testClass;
}
.end annotation

# direct methods
.method public constructor <init>()V
.locals 0

.prologue
.line 6
invoke-direct {p0}, Landroid/app/Activity;-><init>()V

.line 8
return-void
.end method

.method private testMethod1()V
.locals 3

.prologue
.line 32
const/4 v0, 0x0

.local v0, i:I
const/4 v1, 0x0

.local v1, sum:I
const/16 v2, 0xa

if-ge v0, v2, :cond_0

.line 33
add-int/2addr v1, v0

.line 32
add-int/lit8 v0, v0, 0x1

goto :goto_0

.line 35
return-void
.end method

# virtual methods
.method public onCreate(Landroid/os/Bundle;)V
.locals 1
.parameter "savedInstanceState"

.prologue
.line 23
invoke-super {p0, p1}, Landroid/app/Activity;->onCreate(Landroid/os/Bundle;)V

.line 24
const/high16 v0, 0x7f02

invoke-virtual {p0, v0}, Ltest/hello/HelloAndroid;->setContentView(I)V

.line 25
invoke-direct {p0}, Ltest/hello/HelloAndroid;->testMethod1()V

.line 26
new-instance v0, Ltest/hello/HelloAndroid$testClass;

invoke-direct {v0}, Ltest/hello/HelloAndroid$testClass;-><init>()V

.line 27
return-void
.end method


ProGuard適用しない場合、アプリのファイル構成がそのまま解析結果として出力され、クラス・メソッドの構成、コールシーケンスが丸見えになります。また、内部で使用しているクラス(内部クラスを含む)やメソッド名も判るため、何の処理をしているのかが予測しやすい状態です。





ProGuard適用後


ファイル構成:




  • a.smali

  • HelloAndroid.smali


HelloAndroid.smaliの内容:



.class public Ltest/hello/HelloAndroid;
.super Landroid/app/Activity;

# direct methods
.method public constructor <init>()V
.locals 0

invoke-direct {p0}, Landroid/app/Activity;-><init>()V

return-void
.end method

# virtual methods
.method public onCreate(Landroid/os/Bundle;)V
.locals 1

invoke-super {p0, p1}, Landroid/app/Activity;->onCreate(Landroid/os/Bundle;)V

const/high16 v0, 0x7f02

invoke-virtual {p0, v0}, Ltest/hello/HelloAndroid;->setContentView(I)V

new-instance v0, Ltest/hello/a;

invoke-direct {v0}, Ltest/hello/a;-><init>()V

return-void
.end method


a.smaliの内容:



.class final Ltest/hello/a;
.super Ljava/lang/Object;

# direct methods
.method constructor <init>()V
.locals 0

invoke-direct {p0}, Ljava/lang/Object;-><init>()V

return-void
.end method


ProGuardを適用すると、ファイル構成は「エントリポイントとなるクラスファイル」と「難読化されたクラスファイル」だけとなっており、実際のファイル構成とは異なっています。また、クラスやメソッドの解析に失敗しており、この結果から処理を予測することが難しくなっています。





まとめ


以上のようにProGuardを利用すると簡単な手順で実効性のある難読化を行い、Androidのアプリという知的財産を守ることができます。一方で、JNI経由でネイティブメソッドなどを利用している場合、ProGuardでのビルドに失敗するなど、適用に関わる工数が著しく増大することがあります(いわゆる「ハマる」可能性があるということ)。とはいえ、アプリ中のアルゴリズムや手順、利用している技術が特殊であればあるほど、ProGuardを適用する意味は大きいでしょう。何らかの形でアプリ中の知的財産を守る必要がある場合は、ProGuardの利用を検討してみてはいかがでしょうか。


文責:技術部 植物工場研究G 瀬戸 直喜





Androidとセキュリティ:プログラム難読化ツール - ProGuard



f:id:bs-android:20091024120512j:image


はじめに


このエントリでは、Androidアプリという知的財産を守る方法の一つとして、難読化ツールであるProGuardを紹介し、実際にAndroidアプリに組み込む方法を示します。





ソフトウェアの価値


ソフトウェアでは処理の流れ(アルゴリズム)を記述したソースコードが大きな価値を持つため、(特に商用のソフトウェアは)ソースコードを非公開とし、コンピュータで実行可能な必要最小限の中間コードやネイティブコードに限って配布することで、ソフトウェアビジネスを成立させています。つまり、処理の流れを「隠す」ことにより、その会社(あるいは人)にしか解決できないという「情報に対する付加価値」を与え、ソフトウェアビジネスを成立させていると言えます。一方で、何らかの形でこの「隠した部分」が明らかになり白日の下に晒されると、類似したソフトウェアが流通するなど、もはや処理の流れという情報としての「価値」は失われ、ビジネスとして成立しなくなります。


さて、Androidに限らず、最近のソフトウェアは高級言語(Javaなど)を用いて記述され、翻訳(コンパイル)を通じて最終的にはコンピュータが処理可能な「中間コード」や「ネイティブコード」に変換されます。この変換は言語ごとに定められた「文法」によって翻訳されるため、その翻訳ルールさえ判れば逆翻訳(デコンパイルやデアセンブルと言います)が可能です。つまり、「中間コード」や「ネイティブコード」から逆翻訳を行い、人間が理解可能なソースコードを生成することが可能ということです。


このままでは、ちょっとした知識があればソースコードが推測されてしまいます。その為、商用ソフトなどでは難読化を行い、逆翻訳された場合でもソースコードを読みにくくするなどして、簡単に処理の流れが明らかにならないように対策しています。





難読化とは


先に記した通り、難読化とは「ソースコードを読みにくくすること」です。難読化の手法は様々ありますが、下記のような方法によって、翻訳時にソースコードを可能な限り読みにくくします。




  • クラスやメソッド、変数名を省略・無意味化

  • コメントの削除

  • 空白(行)の削除


また、翻訳時に処理パフォーマンスが良くなるように処理の最適化(繰り返し処理の簡略化、関数・メソッドのインライン化等)が行われますが、その結果、人間にとって理解が困難なコードとなることもあります。





Androidの難読化ツール


Androidのビルドプロセスにも適用可能な難読化ツールが存在します。その名も「ProGuard」。


ProGuardは、Javaのクラスファイルの圧縮・難読化・最適化・前検証を行うツールです。使われていないクラス/メソッド/変数を検知・削除したり、バイトコードを最適化したり、クラスやメソッド名を無意味化したりします。ProGuardは一般的なAndroidアプリケーション開発に用いられるEclipseではなく、CUIベースのビルドツール「Ant」に統合される形で利用できます。Antによって、Androidアプリケーションの翻訳や難読化はもちろん、アプリケーションの署名や端末へのインストールも自動化することができます。





ProGuardの概要


f:id:bs-android:20101129144703j:image


引用:http://proguard.sourceforge.net/manual/introduction.html


ProGuardは、jar/war/zip/ディレクトリなどを入力として、次の4つのステップを経て、最終的にjar/war/zip/ディレクトリへ処理結果を出力します。




  • 圧縮ステップ(shrink)

  • 最適化ステップ(optimize)

  • 難読化ステップ(obfuscate)

  • 前検証ステップ(preverify)


圧縮ステップでは、プログラム中の利用されていないクラスやメソッド等を取り除きます。このステップは再帰的に処理されるので、全てのクラス・メソッドが対象となります。


最適化ステップでは、エントリポイントではないクラスやメソッドをprivate/static/final属性に変換、使われていないパラメータは削除され、一部のメソッドはインライン化されます。


難読化ステップでは、エントリポイントではないクラスやメソッドの名前を変更します。エントリポイントとなるクラスやメソッドは、オリジナルの名前でアクセスできるようにするために変更されません。


前検証ステップでは、実行時・ロード時のバイトコードの検証負荷を減らすために、あらかじめ型情報を調査し、その情報をクラスファイル内に添付します。Android(Java6)では使用しません。


開発したプログラムは外部から提供されるライブラリを使用することがありますが、これらはProGuardの処理の対象外となります。





ProGuardの適用


それでは、以下ではAndroidのプロジェクトにProGuardを適用し、難読化&最適化を行う方法について説明しましょう。





システム要件

AndroidのプロジェクトにProGuardを適用する場合、次の条件を満たしている必要があります:




  • Android SDKがインストールされていること

  • Android SDK Toolsがインストールされていて、少なくともリビジョン7以上であること

  • Apache Ant 1.6.5以上(Linux and Mac)/1.7以上(Windows) :Eclipse付属のものを使わず、最新のAntを別途インストールすることが望ましい。


Android SDK Tools Rev.7には、プリコンパイルまたはコンパイル時のユーザー定義処理をサポートするフックを含む、Antビルドルールファイルが同梱されています。





サンプルプロジェクト

今回のサンプルは下記のような比較的シンプルな処理を含みます。ソースコード中には無意味な処理が含まれますが、ProGuardの適用状態が判るようにするためのものです。ここでは処理の内容に注目する必要はありません。


プロジェクトのホームを /HelloAndroidとします。このホームは各自の環境に合わせて読み替えてください。


HelloAndroid/src/test/hello/HelloAndroid.java



package test.hello;

import android.app.Activity;
import android.os.Bundle;

public class HelloAndroid extends Activity
{
public static final class testClass {

testClass() {
methodA(1,"str");
}

private void methodA(int i, String j) {
return;
}
}

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
testMethod1();
new testClass();
}

private void testMethod1()
{
int i,sum;
for( i = 0, sum = 0; i < 10; i++ ) {
sum += i;
}
}
}


リソースファイル等はデフォルトのものをそのまま使用します。





署名キーの用意

ProGuardには直接的に関係無いが、今回はEclipseを使用してビルド・デプロイしないため、ビルド後に自動でデプロイするために予め署名キーを生成しておくと、後が便利です。既に署名キーを用意している場合は、読み飛ばしてもらって構いません。



$ keytool -genkey -v -keystore release.keystore -alias testhello -keyalg RSA -keysize 4096 -validity 10000
キーストアのパスワードを入力してください: <パスワードを入力>
新規パスワードを再入力してください: <もう一度パスワードを入力>
姓名を入力してください。
[Unknown]: Seto Naoki
組織単位名を入力してください。
[Unknown]:
組織名を入力してください。
[Unknown]: Brilliant Service co.,Ltd.
都市名または地域名を入力してください。
[Unknown]: Tokyo
州名または地方名を入力してください。
[Unknown]:
この単位に該当する 2 文字の国番号を入力してください。
[Unknown]: jp
CN=Seto Naoki, OU=Unknown, O=Brilliant Service co.,Ltd., L=Tokyo, ST=Unknown, C=jp でよろしいですか?
[no]: yes

10,000 日間有効な 4,096 ビットの RSA の鍵ペアと自己署名型証明書 (SHA1withRSA) を生成しています
ディレクトリ名: CN=Seto Naoki, OU=Unknown, O="Brilliant Service co.,Ltd.", L=Tokyo, ST=Unknown, C=jp
<testhello> の鍵パスワードを入力してください。
(キーストアのパスワードと同じ場合は RETURN を押してください): <リターンキーを押す>
[release.keystore を格納中]





プロジェクトの更新

下記のコマンドでAntビルドできるようにプロジェクトを更新します。



cd /HelloAndroid/.. (プロジェクトホームの一つ上)
android update project --path ./HelloAndroid


更新すると下記のファイルが作成されているはずです。




  • default.properties

  • local.properties

  • build.properties

  • build.xml





ProGuard用設定ファイルの配置

下記のファイルをプロジェクトのホームに配置します。これらのファイルはオフィシャルブログからもダウンロードできます。




  • add-proguard-release.xml

  • procfg.txt


/HelloAndroid/add-progurad-release.xml




<property name="obfuscate.dir" value="obf" />
<property name="obfuscate.absolute.dir" location="${obfuscate.dir}" />
<property name="android-jar-preobfuscate" value="${obfuscate.absolute.dir}/original.jar" />
<property name="android-jar-postobfuscate" value="${obfuscate.absolute.dir}/postobf.jar" />
<property name="out.dex.input.absolute.dir" value="${android-jar-postobfuscate}" />


<target name="-post-compile" depends="-dex-obfuscate,-dex-no-obfuscate">
</target>

<target name="-dex-no-obfuscate" unless="build.mode.release">
<mkdir dir="${obfuscate.absolute.dir}" />
<jar basedir="${out.classes.dir}" destfile="${android-jar-postobfuscate}" />
</target>


<target name="-dex-obfuscate" if="build.mode.release">
<property name="proguard-jar" value="${proguard.dir}/proguard.jar" />
<property name="proguard-conf.dir" value="" />
<property name="proguard-conf.absolute.dir" location="${proguard-conf.dir}" />
<property name="proguard-conf" value="${proguard-conf.absolute.dir}/procfg.txt" />
<path id="fullclasspath">
<path refid="android.target.classpath"/>
<pathelement path="${external.libs.dir}"/>
</path>
<property name="libraryjarpath" refid="fullclasspath"/>


<taskdef resource="proguard/ant/task.properties" classpath="${proguard-jar}" />

<mkdir dir="${obfuscate.absolute.dir}" />
<delete file="${android-jar-preobfuscate}"/>
<delete file="${android-jar-postobfuscate}"/>
<jar basedir="${out.classes.dir}" destfile="${android-jar-preobfuscate}" />
<proguard>
@${proguard-conf}
-injars ${android-jar-preobfuscate}
-outjars ${android-jar-postobfuscate}
-libraryjars ${libraryjarpath}
-dump ${obfuscate.absolute.dir}/dump.txt
-printseeds ${obfuscate.absolute.dir}/seeds.txt
-printusage ${obfuscate.absolute.dir}/usage.txt
-printmapping ${obfuscate.absolute.dir}/mapping.txt
</proguard>
</target>


このファイルでは、AntでProGuardを使用する際のパラメータ(出力先ディレクトリなど)の定義、ant_rules_r3で定義されるAntのプリコンパイルルールの書き換え、Ant用ProGuardタスクの追加の定義などを行います。


/HelloAndroid/procfg.txt



-optimizationpasses 5
-dontusemixedcaseclassnames
-dontskipnonpubliclibraryclasses
-dontpreverify
-verbose
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*

-keep public class * extends android.app.Activity
-keep public class * extends android.app.Application
-keep public class * extends android.app.Service
-keep public class * extends android.content.BroadcastReceiver
-keep public class * extends android.content.ContentProvider
-keep public class com.android.vending.licensing.ILicensingService

-keepclasseswithmembernames class * {
native <methods>;
}

-keepclasseswithmembernames class * {
public <init>(android.content.Context, android.util.AttributeSet);
}

-keepclasseswithmembernames class * {
public <init>(android.content.Context, android.util.AttributeSet, int);
}

-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}


ここでは最適化の設定や難読化をしない設定(-keep*)を行っています。ビルドエラーが発生する場合、設定を変更する必要があります。この辺りのテクニックは以下のサイトが参考になります。


http://d.hatena.ne.jp/hyoromo/20101120/1290216449





ビルド設定ファイルの修正

build.propertiesとbuild.xmlを改修してProGuardに対応させます。


/HelloAndroid/build.properties


標準の設定ファイルに、下記の設定を追加します。




  • 自動デプロイのオプション設定(12~16行目)

  • 自動署名の設定(18~26行目)

  • ProGuardの有効化(33行目)



01 : # This file is used to override default values used by the Ant build system.
02 : #
03 : # This file must be checked in Version Control Systems, as it is
04 : # integral to the build system of your project.
05 :
06 : # This file is only used by the Ant script.
07 :
08 : # You can use this to override default values such as
09 : # 'source.dir' for the location of your java source folder and
10 : # 'out.dir' for the location of your output folder.
11 :
12 : #-d:device/-e:emulator
13 : adb.device.arg=
14 :
15 : #adb install <option>
16 : adb.install.option=-r
17 :
18 : # You can also use it define how the release builds are signed by declaring
19 : # the following properties:
20 : # 'key.store' for the location of your keystore and
21 : # 'key.alias' for the name of the key to use.
22 : # The password will be asked during the build when you use the 'release' target.
23 : key.store=<キーストアのファイルパス(ファイル名含む)>
24 : key.store.password=<キーストアのパスワード>
25 : key.alias=<キー生成時に指定したエイリアス>
26 : key.alias.password=<エイリアスのパスワード>
27 :
28 : # The name of your application package as defined in the manifest.
29 : # Used by the 'uninstall' rule.
30 : application.package=test.hello
31 :
32 : # For ProGuard
33 : proguard.dir=<ProGuardのlibディレクトリまでのパス>


proguard.dirは<ProGuardのインストール先>\libを指定する必要があります。





/HelloAndroid/build.xml


標準の設定ファイルに、下記の設定を追加します。




  • ProGuard用設定XMLファイルの読み込み(2~6行目)

  • アプリケーションへの自動署名とデプロイタスクの定義(88~103行目)



01 : <?xml version="1.0" encoding="UTF-8"?>
02 : <!DOCTYPE project [
03 : <!ENTITY add-proguard-release SYSTEM "add-proguard-release.xml">
04 : ]>
05 : <project name="HelloAndroid" default="help">
06 : &add-proguard-release;
07 :
08 :
12 : <property file="local.properties" />
13 :
14 :
31 : <property file="build.properties" />
32 :
33 :
37 : <property file="default.properties" />
38 :
39 :
42 : <path id="android.antlibs">
43 : <pathelement path="${sdk.dir}/tools/lib/anttasks.jar" />
44 : <pathelement path="${sdk.dir}/tools/lib/sdklib.jar" />
45 : <pathelement path="${sdk.dir}/tools/lib/androidprefs.jar" />
46 : </path>
47 :
48 : <taskdef name="setup"
49 : classname="com.android.ant.SetupTask"
50 : classpathref="android.antlibs" />
51 :
52 :
54 :
66 :
67 :
68 :
86 : <setup />
87 :
88 :
89 : <macrodef name="install-release-helper">
90 : <sequential>
91 : <echo>Installing ${out.release.file}...</echo>
92 : <exec executable="${adb}" failonerror="true">
93 : <arg line="${adb.device.arg}" />
94 : <arg value="install" />
95 : <arg value="${adb.install.option}" />
96 : <arg path="${out.release.file}" />
97 : </exec>
98 : </sequential>
99 : </macrodef>
101:
101: <target name="deploy" depends="release">
102: <install-release-helper />
103: </target>
104:
105:</project>





ProGuardの適用(ビルド)とデプロイ

ビルドとデプロイは簡単です。アプリを配置したいデバイスを接続し(または、abdコマンドでシミュレータ上にデバイスを作成しておいて)、下記のコマンドを実行します。



$ ant deploy


これまでに示した定義ファイルの記述が正しければ、ProGuardが適用された状態でビルドされ、アプリへの自動署名が行われて端末にアプリがインストールされます。



Buildfile: C:\Users\brilliantservice.brilliant_vaio\anttest\HelloAndroid\build.xml
[setup] Android SDK Tools Revision 7
[setup] Project Target: Google APIs
[setup] Vendor: Google Inc.
[setup] Platform Version: 1.5
[setup] API level: 3
[setup]
[setup] ------------------
[setup] Resolving library dependencies:
[setup] ------------------
[setup] Ordered libraries:
[setup] ------------------
[setup]
[setup] WARNING: No minSdkVersion value set. Application will install on all Android versions.
[setup]
[setup] Importing rules file: tools\ant\ant_rules_r3.xml

-set-release-mode:

-dirs:
[echo] Creating output directories if needed...
[mkdir] Created dir: C:\Users\brilliantservice.brilliant_vaio\anttest\HelloAndroid\bin
[mkdir] Created dir: C:\Users\brilliantservice.brilliant_vaio\anttest\HelloAndroid\gen
[mkdir] Created dir: C:\Users\brilliantservice.brilliant_vaio\anttest\HelloAndroid\bin\classes

-pre-build:

-resource-src:
[echo] Generating R.java / Manifest.java from the resources...

-aidl:
[echo] Compiling aidl files into Java classes...

-pre-compile:

compile:
[javac] C:\android-sdk-windows\tools\ant\ant_rules_r3.xml:336: warning: 'includeantruntime' was not set, defaulting to build.sysclasspath=last; set to false for repeatable builds
[javac] Compiling 2 source files to C:\Users\brilliantservice.brilliant_vaio\anttest\HelloAndroid\bin\classes

-dex-obfuscate:
[mkdir] Created dir: C:\Users\brilliantservice.brilliant_vaio\anttest\HelloAndroid\obf
[jar] Building jar: C:\Users\brilliantservice.brilliant_vaio\anttest\HelloAndroid\obf\original.jar
[proguard] ProGuard, version 4.5.1
[proguard] Reading input...
[proguard] Reading program jar [C:\Users\brilliantservice.brilliant_vaio\anttest\HelloAndroid\obf\original.jar]
[proguard] Reading library jar [C:\android-sdk-windows\platforms\android-3\android.jar]
[proguard] Reading library jar [C:\android-sdk-windows\add-ons\addon_google_apis_google_inc_3\libs\maps.jar]
[proguard] Reading library directory [C:\Users\brilliantservice.brilliant_vaio\anttest\HelloAndroid\libs]
[proguard] Initializing...
[proguard] Note: the configuration refers to the unknown class 'com.android.vending.licensing.ILicensingService'
[proguard] Note: there were 1 references to unknown classes.
[proguard] You should check your configuration for typos.
[proguard] Ignoring unused library classes...
[proguard] Original number of library classes: 2398
[proguard] Final number of library classes: 92
[proguard] Printing kept classes, fields, and methods...
[proguard] Shrinking...
[proguard] Printing usage to [C:\Users\brilliantservice.brilliant_vaio\anttest\HelloAndroid\obf\usage.txt]...
[proguard] Removing unused program classes and class elements...
[proguard] Original number of program classes: 6
[proguard] Final number of program classes: 2
[proguard] Optimizing...
[proguard] Number of finalized classes: 0
[proguard] Number of vertically merged classes: 0 (disabled)
[proguard] Number of horizontally merged classes: 0 (disabled)
[proguard] Number of removed write-only fields: 0 (disabled)
[proguard] Number of privatized fields: 0 (disabled)
[proguard] Number of inlined constant fields: 0 (disabled)
[proguard] Number of privatized methods: 0
[proguard] Number of staticized methods: 2
[proguard] Number of finalized methods: 0
[proguard] Number of removed method parameters: 2
[proguard] Number of inlined constant parameters: 1
[proguard] Number of inlined constant return values: 0
[proguard] Number of inlined short method calls: 0
[proguard] Number of inlined unique method calls: 0
[proguard] Number of inlined tail recursion calls: 0
[proguard] Number of merged code blocks: 0
[proguard] Number of variable peephole optimizations: 0
[proguard] Number of arithmetic peephole optimizations: 0 (disabled)
[proguard] Number of cast peephole optimizations: 0
[proguard] Number of field peephole optimizations: 0
[proguard] Number of branch peephole optimizations: 0
[proguard] Number of simplified instructions: 0
[proguard] Number of removed instructions: 21
[proguard] Number of removed local variables: 0
[proguard] Number of removed exception blocks: 0
[proguard] Number of optimized local variable frames: 0
[proguard] Shrinking...
[proguard] Removing unused program classes and class elements...
[proguard] Original number of program classes: 2
[proguard] Final number of program classes: 2
[proguard] Optimizing...
[proguard] Number of finalized classes: 0
[proguard] Number of vertically merged classes: 0 (disabled)
[proguard] Number of horizontally merged classes: 0 (disabled)
[proguard] Number of removed write-only fields: 0 (disabled)
[proguard] Number of privatized fields: 0 (disabled)
[proguard] Number of inlined constant fields: 0 (disabled)
[proguard] Number of privatized methods: 0
[proguard] Number of staticized methods: 0
[proguard] Number of finalized methods: 0
[proguard] Number of removed method parameters: 0
[proguard] Number of inlined constant parameters: 0
[proguard] Number of inlined constant return values: 0
[proguard] Number of inlined short method calls: 0
[proguard] Number of inlined unique method calls: 0
[proguard] Number of inlined tail recursion calls: 0
[proguard] Number of merged code blocks: 0
[proguard] Number of variable peephole optimizations: 0
[proguard] Number of arithmetic peephole optimizations: 0 (disabled)
[proguard] Number of cast peephole optimizations: 0
[proguard] Number of field peephole optimizations: 0
[proguard] Number of branch peephole optimizations: 0
[proguard] Number of simplified instructions: 0
[proguard] Number of removed instructions: 0
[proguard] Number of removed local variables: 0
[proguard] Number of removed exception blocks: 0
[proguard] Number of optimized local variable frames: 0
[proguard] Obfuscating...
[proguard] Printing mapping to [C:\Users\brilliantservice.brilliant_vaio\anttest\HelloAndroid\obf\mapping.txt]...
[proguard] Writing output...
[proguard] Preparing output jar [C:\Users\brilliantservice.brilliant_vaio\anttest\HelloAndroid\obf\postobf.jar]
[proguard] Copying resources from program jar [C:\Users\brilliantservice.brilliant_vaio\anttest\HelloAndroid\obf\original.jar]
[proguard] Printing classes to [C:\Users\brilliantservice.brilliant_vaio\anttest\HelloAndroid\obf\dump.txt]...

-dex-no-obfuscate:

-post-compile:

-dex:
[echo] Converting compiled files and external libraries into C:\Users\brilliantservice.brilliant_vaio\anttest\HelloAndroid\bin\classes.dex...

-package-resources:
[echo] Packaging resources
[aapt] Creating full resource package...

-package-release:
[apkbuilder] Creating HelloAndroid-unsigned.apk for release...

-release-prompt-for-password:

-release-nosign:

release:
[echo] Signing final apk...
[signjar] Signing JAR: C:\Users\brilliantservice.brilliant_vaio\anttest\HelloAndroid\bin\HelloAndroid-unsigned.apk to C:\Users\brilliantservice.brilliant_vaio\anttest\HelloAndroid\bin\HelloAndroid-unaligned.apk as ky
[signjar] キーストアのパスワードを入力してください:
[echo] Running zip align on final apk...
[echo] Release Package: C:\Users\brilliantservice.brilliant_vaio\anttest\HelloAndroid\bin\HelloAndroid-release.apk

deploy:
[echo] Installing C:\Users\brilliantservice.brilliant_vaio\anttest\HelloAndroid\bin\HelloAndroid-release.apk...
[exec] pkg: /data/local/tmp/HelloAndroid-release.apk
[exec] Success
[exec] 72 KB/s (4211 bytes in 0.057s)

BUILD SUCCESSFUL
Total time: 8 seconds


-dex-obfuscate:のフェーズで[proguard]のログが出力されていれば、ProGuardが適用されています。ログを詳しく見ると、下記のように圧縮、最適化、難読化が行われていることが分かります。




  • [proguard] Shrinking...

  • [proguard] Optimizing...

  • [proguard] Obfuscating...





ProGuard適用前と適用後を比較してみる


実際にProGuardの処理結果を比較して確認してみましょう。





apktoolによるデコンパイル

リエンジニアリングツールであるandroid-apktoolを使って、.apkファイルをデコンパイルし、アプリ内のクラス構成や処理内容を可視化します。





apktoolのシステム要件



  • JRE 1.6 (Java Runtime Environment)

  • 実行パスにaaptコマンドが設定されていること





apktoolのダウンロード

apktoolのダウンロードページから、OSに対応したファイルをダウンロードして下さい。





apktoolのインストール



  1. apktool-install-windows-* ファイルのダウンロード(Windowsの場合)

  2. apktool-* ファイルのダウンロード

  3. 以上の2つのファイルを適当なディレクトリに展開します。





デコンパイルの実行


$ cd <プロジェクトディレクトリ>/bin/
$ apktool d HelloAndroid-release.apk


デコンパイルの結果、HelloAndroid-release.apkのディレクトリ以下に、HelloAndroid-releaseディレクトリが生成され、下記のようなファイルが生成されます。




  • AndroidManifest.xml:アプリのマニフェストファイル

  • apktool.yml:apktoolの処理結果

  • resディレクトリ:アプリに含まれるリソースファイル

  • smaliディレクトリ:アプリの処理手順の解析結果





smaliファイルの比較

最適化や難読化がなされているかどうかは、smaliディレクトリをProGuardを適用しない場合と適用した場合とで見比べてみることで判ります。


ProGuard適用前


ファイル構成:




  • HelloAndroid.smali

  • HelloAndroid$testClass.smali

  • R.smali

  • R$attr.smali

  • R$layout.smali

  • R$string.smali


HelloAndroid.smaliの内容:



.class public Ltest/hello/HelloAndroid;
.super Landroid/app/Activity;
.source "HelloAndroid.java"

# annotations
.annotation system Ldalvik/annotation/MemberClasses;
value = {
Ltest/hello/HelloAndroid$testClass;
}
.end annotation

# direct methods
.method public constructor <init>()V
.locals 0

.prologue
.line 6
invoke-direct {p0}, Landroid/app/Activity;-><init>()V

.line 8
return-void
.end method

.method private testMethod1()V
.locals 3

.prologue
.line 32
const/4 v0, 0x0

.local v0, i:I
const/4 v1, 0x0

.local v1, sum:I
const/16 v2, 0xa

if-ge v0, v2, :cond_0

.line 33
add-int/2addr v1, v0

.line 32
add-int/lit8 v0, v0, 0x1

goto :goto_0

.line 35
return-void
.end method

# virtual methods
.method public onCreate(Landroid/os/Bundle;)V
.locals 1
.parameter "savedInstanceState"

.prologue
.line 23
invoke-super {p0, p1}, Landroid/app/Activity;->onCreate(Landroid/os/Bundle;)V

.line 24
const/high16 v0, 0x7f02

invoke-virtual {p0, v0}, Ltest/hello/HelloAndroid;->setContentView(I)V

.line 25
invoke-direct {p0}, Ltest/hello/HelloAndroid;->testMethod1()V

.line 26
new-instance v0, Ltest/hello/HelloAndroid$testClass;

invoke-direct {v0}, Ltest/hello/HelloAndroid$testClass;-><init>()V

.line 27
return-void
.end method


ProGuard適用しない場合、アプリのファイル構成がそのまま解析結果として出力され、クラス・メソッドの構成、コールシーケンスが丸見えになります。また、内部で使用しているクラス(内部クラスを含む)やメソッド名も判るため、何の処理をしているのかが予測しやすい状態です。





ProGuard適用後


ファイル構成:




  • a.smali

  • HelloAndroid.smali


HelloAndroid.smaliの内容:



.class public Ltest/hello/HelloAndroid;
.super Landroid/app/Activity;

# direct methods
.method public constructor <init>()V
.locals 0

invoke-direct {p0}, Landroid/app/Activity;-><init>()V

return-void
.end method

# virtual methods
.method public onCreate(Landroid/os/Bundle;)V
.locals 1

invoke-super {p0, p1}, Landroid/app/Activity;->onCreate(Landroid/os/Bundle;)V

const/high16 v0, 0x7f02

invoke-virtual {p0, v0}, Ltest/hello/HelloAndroid;->setContentView(I)V

new-instance v0, Ltest/hello/a;

invoke-direct {v0}, Ltest/hello/a;-><init>()V

return-void
.end method


a.smaliの内容:



.class final Ltest/hello/a;
.super Ljava/lang/Object;

# direct methods
.method constructor <init>()V
.locals 0

invoke-direct {p0}, Ljava/lang/Object;-><init>()V

return-void
.end method


ProGuardを適用すると、ファイル構成は「エントリポイントとなるクラスファイル」と「難読化されたクラスファイル」だけとなっており、実際のファイル構成とは異なっています。また、クラスやメソッドの解析に失敗しており、この結果から処理を予測することが難しくなっています。





まとめ


以上のようにProGuardを利用すると簡単な手順で実効性のある難読化を行い、Androidのアプリという知的財産を守ることができます。一方で、JNI経由でネイティブメソッドなどを利用している場合、ProGuardでのビルドに失敗するなど、適用に関わる工数が著しく増大することがあります(いわゆる「ハマる」可能性があるということ)。とはいえ、アプリ中のアルゴリズムや手順、利用している技術が特殊であればあるほど、ProGuardを適用する意味は大きいでしょう。何らかの形でアプリ中の知的財産を守る必要がある場合は、ProGuardの利用を検討してみてはいかがでしょうか。


文責:技術部 植物工場研究G 瀬戸 直喜





2010年11月24日水曜日



ThreeLMの(元GoogleのAndroid統括部長)のトム モスさんから電話があり会ってきました。


みなさんもご存知なようにGoogle Developer Day 2009 Japanで基調講演をされた方ですね。


現在はThreeLMという会社を立ち上げて新しいスタートを切られています。


ThreeLMというのはThree Laws of Mobilesの略でモバイル3原則という意味で、SF作家アイザック・アシモフのロボット3原則からヒントを得たそうです。


凄く日本語が上手で気さくな方でした。


f:id:bs-android:20101123035803j:image


サンフランシスコ国際空港でトム モスさんと


※当然のことながらトム・モスさんの了解を得て掲載しています。





Threelmのトム モスさんに会ってきました



ThreeLMの(元GoogleのAndroid統括部長)のトム モスさんから電話があり会ってきました。


みなさんもご存知なようにGoogle Developer Day 2009 Japanで基調講演をされた方ですね。


現在はThreeLMという会社を立ち上げて新しいスタートを切られています。


ThreeLMというのはThree Laws of Mobilesの略でモバイル3原則という意味で、SF作家アイザック・アシモフのロボット3原則からヒントを得たそうです。


凄く日本語が上手で気さくな方でした。


f:id:bs-android:20101123035803j:image


サンフランシスコ国際空港でトム モスさんと


※当然のことながらトム・モスさんの了解を得て掲載しています。





2010年11月19日金曜日



f:id:bs-android:20101109145845g:image





Androidロボット展示の旅の終着点はロボット縁の地(そしてWilliam Gibson好きにも堪らない)


プラハで開催されたGoogle Developer Day 2010 Pragueです。



f:id:bs-android:20101114000452j:image



プラハではフリーな時間を利用して、市内観光もしてきました。


市内は石畳と古い建物が多く情緒あふれる街並みでした。


プラハでGDDを開催したのは経済の発展が望めること、そして景観が良いからとグーグルの人が言っていたくらいです。





プラハで一番おおきな本屋LUXORにも行ってきました。


Androidの本を探しに! スマートフォンは「ハードウェア」のコーナーにありましたが、Androidの本は置いていません。店員さんに聞いたところチェコ語で書かれたAndroidの本は一冊もないとのことでした。






f:id:bs-android:20101113235944j:image



カレル橋から、市内を流れるヴルタヴァ川(モルダウ)を望む。



f:id:bs-android:20101114002713j:image



観光案内所。セグウェイツアーの文字が見えます。


市内の何箇所かでセグウェイが使われているのを見ました。(セグウェイ屋さんもありました)






f:id:bs-android:20101114011156j:image



市内を走るトラム。線路沿いや道路沿いにはSamsungの企業ロゴが散見されました。


電気屋の商品も、ホテルのTVもSamsung、LGなどが多数でした。









D


観光を終えてホテル入りするAndroidロボット。






f:id:bs-android:20101116021111j:image



GDD前日、Androidロボットの動作確認のために会場へ。


展示スペースのGoogleのパネルの前でおどけるRT社のお二人。






f:id:bs-android:20101116061030j:image



今回、付きっ切りでリモコン操作しなくて済むようにシナリオ再生モードを実装しました。


そして、再生しすぎで(?)首がおかしくなってしまったAndroidロボット。


部屋に戻って修理するRT社西岡さん、とプラハまで来てtwitterなう(の合間にチェコ語のTTSを設定中)な弊社近藤。






f:id:bs-android:20101116173229j:image



当日、会場のCLARION CONGRESS HOTEL PRAGUEエントランス前に貼られた案内。



f:id:bs-android:20101116173327j:image



コングレスフロアーへのエレベーター前に建てられたGoogle Mapsのピン。






f:id:bs-android:20101116173751j:image



キーノート会場でリハーサル中の様子。



f:id:bs-android:20101116173923j:image



開場を待つ参加者。参加者には朝食が振る舞われていました。






f:id:bs-android:20101116182644j:image



キーノートが始まるまでの間、Androidロボットを見にきた参加者。



f:id:bs-android:20101116183624j:image



キーノートが始まりました。


椅子が足りなかったようで、床に座って聴いている人も。


Androidロボットがとても目立つ場所に展示されていることがお分かりいただけるでしょうか。



f:id:bs-android:20101116183038j:image



テーマはChrome & HTML5、 Cloud Computing、Androidです。



f:id:bs-android:20101116193201j:image



ゲストスピーカー、Avast!CEOのセッション。


「Chrome, Android, and HTML5 are great but can we build a business from the Czech Republic?」と始まり、


f:id:bs-android:20101116193437j:image


[Going international」のなかで(潜在顧客として)「Don't forget Japan and France」と述べていました。


他には、Spring RooでApp Engineをライブコーディングするセッションもありました。






f:id:bs-android:20101116195301j:image



キーノートが終わってAndroidロボットを見に来たチェコのGoogle User Group、GUG.czの人たち。


ロボットを見に来てくれた人の意見で多かったのが、リモコンをブラウザインターフェイスにしてURLをQRコードで公開すればいいんじゃない?


というものでした。






f:id:bs-android:20101116225100j:image



GUG.cz主催のMini GUGCampの会場。


チェコのGDDはGoogle以外の出展ブースが少なく、GUG.czとsvetandroidaというところがAndroid端末を展示しているだけでした。






f:id:bs-android:20101116225141j:image



HTML5のセッションは盛況で、立ち見が出ていました。



f:id:bs-android:20101116225555j:image



HTML5に比べると空席の目立つAndroidのセッション、「What's New in the Android Developer's World」


9patchとshape-drawableの比較などを行っていました。



f:id:bs-android:20101117003503j:image



こちらもAndroidのセッション、Developer AdvocateのDan Galpinによる「Close to the Metal: Building with the Android NDK」


NDKを使ったゲーム製作についてのセッションで、「Common Problems」のなかで(G1などの)遅いハードウェア(にインストールして星ひとつをつけるユーザー :p )をマーケットでフィルターする方法として以下の二つが紹介されていました。




  • Open GL Versionでフィルターする



  • CPU Versionでフィルターする方法


    • アプリケーションをARM7向けだけにビルドする


      • (そうするとマーケットはそのアプリケーションをARM7を搭載した端末にしか見えなくする)










f:id:bs-android:20101117041232j:image



セッション終了後のリラックスタイム。


食事とお酒が振る舞われて、2時間まったりムードでした。






D


ミュージシャンと共演するAndroidロボット。






f:id:bs-android:20101117054904j:image



お土産にフィギュアを頂きました。





Google Developer Day 2010 Prague で Androidロボット展示



f:id:bs-android:20101109145845g:image





Androidロボット展示の旅の終着点はロボット縁の地(そしてWilliam Gibson好きにも堪らない)


プラハで開催されたGoogle Developer Day 2010 Pragueです。



f:id:bs-android:20101114000452j:image



プラハではフリーな時間を利用して、市内観光もしてきました。


市内は石畳と古い建物が多く情緒あふれる街並みでした。


プラハでGDDを開催したのは経済の発展が望めること、そして景観が良いからとグーグルの人が言っていたくらいです。





プラハで一番おおきな本屋LUXORにも行ってきました。


Androidの本を探しに! スマートフォンは「ハードウェア」のコーナーにありましたが、Androidの本は置いていません。店員さんに聞いたところチェコ語で書かれたAndroidの本は一冊もないとのことでした。






f:id:bs-android:20101113235944j:image



カレル橋から、市内を流れるヴルタヴァ川(モルダウ)を望む。



f:id:bs-android:20101114002713j:image



観光案内所。セグウェイツアーの文字が見えます。


市内の何箇所かでセグウェイが使われているのを見ました。(セグウェイ屋さんもありました)






f:id:bs-android:20101114011156j:image



市内を走るトラム。線路沿いや道路沿いにはSamsungの企業ロゴが散見されました。


電気屋の商品も、ホテルのTVもSamsung、LGなどが多数でした。









D


観光を終えてホテル入りするAndroidロボット。






f:id:bs-android:20101116021111j:image



GDD前日、Androidロボットの動作確認のために会場へ。


展示スペースのGoogleのパネルの前でおどけるRT社のお二人。






f:id:bs-android:20101116061030j:image



今回、付きっ切りでリモコン操作しなくて済むようにシナリオ再生モードを実装しました。


そして、再生しすぎで(?)首がおかしくなってしまったAndroidロボット。


部屋に戻って修理するRT社西岡さん、とプラハまで来てtwitterなう(の合間にチェコ語のTTSを設定中)な弊社近藤。






f:id:bs-android:20101116173229j:image



当日、会場のCLARION CONGRESS HOTEL PRAGUEエントランス前に貼られた案内。



f:id:bs-android:20101116173327j:image



コングレスフロアーへのエレベーター前に建てられたGoogle Mapsのピン。






f:id:bs-android:20101116173751j:image



キーノート会場でリハーサル中の様子。



f:id:bs-android:20101116173923j:image



開場を待つ参加者。参加者には朝食が振る舞われていました。






f:id:bs-android:20101116182644j:image



キーノートが始まるまでの間、Androidロボットを見にきた参加者。



f:id:bs-android:20101116183624j:image



キーノートが始まりました。


椅子が足りなかったようで、床に座って聴いている人も。


Androidロボットがとても目立つ場所に展示されていることがお分かりいただけるでしょうか。



f:id:bs-android:20101116183038j:image



テーマはChrome & HTML5、 Cloud Computing、Androidです。



f:id:bs-android:20101116193201j:image



ゲストスピーカー、Avast!CEOのセッション。


「Chrome, Android, and HTML5 are great but can we build a business from the Czech Republic?」と始まり、


f:id:bs-android:20101116193437j:image


[Going international」のなかで(潜在顧客として)「Don't forget Japan and France」と述べていました。


他には、Spring RooでApp Engineをライブコーディングするセッションもありました。






f:id:bs-android:20101116195301j:image



キーノートが終わってAndroidロボットを見に来たチェコのGoogle User Group、GUG.czの人たち。


ロボットを見に来てくれた人の意見で多かったのが、リモコンをブラウザインターフェイスにしてURLをQRコードで公開すればいいんじゃない?


というものでした。






f:id:bs-android:20101116225100j:image



GUG.cz主催のMini GUGCampの会場。


チェコのGDDはGoogle以外の出展ブースが少なく、GUG.czとsvetandroidaというところがAndroid端末を展示しているだけでした。






f:id:bs-android:20101116225141j:image



HTML5のセッションは盛況で、立ち見が出ていました。



f:id:bs-android:20101116225555j:image



HTML5に比べると空席の目立つAndroidのセッション、「What's New in the Android Developer's World」


9patchとshape-drawableの比較などを行っていました。



f:id:bs-android:20101117003503j:image



こちらもAndroidのセッション、Developer AdvocateのDan Galpinによる「Close to the Metal: Building with the Android NDK」


NDKを使ったゲーム製作についてのセッションで、「Common Problems」のなかで(G1などの)遅いハードウェア(にインストールして星ひとつをつけるユーザー :p )をマーケットでフィルターする方法として以下の二つが紹介されていました。




  • Open GL Versionでフィルターする



  • CPU Versionでフィルターする方法


    • アプリケーションをARM7向けだけにビルドする


      • (そうするとマーケットはそのアプリケーションをARM7を搭載した端末にしか見えなくする)










f:id:bs-android:20101117041232j:image



セッション終了後のリラックスタイム。


食事とお酒が振る舞われて、2時間まったりムードでした。






D


ミュージシャンと共演するAndroidロボット。






f:id:bs-android:20101117054904j:image



お土産にフィギュアを頂きました。





2010年11月14日日曜日



本日「FeliCaハッカソン」が日経BPさん主催で行われました。


FeliCaハッカソンは、Androidで初めてFeliCaチップが載るIS03端末を使用して、FeliCaAPIを使ったアプリを一日掛けて開発するイベントです。


当日行われた資料とコードはGoogle Codeにアップされ、開催模様はUSTにて録画されております。


参加メンバー


事前応募された開発者約20名、スタッフはKDDIさん・SHARPさん・フェリカネットワークさん・日経BPさん・ブリリアントサービスの5社から各社2-6名ほど加えた計40名近く集まったハッカソンとなりました。


弊社はハッカソンの講師を担当させて頂きました。


午前中のセッション


KDDIさんとSHARPさんによるIS03の説明と、フェリカネットワークさんによるFeliCaAPI利用方法の解説が行われました。
フェリカネットワークさんによるプレゼン資料及びサンプルコードがGoogle Code上に公開されています。


午後のハッカソン


SHARPさんとフェリカネットワークさんも加えた9チームに別れ、約5時間に渡り開発が行われました。
初めはFeliCaAPIで何が出来るかが分からず、何が出来るかをディスカッションする事に時間が掛かってしまいましたが、作りたい物が決まってからは各自もくもくと開発が進められていました。


夕方の成果物発表会


チーム毎による成果物のプレゼンテーションが行われました。


以下、チーム毎にどのようなアプリを開発されたかの概要になります。


伝言ゲーム

言葉そのままではなく、文字を一部変換して他端末に送るゲーム。
送られた人は、変換された文字を推測し、修正した文字を他の端末に送っていきます。


スタンドアローン

試しに色んな情報をPushする実験を行われていました。
GoogleNaviはロケールが日本だと起動しないが、intentなら起動するようです。


共有コミュニケーション

ブラウザで観覧中のURLや地図、Youtube、電話番号、メールアドレスをPush送信できるアプリ。
一番のミソはPushするまでの時間を任意に決められ、その間は他端末とタッチ出来るのでタッチコミュニケーション時間を多く取りたいだけ取れます。


潜水艦ゲーム

Pushする際に端末の背面同士を引っ付けるため、相手画面が見えない特性を生かした潜水艦ゲームを作られていました。


フェリカで相性占い

FeliCaチップ毎に持っているIDを使った相性占い。を作る予定が、FeliCaAPIにてIDが取得出来ない事が分かりました。


Taico

端末に1つ音声をインストールしておき、FeliCaリーダーにかざすとその音が鳴るアプリ。
色んな端末に別々の音声を入れておけばハンドベルになります。


ブラックジャック

複数端末で行うトランプのブラックジャックをするアプリ。
各端末には自分の手札が表示され、ホスト端末にタッチする事でゲームが進行します。


うさぎクラブ

タッチすると受信端末内にインストールされているアプリが起動されます。


チーム串かつ

FeliCaAPIを知らない人でもFeliCaを使えるラッパーの実装。
それを使った電話番号をタッチで交換して、どこで誰と電話番号を交換したか記憶するアプリが作られました。


結果発表


1位「共有コミュニケーション」、2位「チーム串かつ」、3位は「うさぎクラブ」チームでした。
1位チームの勝因は、アプリ完成度とプレゼン方法が上手かったのだと思われます。


チーム別のソースはGoogle CodeにSVN管理されています。


全体を通しての感想


全体的にレベルが高く。
午前中にFeliCaAPIを聞いてから、午後の数時間でここまでの完成度なアプリを作れてしまうのは凄いと思いました。


技術力の高い開発者の方々が集まり、KDDIさんからご提供頂いた豊富な端末数があり、SHARPさん・フェリカネットワークスさんの技術的サポートがあり、日経BPさんが開発しやすい環境をセッティング頂けた事にあると思います。


どうもありがとうございました。





FeliCaハッカソンが開催されました



本日「FeliCaハッカソン」が日経BPさん主催で行われました。


FeliCaハッカソンは、Androidで初めてFeliCaチップが載るIS03端末を使用して、FeliCaAPIを使ったアプリを一日掛けて開発するイベントです。


当日行われた資料とコードはGoogle Codeにアップされ、開催模様はUSTにて録画されております。


参加メンバー


事前応募された開発者約20名、スタッフはKDDIさん・SHARPさん・フェリカネットワークさん・日経BPさん・ブリリアントサービスの5社から各社2-6名ほど加えた計40名近く集まったハッカソンとなりました。


弊社はハッカソンの講師を担当させて頂きました。


午前中のセッション


KDDIさんとSHARPさんによるIS03の説明と、フェリカネットワークさんによるFeliCaAPI利用方法の解説が行われました。
フェリカネットワークさんによるプレゼン資料及びサンプルコードがGoogle Code上に公開されています。


午後のハッカソン


SHARPさんとフェリカネットワークさんも加えた9チームに別れ、約5時間に渡り開発が行われました。
初めはFeliCaAPIで何が出来るかが分からず、何が出来るかをディスカッションする事に時間が掛かってしまいましたが、作りたい物が決まってからは各自もくもくと開発が進められていました。


夕方の成果物発表会


チーム毎による成果物のプレゼンテーションが行われました。


以下、チーム毎にどのようなアプリを開発されたかの概要になります。


伝言ゲーム

言葉そのままではなく、文字を一部変換して他端末に送るゲーム。
送られた人は、変換された文字を推測し、修正した文字を他の端末に送っていきます。


スタンドアローン

試しに色んな情報をPushする実験を行われていました。
GoogleNaviはロケールが日本だと起動しないが、intentなら起動するようです。


共有コミュニケーション

ブラウザで観覧中のURLや地図、Youtube、電話番号、メールアドレスをPush送信できるアプリ。
一番のミソはPushするまでの時間を任意に決められ、その間は他端末とタッチ出来るのでタッチコミュニケーション時間を多く取りたいだけ取れます。


潜水艦ゲーム

Pushする際に端末の背面同士を引っ付けるため、相手画面が見えない特性を生かした潜水艦ゲームを作られていました。


フェリカで相性占い

FeliCaチップ毎に持っているIDを使った相性占い。を作る予定が、FeliCaAPIにてIDが取得出来ない事が分かりました。


Taico

端末に1つ音声をインストールしておき、FeliCaリーダーにかざすとその音が鳴るアプリ。
色んな端末に別々の音声を入れておけばハンドベルになります。


ブラックジャック

複数端末で行うトランプのブラックジャックをするアプリ。
各端末には自分の手札が表示され、ホスト端末にタッチする事でゲームが進行します。


うさぎクラブ

タッチすると受信端末内にインストールされているアプリが起動されます。


チーム串かつ

FeliCaAPIを知らない人でもFeliCaを使えるラッパーの実装。
それを使った電話番号をタッチで交換して、どこで誰と電話番号を交換したか記憶するアプリが作られました。


結果発表


1位「共有コミュニケーション」、2位「チーム串かつ」、3位は「うさぎクラブ」チームでした。
1位チームの勝因は、アプリ完成度とプレゼン方法が上手かったのだと思われます。


チーム別のソースはGoogle CodeにSVN管理されています。


全体を通しての感想


全体的にレベルが高く。
午前中にFeliCaAPIを聞いてから、午後の数時間でここまでの完成度なアプリを作れてしまうのは凄いと思いました。


技術力の高い開発者の方々が集まり、KDDIさんからご提供頂いた豊富な端末数があり、SHARPさん・フェリカネットワークスさんの技術的サポートがあり、日経BPさんが開発しやすい環境をセッティング頂けた事にあると思います。


どうもありがとうございました。





2010年11月13日土曜日



現地時刻2010年11月12日18時から在チェコ共和国日本国大使館でロボットについてとGoogle Androidに関する講演をしました。





チェコ、プラハにある日本大使館前です。日の丸の国旗と菊の御紋があります。


f:id:bs-android:20101113005814j:image


f:id:bs-android:20101113044532j:image





弊社の杉本は、Google Androidに関して、日本には日本Androidの会という会があるということ、ブリリアントサービスの取組みについて、Google Androidとロボットとクラウドコンピューティングがなぜ関連するのか?の説明などをしました。


f:id:bs-android:20101113033203j:image





ロボットに関する説明は株式会社アールティの代表取締役の中川さんが説明します。IT(Information technology)とRT(Robot technology)がどの様に関係するのかを説明。プラハにはGoogleさんから招待されてAndroid ロボを展示しブリリアントサービスと一緒に来たという話も。


f:id:bs-android:20101113032047j:image





会場はすごい熱気でした。30人の部屋が入れずにイスを急遽50席に増やしましたがそれでも足りなかったようです。会場に入りきれない人が廊下から講演を聞いていました。


f:id:bs-android:20101113034418j:image





Androidスマートフォンの所持者も数多くみられました、みなさんAdnroidよりもロボットに興味があるようで熱心に質問されてました。外務省のチェコ日本大使館の皆様へ、このような機会をいただきましてありがとうございます!





チェコ プラハ 日本大使館でAndroidとロボットの講演しました



現地時刻2010年11月12日18時から在チェコ共和国日本国大使館でロボットについてとGoogle Androidに関する講演をしました。





チェコ、プラハにある日本大使館前です。日の丸の国旗と菊の御紋があります。


f:id:bs-android:20101113005814j:image


f:id:bs-android:20101113044532j:image





弊社の杉本は、Google Androidに関して、日本には日本Androidの会という会があるということ、ブリリアントサービスの取組みについて、Google Androidとロボットとクラウドコンピューティングがなぜ関連するのか?の説明などをしました。


f:id:bs-android:20101113033203j:image





ロボットに関する説明は株式会社アールティの代表取締役の中川さんが説明します。IT(Information technology)とRT(Robot technology)がどの様に関係するのかを説明。プラハにはGoogleさんから招待されてAndroid ロボを展示しブリリアントサービスと一緒に来たという話も。


f:id:bs-android:20101113032047j:image





会場はすごい熱気でした。30人の部屋が入れずにイスを急遽50席に増やしましたがそれでも足りなかったようです。会場に入りきれない人が廊下から講演を聞いていました。


f:id:bs-android:20101113034418j:image





Androidスマートフォンの所持者も数多くみられました、みなさんAdnroidよりもロボットに興味があるようで熱心に質問されてました。外務省のチェコ日本大使館の皆様へ、このような機会をいただきましてありがとうございます!





2010年11月10日水曜日



f:id:bs-android:20101109145845g:image


GoogleよりミュンヘンとプラハのGoogle Developer Day 2010(以下GDD)に招待され、まずはミュンヘンのGDDで展示を行ったの巻、の続きです。


f:id:bs-android:20101109203409j:image


男性比率が高かったのですが、特に女性に大人気でした。プラハのGDDでは簡易占い機能でも付けようかと思います。


f:id:bs-android:20101110004228j:image





表にあったでっかいGoogle風船


f:id:bs-android:20101110011038j:image





RTの社長の中川さん。わが子に対するような愛情を感じるショット。


f:id:bs-android:20101110023112j:image





セッションがひと通り終わり、2Fに移動すると、そこにはドイツらしく、ビールが振舞われました。


f:id:bs-android:20101110033809j:image





当然のように生ビールも!


f:id:bs-android:20101110033850j:image


f:id:bs-android:20101110043633j:image





オリゼーっぽいどろいどくん(仮称)


f:id:bs-android:20101110034131j:image





そんな中、blinkendroidというアプリを使った、ギネスへの挑戦が始まっていました。


f:id:bs-android:20101110040423j:image


f:id:bs-android:20101110040453j:image





参加者から借りたAndroidデバイスを並べて、ひとつの大きなディスプレイとして使うという面白い試みです。


下の写真は端末を並べたところを上から撮影したもの。


静止画なのでわかりませんが、実際にはぐりぐりと端末をまたいで動画がうごいています。


f:id:bs-android:20101110041816j:image


f:id:bs-android:20101110041817j:image





81台の端末が揃って、見事にギネス認定されたようです!


f:id:bs-android:20101110042452j:image





blinkendroid、是非日本でもやって、ギネス記録を塗り替えたいですね!





帰り際になって、たくさんの人達が記念写真に押し寄せました。


取り外し可能な耳(?)を自分につけて写真を撮るのが大流行。耳をかじる人まで出てきました。


f:id:bs-android:20101110045745j:image





展示途中、電源の線が切れたり、ネットワークが不調になったりなどのトラブルがありましたが、なんとか上手く乗り切ることができました!


ミュンヘンのGDDは東京のGDDに比べてると、ゲームコーナーやフリードリンク、朝食、昼食などがあったり、会場に響き渡るBGMでよい雰囲気を醸しだしており、Google I/Oの雰囲気に非常に近い感じでした。


今年のミュンヘンGDDの参加者は1100人だったそうです。





次は自律行動させるなど、プラハに向けてさらにレベルアップしたいと思います!





Google Developer Day 2010 MunchenでAndroidロボ展示(続き)



f:id:bs-android:20101109145845g:image


GoogleよりミュンヘンとプラハのGoogle Developer Day 2010(以下GDD)に招待され、まずはミュンヘンのGDDで展示を行ったの巻、の続きです。


f:id:bs-android:20101109203409j:image


男性比率が高かったのですが、特に女性に大人気でした。プラハのGDDでは簡易占い機能でも付けようかと思います。


f:id:bs-android:20101110004228j:image





表にあったでっかいGoogle風船


f:id:bs-android:20101110011038j:image





RTの社長の中川さん。わが子に対するような愛情を感じるショット。


f:id:bs-android:20101110023112j:image





セッションがひと通り終わり、2Fに移動すると、そこにはドイツらしく、ビールが振舞われました。


f:id:bs-android:20101110033809j:image





当然のように生ビールも!


f:id:bs-android:20101110033850j:image


f:id:bs-android:20101110043633j:image





オリゼーっぽいどろいどくん(仮称)


f:id:bs-android:20101110034131j:image





そんな中、blinkendroidというアプリを使った、ギネスへの挑戦が始まっていました。


f:id:bs-android:20101110040423j:image


f:id:bs-android:20101110040453j:image





参加者から借りたAndroidデバイスを並べて、ひとつの大きなディスプレイとして使うという面白い試みです。


下の写真は端末を並べたところを上から撮影したもの。


静止画なのでわかりませんが、実際にはぐりぐりと端末をまたいで動画がうごいています。


f:id:bs-android:20101110041816j:image


f:id:bs-android:20101110041817j:image





81台の端末が揃って、見事にギネス認定されたようです!


f:id:bs-android:20101110042452j:image





blinkendroid、是非日本でもやって、ギネス記録を塗り替えたいですね!





帰り際になって、たくさんの人達が記念写真に押し寄せました。


取り外し可能な耳(?)を自分につけて写真を撮るのが大流行。耳をかじる人まで出てきました。


f:id:bs-android:20101110045745j:image





展示途中、電源の線が切れたり、ネットワークが不調になったりなどのトラブルがありましたが、なんとか上手く乗り切ることができました!


ミュンヘンのGDDは東京のGDDに比べてると、ゲームコーナーやフリードリンク、朝食、昼食などがあったり、会場に響き渡るBGMでよい雰囲気を醸しだしており、Google I/Oの雰囲気に非常に近い感じでした。


今年のミュンヘンGDDの参加者は1100人だったそうです。





次は自律行動させるなど、プラハに向けてさらにレベルアップしたいと思います!







Google Developer Day 2010 Munchenの朝。 


Googleさんに招待頂き2010年11月9日 ドイツ ミュンヘン(MOC Munich Order Center)で開催されたGoogle Developer Day 2010 ミュンヘンにAndroidで動くアンドロイド(ロボット)を展示しました。その様子を写真付きで紹介します。


f:id:bs-android:20101109145845g:image


f:id:bs-android:20101109153121j:image


f:id:bs-android:20101109154703j:image


朝6時20分会場に着きました。気温2.5度寒い!まだ暗いですが会場内はすでに行列ですごい熱気です。会場にAndroidロボを設置の準備にかかりました。ドイツの人達にもかなりAnroidロボは興味を持っていただいたようです。


f:id:bs-android:20101109155944j:image


f:id:bs-android:20101109162503j:image


f:id:bs-android:20101109161042j:image


f:id:bs-android:20101109160152j:image


さすがドイツ、ベーコンやサラミを使ったサンドイッチが振舞われました。


すごく美味しいです。





Google Developer Day 2010 MunchenでAndroidロボ展示



Google Developer Day 2010 Munchenの朝。 


Googleさんに招待頂き2010年11月9日 ドイツ ミュンヘン(MOC Munich Order Center)で開催されたGoogle Developer Day 2010 ミュンヘンにAndroidで動くアンドロイド(ロボット)を展示しました。その様子を写真付きで紹介します。


f:id:bs-android:20101109145845g:image


f:id:bs-android:20101109153121j:image


f:id:bs-android:20101109154703j:image


朝6時20分会場に着きました。気温2.5度寒い!まだ暗いですが会場内はすでに行列ですごい熱気です。会場にAndroidロボを設置の準備にかかりました。ドイツの人達にもかなりAnroidロボは興味を持っていただいたようです。


f:id:bs-android:20101109155944j:image


f:id:bs-android:20101109162503j:image


f:id:bs-android:20101109161042j:image


f:id:bs-android:20101109160152j:image


さすがドイツ、ベーコンやサラミを使ったサンドイッチが振舞われました。


すごく美味しいです。





Related Posts Plugin for WordPress, Blogger...