Existe-t-il un moyen de regarder à l'intérieur et de modifier un fichier créé par une sauvegarde adb?

40

J'ai créé une sauvegarde de mon Galaxy Nexus avec adb backup. Le fichier résultant s'appelle backup.db et est en quelque sorte crypté.

Je voulais restaurer la sauvegarde, mais elle s’arrête quand il s’agit de restaurer com.android.providers.contacts. J'avais l'habitude adb logcatde savoir ce qui se passait et de constater que se com.android.acorebloquait lors du processus de restauration.

J'aimerais accéder aux données de la sauvegarde et supprimer la base de données de contacts pour tout restaurer sur mon téléphone. Existe-t-il d'autres moyens de restaurer les données à partir de la sauvegarde?

ingorichter
la source

Réponses:

14

Le fichier n'est pas crypté, sauf indication contraire de votre part lors de la création de la sauvegarde. Il est cependant compressé (en utilisant deflate). Vous pouvez connaître le format exact en consultant le code source Android (com / android / server / BackupManagerService.java) et, techniquement, il devrait pouvoir en extraire des données spécifiques. Cependant, IIRC met en place des contrôles d'intégrité des fichiers. Par conséquent, cela ne fonctionnera probablement pas si vous supprimez simplement un tas de données. Malheureusement, la restorecommande ne semble pas avoir l'option de restaurer uniquement une application / un package particulier ou d'exclure un package.

Nikolay Elenkov
la source
Merci! C'est au moins un point de départ pour regarder à l'intérieur du fichier. Cela aurait été plus facile si je n'avais pas fourni de mot de passe pour la sauvegarde.
Ingorichter
Si vous avez fourni un mot de passe, il est effectivement crypté. `BackupManagerService 'contient des détails sur les algorithmes de chiffrement réels et les paramètres de dérivation de clé (sel, nombre d'itérations, etc.) sont écrits dans l'en-tête du fichier. Puisque vous connaissez le mot de passe, vous pouvez obtenir la clé et déchiffrer les données. Donc, c'est encore faisable, mais pas particulièrement facile ...
Oui, je suis en train de tout extraire BackupManagerServicepour lire le contenu du fichier de sauvegarde. C'est une bonne quantité de travail, mais j'ai besoin de récupérer mes données ...
ingorichter
@ingorichter aucun progrès?
jon
@ingorichter J'ai commencé à travailler dessus et j'ai posté une tonne de notes ci-dessous, dans une réponse "wiki de communauté". N'hésitez pas à ajouter.
jon
50

J'ai commencé à travailler sur ça. Je publie mes résultats jusqu'ici comme réponse de "wiki de communauté" pour deux raisons: premièrement, si quelqu'un d'autre souhaite y participer, il existe un lieu de discussion; Deuxièmement, si je suis éloigné de ce projet, il y aura des indices pour que quelqu'un d'autre commence à travailler.

 

La logique de sauvegarde sur l'hôte est entièrement contenue dans https://github.com/android/platform_system_core/blob/master/adb/commandline.cpp , dans la fonction nommée backup. La fonction est très simple: elle valide les options de ligne de commande, envoie la commande essentiellement telle quelle au démon adb du téléphone et écrit la sortie du téléphone dans le fichier. Il n'y a même pas de vérification d'erreur: si, par exemple, vous refusez la sauvegarde sur le téléphone, écrivez adbsimplement un fichier vide.

Sur le téléphone, la logique de sauvegarde commence service_to_fd()dans https://github.com/android/platform_system_core/blob/master/adb/services.cpp . La fonction identifie la commande de l'hôte "backup"et transmet la commande non analysée à /system/bin/bu, ce qui est un script shell trivial à lancer en com.android.commands.bu.Backuptant que classe principale d'un nouveau processus d'application Android. Cela appelle ServiceManager.getService("backup")pour obtenir le service de sauvegarde en tant que IBackupManager, et appelle IBackupManager.fullBackup(), en lui transmettant le descripteur de fichier encore inutilisé (très indirectement) connecté au backup.abfichier sur l'hôte.

Le contrôle passe fullBackup()dans com.android.server.backup.BackupManagerService , qui affiche l'interface graphique demandant à l'utilisateur de confirmer / refuser la sauvegarde. Lorsque l'utilisateur le fait, acknowledgeFullBackupOrRestore()(même fichier) est appelé. Si l'utilisateur a approuvé la demande, acknowledgeFullBackupOrRestore()détermine si la sauvegarde est cryptée et passe un message à BackupHandler(même fichier.) BackupHandlerPuis instancie et lance un PerformAdbBackupTask( même fichier, ligne 4004 à la date de rédaction).

Nous commençons enfin à générer une sortiePerformAdbBackupTask.run() entre les lignes 4151 et 4330 .

Commencez par run()écrire un en-tête composé de 4 ou 9 lignes ASCII:

  1. "ANDROID BACKUP"
  2. la version du format de sauvegarde: actuellement "4"
  3. soit "0"si la sauvegarde est décompressée ou "1"si elle est
  4. la méthode de cryptage: actuellement "none"ou"AES-256"
  5. (si crypté), le "sel de mot de passe de l'utilisateur" encodé en hexadécimal, en majuscules
  6. (si chiffré), le "sel de la clé de contrôle de la clé principale" codé en hexadécimal, toutes les majuscules
  7. (si chiffré), le "nombre de tours PBKDF2 utilisées" sous forme de nombre décimal: actuellement "10000"
  8. (si crypté), le "IV de la clé d'utilisateur" encodé en hexadécimal, toutes les majuscules
  9. (si crypté), le "blob maître IV + clé, crypté par la clé d'utilisateur" codé en hexadécimal, tout en majuscule

Les données de sauvegarde réelle suit, soit ( en fonction de la compression et le cryptage) tar, deflate(tar), encrypt(tar)ou encrypt(deflate(tar)).

 

TODO : écrivez le chemin du code qui génère la sortie de tar - vous pouvez simplement utiliser tar tant que les entrées sont dans le bon ordre (voir ci-dessous).

Format d'archive Tar

Les données d'application sont stockées dans le répertoire app /, en commençant par un fichier _manifest, l'APK (si demandé) dans un /, les fichiers d'application en f /, les bases de données en db / et les préférences partagées en sp /. Si vous avez demandé une sauvegarde de stockage externe (à l'aide de l'option -shared), il y aura également un répertoire partagé / dans l'archive contenant les fichiers de stockage externes.

$ tar tvf mybackup.tar
-rw------- 1000/1000      1019 2012-06-04 16:44 apps/org.myapp/_manifest
-rw-r--r-- 1000/1000   1412208 2012-06-02 23:53 apps/org.myapp/a/org.myapp-1.apk
-rw-rw---- 10091/10091     231 2012-06-02 23:41 apps/org.myapp/f/share_history.xml
-rw-rw---- 10091/10091       0 2012-06-02 23:41 apps/org.myapp/db/myapp.db-journal
-rw-rw---- 10091/10091    5120 2012-06-02 23:41 apps/org.myapp/db/myapp.db
-rw-rw---- 10091/10091    1110 2012-06-03 01:29 apps/org.myapp/sp/org.myapp_preferences.xml

Détails du chiffrement

  1. Une clé AES 256 est dérivée du mot de passe de chiffrement de sauvegarde en utilisant 10000 tours de PBKDF2 avec un sel de 512 bits généré de manière aléatoire.
  2. Une clé principale AES 256 est générée de manière aléatoire.
  3. Une "clé de contrôle" est générée en exécutant la clé principale sur 10000 tours de PBKDF2 avec un nouveau sel de 512 bits généré de manière aléatoire.
  4. Un chiffrement de sauvegarde aléatoire IV est généré.
  5. Le IV, la clé principale et la somme de contrôle sont concaténés et chiffrés avec la clé obtenue en 1. Le blob résultant est enregistré dans l'en-tête en tant que chaîne hexagonale.
  6. Les données de sauvegarde réelles sont cryptées avec la clé principale et ajoutées à la fin du fichier.

Exemple d'implémentation / décompression du code (produit / utilise) les archives tar: https://github.com/nelenkov/android-backup-extractor

Quelques détails supplémentaires ici: http://nelenkov.blogspot.com/2012/06/unpacking-android-backups.html

Scripts Perl pour emballer / décompresser et réparer les archives endommagées:

http://forum.xda-developers.com/showthread.php?p=27840175#post27840175

jon
la source
Si vous mettez le code quelque part, je pourrais peut-être rejoindre. L'OP (@ngorichter) a probablement aussi du code de travail maintenant :) Un utilitaire qui décompresse et extrait les fichiers réels peut être utile, de sorte que vous ne puissiez restaurer que des parties (si vous avez la racine bien sûr).
Nikolay Elenkov
1
En ce qui concerne la partie chiffrement, je dois rechercher les détails, mais la clé est dérivée à l’aide de PBKDF2 par le sel et le code PIN, le mot de passe ou le modèle de déverrouillage du périphérique (converti en chaîne). La clé principale est générée aléatoirement et chiffrée avec la clé dérivée du mot de passe. Faites-le fonctionner pour les archives non cryptées en premier. Je peux implémenter la partie décryptage si vous rencontrez des problèmes.
Nikolay Elenkov
Désolé, la clé est réellement dérivée en fonction du mot de passe que vous avez spécifié lors du démarrage de la sauvegarde.
Nikolay Elenkov
@ NikolayElenkov Je n'ai pas encore de code, mais je prévois d'écrire un utilitaire pour manipuler les fichiers ab. Cryptage, je ne pense pas que ce sera difficile; c'est juste que j'ai seulement jeté un coup d'œil sur cette partie du code. De même, j'ai tracé le chemin du code (pas encore écrit ci-dessus) qui génère le flux tar, mais je n'ai pas encore vérifié que le format actuel est GNU tar.
jon
Wow, je suis impressionné par votre analyse. J'ai extrait du code de BackupManagerService dans un script groovy simple, mais lorsque j'exécute le programme, le résultat est toujours le même: mot de passe incorrect! J'ai créé une nouvelle sauvegarde avec un mot de passe simple, mais la vérification du mot de passe a échoué à nouveau. Actuellement, j'essaie de suivre le programme décrit ci-dessus pour trouver mon erreur.
Ingorichter
7

Réponse géniale et détaillée de Nikolay Elenkov . Cependant, je devrais ajouter que quelqu'un a déjà développé un logiciel qui ne fait que cela et le conditionne ici: http://sourceforge.net/projects/adbextractor/

Le paquet contient les outils Java et Perl. Moi-même, je préfère chaque jour Perl à Java, donc j’ai extrait les codes Perl, je me suis assuré qu’ils sont exécutables, j’ai installé la bibliothèque Perl requise et backupdecrypt.plj’ai exécuté le fichier de sauvegarde adb. problème.

J'ai même créé une couche dans Bash 3 qui me permet de faire une sauvegarde adb directement dans un fichier tar compressé:

adb backup -f >(backupdecrypt.pl -D -z - backup.tgz) -all

J'espère que ça aide.

SP Arif Sahari Wibowo
la source
6
Oui, ils ont emballé l'outil (celui en Java) que j'ai écrit :) J'ai aussi aidé à porter le truc sur Perl. Si vous n'avez pas lu les fichiers README, il ne sera peut-être pas immédiatement évident que la rédaction est arrivée en premier, puis les outils ....
Nikolay Elenkov
J'ai pris une sauvegarde mais il n'a pas créé de fichier .ab, mais un fichier .backup. Je veux savoir comment l'extraire. Aussi, je ne suis pas sûr s'il a pris toutes les photos et vidéos en sauvegarde?
hajirazin
-4

Pour explorer le fichier de sauvegarde existant, essayez la page http://www.adb-backup.com , elle est simple, sans "dd", "tar", ...

Les données ne sont pas stockées sur ce serveur. J'ai développé ce service en ligne pour faciliter la visualisation des sauvegardes sans manipulation avec dd / tar ni installation de logiciel supplémentaire. Je suis l'auteur www.adb-backup.com

Liszak
la source
7
Je ferais très attention au téléchargement d'une sauvegarde adb (et à la fourniture du mot de passe) sur un site Web aléatoire ... Les données incluses dans la sauvegarde adb sont privées et vous n'avez aucun moyen de savoir ce que le site fait avec la sauvegarde. Cela pourrait être inoffensif mais je ne recommanderais pas cela.
bmdixon
Selon Metasmoke, il s'agit d'une URL de spam . En dehors de cela, je suis entièrement d'accord avec @bmdixon ici - d'autant plus qu'il existe des moyens sûrs d'effectuer la tâche localement.
Izzy
@ Izzy Quoi qu'il en soit, je l'ai signalé comme courrier indésirable et l'ai signalé à SmokeDetector.
iBug
Les données ne sont pas stockées sur ce serveur. J'ai développé ce service en ligne pour faciliter la visualisation des sauvegardes sans manipulation avec dd / tar ni installation de logiciel supplémentaire. Je suis l'auteur www.adb-backup.com
Liszak le