私はこれに取り組み始めました。ここでは、2つの理由で「コミュニティwiki」の回答として結果を投稿しています。1つ目は、他の誰かが参加したい場合、話し合う場所があることです。第二に、私がこのプロジェクトから引き離された場合、他の誰かが作業を開始するためのヒントがあります。
ホストのバックアップロジックは、https://github.com/android/platform_system_core/blob/master/adb/commandline.cppの名前が付けられた関数に完全に含まれていますbackup
。この関数は非常に単純です。コマンドラインオプションを検証し、コマンドをほとんどそのまま電話のadbデーモンに送信し、電話の出力をファイルに書き込みます。エラーチェックすらありません。たとえば、電話でのバックアップを拒否adb
した場合、空のファイルを書き出すだけです。
電話では、バックアップロジックはhttps://github.com/android/platform_system_core/blob/master/adb/services.cppで開始さservice_to_fd()
れます。この関数は"backup"
、ホストからのコマンドがであることを識別し、未解析のコマンドをに渡します/system/bin/bu
。これは、新しいAndroidアプリプロセスのメインクラスとして起動する簡単なシェルスクリプトcom.android.commands.bu.Backup
です。これはServiceManager.getService("backup")
、バックアップサービスを取得するためIBackupManager
にを呼び出しIBackupManager.fullBackup()
、を呼び出しbackup.ab
て、ホスト上のファイルに接続された(非常に間接的に)未使用のファイル記述子を渡します。
制御fullBackup()
はcom.android.server.backup.BackupManagerServiceに移り、ユーザーにバックアップの確認/拒否を求めるGUIがポップアップ表示されます。ユーザーがそうすると、acknowledgeFullBackupOrRestore()
(同じファイル)が呼び出されます。ユーザーがリクエストを承認しacknowledgeFullBackupOrRestore()
、バックアップが暗号化されているかどうかを判断し、メッセージをBackupHandler
(同じファイルに)渡し、BackupHandler
インスタンス化して開始しますPerformAdbBackupTask
(同じファイル、執筆時点の行4004)。
最後にPerformAdbBackupTask.run()
、行4151と行4330の間で、出力の生成を開始します。
最初に、run()
4行または9行のASCII行で構成されるヘッダーを書き込みます。
"ANDROID BACKUP"
- バックアップ形式のバージョン:現在
"4"
- いずれかの
"0"
バックアップが圧縮されていない場合、または"1"
それがある場合
- 暗号化方式:現在
"none"
または"AES-256"
- (暗号化されている場合)、16進数でエンコードされた「ユーザーパスワードソルト」、すべて大文字
- (暗号化されている場合)、16進数でエンコードされた「マスターキーチェックサムソルト」、すべて大文字
- (暗号化されている場合)、10進数としての「使用されたPBKDF2ラウンドの数」:現在
"10000"
- (暗号化されている場合)、16進数でエンコードされた「ユーザーキーのIV」、すべて大文字
- (暗号化されている場合)、16進数でエンコードされた「ユーザーIVで暗号化されたマスターIV +キーBLOB」、すべて大文字
実際のバックアップデータ(圧縮および暗号化に依存する)のいずれかとして、以下tar
、deflate(tar)
、encrypt(tar)
、またはencrypt(deflate(tar))
。
TODO:tar出力を生成するコードパスを作成します。エントリが適切な順序である限り、単純にtarを使用できます(以下を参照)。
タールアーカイブ形式
アプリデータは、_manifestファイル、a /のAPK(要求された場合)、f /のアプリファイル、db /のデータベース、sp /の共有設定で始まるapp /ディレクトリの下に保存されます。外部ストレージのバックアップを要求した場合(-sharedオプションを使用)、外部ストレージファイルを含むアーカイブ内のshared /ディレクトリもあります。
$ tar tvf mybackup.tar
-rw------- 1000/1000 1019 2012-06-04 16:44 apps/org.myapp/_manifest
-rw-r--r-- 1000/1000 1412208 2012-06-02 23:53 apps/org.myapp/a/org.myapp-1.apk
-rw-rw---- 10091/10091 231 2012-06-02 23:41 apps/org.myapp/f/share_history.xml
-rw-rw---- 10091/10091 0 2012-06-02 23:41 apps/org.myapp/db/myapp.db-journal
-rw-rw---- 10091/10091 5120 2012-06-02 23:41 apps/org.myapp/db/myapp.db
-rw-rw---- 10091/10091 1110 2012-06-03 01:29 apps/org.myapp/sp/org.myapp_preferences.xml
暗号化の詳細
- AES 256キーは、ランダムに生成された512ビットのソルトで10000ラウンドのPBKDF2を使用して、バックアップ暗号化パスワードから取得されます。
- AES 256マスターキーがランダムに生成されます
- マスターキー「チェックサム」は、ランダムに生成された新しい512ビットソルトを使用して、PBKDF2の10000ラウンドでマスターキーを実行することによって生成されます。
- ランダムバックアップ暗号化IVが生成されます。
- IV、マスターキー、およびチェックサムは、1で導出されたキーで連結および暗号化されます。結果のblobは、16進文字列としてヘッダーに保存されます。
- 実際のバックアップデータはマスターキーで暗号化され、ファイルの最後に追加されます。
サンプルパック/アンパックコードの実装(プロデュース/使用)tarアーカイブ:https : //github.com/nelenkov/android-backup-extractor
詳細はこちら:http : //nelenkov.blogspot.com/2012/06/unpacking-android-backups.html
壊れたアーカイブをパック/アンパックおよび修正するためのPerlスクリプト:
http://forum.xda-developers.com/showthread.php?p=27840175#post27840175