Come si possono estrarre i dati (privati) dalla propria app Android?


97

Tentativo di estrarre un singolo file utilizzando

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

fallisce con

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

nonostante il debug USB sia abilitato sul dispositivo.

Possiamo aggirare il problema attraverso il percorso arcaico

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

ma questo è poco maneggevole per più di un file.

Come posso trasferire la directory /data/data/com.corp.appName/files sul mio MacBook?

Farlo direttamente o tramite un transito in `/ storage / sdcard0 / myDir (da dove posso continuare con Android File Transfer) va bene.

Commento aggiuntivo

Potrebbe essere solo in esecuzione

adb backup  -f myFiles com.corp.appName

genererà i file che sto cercando. In tal caso, sto cercando un modo per decomprimere / decomprimere il backup risultante!


5
A meno che il dispositivo non sia rootato, semplicemente non puoi farlo.
323go

Spero che ti sbagli, ma per ogni evenienza, sposta il tuo commento in modo che sia una risposta. Potresti aggiungere una sorta di riferimento per sostenere il motivo per cui la pensi così? Vorrei salvare tutti i file spazzatura che le versioni difettose del mio programma hanno salvato per assicurarmi lungo la strada che il mio programma più prossimo al rilascio gestirà con grazia tutti i tipi di file di input.
Calaf

1
Ciò significa che si potrebbe modificare la directory da world: - x a world: rx abbastanza a lungo da poter recuperare i file?
Calaf

1
@Knossos Nonostante sia la mia app, non è legittimo che gli utenti possano salvare una copia dei dati privati ​​che un'app ha memorizzato sui propri dispositivi? Dopotutto, i dati appartengono presumibilmente al proprietario del dispositivo, non all'autore dell'app.
Calaf

1
Il problema è come distinguere tra il proprietario e un'app / programma dannoso, cercando di interfacciarsi con i dati privati ​​delle app. (che potrebbe contenere i dati personali di un utente)
Knossos

Risposte:


101

adb backup scriverà un archivio specifico per Android:

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

Questo archivio può essere convertito in formato tar utilizzando:

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

Riferimento:

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

Cerca "Aggiorna" a quel link.


In alternativa, utilizza l' estrattore di backup Android per estrarre i file dal file di backup di Android ( .ab).


5
bs=24 skip=1è molto più veloce di bs=1 skip=24(sul mio sistema, 38,6 MB / s contro 1,7 MB / s) :)
netvope

18
Alternativa a Python per cui openssl non è stato compilato con zlib: dd if=data.ab bs=1 skip=24 | python -c "import zlib,sys;sys.stdout.write(zlib.decompress(sys.stdin.read()))" | tar -xvf -(dalla fonte sopra)
OJFord

6
Non ho mai avuto successo con il ddcomando sul mio MacBook al lavoro. Invece, io uso java -jar ./abe.jar unpack data.ab data.tar. Puoi scaricare l'utility abe da sourceforge.net/projects/adbextractor/files/?source=navbar
Someone Somewhere

3
Inoltre, ho notato che ho dovuto chiudere forzatamente l'app di cui voglio eseguire il backup dei dati altrimenti il ​​backup è vuoto! (Android 4.4.2) Che è lo stesso effetto di quando viene visualizzato il manifestandroid:allowBackup="false"
Someone Somewhere,

2
Ancora meglio, estrai direttamente i file nella directory locale:dd if=myAndroidBackup.ab bs=24 skip=1 | openssl zlib -d | tar -x
mreichelt

50

Ho avuto lo stesso problema ma l'ho risolto in esecuzione seguendo:

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

Dopo questo puoi correre

$ adb pull /mnt/sdcard/{file}

1
grazie uomo! devi anche usare "cp -r" per renderlo una copia ricorsiva. stackoverflow.com/questions/39961621/...
朱西西

31

Ecco cosa ha funzionato per me:

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

Sto stampando il database direttamente nel file locale.


3
Esattamente questo comando ha danneggiato il mio file db. Ma sono riuscito a funzionare con i seguenti passaggi: ------ adb shell ------ all'interno della shell run run-as com.example.test ------ all'interno della shell run cat ...db > /mnt/sdcard/file.db------ adb pull /mnt/sdcard/file.db .------ fine (scusate, le interruzioni di riga non funzionano)
Kirill Oficerov

@KirillOficerov sarebbe bello se questi comandi potessero essere scritti in una riga
emen

Ottimo quando hai bisogno di 1 file. L'ho usato per il database. Affrontando ora il caso in cui ho bisogno di più file.
Dave Thomas,

Per qualche motivo l'utilizzo adb shellnon ha funzionato per me, ma seguendo questa risposta e usandola adb exec-outha funzionato!
EpicPandaForce

21

Su MacOSX, combinando le risposte di Calaf e Ollie Ford, quanto segue ha funzionato per me.

Sulla riga di comando (assicurati che adb sia nel tuo percorso, il mio era in ~ / Library / Android / sdk / platform-tools / adb) e con il tuo dispositivo Android collegato e in modalità debug USB, esegui:

 adb backup -f backup com.mypackage.myapp

Il tuo dispositivo Android ti chiederà l'autorizzazione per il backup dei tuoi dati. Seleziona "BACKUP DEI MIEI DATI"

Aspetta qualche istante.

Il backup del file apparirà nella directory in cui hai eseguito adb.

Adesso corri:

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

Ora avrai un file backup.tar che puoi decomprimere in questo modo:

 tar xvf backup.tar

E guarda tutti i file archiviati dalla tua applicazione.


La tua versione per Mac funziona! NOTA: sia adb backupi ddpassaggi di conversione tar non forniscono lo stato durante il lavoro e possono richiedere minuti se si dispone di molti dati. Essere pazientare!
MechEthan

2
Ricevo: "zlib.error: errore -3 durante la decompressione dei dati: controllo intestazione errato" Il mio backup richiede una password per crittografare. Questo metodo python non richiede la password per decrittografare il backup. Il file abe.jar nei commenti nell'esempio sopra richiede la password, ma non ho ricevuto tutti i file dopo aver decompresso utilizzando quel metodo.
Dave Thomas,

Il mio secondo tentativo con abe.jar su un backup crittografato ha funzionato.
Dave Thomas,

7

Le versioni più recenti di Android Studio includono Device File Explorer che ho trovato essere un pratico metodo GUI per scaricare file dal mio Nexus 7 di sviluppo.

È necessario assicurarsi di aver abilitato il debug USB sul dispositivo

  1. Fare clic su Visualizza> Finestre degli strumenti> Esplora file del dispositivo o fare clic sul pulsante Esplora file del dispositivo nella barra della finestra degli strumenti per aprire Esplora file del dispositivo.
  2. Seleziona un dispositivo dall'elenco a discesa.
  3. Interagisci con il contenuto del dispositivo nella finestra Esplora file. Fare clic con il pulsante destro del mouse su un file o una directory per creare un nuovo file o directory, salvare il file o la directory selezionata sulla macchina, caricare, eliminare o sincronizzare. Fare doppio clic su un file per aprirlo in Android Studio.

    Android Studio salva i file che apri in questo modo in una directory temporanea al di fuori del tuo progetto. Se si apportano modifiche a un file aperto utilizzando Esplora file del dispositivo e si desidera salvare nuovamente le modifiche sul dispositivo, è necessario caricare manualmente la versione modificata del file sul dispositivo.

esploratore di file

Documentazione completa


6

Puoi usare questo script di shell qui sotto. È anche in grado di estrarre file dalla cache dell'app, non come lo adb backupstrumento:

#!/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'"

Quindi puoi usarlo in questo modo:

./pull.sh files/myFile.txt
./pull.sh cache/someCachedData.txt

10
La parte migliore è quando non dai argomenti e poi rm /sdcard/sostituisci, fortunatamente non lo è -rf.
TWiStErRob

3
Puoi semplicemente cat direttamente su un file sull'host: "adb shell run-as com.wwhat.Fnord cat /data/data/com.wwhat.Fnord/databases/logging.db> / tmp / foo" (dove / tmp / foo è un file sulla macchina host, non sul dispositivo Android)
James Moore

Solo ora ho capito che @ dave-thomas ha risolto il problema tempo fa. Rimozione del mio voto negativo.
Don Hatch

Oppure no :-( "Il tuo voto è ora bloccato a meno che questa risposta non venga modificata."
Don Hatch

TBH Non capisco il clamore di questo. Lo script (originale) non avrebbe mai cancellato la directory (opzione -rf mancante), a meno che non fosse vuota. Non ho controllato ma anche se la directory è vuota, dubito che lo script elimini la directory poiché è un punto di montaggio. Il copione sembrava pericoloso, ma non è mai stato ...
Tamas

5

Se stai usando una macchina Mac e un telefono Samsung, questo è quello che devi fare (poiché run-as non funziona su Samsung e zlib non funziona su Mac)

  1. Fai un backup della directory dei dati della tua app adb backup -f /Users/username/Desktop/data.ab com.example

  2. Ti verrà richiesta una password per crittografare il tuo telefono, non inserirne alcuna. Basta toccare "Backup dei miei dati". Vedi Come prendere BackUp?

  3. Una volta eseguito correttamente il backup, vedrai il data.abfile sul desktop. Ora dobbiamo convertirlo in tarformato.

  4. Usa Android Backup Extractor per questo. Scarica | Codice sorgente

  5. Scaricalo e vedrai il abe.jarfile. Aggiungilo alla tua variabile PATH.

  6. Esegui questo per generare il file tar :java -jar abe.jar unpack /Users/username/Desktop/data.ab /Users/username/Desktop/data.tar

  7. Estrai il file data.tar per accedere a tutti i file


2
Ho seguito esattamente questo e gli data.tarestratti giusti a data.tar.cpgz@henry
user-44651

2

Questa risposta si basa sulla mia esperienza con altre risposte e sui commenti nelle risposte. La mia speranza è di poter aiutare qualcuno in una situazione simile.

Lo sto facendo su OSX tramite terminale.

In precedenza, la risposta di Vinicius Avellar funzionava benissimo per me. La maggior parte delle volte ho sempre avuto bisogno del database dal dispositivo da un'applicazione di debug.

Oggi ho avuto un caso d'uso in cui avevo bisogno di più file privati . Ho trovato due soluzioni che hanno funzionato bene per questo caso.

  1. Usa la risposta accettata insieme ai commenti specifici per OSX di Someone Somewhere. Crea un backup e utilizza la soluzione di terze parti, sourceforge.net/projects/adbextractor/files/?source=navbar per decomprimere in un tar. Scriverò di più sulla mia esperienza con questa soluzione in fondo a questa risposta. Scorri verso il basso se questo è quello che stai cercando.

  2. Una soluzione più rapida con la quale ho deciso. Ho creato uno script per estrarre più file simile alla risposta di Tamas. Sono in grado di farlo in questo modo perché la mia app è un'app di debug e ho accesso a run-as sul mio dispositivo. Se non hai accesso a run-as questo metodo non funzionerà per te su OSX.

Ecco il mio script per estrarre più file privati ​​che condividerò con te, il lettore, che sta anche indagando su questa fantastica domanda;):

#!/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


Torna al metodo 1 , decrittografare un backup utilizzando Android Backup Extractor

Ecco i passaggi che ho eseguito sul mio Mac e i problemi che ho riscontrato:

Per prima cosa ho messo in coda un backup (e ho impostato una password per crittografare il mio backup, il mio dispositivo lo richiedeva):

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

Secondo ho scaricato solo abe.jar da qui: https://sourceforge.net/projects/adbextractor/files/abe.jar/download

Successivamente ho eseguito:

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

A questo punto ho ricevuto un messaggio di errore. Poiché il mio archivio è crittografato, java mi ha fornito un errore che mi serviva per installare alcune librerie di criteri di sicurezza.

  • Quindi sono andato su http://www.oracle.com/technetwork/java/javase/downloads/jce8-download-2133166.html e ho scaricato i file dei criteri di sicurezza di cui avevo bisogno. Ora nel mio caso le istruzioni di installazione mi hanno detto che la posizione sbagliata per mettere i file jar. Dice che la posizione corretta è <java-home> / lib / security . Li ho inseriti per primi e ho ancora ricevuto il messaggio di errore. Quindi ho indagato e sul mio Mac con Java 1.8 il posto corretto per metterli era: <java-home> / jre / lib / security . Mi sono assicurato di eseguire il backup dei file dei criteri originali e di inserirli lì. Vola Sono stato in grado di inserire una password con abe.jar e decifrare in un file tar.

Infine ho appena eseguito ( dopo aver eseguito di nuovo il comando precedente )

tar xvf myAndroidBackup.tar

Ora è importante notare che se puoi semplicemente correre come e gatto, è molto molto più veloce. Uno, ottieni solo i file che desideri e non l'intera applicazione. Due, più file (+ crittografia per me) rende più lento il trasferimento. Quindi sapere in questo modo è importante se non hai run-as su OSX, ma lo script dovrebbe essere prima goto per un'applicazione di debug.

Intendiamoci, l'ho scritto oggi e l'ho testato un paio di volte, quindi per favore avvisatemi di eventuali bug!


1
Grazie alla tua risposta con il metodo n. 1 sono stato in grado di ottenere ed esplorare un backup del pacchetto da un'app mirata al debug installata su un dispositivo di produzione non rooted, ma il backup contiene solo il file manifest. Con il metodo n. 2 ho scaricato tutti i dati dell'app, ma i file binari (cioè i file SQLite) sono illeggibili. Aggiungo una soluzione basata sul tuo script che ha funzionato per me.
Paolone

1

Dopo aver impostato le autorizzazioni corrette aggiungendo il codice seguente:

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

adb pull funziona come desiderato.

vedere File.setReadable ()


Va bene modificare le autorizzazioni durante il debug, ma a un certo punto vicino al rilascio ciò annullerebbe la protezione offerta per impostazione predefinita (per impedire ad altre app di accedere / confondere i file). Quindi un modo per lo sviluppatore di accedere ai file anche se sono solo leggibili / scrivibili dall'utente è più desiderabile.
Calaf

1

Partendo dallo script di Dave Thomas sono stato in grado di scrivere la mia soluzione per superare 2 problemi:

  1. il mio backup conteneva solo il file manifest
  2. file binari ottenuti con Dave Thomas dove illeggibili

Questo è il mio script, che copia i dati dell'app su sdcard e poi li estrae

#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

1

Simile alla risposta di Tamas , ecco un one-liner per Mac OS X per recuperare tutti i file per l'app your.app.iddal tuo dispositivo e salvarli in (in questo caso) ~/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
)
  • Escludere il -dpull dall'emulatore
  • Non calpesta le variabili di sessione
  • Puoi incollare l'intero blocco in Terminal.app (o rimuovere le nuove righe se lo desideri)

0

Backup dei dati di gioco con apk . Torrone Oneplus 2.

**adb backup "-apk com.nekki.shadowfight" -f "c:\myapk\samsung2.ab"**

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

Ciò significa che si potrebbe modificare la directory da world: - x a world: rx abbastanza a lungo da poter recuperare i file?

Si, esattamente. Stranamente, hai anche bisogno del file per avere il xbit impostato. (almeno su Android 2.3)

chmod 755 fino in fondo ha funzionato per copiare un file (ma dovresti ripristinare le autorizzazioni in seguito, se prevedi di continuare a utilizzare il dispositivo).


0

tu puoi fare:

adb pull / storage / emulated / 0 / Android / data //


2
Non fraintendetemi ma avete letto correttamente la domanda? OP chiede di estrarre i dati "privati" NON "pubblici"
baburao
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.