adb backup で特定のアプリをバックアップし、中身をPC(Mac)で確認する

Androidにインストールされている特定のアプリをバックアップし、中身を表示する手順を紹介します。

なお、これらの手順でアプリケーションのファイルを解析したり、逆コンパイルしたりすることは、一般的には利用規約などによって禁止されているはずです。
自分が作ったアプリケーションの解析目的以外では実行しないようお願いします。


## 環境
AndroidをUSBケーブルでMacに接続し、adbコマンドが使える状態になっていることを前提とします。
手元では下記の環境で動作確認しました。

- Mac OS X 10.11.6
	- JDK 1.8.0
	- Android SDK Platform-tools 24.0.3
- Android 7.1.1

なお、該当アプリの `AndroidManifest.xml` で下記のように設定されている場合、後述の手順では展開できなくなります。

```
<application
	android:allowBackup="false"
	...
```


## バックアップの取得

バックアップしたいアプリのパッケージ名を `com.example.testapp` とします。
Macのターミナルで任意のディレクトリに移動し、下記のように実行します。

```
adb backup -apk com.example.testapp
```

実行すると、Android端末側にパスワード入力画面が表示されます。任意のパスワードを入力し、[データをバックアップ]をタップするとバックアップが実行されます。

バックアップが完了すると、adbコマンドを実行したカレントディレクトリに `backup.ab` というファイルが生成されます。


## バックアップファイルの展開

バックアップしたファイルは、`Android Backup Extractor`というツールを使うと展開できます。

- https://sourceforge.net/projects/adbextractor/

上記よりダウンロードした.zipファイルを解凍すると、`abe.jar` というファイルがあり、これがツールの実体になります。
今回はこのjarファイルを直接起動してバックアップを展開します。

先程バックアップを保存したディレクトリに `abe.jar` ファイルを移動し、下記のように実行します。

```
java -jar abe.jar unpack backup.ab backup.tar <バックアップ時に入力したパスワード>
```

しかし、下記のようなエラーが出て展開できませんでした。
Javaでは、デフォルトだとAESの鍵長が128bitしか扱えないようなので、ポリシーファイルを書き換える必要があります。

```
$ java -jar abe.jar unpack backup.ab backup.tar password
Password is set but strong AES encryption is not allowed
Please install Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files 7 or 8
http://www.oracle.com/technetwork/java/javase/downloads/jce-7-download-432124.html
http://www.oracle.com/technetwork/java/javase/downloads/jce8-download-2133166.html
Exiting.
```

今回はJDK1.8を使用しているため後者のURLからポリシーファイルをダウンロードし、書き換えます。
JDKのインストール場所は下記コマンドで調べられました。

```
$ /usr/libexec/java_home
/Library/Java/JavaVirtualMachines/jdk1.8.0_102.jdk/Contents/Home
```

念のため、元のポリシーファイルをバックアップして、ダウンロードしたポリシーファイルに置き換えます。

```
cd /Library/Java/JavaVirtualMachines/jdk1.8.0_102.jdk/Contents/Home/jre/lib/security/
sudo cp US_export_policy.jar US_export_policy.jar.orig
sudo cp local_policy.jar local_policy.jar.orig

sudo cp ~/Downloads/UnlimitedJCEPolicyJDK8/US_export_policy.jar .
sudo cp ~/Downloads/UnlimitedJCEPolicyJDK8/local_policy.jar .
```

これで、最初にエラーになった下記コマンドを実行できるようになりました。

```
java -jar abe.jar unpack backup.ab backup.tar <バックアップ時に入力したパスワード>
```

tarファイルを展開すると、.apk ファイルを含むバックアップデータが確認できます。
openFileOutput()で保存したデータや、SharedPreferencesで保存されたデータも丸見えですね。。

APKの逆コンパイルについては下記など、多くの解説があるので省略します。

- http://qiita.com/chibi929/items/940623d33d9f6eb3877f


## まとめ
adb backupコマンドでバックアップしたファイルの中身を確認する手順を解説しました。

`AndroidManifest.xml` の設定において、 `android:allowBackup="true"` になっている場合、端末のroot化なども必要なく簡単に内部データを取得・展開できるようになってしまうため、本番アプリを作成する際には注意が必要です。



## 参考
- AndroidManifest.xml の設定項目
	- https://developer.android.com/guide/topics/manifest/application-element.html
- Java SE
	- http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html
- Android SDK
	- https://developer.android.com/studio/index.html?hl=ja
- MacでインストールされているJDKバージョンの確認
	- http://qiita.com/mas0061/items/2fe9333f045800d00b5c
- AndroidでUSBデバッグを有効にする
	- https://developer.android.com/studio/run/device.html#setting-up
- `adb` コマンドのオプションについて
	- http://qiita.com/niusounds/items/7b4959c3b1c1272d6c9a
- 暗号強度の制限について
	- http://blog.scheakur.com/post/50807486592/%E3%81%AA%E3%81%9C-java-cryptography-extension-jce-unlimited
- allowBackupの設定について
	- http://qiita.com/bowyer-app/items/76e86c7303de8784a8bd