adb backup 。生成的文件名为backup.db，它是某种方式加密。
adb logcat ，了解正在发生的事情，并发现
I created a backup of my Galaxy Nexus with
adb backup. The resulting file is named backup.db and it's somehow encrypted.
I wanted to restore the backup, but it stops when it comes to restoring
com.android.providers.contacts. I used
adb logcat to find out what's going on and found out that
com.android.acore crashes during the restore process.
I'd like to gain access to the data in the backup and remove the contacts database to restore everything back to my phone. Are there any other ways restoring the data from the backup?
I started working on this. I'm posting my results so far here as a "community wiki" answer for two reasons: first, if someone else wants to join in, there's a place to talk; second, if I get pulled away from this project, there'll be hints for someone else to start working.
The backup logic on the host is entirely contained within https://github.com/android/platform_system_core/blob/master/adb/commandline.cpp, in the function named
backup. The function is very simple: it validates the command line options, sends the command mostly as-is to the adb daemon on the phone, and writes the phone's output to the file. There isn't even error-checking: if, for example, you refuse the backup on the phone,
adb just writes out an empty file.
On the phone, the backup logic starts in
service_to_fd() in https://github.com/android/platform_system_core/blob/master/adb/services.cpp. The function identifies that the command from the host is
"backup", and passes the unparsed command to
/system/bin/bu, which is a trivial shell script to launch
com.android.commands.bu.Backup as the main-class of a new Android app process. That calls
ServiceManager.getService("backup") to get the backup service as an
IBackupManager, and calls
IBackupManager.fullBackup(), passing it the still-unused file descriptor (very indirectly) connected to the
backup.ab file on the host.
Control passes to
fullBackup() in com.android.server.backup.BackupManagerService, which pops up the GUI asking the user to confirm/reject the backup. When the user do so,
acknowledgeFullBackupOrRestore() (same file) is called. If the user approved the request,
acknowledgeFullBackupOrRestore() figures out if the backup is encrypted, and passes a message to
BackupHandler (same file.)
BackupHandler then instantiates and kicks off a
PerformAdbBackupTask (same file, line 4004 as of time of writing)
We finally start generating output there, in
PerformAdbBackupTask.run(), between line 4151 and line 4330.
run() writes a header, which consists of either 4 or 9 ASCII lines:
"0"if the backup is uncompressed or
"1"if it is
The actual backup data follows, either as (depending on compression and encryption)
TODO: write up the code path that generates the tar output -- you can simply use tar as long as entries are in the proper order (see below).
Tar archive format
App data is stored under the app/ directory, starting with a _manifest file, the APK (if requested) in a/, app files in f/, databases in db/ and shared preferences in sp/. If you requested external storage backup (using the -shared option), there will also be a shared/ directory in the archive containing external storage files.
$ 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
Sample pack/unpack code implementation (produces/uses) tar archives: https://github.com/nelenkov/android-backup-extractor
Some more details here: http://nelenkov.blogspot.com/2012/06/unpacking-android-backups.html
Perl scripts for packing/unpacking and fixing broken archives:
The file is not encrypted, unless your specify so when creating the backup. It is however compressed (using deflate). You can find out the exact format by looking at Android source (com/android/server/BackupManagerService.java) code, and, technically, should be able to extract specific data from it. However, IIRC, there are some file integrity checks in place, so it most probably won't work if you just delete a bunch of data from it. Unfortunately the
restore command doesn't seem to have an option to restore a particular app/package only or exclude a package.
Great and detailed answer from Nikolay Elenkov. However I should added that somebody already develop a software that do just that and package it here: http://sourceforge.net/projects/adbextractor/
The package contains both Java and Perl tool. I myself prefer Perl over Java any day, so I extracted the Perl codes, make sure they are executable, installed the required Perl library, and run the
backupdecrypt.pl against an adb backup file, and it convert it into a tar or gzipped tar file without any issue.
I even formed a one liner in Bash 3 that allow me to do adb backup directly to gzipped tar file:
adb backup -f >(backupdecrypt.pl -D -z - backup.tgz) -all
Hope it helps.
For explore existing backup file, try http://www.adb-backup.com page, it is simple without "dd", "tar", ...
Data is not stored on this server. I've developed this online service to make it easier to view backups without manipulating with dd / tar or installing additional software. I'm author www.adb-backup.com