Comment extraire les données (privées) de sa propre application Android?

97

Tentative d'extraction d'un seul fichier à l'aide de

adb pull /data/data/com.corp.appName/files/myFile.txt myFile.txt

échoue avec

failed to copy '/data/data/com.corp.appName/files/myFile.txt myFile.txt' to 'myFile.txt': Permission denied

malgré que le débogage USB soit activé sur l'appareil.

On peut contourner le problème par la voie archaïque

adb shell
run-as com.corp.appName
cat files/myFile.txt > myFile.txt

mais c'est compliqué pour plus d'un fichier.

Comment puis-je extraire le répertoire /data/data/com.corp.appName/files sur mon MacBook?

Faire cela directement ou via un transit dans `/ storage / sdcard0 / myDir (d'où je peux continuer avec Android File Transfer) est très bien.

Commentaire additionnel

C'est peut-être que courir

adb backup  -f myFiles com.corp.appName

générera les fichiers que je recherche. Dans ce cas, je cherche un moyen de décompresser / décompresser la sauvegarde résultante!

Calaf
la source
5
À moins que l'appareil ne soit enraciné, vous ne pouvez tout simplement pas le faire.
323go
J'espère que vous vous trompez, mais au cas où, veuillez déplacer votre commentaire pour être une réponse. Pourriez-vous ajouter une sorte de référence pour étayer pourquoi vous le pensez? Je voudrais enregistrer tous les fichiers inutiles que les versions boguées de mon programme ont sauvegardées pour m'assurer que mon programme plus proche de la version gérera gracieusement toutes sortes de fichiers d'entrée.
Calaf
1
Cela signifie-t-il que l'on pourrait chmoder le répertoire de world: - x vers world: rx assez longtemps pour pouvoir récupérer les fichiers?
Calaf
1
@Knossos Nonobstant le fait qu'il s'agit de mon application, n'est-il pas légitime pour les utilisateurs de pouvoir enregistrer une copie des données privées qu'une application a stockées sur leurs appareils? Après tout, les données appartiennent vraisemblablement au propriétaire de l'appareil, pas à l'auteur de l'application.
Calaf
1
Le problème est de savoir comment différencier le propriétaire d'une application / d'un programme malveillant en essayant de s'interfacer avec les données privées de vos applications. (qui pourrait avoir des données personnelles d'un utilisateur)
Knossos

Réponses:

101

adb backup écrira une archive spécifique à Android:

adb backup  -f myAndroidBackup.ab  com.corp.appName

Cette archive peut être convertie au format tar en utilisant:

dd if=myAndroidBackup.ab bs=4K iflag=skip_bytes skip=24 | openssl zlib -d > myAndroidBackup.tar

Référence:

http://nelenkov.blogspot.ca/2012/06/unpacking-android-backups.html

Recherchez «Mettre à jour» sur ce lien.


Vous pouvez également utiliser l' extracteur de sauvegarde Android pour extraire les fichiers du fichier de sauvegarde Android ( .ab).

Calaf
la source
5
bs=24 skip=1est beaucoup plus rapide que bs=1 skip=24(sur mon système, 38,6 Mo / s contre 1,7 Mo / s) :)
netvope
18
Alternative à Python pour où openssl n'a pas été compilé avec zlib: dd if=data.ab bs=1 skip=24 | python -c "import zlib,sys;sys.stdout.write(zlib.decompress(sys.stdin.read()))" | tar -xvf -(à partir de la source ci-dessus)
OJFord
6
Je n'ai jamais eu de succès avec la ddcommande sur mon MacBook au travail. Au lieu de cela, j'utilise java -jar ./abe.jar unpack data.ab data.tar. Vous pouvez télécharger l'utilitaire abe depuis sourceforge.net/projects/adbextractor/files/?source=navbar
Someone Somewhere
3
De plus, j'ai remarqué que j'ai dû forcer la fermeture de l'application dont je souhaite sauvegarder les données, sinon la sauvegarde est vide! (Android 4.4.2) Ce qui est le même effet que lorsque le manifeste s'afficheandroid:allowBackup="false"
Someone Somewhere
2
Mieux encore, extrayez directement les fichiers dans le répertoire local:dd if=myAndroidBackup.ab bs=24 skip=1 | openssl zlib -d | tar -x
mreichelt
50

J'ai eu le même problème mais je l'ai résolu en suivant:

$ adb shell
$ run-as {app-package-name}
$ cd /data/data/{app-package-name}
$ chmod 777 {file}
$ cp {file} /mnt/sdcard/

Après cela, vous pouvez courir

$ adb pull /mnt/sdcard/{file}
Trunst
la source
1
Merci mec! vous devez également utiliser "cp -r" pour en faire une copie récursive. stackoverflow.com/questions/39961621/…
朱 西西
31

Voici ce qui a fonctionné pour moi:

adb -d shell "run-as com.example.test cat /data/data/com.example.test/databases/data.db" > data.db

J'imprime la base de données directement dans le fichier local.

Vinicius Avellar
la source
3
C'est précisément cette commande qui a corrompu mon fichier db. Mais je l'ai fait fonctionner avec les étapes suivantes: ------ adb shell ------ à l'intérieur du shell run run-as com.example.test ------ à l'intérieur du shell run cat ...db > /mnt/sdcard/file.db------ adb pull /mnt/sdcard/file.db .------ end (désolé, les sauts de ligne ne fonctionnent pas)
Kirill Oficerov
@KirillOficerov, ce serait bien si ces commandes peuvent être écrites sur une ligne
emen
Idéal lorsque vous avez besoin d'un fichier. J'utilise ceci pour la base de données. Face au cas maintenant où j'ai besoin de plusieurs fichiers.
Dave Thomas
Pour une raison quelconque, l'utilisation adb shelln'a pas fonctionné pour moi, mais suivre cette réponse et l'utiliser adb exec-outa fonctionné!
EpicPandaForce
21

Sur MacOSX, en combinant les réponses de Calaf et d'Ollie Ford, ce qui suit a fonctionné pour moi.

Sur la ligne de commande (assurez-vous que adb est dans votre chemin, le mien était dans ~ / Library / Android / sdk / platform-tools / adb) et avec votre appareil Android branché et en mode de débogage USB, exécutez:

 adb backup -f backup com.mypackage.myapp

Votre appareil Android vous demandera la permission de sauvegarder vos données. Sélectionnez "SAUVEGARDER MES DONNÉES"

Attendez quelques instants.

La sauvegarde de fichier apparaîtra dans le répertoire où vous avez exécuté adb.

Maintenant, exécutez:

dd if=backup bs=1 skip=24 | python -c "import zlib,sys;sys.stdout.write(zlib.decompress(sys.stdin.read()))" > backup.tar

Vous avez maintenant un fichier backup.tar que vous pouvez décompresser comme ceci:

 tar xvf backup.tar

Et voyez tous les fichiers stockés par votre application.

Eric Van Bezooijen
la source
Votre version Mac fonctionne! REMARQUE: les deux adb backupet les ddétapes de conversion de goudron fournissent pas de statut tout en travaillant et peut prendre quelques minutes si vous avez beaucoup de données. Sois patient!
MechEthan
2
J'obtiens: "zlib.error: Erreur -3 lors de la décompression des données: vérification d'en-tête incorrecte" Ma sauvegarde demande un mot de passe à crypter. Cette méthode python ne demande pas de mot de passe pour décrypter la sauvegarde. L'abe.jar dans les commentaires de l'exemple ci-dessus demande un mot de passe, mais je n'ai pas obtenu tous les fichiers après le décompression en utilisant cette méthode.
Dave Thomas
Ma deuxième tentative avec abe.jar sur une sauvegarde chiffrée a fonctionné.
Dave Thomas
7

Les nouvelles versions d'Android Studio incluent l' Explorateur de fichiers de périphériques que j'ai trouvé être une méthode GUI pratique pour télécharger des fichiers à partir de mon Nexus 7 de développement.

Vous devez vous assurer que vous avez activé le débogage USB sur l'appareil

  1. Cliquez sur Affichage> Fenêtres d'outils> Explorateur de fichiers de périphériques ou cliquez sur le bouton Explorateur de fichiers de périphériques dans la barre de fenêtres d'outils pour ouvrir l'Explorateur de fichiers de périphériques.
  2. Sélectionnez un appareil dans la liste déroulante.
  3. Interagissez avec le contenu de l'appareil dans la fenêtre de l'explorateur de fichiers. Cliquez avec le bouton droit sur un fichier ou un répertoire pour créer un nouveau fichier ou répertoire, enregistrer le fichier ou répertoire sélectionné sur votre machine, télécharger, supprimer ou synchroniser. Double-cliquez sur un fichier pour l'ouvrir dans Android Studio.

    Android Studio enregistre les fichiers que vous ouvrez de cette manière dans un répertoire temporaire en dehors de votre projet. Si vous apportez des modifications à un fichier que vous avez ouvert à l'aide de l'explorateur de fichiers de périphérique et que vous souhaitez enregistrer vos modifications sur le périphérique, vous devez télécharger manuellement la version modifiée du fichier sur le périphérique.

explorateur de fichiers

Documentation complète

Jon
la source
6

Vous pouvez utiliser ce script shell ci-dessous. Il est également capable d'extraire des fichiers du cache de l'application, contrairement à l' adb backupoutil:

#!/bin/sh

if [ -z "$1" ]; then 
    echo "Sorry script requires an argument for the file you want to pull."
    exit 1
fi

adb shell "run-as com.corp.appName cat '/data/data/com.corp.appNamepp/$1' > '/sdcard/$1'"
adb pull "/sdcard/$1"
adb shell "rm '/sdcard/$1'"

Ensuite, vous pouvez l'utiliser comme ceci:

./pull.sh files/myFile.txt
./pull.sh cache/someCachedData.txt
Tamas
la source
10
La meilleure partie est lorsque vous ne donnez pas d'arguments et de rm /sdcard/substituts, heureusement que ce n'est pas le cas -rf.
TWiStErRob
3
Vous pouvez simplement envoyer un chat directement dans un fichier sur l'hôte: "adb shell run-as com.wwhat.Fnord cat /data/data/com.wwhat.Fnord/databases/logging.db> / tmp / foo" (où / tmp / foo est un fichier sur la machine hôte, pas sur l'appareil Android)
James Moore
Je viens de réaliser que @ dave-thomas a corrigé le problème il y a quelque temps. Suppression de mon vote défavorable.
Don Hatch
Ou pas :-( "Votre vote est maintenant verrouillé sauf si cette réponse est modifiée."
Don Hatch
TBH Je ne comprends pas le bruit à ce sujet. Le script (d'origine) n'aurait jamais supprimé le répertoire (commutateur -rf manquant), à moins qu'il ne soit vide. Je n'ai pas vérifié mais même si le répertoire est vide, je doute que le script supprime le répertoire car c'est un point de montage. Le scénario avait l'air dangereux, mais il ne l'a jamais été ...
Tamas
5

Si vous utilisez une machine Mac et un téléphone Samsung, voici ce que vous devez faire (car run-as ne fonctionne pas sur Samsung et zlib ne fonctionne pas sur Mac)

  1. Faites une sauvegarde du répertoire de données de votre application adb backup -f /Users/username/Desktop/data.ab com.example

  2. Il vous sera demandé un mot de passe à crypter dans votre téléphone, n'en saisissez aucun. Appuyez simplement sur "Sauvegarder mes données". Voir Comment prendre BackUp?

  3. Une fois la sauvegarde réussie, vous verrez le data.abfichier sur votre bureau. Nous devons maintenant le convertir au tarformat.

  4. Utilisez Android Backup Extractor pour cela. Télécharger | Code source

  5. Téléchargez-le et vous verrez le abe.jarfichier. Ajoutez ceci à votre variable PATH.

  6. Exécutez ceci pour générer le fichier tar :java -jar abe.jar unpack /Users/username/Desktop/data.ab /Users/username/Desktop/data.tar

  7. Extrayez le fichier data.tar pour accéder à tous les fichiers

Henri
la source
2
A suivi cela exactement et les data.tarextraits justes à un data.tar.cpgz@henry
user-44651
2

Cette réponse est basée sur mon expérience avec d'autres réponses et des commentaires dans les réponses. J'espère que je peux aider quelqu'un dans une situation similaire.

Je fais cela sur OSX via un terminal.

Auparavant, la réponse de Vinicius Avellar fonctionnait très bien pour moi. J'avais seulement la plupart du temps besoin de la base de données de l'appareil à partir d'une application de débogage.

Aujourd'hui, j'ai eu un cas d'utilisation où j'avais besoin de plusieurs fichiers privés . Je me suis retrouvé avec deux solutions qui ont bien fonctionné pour ce cas.

  1. Utilisez la réponse acceptée avec les commentaires spécifiques OSX de Someone Somewhere. Créez une sauvegarde et utilisez la solution tierce, sourceforge.net/projects/adbextractor/files/?source=navbar pour décompresser dans un tar. J'écrirai plus sur mon expérience avec cette solution au bas de cette réponse. Faites défiler vers le bas si c'est ce que vous recherchez.

  2. Une solution plus rapide avec laquelle je me suis installé. J'ai créé un script pour extraire plusieurs fichiers similaires à la réponse de Tamas. Je peux le faire de cette façon car mon application est une application de débogage et j'ai accès à run-as sur mon appareil. Si vous n'avez pas accès à run-as, cette méthode ne fonctionnera pas pour vous sous OSX.

Voici mon script pour extraire plusieurs fichiers privés que je partagerai avec vous, le lecteur, qui étudie également cette question géniale;):

#!/bin/bash
#
# Strict mode: http://redsymbol.net/articles/unofficial-bash-strict-mode/
set -euo pipefail
IFS=$'\n\t'

# 
# Usage: script -f fileToPull -p packageName
# 

# This script is for pulling private files from an Android device
# using run-as. Note: not all devices have run-as access, and
# application must be a debug version for run-as to work.
# 
# If run-as is deactivated on your device use one of the
# alternative methods here:
# http://stackoverflow.com/questions/15558353/how-can-one-pull-the-private-data-of-ones-own-android-app
# 
# If you have encrypted backup files use:
# sourceforge.net/projects/adbextractor/files/?source=navbar 
# From comments in the accepted answer in the above SO question
# 
# If your files aren't encrypted use the accepted answer 
# ( see comments and other answers for OSX compatibility )
# 
# This script is open to expansions to allow selecting 
# device used. Currently first selected device from
# adb shell will be used.

#Check we have one connected device
adb devices -l | grep -e 'device\b' > /dev/null

if [ $? -gt 0 ]; then
    echo "No device connected to adb."
    exit 1
fi

# Set filename or directory to pull from device
# Set package name we will run as
while getopts f:p: opt; do
    case $opt in
        f)
            fileToPull=$OPTARG
            ;;
        p)
            packageName=$OPTARG
            ;;
    esac
done;

# Block file arg from being blank
if [ -z "$fileToPull" ]; then
    echo "Please specify file or folder to pull with -f argument"
    exit 1
fi

# Block package name arg from being blank
if [ -z "$packageName" ]; then
    echo "Please specify package name to run as when pulling file"
    exit 1
fi

# Check package exists
adb shell pm list packages | grep "$packageName" > /dev/null
if [ $? -gt 0 ]; then
    echo "Package name $packageName does not exist on device"
    exit 1
fi

# Check file exists and has permission with run-as
fileCheck=`adb shell "run-as $packageName ls $fileToPull"`
if [[ $fileCheck =~ "Permission denied" ]] || [[ $fileCheck =~ "No such file or directory" ]]; then
    echo "Error: $fileCheck"
    echo "With file -> $fileToPull"
    exit 1
fi

# Function to pull private file
#
# param 1 = package name
# param 2 = file to pull
# param 3 = output file
function pull_private_file () {

    mkdir -p `dirname $3`

    echo -e "\033[0;35m***" >&2
    echo -e "\033[0;36m Coping file $2 -> $3" >&2
    echo -e "\033[0;35m***\033[0m" >&2

    adb shell "run-as $1 cat $2" > $3
}

# Check if a file is a directory
# 
# param 1 = directory to check
function is_file_dir() {

    adb shell "if [ -d \"$1\" ]; then echo TRUE; fi"
}

# Check if a file is a symbolic link
# 
# param 1 = directory to check
function is_file_symlink() {

    adb shell "if [ -L \"$1\" ]; then echo TRUE; fi"
}

# recursively pull files from device connected to adb
# 
# param 1 = package name
# param 2 = file to pull
# param 3 = output file
function recurse_pull_private_files() {

    is_dir=`is_file_dir "$2"`
    is_symlink=`is_file_symlink "$2"`

    if [ -n "$is_dir" ]; then

        files=`adb shell "run-as $1 ls \"$2\""`

        # Handle the case where directory is a symbolic link
        if [ -n "$is_symlink" ]; then
            correctPath=`adb shell "run-as $1 ls -l \"$2\"" | sed 's/.*-> //' | tr -d '\r'`
            files=`adb shell "run-as $1 ls \"$correctPath\""`
        fi

        for i in $files; do

            # Android adds nasty carriage return that screws with bash vars
            # This removes it. Otherwise weird behavior happens
            fileName=`echo "$i" | tr -d '\r'` 

            nextFile="$2/$fileName"
            nextOutput="$3/$fileName"
            recurse_pull_private_files "$1" "$nextFile" "$nextOutput"
        done
    else

        pull_private_file "$1" "$2" "$3"
    fi
}

recurse_pull_private_files "$packageName" "$fileToPull" "`basename "$fileToPull"`"

Gist: https://gist.github.com/davethomas11/6c88f92c6221ffe6bc26de7335107dd4


Retour à la méthode 1 , décrypter une sauvegarde à l'aide d' Android Backup Extractor

Voici les étapes que j'ai suivies sur mon Mac et les problèmes que j'ai rencontrés:

J'ai d'abord mis une sauvegarde en file d'attente (et défini un mot de passe pour crypter ma sauvegarde, mon appareil en avait besoin):

adb backup -f myAndroidBackup.ab  com.corp.appName

Deuxièmement, j'ai téléchargé juste abe.jar à partir d'ici: https://sourceforge.net/projects/adbextractor/files/abe.jar/download

Ensuite, j'ai couru:

java -jar ./abe.jar unpack myAndroidBackup.ab myAndroidBackup.tar

À ce stade, j'ai reçu un message d'erreur. Comme mon archive est chiffrée, java m'a donné une erreur dont j'avais besoin pour installer certaines bibliothèques de politiques de sécurité.

  • Je suis donc allé sur http://www.oracle.com/technetwork/java/javase/downloads/jce8-download-2133166.html et j'ai téléchargé les jars de politique de sécurité dont j'avais besoin. Maintenant, dans mon cas, les instructions d'installation m'ont indiqué le mauvais emplacement pour mettre les fichiers jar. Il dit que l'emplacement approprié est <java-home> / lib / security . Je les ai mis là en premier et j'ai toujours le message d'erreur. J'ai donc enquêté et sur mon Mac avec Java 1.8, le bon endroit pour les mettre était: <java-home> / jre / lib / security . Je me suis assuré de sauvegarder les jars de politique d'origine et de les y mettre. Vola J'ai pu entrer un mot de passe avec abe.jar et déchiffrer dans un fichier tar.

Enfin, je viens de courir ( après avoir réexécuté la commande précédente )

tar xvf myAndroidBackup.tar

Maintenant, il est important de noter que si vous pouvez simplement courir en tant que chat, c'est beaucoup plus rapide. Premièrement, vous n'obtenez que les fichiers souhaités et non l'application entière. Deuxièmement, plus il y a de fichiers (+ cryptage pour moi), plus le transfert est lent. Il est donc important de savoir comment procéder de cette manière si vous ne disposez pas de run-as sur OSX, mais le script doit être utilisé en premier pour une application de débogage.

Remarquez que je viens de l'écrire aujourd'hui et de l'avoir testé quelques fois, alors veuillez me signaler tout bogue!

Dave Thomas
la source
1
Grâce à votre réponse avec la méthode n ° 1, j'ai pu obtenir et explorer une sauvegarde de package à partir d'une application ciblée de débogage installée sur un périphérique de production non rooté, mais la sauvegarde ne contient que le fichier manifeste. Avec la méthode n ° 2, j'ai téléchargé toutes les données de l'application, mais les binaires (c'est-à-dire les fichiers SQLite) sont illisibles. J'ajoute une solution basée sur votre script qui a fonctionné pour moi.
Paolone
1

Après avoir défini les bonnes autorisations en ajoutant le code suivant:

File myFile = ...;
myFile.setReadable(true, false); // readable, not only for the owner

adb pull fonctionne comme vous le souhaitez.

voir File.setReadable ()

18446744073709551615
la source
1
Il est normal de modifier les autorisations pendant le débogage, mais à un moment donné, près de la publication, cela annulerait la protection offerte par défaut (pour empêcher d'autres applications d'accéder / de gâcher les fichiers). Par conséquent, un moyen pour le développeur d'accéder aux fichiers même s'ils sont simplement lisibles par l'utilisateur / inscriptibles est plus souhaitable.
Calaf
1

À partir du script Dave Thomas, j'ai pu écrire ma propre solution pour surmonter 2 problèmes:

  1. ma sauvegarde ne contenait que le fichier manifeste
  2. fichiers binaires obtenus avec Dave Thomas où illisibles

Ceci est mon script, qui copie les données de l'application sur sdcard, puis les extrait

#Check we have one connected device
adb devices -l | grep -e 'device\b' > /dev/null

if [ $? -gt 0 ]; then
    echo "No device connected to adb."
    exit 1
fi

# Set filename or directory to pull from device
# Set package name we will run as
while getopts f:p: opt; do
    case $opt in
        f)
            fileToPull=$OPTARG
            ;;
        p)
            packageName=$OPTARG
            ;;
    esac
done;

# Block package name arg from being blank
if [ -z "$packageName" ]; then
    echo "Please specify package name to run as when pulling file"
    exit 1
fi

# Check package exists
adb shell pm list packages | grep "$packageName" > /dev/null
if [ $? -gt 0 ]; then
    echo "Package name $packageName does not exist on device"
    exit 1
fi

    adb shell "run-as $packageName cp -r /data/data/$packageName/ /sdcard/$packageName"
    adb pull /sdcard/$packageName
    adb shell rm -rf /sdcard/$packageName
Paolone
la source
1

Semblable à la réponse de Tamas , voici une ligne unique pour Mac OS X pour récupérer tous les fichiers pour l'application avec your.app.idde votre appareil et les enregistrer (dans ce cas) ~/Desktop/your.app.id:

(
    id=your.app.id &&
    dest=~/Desktop &&
    adb shell "run-as $id cp -r /data/data/$id /sdcard" &&
    adb -d pull "/sdcard/$id" "$dest" &&
    if [ -n "$id" ]; then adb shell "rm -rf /sdcard/$id"; fi
)
  • Exclure le -dà tirer de l'émulateur
  • Ne piétine pas vos variables de session
  • Vous pouvez coller le bloc entier dans Terminal.app (ou supprimer les nouvelles lignes si vous le souhaitez)
Zack Morris
la source
0

Sauvegarde des données du jeu avec apk . Nougat Oneplus 2.

**adb backup "-apk com.nekki.shadowfight" -f "c:\myapk\samsung2.ab"**
Samin
la source
adb backup -f myapp.ab -apk com.myapp # backup on one device adb restore myapp.ab # restore to the same or any other device
Steven Linn
0

Cela signifie-t-il que l'on pourrait chmoder le répertoire de world: - x vers world: rx assez longtemps pour pouvoir récupérer les fichiers?

Oui, exactement. Curieusement, vous avez également besoin du fichier pour que le xbit soit défini. (au moins sur Android 2.3)

chmod 755 tout en bas a travaillé pour copier un fichier (mais vous devez revenir sur les autorisations par la suite, si vous prévoyez de continuer à utiliser l'appareil).

serv-inc
la source
0

tu peux faire:

adb pull / stockage / émulé / 0 / Android / data //

Roi Bareket
la source
2
Ne vous méprenez pas, mais avez-vous bien lu la question? OP demande d'extraire les données `` privées '' PAS `` publiques ''
baburao