Como alguém pode extrair os dados (privados) de seu próprio aplicativo Android?

97

Tentar puxar um único arquivo usando

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

falha com

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

apesar de que a depuração USB está habilitada no dispositivo.

Podemos contornar o problema pela rota arcaica

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

mas isso é complicado para mais de um arquivo.

Como posso obter o diretório /data/data/com.corp.appName/files para meu MacBook?

Fazer isso diretamente ou por meio de um trânsito em `/ storage / sdcard0 / myDir (de onde posso continuar com a transferência de arquivos do Android) está bem.

Comentário adicional

Pode ser que apenas correndo

adb backup  -f myFiles com.corp.appName

irá gerar os arquivos que procuro. Nesse caso, estou procurando uma maneira de descompactar / descompactar o backup resultante!

Calaf
fonte
5
A menos que o dispositivo esteja enraizado, você simplesmente não pode fazer isso.
323go
Espero que você esteja errado, mas, por precaução, mova seu comentário para ser uma resposta. Você poderia adicionar algum tipo de referência para justificar porque você pensa assim? Gostaria de salvar todos os arquivos inúteis que as versões com erros do meu programa salvaram para ter certeza de que meu programa mais próximo do lançamento irá lidar com todos os tipos de arquivos de entrada.
Calaf
1
Isso significa que pode-se fazer um chmod no diretório de world: - x para world: rx por tempo suficiente para poder buscar os arquivos?
Calaf de
1
@Knossos Apesar de ser meu aplicativo, não é legítimo que os usuários possam salvar uma cópia dos dados privados que um aplicativo armazenou em seus dispositivos? Afinal, os dados provavelmente pertencem ao proprietário do dispositivo, não ao autor do aplicativo.
Calaf
1
O problema é como você diferencia entre o proprietário e um aplicativo / programa malicioso, tentando fazer a interface com os dados privados de seus aplicativos. (que poderia ter os dados pessoais de um usuário)
Knossos

Respostas:

101

O backup do adb gravará um arquivo específico do Android:

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

Este arquivo pode ser convertido para o formato tar usando:

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

Referência:

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

Procure por "Atualizar" nesse link.


Como alternativa, use o extrator de backup do Android para extrair arquivos do arquivo de backup do Android ( .ab).

Calaf
fonte
5
bs=24 skip=1é muito mais rápido do que bs=1 skip=24(no meu sistema, 38,6 MB / s vs 1,7 MB / s) :)
netvope
18
Alternativa Python para onde o openssl não foi compilado com zlib: dd if=data.ab bs=1 skip=24 | python -c "import zlib,sys;sys.stdout.write(zlib.decompress(sys.stdin.read()))" | tar -xvf -(da fonte acima)
OJFord
6
Nunca tive sucesso com o ddcomando no meu MacBook no trabalho. Em vez disso, eu uso java -jar ./abe.jar unpack data.ab data.tar. Você pode baixar o utilitário abe em sourceforge.net/projects/adbextractor/files/?source=navbar
Someone Somewhere
3
Além disso, percebi que tive que forçar o fechamento do aplicativo cujos dados desejo fazer backup, caso contrário, o backup ficará vazio! (Android 4.4.2) Que é o mesmo efeito de quando o manifesto é android:allowBackup="false"
exibido
2
Melhor ainda, extraia os arquivos diretamente no diretório local:dd if=myAndroidBackup.ab bs=24 skip=1 | openssl zlib -d | tar -x
mreichelt
50

Eu tive o mesmo problema, mas resolvi executando o seguinte:

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

Depois disso, você pode executar

$ adb pull /mnt/sdcard/{file}
Trunst
fonte
1
obrigado cara! você também precisa usar "cp -r" para torná-lo uma cópia recursiva. stackoverflow.com/questions/39961621/…
朱 西西
31

Aqui está o que funcionou para mim:

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

Estou imprimindo o banco de dados diretamente no arquivo local.

Vinicius Avellar
fonte
3
Exatamente este comando fez com que meu arquivo db fosse corrompido. Mas eu fiz para funcionar com as seguintes etapas: ------ adb shell ------ dentro do shell run run-as com.example.test ------ dentro do shell run cat ...db > /mnt/sdcard/file.db------ adb pull /mnt/sdcard/file.db .------ end (desculpe, as quebras de linha não estão funcionando)
Kirill Oficerov
@KirillOficerov seria bom se esses comandos pudessem ser escritos em uma linha
emen
Ótimo quando você precisa de 1 arquivo. Tenho usado isso para banco de dados. Enfrentando o caso agora em que preciso de vários arquivos.
Dave Thomas
Por algum motivo, usar adb shellnão funcionou para mim, mas seguir esta resposta e usá- adb exec-outla funcionou!
EpicPandaForce
21

No MacOSX, combinando as respostas de Calaf e Ollie Ford, o seguinte funcionou para mim.

Na linha de comando (certifique-se de que adb está em seu caminho, o meu estava em ~ / Library / Android / sdk / platform-tools / adb) e com seu dispositivo Android conectado e no modo de depuração USB, execute:

 adb backup -f backup com.mypackage.myapp

Seu dispositivo Android irá pedir permissão para fazer backup de seus dados. Selecione "BACKUP MEUS DADOS"

Espere um pouco.

O backup do arquivo aparecerá no diretório onde você executou o adb.

Agora execute:

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

Agora você tem um arquivo backup.tar que pode descompactar assim:

 tar xvf backup.tar

E veja todos os arquivos armazenados pelo seu aplicativo.

Eric Van Bezooijen
fonte
Sua versão para Mac funciona! NOTA: as etapas de conversão adb backupe de ddtar não fornecem nenhum status durante o trabalho e podem levar minutos se você tiver muitos dados. Seja paciente!
MechEthan
2
Estou recebendo: "zlib.error: Erro -3 ao descompactar dados: verificação de cabeçalho incorreta" No entanto, meu backup está pedindo uma senha para criptografar. Este método python não pede senha para descriptografar o backup. O abe.jar nos comentários do exemplo acima pede a senha, mas não obtive todos os arquivos depois de descompactar usando esse método.
Dave Thomas
Minha segunda tentativa com abe.jar em um backup criptografado funcionou.
Dave Thomas
7

As versões mais recentes do Android Studio incluem o Device File Explorer, que descobri ser um método GUI útil para baixar arquivos do meu Nexus 7 de desenvolvimento.

Você deve se certificar de que ativou a depuração USB no dispositivo

  1. Clique em Exibir> Janelas de ferramentas> Explorador de arquivos de dispositivos ou clique no botão Explorador de arquivos de dispositivos na barra da janela de ferramentas para abrir o Explorador de arquivos de dispositivos.
  2. Selecione um dispositivo na lista suspensa.
  3. Interaja com o conteúdo do dispositivo na janela do explorador de arquivos. Clique com o botão direito em um arquivo ou diretório para criar um novo arquivo ou diretório, salve o arquivo ou diretório selecionado em sua máquina, carregue, exclua ou sincronize. Clique duas vezes em um arquivo para abri-lo no Android Studio.

    O Android Studio salva os arquivos abertos dessa forma em um diretório temporário fora do seu projeto. Se você fizer modificações em um arquivo que abriu usando o Device File Explorer e gostaria de salvar suas alterações de volta no dispositivo, deverá carregar manualmente a versão modificada do arquivo para o dispositivo.

explorador de arquivos

Documentação Completa

Jon
fonte
6

Você pode usar este script de shell abaixo. Ele também pode extrair arquivos do cache do aplicativo, ao contrário da adb backupferramenta:

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

Então você pode usá-lo assim:

./pull.sh files/myFile.txt
./pull.sh cache/someCachedData.txt
Tamas
fonte
10
A melhor parte é quando você não dá argumentos e depois os rm /sdcard/substitui, por sorte não é -rf.
TWiStErRob
3
Você pode apenas catar diretamente para um arquivo no host: "adb shell run-as com.whatever.Fnord cat /data/data/com.whatever.Fnord/databases/logging.db> / tmp / foo" (onde / tmp / foo é um arquivo na máquina host, não no dispositivo Android)
James Moore
Só agora percebi que @dave-thomas corrigiu o problema há um tempo. Removendo meu voto negativo.
Don Hatch
Ou não :-( "Seu voto agora está bloqueado, a menos que esta resposta seja editada."
Don Hatch
TBH Eu não entendo a confusão sobre isso. O script (original) nunca teria excluído o diretório (chave -rf ausente), a menos que estivesse vazio. Não verifiquei, mas mesmo se o diretório estiver vazio, duvido que o script exclua o diretório, pois é um ponto de montagem. O script parecia perigoso, mas nunca foi ...
Tamas
5

Se você estiver usando uma máquina Mac e um telefone Samsung, isso é o que você deve fazer (já run-as que não funciona no Samsung e zlib não funciona no Mac)

  1. Faça um backup do diretório de dados do seu aplicativo adb backup -f /Users/username/Desktop/data.ab com.example

  2. Será solicitada uma senha para criptografar em seu telefone, não digite nenhuma. Basta tocar em "Fazer backup dos meus dados". Veja como fazer o BackUp?

  3. Depois de fazer o backup com sucesso, você verá o data.abarquivo na sua área de trabalho. Agora precisamos converter isso para o tarformato.

  4. Use o Android Backup Extractor para isso. Baixar | Código fonte

  5. Baixe e você verá o abe.jararquivo. Adicione isso à sua variável PATH.

  6. Execute para gerar o arquivo tar :java -jar abe.jar unpack /Users/username/Desktop/data.ab /Users/username/Desktop/data.tar

  7. Extraia o arquivo data.tar para acessar todos os arquivos

Henry
fonte
2
Seguido exatamente e data.tarapenas data.tar.cpgzextrações para um @henry
user-44651
2

Esta resposta é baseada na minha experiência com outras respostas e comentários nas respostas. Minha esperança é poder ajudar alguém em uma situação semelhante.

Estou fazendo isso no OSX via terminal.

Anteriormente, a resposta de Vinicius Avellar funcionou muito bem para mim. Na maioria das vezes, eu só precisava do banco de dados do dispositivo de um aplicativo de depuração.

Hoje tive um caso de uso em que precisava de vários arquivos privados . Acabei com duas soluções que funcionaram bem para este caso.

  1. Use a resposta aceita junto com os comentários específicos de OSX de Someone Somewhere. Crie um backup e use a solução de terceiros, sourceforge.net/projects/adbextractor/files/?source=navbar para descompactar em um tar. Escreverei mais sobre minha experiência com essa solução no final desta resposta. Role para baixo se for isso que você está procurando.

  2. Uma solução mais rápida com a qual resolvi. Criei um script para puxar vários arquivos semelhante à resposta de Tamas. Posso fazer isso dessa forma porque meu aplicativo é um aplicativo de depuração e tenho acesso ao run-as no meu dispositivo. Se você não tiver acesso ao run-as, este método não funcionará para você no OSX.

Aqui está meu script para extrair vários arquivos privados que irei compartilhar com você, o leitor, que também está investigando esta questão incrível;):

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

Síntese: https://gist.github.com/davethomas11/6c88f92c6221ffe6bc26de7335107dd4


De volta ao método 1 , descriptografando um backup usando o Android Backup Extractor

Aqui estão as etapas que executei no meu Mac e os problemas que encontrei:

Primeiro coloquei um backup na fila (e defini uma senha para criptografar meu backup, meu dispositivo exigiu):

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

Em segundo lugar, baixei apenas abe.jar daqui: https://sourceforge.net/projects/adbextractor/files/abe.jar/download

Em seguida, corri:

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

Neste ponto, recebi uma mensagem de erro. Como meu arquivo está criptografado, java me deu um erro de que eu precisava para instalar algumas bibliotecas de políticas de segurança.

  • Então, fui para http://www.oracle.com/technetwork/java/javase/downloads/jce8-download-2133166.html e baixei os jars da política de segurança de que precisava. Agora, no meu caso, as instruções de instalação me disseram o local errado para colocar os arquivos jar. Ele diz que o local apropriado é <java-home> / lib / security . Coloquei-os lá primeiro e ainda recebo a mensagem de erro. Então eu investiguei e no meu Mac com Java 1.8 o lugar correto para colocá-los era: <java-home> / jre / lib / security . Fiz o backup dos jars de política originais e os coloquei lá. Vola Consegui inserir uma senha com abe.jar e descriptografar para um arquivo tar.

Por último, acabei de executar ( depois de executar o comando anterior novamente )

tar xvf myAndroidBackup.tar

Agora é importante notar que se você pode apenas correr como e gato, é muito mais rápido. Primeiro, você obtém apenas os arquivos que deseja e não o aplicativo inteiro. Dois, quanto mais arquivos (+ criptografia para mim), a transferência fica mais lenta. Portanto, saber fazer dessa maneira é importante se você não tiver o run-as no OSX, mas o script deve ser primeiro ir para um aplicativo de depuração.

Lembre-se de que escrevi hoje e testei algumas vezes, portanto, avise-me sobre quaisquer bugs!

Dave Thomas
fonte
1
Graças à sua resposta com o método nº 1, consegui obter e explorar um backup de pacote de um aplicativo direcionado para depuração instalado em um dispositivo de produção sem acesso root, mas o backup contém apenas o arquivo de manifesto. Com o método 2, baixei todos os dados do aplicativo, mas os binários (ou seja, arquivos SQLite) são ilegíveis. Eu adicionei uma solução baseada no seu script que funcionou para mim.
Paolone,
1

Depois de definir as permissões corretas, adicionando o seguinte código:

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

adb pull funciona como desejado.

veja File.setReadable ()

18446744073709551615
fonte
Não há problema em alterar as permissões durante a depuração, mas em algum ponto próximo ao lançamento, isso anularia a proteção oferecida por padrão (para evitar que outros aplicativos acessem / bagunçam os arquivos). Portanto, é mais desejável uma forma de o desenvolvedor acessar os arquivos, mesmo que sejam apenas legíveis / graváveis ​​pelo usuário.
Calaf
1

A partir do script Dave Thomas, fui capaz de escrever minha própria solução para superar 2 problemas:

  1. meu backup continha apenas o arquivo de manifesto
  2. arquivos binários obtidos com Dave Thomas onde ilegíveis

Este é o meu script, que copia os dados do app para o sdcard e depois puxa

#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
fonte
1

Semelhante à resposta de Tamas , aqui está um one-liner para Mac OS X para buscar todos os arquivos para o aplicativo your.app.iddo seu dispositivo e salvá-los (neste 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
)
  • Exclua o -d para puxar do emulador
  • Não pisa nas variáveis ​​da sua sessão
  • Você pode colar todo o bloco em Terminal.app (ou remover novas linhas, se desejar)
Zack Morris
fonte
0

Backup de dados do jogo com apk . Nougat Oneplus 2.

**adb backup "-apk com.nekki.shadowfight" -f "c:\myapk\samsung2.ab"**
Samin
fonte
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

Isso significa que pode-se fazer um chmod no diretório de world: - x para world: rx por tempo suficiente para poder buscar os arquivos?

Sim, exatamente. Estranhamente, você também precisa que o arquivo tenha o xconjunto de bits. (pelo menos no Android 2.3)

chmod 755 todo o caminho trabalhou para copiar um arquivo (mas você deve reverter as permissões depois, se você planeja continuar usando o dispositivo).

serv-inc
fonte
0

você pode fazer:

adb pull / storage / emulado / 0 / Android / data //

Roi Bareket
fonte
2
Não me interpretem mal, mas você leu a pergunta corretamente? OP está pedindo para extrair os dados 'privados', NÃO 'públicos'
baburao