我一直在备份Nexus 7,并将adb backup
所有文件备份到加密备份中。我发现您可以使用进行备份还原adb restore
,但这会擦除设备上所有现有的数据。
我如何从该加密的备份文件中提取一个应用程序的数据?
我一直在备份Nexus 7,并将adb backup
所有文件备份到加密备份中。我发现您可以使用进行备份还原adb restore
,但这会擦除设备上所有现有的数据。
我如何从该加密的备份文件中提取一个应用程序的数据?
Answers:
仅供参考,以下是.ab文件格式的一些背景知识。
Android备份(* .ab)文件是压缩的TAR文件。使用DEFLATE算法对其进行压缩。最重要的是,可以使用AES加密。这是在创建备份时确定的,如果输入密码,则备份将被加密,否则;没有加密,只有压缩。
文件的HEADER与普通的DEFLATE存档略有不同。它包含有关备份的信息,如下所示:
ANDROID BACKUP
1
1
none
第一行是“魔术”行。下一行是Android备份文件格式的版本。下一行是布尔值(true或false,1或0),指示文件是否已压缩。最后一行是加密类型。本示例未使用任何加密。如果有密码,该行将显示为“ AES-256”。之后是加密密码。如果没有密码,则开始DEFLATE“归档”。
它使用Java Deflater压缩。从开发人员的角度来看,如果您想使用Java以外的任何方式来提取它,则会导致问题。即使我发现的所有内容(例如C#)都应该遵循“ SPEC”,也无法使用相同的算法找到任何可以缩小它的内容。
话虽如此,有一个由Apache Nikolay Elenkov编写的Apache 2.0许可下的开源项目,它允许您将.ab提取到tar文件中。
用法:
java -jar abe.jar unpack <backup.ab> <backup.tar> <password>
如果您不确定如何真正使用它(超出了此答案的范围),则下一版Droid Explorer v0.8.8.7(在此处可用)将使您可以直接从Explorer执行此操作,以及执行更多操作。您可以在我的博客上阅读有关功能的更多信息(是的,我知道,无耻的插件。我会在适合问题时这样做)
或单线:
( printf "\x1f\x8b\x08\x00\x00\x00\x00\x00" ; tail -c +25 backup.ab ) | tar xfvz -
.tar.gz
使用printf
命令(0x1F 0x8B
是签名,0x08
压缩方法,0x00
标志和4x 0x00
是时间戳)为命令创建文件的标准Zlib文件头,然后将backup.ab
文件内容附加到此头,从偏移25d开始。这样的流是有效.tar.gz
文件,并且tar xfvz
命令可以将其识别为有效文件,因此它可以成功解压缩该流。
invalid compressed data--format violated
还有一个选择是使用bash
,cat
和gunzip
(gzip
)。
整个过程可能是这样的(使用未加密的备份):
备份一个应用程序的数据(例如“ 为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文件
$ tar xf decompressed-data.tar
gzip: stdin: invalid compressed data--format violated
。我认为提取成功,如dd
报告所示22763821+0 records in 22763821+0 records out
。
另一个选择是使用此XDA线程中的Perl AdbBackupRoutines 。但是,它们有一些要求:Perl加上libterm-readkey-perl
,libcrypt-cbc-perl
和libcrypt-pbkdf2-perl
(如果您的备份未加密,则可以通过简单地注释掉backupdecrypt.pl
其中包含的行103来跳过最后一个依赖项-对我来说很好用)。
用法很简单:
./backupdecrypt.pl [options] <backupfile.ab> <outfile.tar>
.tar
然后可以像其他任何tarball一样调查生成的文件。其结构是在至少一个方面很有趣:它不反映文件已经从采取的实际路径(例如没有/data/data/com.app.name/databases/whatever.db
,而是apps/com.app.name/db/whatever.db
) -这表明一个设备上的应用程序备份/ ROM 可能恢复到任何其他设备/ ROM都不会遇到麻烦,因为adb restore
必须弄清楚实际路径本身。
根据其他人的信息,现在我知道备份文件只是前缀的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或其他工具容易。
优点:
缺点:
要使其成为命令行工具,请创建unab.bat
内容为:java -cp "%~dp0." unab %*
的目录为PATH
。
同样隐式的问题是,如何还原单个应用程序数据,我想提到这个漂亮的脚本,该脚本将给定的full-backup.ab拆分为single-app.ab文件:
https://sourceforge.net/projects/adb-split/
它需要jar文件:abe.jar和tar-bin-split.jar,可以在这里找到:
它至少对我的测试用例有效。