Android のバックアップファイルを展開する
Android 4.0 以降?でサポートされた adb backup
で生成されるファイルを展開してみた。
AOSP とか読まずにネットで拾った情報からだが,
という構造らしい。
# backup2tar.py import sys, zlib buflen = 4096 f = open(sys.argv[1], 'rb') try: if f.readline() != "ANDROID BACKUP\x0a": raise IOError, "Invalid backup file" if f.readline() != "1\x0a": raise IOError, "Invalid version number" if f.readline() != "1\x0a": raise IOError, "Invalid version number" if f.readline() != "none\x0a": raise IOError, "Encrypted backup file is not supported" z = zlib.decompressobj() while True: buf = f.read(buflen) if len(buf) <= 0: break decompressed = z.decompress(buf) sys.stdout.write(decompressed) decompressed = z.flush() sys.stdout.write(decompressed) sys.stdout.flush() finally: f.close()
tar による展開まではやっていないので,
$ python backup2tar.py backup_file | tar xvf -
のように tar コマンドと組み合わせて使う。
tar アーカイブの中身は,基本的に対象パッケージの /data/data
ディレクトリの内容物をまとめたものであるようだ。ただし _manifest
ファイルの構造はわからなかった。
Python の tarfile
モジュールを使えば tar 部分までやってやれなくはないのだが,uid / gid 等の情報*1を失うのがイヤなので,とりあえず tar 形式に変換する部分まで作った。
逆に tar アーカイブからバックアップ形式に変換するスクリプトはこちら。
# tar2backup.py import sys, zlib buflen = 4096 f = open(sys.argv[1], 'rb') try: sys.stdout.write("ANDROID BACKUP\x0a1\x0a1\x0anone\x0a") z = zlib.compressobj(9) while True: buf = f.read(buflen) if len(buf) <= 0: break compressed = z.compress(buf) sys.stdout.write(compressed) compressed = z.flush() sys.stdout.write(compressed) sys.stdout.flush() finally: f.close()