有没有办法查看和修改adb备份创建的文件?


40

我使用创建了Galaxy Nexus的备份adb backup。生成的文件名为backup.db,并以某种方式进行了加密。

我想还原备份,但是在还原时它停止了com.android.providers.contacts。我曾经adb logcat了解正在发生的事情,com.android.acore并发现在还原过程中崩溃了。

我想访问备份中的数据,并删除通讯录数据库以将所有内容恢复到我的手机中。还有其他方法可以从备份中还原数据吗?

Answers:


14

除非您在创建备份时指定,否则文件不会加密。但是,它已压缩(使用放气)。您可以通过查看Android源代码(com / android / server / BackupManagerService.java)找出确切的格式,并且从技术上讲应该可以从中提取特定数据。但是,IIRC进行了一些文件完整性检查,因此,如果仅从文件中删除一堆数据,它很可能将无法工作。不幸的是,该restore命令似乎没有选择仅还原特定应用程序/软件包或排除软件包的选项。


谢谢!这至少是查看文件内部的起点。如果我没有为备份提供密码,那会更容易。
ingorichter

如果您提供了密码,则它确实是加密的。BackupManagerService包含有关实际加密算法的详细信息,并且密钥派生参数(盐,迭代计数等)写在文件头中。由于您知道密码,因此可以派生密钥并解密数据。因此,它仍然可行,但并非特别简单……

是的,我目前正在从中提取所有BackupManagerService内容以读取备份文件的内容。这是一项
艰巨

@ingorichter有什么进展吗?
2012年

@ingorichter我开始研究此问题,并在“社区Wiki”答案中在下面发布了大量注释。随时添加。
2012年

50

我开始研究这个。到目前为止,我将我的结果作为“社区Wiki”答案发布在这里,其原因有两个:第一,如果其他人想加入,那么有个交流的地方。第二,如果我不参与这个项目,就会有其他人开始工作的提示。

 

主机上的备份逻辑完全包含在名为的函数中的https://github.com/android/platform_system_core/blob/master/adb/commandline.cppbackup。该函数非常简单:它验证命令行选项,将命令大部分原样发送到电话上的adb守护程序,并将电话的输出写入文件。甚至没有错误检查:例如,如果您拒绝手机上的备份,adb只需写出一个空文件。

在电话中,逻辑备份开始于service_to_fd()https://github.com/android/platform_system_core/blob/master/adb/services.cpp。该函数标识来自主机的命令为"backup",并将未解析的命令传递给/system/bin/bu,这是一个琐碎的Shell脚本,可以com.android.commands.bu.Backup作为新的Android应用程序进程的主类启动。调用ServiceManager.getService("backup")将备份服务作为进行获取IBackupManager,并调用IBackupManager.fullBackup(),将仍未使用的文件描述符(非常间接地)传递给该backup.ab文件,该文件描述符已连接到主机上的文件。

控制转到fullBackup()com.android.server.backup.BackupManagerService,其中弹出/图形用户界面询问用户以确认拒绝备用。用户这样做时,acknowledgeFullBackupOrRestore()将调用(相同的文件)。如果用户批准了该请求,acknowledgeFullBackupOrRestore()则确定备份是否已加密,然后将消息传递到BackupHandler(相同文件。)BackupHandler然后实例化并启动PerformAdbBackupTask(在编写本文时,相同的文件,第4004行

我们终于开始在PerformAdbBackupTask.run()4151 4330行之间的那里开始生成输出

首先,run()写一个标头,它由4或9个ASCII行组成:

  1. "ANDROID BACKUP"
  2. 备份格式版本:当前 "4"
  3. 或者"0"如果备份未压缩或者"1"如果它是
  4. 加密方法:当前"none"或者"AES-256"
  5. (如果已加密),则用十六进制编码的“用户密码盐”,大写
  6. (如果已加密),则以十六进制编码的“主密钥校验和盐”,全部大写
  7. (如果已加密),则“使用的PBKDF2轮数”为十进制数字:当前 "10000"
  8. (如果已加密),则以十六进制编码的“用户密钥的IV”,全部大写
  9. (如果已加密),则以十六进制编码的“主IV +密钥blob,由用户密钥加密”,全部大写

实际备份数据如下,无论是作为(取决于压缩和加密)tardeflate(tar)encrypt(tar),或encrypt(deflate(tar))

 

TODO:写出生成tar输出的代码路径-只要条目按正确的顺序即可使用tar(请参见下文)。

Tar存档格式

应用程序数据存储在app /目录下,以_manifest文件,a /中的APK(如果需要),f /中的应用程序文件,db /中的数据库以及sp /中的共享首选项开头。如果您请求外部存储备份(使用-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

加密细节

  1. 使用10000轮PBKDF2和随机生成的512位盐从备份加密密码中获得AES 256密钥。
  2. 随机生成AES 256主密钥
  3. 通过使用新随机生成的512位盐通过10000轮PBKDF2运行主密钥来生成主密钥“校验和”。
  4. 生成一个随机备份加密IV。
  5. IV,主密钥和校验和与从1中派生的密钥进行连接和加密。生成的Blob作为十六进制字符串保存在标头中。
  6. 实际的备份数据使用主密钥加密,并附加到文件末尾。

打包/解压缩代码实现示例(生产/使用)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


如果您将代码放在某个地方,我也许可以加入。OP(@ngorichter)可能现在也有一些工作代码:)解压缩并提取实际文件的实用程序可能会很有用,因此您只能还原部分(如果您具有root用户)。
Nikolay Elenkov

1
至于加密部分,我必须查找它的详细信息,但是密钥是使用PBKDF2由Salt和设备解锁PIN,密码或模式(转换为字符串)派生的。主密钥是随机生成的,并使用源自密码的密钥进行加密。首先将其用于未加密的档案。如果您遇到问题,可以实施解密部分。
Nikolay Elenkov

抱歉,该密钥实际上是根据您在开始备份时指定的密码得出的。
尼古拉·埃伦科夫

@NikolayElenkov我还没有任何代码,但是我打算写一个实用程序来操纵Ab文件。Wrt加密,我认为这并不困难;只是我只看了一眼那部分代码。同样,我已经跟踪了生成tar流的代码路径(尚未在上面编写),但尚未检查实际格式是否为GNU tar。
2012年

哇,您的分析给我留下了深刻的印象。我从BackupManagerService中提取了一些代码到一个简单的Groovy脚本中,但是当我运行该程序时,结果总是一样的:输入了错误的密码!我使用简单的密码创建了一个新备份,但是密码验证再次失败。目前,我尝试按照上述程序查找错误。
ingorichter

7

尼古拉·埃伦科夫Nikolay Elenkov)给出了详尽而详尽的答案。但是,我应该补充一点,有人已经开发了可以执行此操作的软件,并将其打包在此处:http : //sourceforge.net/projects/adbextractor/

该软件包包含Java和Perl工具。我自己每天都比Java更喜欢Perl,因此我提取了Perl代码,确保它们可执行,安装了所需的Perl库,并backupdecrypt.pl针对adb备份文件运行,然后将其转换为tar或gzip压缩的tar文件,问题。

我什至在Bash 3中形成了一个衬板,使我可以直接将adb备份到压缩的tar文件中:

adb backup -f >(backupdecrypt.pl -D -z - backup.tgz) -all

希望能帮助到你。


6
是的,他们打包了我编写的工具(Java编写的工具):)我还帮助将其移植到Perl。如果你没看过的README文件,它可能不会立即显现的书面记录来第一次,然后在工具....
尼古拉Elenkov

我已进行备份,但尚未创建.ab文件,而是已创建.backup文件。我想知道如何提取它。此外,我不确定是否已将所有照片和视频作为备份?
hajirazin

-4

要浏览现有的备份文件,请尝试http://www.adb-backup.com页面,它很简单,没有“ dd”,“ tar”,...

数据未存储在此服务器上。我开发了此在线服务,以使其更轻松地查看备份而无需使用dd / tar或安装其他软件。我是www.adb-backup.com


7
对于将adb备份(并提供密码)上传到随机网站,我会非常小心... adb备份中包含的数据是私有的,您无法知道该站点对备份的处理方式。它可能无害,但我不建议您这样做。
bmdixon

根据Metasmoke的说法,这是垃圾邮件网址。除此之外,我完全同意@bmdixon的意见-尤其是在存在安全方式的情况下,请务必在本地执行任务。
伊齐

@Izzy无论如何,我将其标记为垃圾邮件并将其报告给SmokeDetector。
iBug

数据未存储在此服务器上。我开发了此在线服务,以使其更轻松地查看备份而无需使用dd / tar或安装其他软件。我是作者www.adb-backup.com
Liszak,
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.