我一直使用adb backup备份Nexus 7,以将所有文件备份到加密备份中。我看到您可以使用adb restore从备份中还原,但这会擦除设备上所有现有的数据。

我如何从该加密的备份文件中提取一个应用程序的数据呢?

评论

另请参阅:有没有办法查看和修改adb备份创建的文件?

我相信没有使用Java的答案都不会在加密电话上起作用。请参阅以下我的答案,总结使用nelenkov的应用程序(github.com/nelenkov/android-backup-extractor)。不幸的是,Izzy的Adebar perl脚本ab2tar不适用于加密的备份文件。相似:android.stackexchange.com/questions/23357/…

相关-dd if = data.ab bs = 1 skip = 24 | openssl zlib -d | tar -xvf-提到了stackoverflow.com/questions/18533567/…

#1 楼

如何提取ab文件
有一个由Apache Nikolay Elenkov编写的Apache 2.0许可下的开源项目,它允许您将.ab提取到tar文件中。
用法:
java -jar abe.jar unpack <backup.ab> <backup.tar> <password>

背景
这里只是.ab文件格式的背景知识。
Android Backup(* .ab)文件是压缩的TAR文件。使用DEFLATE算法对其进行压缩。最重要的是,可以使用AES加密。这是在创建备份时确定的,如果您输入密码,则备份将被加密,否则;没有加密,只能压缩。
文件的HEADER与普通的DEFLATE存档略有不同。它包含有关备份的信息,如下所示:
ANDROID BACKUP
1
1
none

第一行是“ Magic”行。下一行是Android备份文件格式的版本。下一行是指示文件是否被压缩的布尔型(真或假,1或0)。最后一行是加密类型。本示例未使用任何加密。如果有密码,该行将显示为“ AES-256”。之后是加密密码。如果没有密码,然后放气“档案”启动。
这是使用Java Deflater压缩。从开发人员的角度来看,如果您想使用Java以外的任何方式来提取它,则会导致问题。即使我发现的所有内容(例如C#)都应该遵循“ SPEC”,也无法使用相同的算法找到任何可以缩小它的内容。
如果不确定如何真正使用Droid Explorer(不在此答案的范围之内),因为v0.8.8.7(在此处可用)允许您完全从Explorer执行此操作,并且可以执行更多操作。您可以在我的博客上阅读有关功能的更多信息(是的,我知道,无耻的插件。我会在适合问题时这样做)


评论


如果我有声誉,我会投票给你,我的上帝,谢谢!

–user11553
2012年8月30日在1:41

别客气。我只知道所有这些信息,因为这是我最近添加到Droid Explorer代码库中的一项功能,因此我必须对此进行一些研究。

–瑞安·康拉德(Ryan Conrad)
2012年8月30日在1:44

嗨,瑞安(Ryan),您尝试使用Droid Explorer,但即使安装了Android SDK,而且我提供的路径正确,它也无法开始抱怨Android SDK的位置。

– Umar Farooq Khawaja
2014年1月1日的16:11

@UmarFarooqKhawaja查看droid资源管理器的常见问题解答。最后一个问题解答解决了您的问题。

–瑞安·康拉德(Ryan Conrad)
2014年1月2日,下午1:21

好的,已经从tar中提取了相关的'com.app.name'文件夹,但是我该如何使用它来恢复应用程序数据呢?只是将文件夹复制到sdcard / Android / data /似乎不起作用...

–茎
2014年4月27日在0:07

#2 楼

或使用单线:

( printf "\x1f\x8b\x08\x00\x00\x00\x00\x00" ; tail -c +25 backup.ab ) |  tar xfvz -


评论


真好!您是否也具有“ pack”的等同功能(以获取未压缩的目录树并创建一个.db文件)?

–dailyglen
2015年5月3日23:46

您能在答案中添加解释吗?

–幸运
15年7月31日在9:23

这是最好的答案:D可以很好地工作!立即提取。

–xdevs23
16年4月1日在17:43

说明:作者使用printf命令为.tar.gz文件创建一个标准的Zlib文件头(0x1F 0x8B是签名,0x08是压缩方法,0x00是标志,4 x 0x00是时间戳),然后将内容附加到此头从偏移25d开始的backup.ab文件。这样的流是有效的.tar.gz文件,并且tar xfvz命令将其识别为这样,因此可以成功解压缩该流。

–蒽酮
16年6月12日在7:31



我使用adb 1.0.36(修订版1.7.0.0 + r33-2)进行了备份,此方法从zgip中产生了一个错误:无效的压缩数据-违反了格式

–拉奇
17年11月21日在19:42

#3 楼

另一种选择是使用bashcatgunzipgzip)。

完整的过程可能是这样的(使用未加密的备份):



备份一个应用程序的数据(例如“覆盖KitKat的DNS”):

$ adb backup -f net.mx17.overridedns.ab -noapk net.mx17.overridedns
Now unlock your device and confirm the backup operation.



提取压缩数据

$ dd if=net.mx17.overridedns.ab bs=1 skip=24 > compressed-data
1285+0 records in
1285+0 records out
1285 bytes (1,3 kB) copied, 0,00745877 s, 172 kB/s



解压缩压缩的数据

$ printf "\x1f\x8b\x08\x00\x00\x00\x00\x00" \
    | cat - compressed-data | gunzip -c > decompressed-data.tar
gzip: stdin: unexpected end of file




$ tar xf decompressed-data.tar




评论


是否可以预期“文件意外结束”?

–hft
16 Sep 2'在23:57

2中的提取出人意料地对加密文件起作用。这怎么可能?然后解压缩失败,并显示gzip:stdin:无效的压缩数据-违反格式。我假设提取成功,因为dd在22763821 + 0条记录中报告了22763821 + 0条记录。

–汤姆·罗素
18年7月31日在2:28



@TomRussell提取仅从开始处修剪字节。

–所罗门·乌科(Solomon Ucko)
4月25日22:33

#4 楼

根据其他人的信息,现在我知道备份文件只是前缀的Deflated(GZip)流,基于此信息,此简单程序可以为您解压缩该文件:

import java.io.*;
import java.util.zip.*;

/** Run: javac unab.java && java unab backupfile.ab */
public class unab {
    private static final int BACKUP_HEADER_LENGTH = 24;
    public static void main(String[] args) throws IOException {
        InputStream in = new FileInputStream(args[0]);
        try {
            OutputStream out = new FileOutputStream(args[0] + ".tar");
            try {
                if (in.skip(BACKUP_HEADER_LENGTH) != BACKUP_HEADER_LENGTH) {
                    throw new IOException("Unexpected end of file while skipping backup header.");
                }
                byte[] buffer = new byte[100 * 1024];
                int count;
                InputStream zip = new InflaterInputStream(in);
                while ((count = zip.read(buffer)) > 0) {
                    out.write(buffer, 0, count);
                }
            } finally {
                out.close();
            }
        } finally {
            in.close();
        }
    }
}


我写这篇文章是因为我没有上面提到的任何Unix工具,并且比安装Cygwin或其他工具更容易。



跨平台
简单(无深奥参数)
不需要管道工具



需要JDK(您可能已经拥有了它,因为您弄乱了Android SDK)
不支持加密备份
需要一些东西来提取生成的tar文件(我使用Total Commander)

要使其成为命令行工具,请创建内容为unab.batjava -cp "%~dp0." unab %*和目录为PATH

#5 楼

同样隐式的问题是,如何还原单个应用程序数据,我想提到这个漂亮的脚本,该脚本将给定的full-backup.ab拆分为single-app.ab文件:

https ://sourceforge.net/projects/adb-split/

它需要jar文件:abe.jar和tar-bin-split.jar
,可以在这里找到:


https://sourceforge.net/projects/adbextractor/files/
https://sourceforge.net/projects/tar-binary-splitter/files/

它至少对我的测试用例有效。

#6 楼

另一个选择是使用此XDA线程中的Perl AdbBackupRoutines。但是,它们有一些要求:Perl加上libterm-readkey-perllibcrypt-cbc-perllibcrypt-pbkdf2-perl(如果您的备份未加密,则可以通过简单地注释掉backupdecrypt.pl的103行(包括它的行)来跳过最后一个依赖项-对我来说很好用)。

用法非常简单:

./backupdecrypt.pl [options] <backupfile.ab> <outfile.tar>


然后可以像对待其他tarball一样调查生成的.tar文件。它的结构至少在一个方面很有趣:它不反映文件取自的真实路径(例如,不是/data/data/com.app.name/databases/whatever.db,而是apps/com.app.name/db/whatever.db),这表明在一个设备/ ROM上备份的应用程序可能是可以毫无问题地恢复到其他任何设备/ ROM,因为adb restore必须找出真实路径。

评论


还有另一个工具(维护得更好一点)可以做到这一点:github.com/nelenkov/android-backup-extractor

–盖
15年5月23日在15:22

谢谢,@ lid!我的工具Adebar(Android DEvice备份和报告)中还包含了一个小的shell脚本(几乎只有一个脚本),该脚本将ADB备份(.ab)转换为.tar.gz存档:)

– Izzy♦
15年5月23日在15:27

#7 楼

只是为了增加其他答案,我终于使用nelenkov的应用程序(https://github.com/nelenkov/android-backup-extractor)和此处的说明获得了它:https://forum.xda-developers.com/showthread.php ?t = 2011811。我试图避免为Java占用额外的800mb磁盘空间。默认情况下,大多数电话都朝着加密迈进,我认为nelenkov的应用程序是唯一可与加密配合使用的解决方案。

这里是nelenkov的jar编译版本的直接链接。检查其是否最新:https://github.com/nelenkov/android-backup-extractor/releases/tag/20181012025725-d750899

然后按照上面的链接中的说明进行操作。它具有有关氦气以及将ab文件拆分为单个应用程序文件的更多信息。还有一种更改未设置为不使用root的adb备份的应用程序的方法。如果使用此发行版文件,请替换abe-all.jar


1)将原始adb备份转换为tar格式:

java -jar abe.jar unpack nexus7.ab nexus7.tar <password>

2)提取tar归档文件的内容。这应该在保存了tar内部文件权限的
文件系统上完成,例如使用linux,mac或bsd。最多可能出现两个文件夹,应用程序和共享文件夹:

tar -xvf nexus7.tar


顺便说一句,Izzy的回答很好(https://android.stackexchange.com/a/42224/95893),但是他的脚本需要几个perl模块安装后,我找不到第三。他的应用程序功能齐全,但可以在Adebar-master / tools /中找到adb2tar。同样,它不适用于加密的ab文件。