Comment extraire les données d'une application à partir d'une sauvegarde complète effectuée via «sauvegarde adb»?

117

J'ai sauvegardé mon Nexus 7 avec adb backuppour sauvegarder tous les fichiers dans une sauvegarde cryptée. Je vois que vous pouvez restaurer à partir d'une sauvegarde avec adb restore, mais cela effacerait toutes mes données existantes sur le périphérique.

Comment puis-je extraire les données d'une application à partir de ce fichier de sauvegarde crypté?

Ryan Conrad
la source
3
Voir aussi: Existe
Izzy

Réponses:

113

Juste pour la référence des autres, voici quelques informations sur le format de fichier .ab.

Le fichier de sauvegarde Android (* .ab) est un fichier TAR compressé . Il est compressé à l'aide de l' algorithme DEFLATE . En plus de cela, il peut y avoir un cryptage AES utilisé. Ceci est déterminé lors de la création de la sauvegarde. Si vous entrez un mot de passe, la sauvegarde est cryptée, sinon; il n'y a pas de cryptage, il est seulement compressé.

L'en-tête du fichier est un peu différent d'une archive DEFLATE normale. Il contient des informations sur la sauvegarde et se présente comme suit:

ANDROID BACKUP
1
1
none

La première ligne est la ligne "Magic" . La ligne suivante est la version du format de fichier de sauvegarde Android. La ligne suivante est un booléen (vrai ou faux, 1 ou 0) indiquant si le fichier est compressé. La dernière ligne est le type de cryptage. Cet exemple n'utilise aucun chiffrement. S'il y avait un mot de passe, la ligne se lirait "AES-256". Après c'est le chiffrement de chiffrement. S'il n'y a pas de mot de passe, "l'archive" DEFLATE démarre.

Il est compressé à l'aide de Java Deflater . Du point de vue des développeurs, cela pose des problèmes si vous souhaitez utiliser quelque chose en plus de Java pour l'extraire. Je n'ai pas été capable de trouver quoi que ce soit qui puisse le dégonfler en utilisant le même algorithme, même si tout ce que j'ai trouvé (comme C #) est supposé suivre le "SPEC".

Cela dit, il existe un projet open source sous licence Apache 2.0, écrit par Nikolay Elenkov, qui vous permettra d'extraire le fichier .ab dans un fichier tar.

Usage:

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

Si vous ne savez pas vraiment comment l'utiliser (ce qui dépasse le cadre de cette réponse), la prochaine version de Droid Explorer v0.8.8.7 ( disponible ici ) vous permettra de faire exactement cela, et plus encore, directement depuis Explorer. Vous pouvez en savoir plus sur les fonctionnalités de mon blog (oui, je sais, plug éhonté. Je le fais quand ça correspond à la question)

déballer

Ryan Conrad
la source
1
Je te voterais si j'avais la réputation, mon dieu merci!
vous êtes le bienvenu. Je ne connais que toutes ces informations, car il s’agit d’une fonctionnalité que j’ai récemment ajoutée à la base de code de Droid Explorer; j’ai donc dû effectuer quelques recherches.
Ryan Conrad
Bonjour Ryan, a essayé d'utiliser Droid Explorer, mais il ne parvient pas à se plaindre de l'emplacement du SDK Android, même s'il est installé et que je fournis le bon chemin.
Umar Farooq Khawaja
@UmarFarooqKhawaja Jetez un coup d'œil à la FAQ pour l'explorateur de droïdes. La dernière question / réponse porte sur votre problème.
Ryan Conrad
OK, avez extrait le dossier 'com.app.name' approprié du fichier tar, mais comment l'utiliser pour restaurer les données de l'application? Copier simplement le dossier sur sdcard / Android / data / ne semble pas fonctionner ...
pelms
91

Ou avec un one-liner:

( printf "\x1f\x8b\x08\x00\x00\x00\x00\x00" ; tail -c +25 backup.ab ) |  tar xfvz -
Kari
la source
2
Agréable! Avez-vous également l'équivalent de "pack" (pour prendre l'arborescence de répertoires non compressés et créer un fichier .db)?
dailyglen
4
Pourriez-vous ajouter une explication à la réponse?
Chanceux
2
CECI est la meilleure réponse: D Fonctionne parfaitement bien! Extraire maintenant.
xdevs23
16
Explication: author crée un en-tête de fichier Zlib standard pour un .tar.gzfichier avec la printfcommande ( 0x1F 0x8Best une signature, 0x08est la méthode de compression, 0x00est un indicateur et 4 x 0x00est un horodatage), puis ajoute à cet en-tête le contenu du backup.abfichier à partir du décalage 25d. Un tel flux est un .tar.gzfichier valide , et la tar xfvzcommande le reconnaît comme tel, afin de pouvoir décompresser le flux avec succès.
antonone
3
J'ai fait une sauvegarde avec adb 1.0.36 (Révision 1.7.0.0 + r33-2) et cette méthode a généré une erreur de zgip:invalid compressed data--format violated
Rache
31

Une autre option consiste à utiliser bash, catet gunzip( gzip).

Le processus complet pourrait être le suivant ( avec une sauvegarde non chiffrée ):

  1. sauvegarder les données d'une application (par exemple, " Remplacer le DNS pour KitKat "):

    $ adb backup -f net.mx17.overridedns.ab -noapk net.mx17.overridedns
    Now unlock your device and confirm the backup operation.
    
  2. extraire les données compressées

    $ 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. décompresser les données compressées

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

    $ tar xf decompressed-data.tar
    
MaxChinni
la source
4
La "fin de fichier inattendue" est-elle à prévoir?
hft
L'extraction en 2 travaillait étonnamment sur un fichier crypté. Comment est-ce possible? La décompression a ensuite échoué avec gzip: stdin: invalid compressed data--format violated. Je suppose que l'extraction a réussi, comme les ddrapports 22763821+0 records in 22763821+0 records out.
Tom Russell
4

Une autre option consiste à utiliser les règles Perl AdbBackupRoutines à partir de ce thread XDA . Cependant, ils ont quelques exigences: Perl évidemment, plus libterm-readkey-perl, libcrypt-cbc-perlet libcrypt-pbkdf2-perl(si vos sauvegardes ne sont pas chiffrées, vous pouvez ignorer la dernière dépendance en commentant simplement la ligne 103 de backupdecrypt.plson inclusion - cela a bien fonctionné pour moi).

L'utilisation est assez facile:

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

Le .tarfichier résultant peut alors être examiné comme n'importe quelle autre archive. Sa structure est assez intéressante au moins pour un aspect: elle ne reflète pas les chemins réels où les fichiers ont été extraits (par exemple, pas /data/data/com.app.name/databases/whatever.db, mais à la place apps/com.app.name/db/whatever.db) - ce qui indique qu'une application sauvegardée sur un périphérique / ROM peut être restaurée. tout autre périphérique / ROM sans problème, car il adb restorefaut déterminer les véritables chemins lui-même.

Izzy
la source
Il existe un autre outil (un peu mieux entretenu) qui fait cela: github.com/nelenkov/android-backup-extractor
lid
Merci, @lid! J'ai également inclus un petit script shell (presque une seule ligne) avec mon outil Adebar (Android DEvice Backup And Report), qui convertit les sauvegardes de la BAD ( .ab) en .tar.gzarchives :)
Izzy
4

D'après les informations communiquées par d'autres utilisateurs, je sais maintenant que le fichier de sauvegarde est simplement un flux préfixé Deflated (GZip). Ce programme simple, basé sur ces informations, peut le décompresser pour vous:

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

J'ai écrit ceci parce que je n'avais aucun des outils Unix mentionnés ci-dessus, et c'était plus facile que d'installer Cygwin ou d'autres outils.

Avantages :

  • multiplateforme
  • simple (pas de paramètres ésotériques)
  • pas besoin d'outils de tuyauterie

Inconvénients :

  • besoin d'un JDK (que vous avez probablement déjà parce que vous jouez avec le SDK Android)
  • pas de support pour les sauvegardes cryptées
  • besoin de quelque chose pour extraire le fichier tar résultant (j'utilise Total Commander)

Pour en faire un outil de ligne de commande, créez unab.batavec le contenu: java -cp "%~dp0." unab %*et le répertoire dans PATH.

TWiStErRob
la source
4

Comme la question implicite est également, comment restaurer des données d'applications simples, je voudrais mentionner ce script astucieux, qui divise un fichier full-backup.ab donné en fichiers single-app.ab:

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

Il nécessite les fichiers jar: abe.jar et tar-bin-split.jar qui peuvent être trouvés ici:

Cela a fonctionné au moins pour mon test.

joe_zeroh
la source