Wie extrahieren Sie die Daten einer App aus einem vollständigen Backup, das mit „adb backup“ erstellt wurde?

117

Ich habe mein Nexus 7 mit adb backupgesichert, um alle Dateien in einem verschlüsselten Backup zu sichern. Ich sehe, dass Sie von einem Backup mit wiederherstellen können adb restore, aber das würde alle meine vorhandenen Daten auf dem Gerät löschen.

Wie genau würde ich die Daten einer App aus dieser verschlüsselten Sicherungsdatei extrahieren?

Ryan Conrad
quelle

Antworten:

113

Hier finden Sie Hintergrundinformationen zum .ab-Dateiformat.

Die Android-Sicherungsdatei (* .ab) ist eine komprimierte TAR- Datei. Es wird mit dem DEFLATE- Algorithmus komprimiert . Darüber hinaus kann eine AES-Verschlüsselung verwendet werden. Dies wird beim Erstellen der Sicherung festgelegt. Wenn Sie ein Kennwort eingeben, wird die Sicherung verschlüsselt. Es gibt keine Verschlüsselung, es wird nur komprimiert.

Der HEADER der Datei unterscheidet sich ein wenig von einem normalen DEFLATE-Archiv. Es enthält Informationen zur Sicherung und sieht folgendermaßen aus:

ANDROID BACKUP
1
1
none

Die erste Zeile ist die "Magic" -Zeile . Die nächste Zeile ist die Version des Android Backup-Dateiformats. Die nächste Zeile ist ein Boolescher Wert (true oder false, 1 oder 0), der angibt, ob die Datei komprimiert ist. Die letzte Zeile gibt die Art der Verschlüsselung an. In diesem Beispiel wird keine Verschlüsselung verwendet. Wenn es ein Passwort gäbe, würde die Zeile "AES-256" lauten. Danach folgt die Verschlüsselung. Wenn kein Passwort vorhanden ist, startet das DEFLATE "Archiv".

Es wird mit dem Java Deflater komprimiert . Was aus Entwicklersicht zu Problemen führt, wenn Sie etwas anderes als Java zum Extrahieren verwenden möchten. Ich habe mit dem gleichen Algorithmus nichts gefunden, das die Luft entleeren könnte, obwohl alles, was ich gefunden habe (zum Beispiel C #), dem "SPEC" folgen soll.

Vor diesem Hintergrund gibt es ein Open-Source-Projekt unter der Apache 2.0-Lizenz von Nikolay Elenkov , mit dem Sie die .ab-Datei in eine tar-Datei extrahieren können.

Verwendungszweck:

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

Wenn Sie sich nicht sicher sind, wie Sie das wirklich verwenden sollen (was über den Rahmen dieser Antwort hinausgeht), können Sie mit der nächsten Version von Droid Explorer v0.8.8.7 ( hier verfügbar ) genau dies und mehr direkt aus dem Explorer heraus tun. Sie können mehr über die Funktionen in meinem Blog lesen (ja, ich weiß, schamloser Stecker. Ich mache das, wenn es die Frage passt)

auspacken

Ryan Conrad
quelle
1
Ich würde dich wählen, wenn ich den Ruf hätte, mein Gott, danke!
ihr willkommen. Ich kenne nur all diese Informationen, da dies eine Funktion ist, die ich kürzlich zur Droid Explorer-Codebasis hinzugefügt habe, sodass ich einige Nachforschungen anstellen musste.
Ryan Conrad
Hallo Ryan, ich habe versucht, Droid Explorer zu verwenden, aber es klagt nicht über den Speicherort des Android SDK, obwohl es installiert ist und ich den richtigen Pfad angeben kann.
Umar Farooq Khawaja
@UmarFarooqKhawaja Schauen Sie sich die FAQ für den Droiden-Explorer an. Das letzte Q / A befasst sich mit Ihrem Problem.
Ryan Conrad
OK, habe den entsprechenden Ordner 'com.app.name' aus dem tar extrahiert, aber wie verwende ich das, um die App-Daten wiederherzustellen? Das einfache Kopieren des Ordners auf die SD-Karte / Android / data / scheint nicht zu funktionieren ...
Pelms
91

Oder mit einem Einzeiler:

( printf "\x1f\x8b\x08\x00\x00\x00\x00\x00" ; tail -c +25 backup.ab ) |  tar xfvz -
Kari
quelle
2
Nett! Haben Sie auch das Äquivalent von "pack" (um den unkomprimierten Verzeichnisbaum zu nehmen und eine .db-Datei zu erstellen)?
Täglich
4
Können Sie der Antwort eine Erklärung hinzufügen?
Lucky
2
DAS ist die beste Antwort: D Funktioniert einwandfrei! Jetzt extrahieren.
xdevs23
16
Erläuterung: Der Autor erstellt einen Standard-Zlib-Dateikopf für eine .tar.gzDatei mit dem printfBefehl ( 0x1F 0x8Bist eine Signatur, 0x08ist die Komprimierungsmethode, 0x00sind Flags und 4 x 0x00ist ein Zeitstempel). Anschließend wird der Inhalt der backup.abDatei beginnend mit Offset 25d an diesen Kopf angehängt . Ein solcher Stream ist eine gültige .tar.gzDatei, und der tar xfvzBefehl erkennt ihn als solche, sodass er den Stream erfolgreich dekomprimieren kann.
Antonone
3
Ich habe ein Backup mit adb 1.0.36 (Revision 1.7.0.0 + r33-2) erstellt und diese Methode hat einen Fehler von zgip erzeugt:invalid compressed data--format violated
Rache
31

Eine weitere Option ist die Verwendung bash, catund gunzip( gzip).

Der vollständige Vorgang kann wie folgt aussehen ( mit einer unverschlüsselten Sicherung ):

  1. Sichern Sie die Daten einer App (zum Beispiel " DNS für KitKat überschreiben "):

    $ adb backup -f net.mx17.overridedns.ab -noapk net.mx17.overridedns
    Now unlock your device and confirm the backup operation.
    
  2. extrahieren Sie die komprimierten Daten

    $ 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
    
  3. Dekomprimieren Sie die komprimierten Daten

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

    $ tar xf decompressed-data.tar
    
MaxChinni
quelle
4
Ist das "unerwartete Dateiende" zu erwarten?
hft
Die Extraktion in 2 funktionierte überraschenderweise auf einer verschlüsselten Datei. Wie ist das möglich? Die Dekompression schlug dann mit fehl gzip: stdin: invalid compressed data--format violated. Ich gehe davon aus, die Extraktion erfolgreich ist, wie ddberichtet 22763821+0 records in 22763821+0 records out.
Tom Russell
4

Eine andere Option ist die Verwendung der Perl AdbBackupRoutines aus diesem XDA-Thread . Sie haben jedoch ein paar Anforderungen: Perl natürlich plus libterm-readkey-perl, libcrypt-cbc-perlund libcrypt-pbkdf2-perl(wenn Ihre Backups unverschlüsselt sind, können Sie die letzte Abhängigkeit überspringen, indem Sie einfach Zeile 103 auskommentieren, backupdecrypt.plwo sie enthalten ist - hat für mich gut funktioniert).

Die Bedienung ist ganz einfach:

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

Die resultierende .tarDatei kann dann wie jeder andere Tarball untersucht werden. Die Struktur ist zumindest in einer Hinsicht sehr interessant: Sie spiegelt nicht die tatsächlichen Pfade wider, von denen die Dateien stammen (z. B. nicht /data/data/com.app.name/databases/whatever.db, sondern apps/com.app.name/db/whatever.db) - was darauf hinweist, dass eine App, die auf einem Gerät / ROM gesichert wurde, möglicherweise wiederhergestellt wird jedes andere Gerät / ROM ohne Probleme, wie adb restoredie tatsächlichen Pfade selbst herausfinden müssen.

Izzy
quelle
Es gibt ein anderes Tool (etwas besser gewartet), das dies erledigt: github.com/nelenkov/android-backup-extractor
lid
Danke, @lid! Ich habe meinem Tool Adebar (Android DEvice Backup And Report) auch ein kleines Shell-Skript (fast nur einzeilig) beigefügt, das ADB-Backups ( .ab) in .tar.gzArchive konvertiert :)
Izzy
4

Aufgrund der Informationen von anderen weiß ich jetzt, dass die Sicherungsdatei nur ein vorangestellter GZip-Stream (Deflated Stream) ist. Auf der Grundlage dieser Informationen kann dieses einfache Programm sie für Sie entpacken:

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();
        }
    }
}

Ich habe dies geschrieben, weil ich keines der oben genannten Unix-Tools besitze und es einfacher war, Cygwin oder andere Tools zu installieren.

Vorteile :

  • plattformübergreifend
  • einfach (keine esoterischen Parameter)
  • Keine Rohrwerkzeuge erforderlich

Nachteile :

  • brauche ein JDK (das du wahrscheinlich schon hast, weil du mit Android SDK rumspielst)
  • Keine Unterstützung für verschlüsselte Backups
  • brauche etwas, um die resultierende tar-Datei zu extrahieren (ich benutze Total Commander)

Um es zu einem Befehlszeilentool zu machen, erstellen Sie es unab.batmit Inhalt: java -cp "%~dp0." unab %*und dem Verzeichnis zu PATH.

TWiStErRob
quelle
4

Da die implizite Frage auch ist, wie einzelne Anwendungsdaten wiederhergestellt werden können, möchte ich dieses raffinierte Skript erwähnen, das eine gegebene full-backup.ab in single-app.ab-Dateien aufteilt:

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

Es werden die JAR-Dateien benötigt: abe.jar und tar-bin-split.jar, die hier zu finden sind:

Zumindest für meinen Testfall hat es funktioniert.

joe_zeroh
quelle