Как можно вытащить (частные) данные из одного собственного приложения для Android?

Попытка вытащить один файл с помощью

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

не работает с

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

несмотря на то, что USB-отладка включена на устройстве.

Мы можем решить проблему через архаичный маршрут

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

но это громоздко для более чем одного файла.

Как я могу вытащить каталог /data/data/com.corp.appName/files на свой MacBook?

Выполнение этого прямо или через транзит в `/storage/sdcard0/myDir (откуда я могу продолжить передачу файлов Android) в порядке.

Дополнительный комментарий

Возможно, что только запуск

adb backup  -f myFiles com.corp.appName

будет генерировать файлы, которые я ищу. В этом случае я ищу способ распаковать/распаковать результирующую резервную копию!

Ответ 1

adb backup напишет архив для Android:

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

Этот архив можно преобразовать в формат tar, используя:

dd if=myAndroidBackup.ab  bs=24 skip=1 | openssl zlib -d > myAndroidBackup.tar

Ссылка:

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

Найдите "Обновить" по этой ссылке.


В качестве альтернативы воспользуйтесь экстрактором Android для удаления файлов, чтобы извлечь файлы из файла резервного копирования Android (.ab).

Ответ 2

У меня была такая же проблема, но я решил, что она работает следующим образом:

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

После этого вы можете запустить

$ adb pull /mnt/sdcard/{file}

Ответ 3

Вот что сработало для меня:

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

Я печатаю базу данных непосредственно в локальном файле.

Ответ 4

В MacOSX, объединив ответы от Calaf и Ollie Ford, для меня это работало.

В командной строке (убедитесь, что adb находится на вашем пути, мой был в ~/Library/Android/sdk/platform-tools/adb), а ваше устройство Android подключено и в режиме отладки USB запустите:

 adb backup -f backup com.mypackage.myapp

Ваше устройство Android запросит разрешение на резервное копирование ваших данных. Выберите "BACKUP MY DATA"

Подождите несколько минут.

Резервная копия файла появится в каталоге, в котором вы запустили adb.

Теперь запустите:

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

Теперь у вас будет файл backup.tar, который вы можете распаковать следующим образом:

 tar xvf backup.tar

И посмотрите все файлы, хранящиеся в вашем приложении.

Ответ 5

Вы можете использовать эту оболочку script ниже. Он также может извлекать файлы из кеша приложений, а не как инструмент adb backup:

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

Затем вы можете использовать его следующим образом:

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

Ответ 6

Этот ответ основан на моем опыте с другими ответами и комментариях в ответах. Я надеюсь, что я смогу помочь кому-то в подобной ситуации.

Я делаю это на OSX через терминал.

Раньше ответ Vinicius Avellar отлично работал у меня. Я только когда-либо большую часть времени нуждался в базе данных с устройства из приложения отладки.

Сегодня у меня был прецедент, где мне понадобилось несколько личных файлов. Я закончил с двумя решениями, которые работали хорошо для этого случая.

  • Используйте принятый ответ вместе со специальными комментариями Someone Somewhere OSX. Создайте резервную копию и используйте стороннее решение, sourceforge.net/projects/adbextractor/files/?source=navbar для распаковки в смолу. Я напишу больше о своем опыте с этим решением в нижней части этого ответа. Прокрутите вниз, если это то, что вы ищете.

  • Более быстрое решение, с которым я согласился. Я создал script для вытягивания нескольких файлов, похожих на ответ Тамаса. Я могу это сделать таким образом, потому что мое приложение является отладочным приложением, и у меня есть доступ к run-as on мое устройство. Если у вас нет доступа к запуску, поскольку этот метод не будет работать для вас на OSX.

Вот мой script для того, чтобы вытащить несколько личных файлов, которые я поделюсь с вами, читатель, который также исследует этот удивительный вопрос;):

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

Суть: https://gist.github.com/davethomas11/6c88f92c6221ffe6bc26de7335107dd4


Возврат к методу 1, дешифрование резервной копии с помощью Android Backup Extractor

Вот шаги, которые я предпринял на своем Mac, и проблемы, с которыми я столкнулся:

Сначала я поставил в очередь резервную копию (и установил пароль для шифрования моей резервной копии, мое устройство потребовало ее):

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

Второй я скачал только abe.jar отсюда: https://sourceforge.net/projects/adbextractor/files/abe.jar/download

Далее я побежал:

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

В этот момент я получил сообщение об ошибке. Поскольку мой архив зашифрован, java дал мне ошибку, что мне нужно было установить некоторые библиотеки политик безопасности.

  • Итак, я пошел в http://www.oracle.com/technetwork/java/javase/downloads/jce8-download-2133166.html и загрузил необходимые мне банки безопасности. Теперь в моем случае инструкции по установке сказали мне неправильное местоположение, чтобы поместить файлы jar. В нем указано, что правильное расположение < java-home > /lib/security. Я положил их туда первым и все еще получил сообщение об ошибке. Поэтому я исследовал, и на моем Mac с Java 1.8 правильное место для их размещения было: < java-home > /jre/lib/security. Я сделал резервную копию исходных флагов политики и поместил их туда. Vola Мне удалось ввести пароль с помощью abe.jar и дешифровать файл tar.

Наконец, я просто побежал (после повторного выполнения предыдущей команды)

tar xvf myAndroidBackup.tar

Теперь важно отметить, что если вы можете просто запускать как и кошку, это намного быстрее. Во-первых, вы получаете только файлы, которые хотите, а не все приложение. Два, тем больше файлов (+ шифрование для меня) замедляет передачу. Поэтому знание этого способа важно, если вы не запускаете, как в OSX, но script должен быть первым goto для приложения отладки.

Помните, я только что написал его сегодня и протестировал его несколько раз, поэтому, пожалуйста, сообщите мне об ошибках!

Ответ 7

После установки правильных разрешений, добавив следующий код:

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

adb pull работает по желанию.

см. File.setReadable()

Ответ 8

Стартовая форма Dave Thomas script Я смог написать собственное решение, чтобы преодолеть 2 проблемы:

  • моя резервная копия содержала только файл манифеста
  • бинарные файлы, полученные с Дэйвом Томасом, которые не читаются

Это мой script, который копирует данные приложения на SD-карту, а затем вытаскивает его

#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

Ответ 9

Подобно Ответу Tamas, вот один-лайнер для Mac OS X, чтобы извлечь все файлы для приложения с your.app.id с вашего устройства и сохранить их к (в этом случае) ~/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
)
  • Исключить -d, чтобы вытащить из эмулятора
  • Не топает ваши переменные сеанса
  • Вы можете вставить весь блок в Terminal.app(или удалить новые строки при желании)

Ответ 10

Если вы используете компьютер Mac и телефон Samsung, это то, что вам нужно сделать (поскольку run-as не работает на Samsung и zlib не работает на Mac)

  • Сделайте резервную копию своего каталога данных приложения adb backup -f /Users/username/Desktop/data.ab com.example

  • Вам будет предложено ввести пароль для шифрования на своем телефоне, не вводите его. Просто нажмите "Резервное копирование моих данных". См. Как взять BackUp?

  • После успешной резервной копии вы увидите файл data.ab на рабочем столе. Теперь нам нужно преобразовать это в формат tar.

  • Для этого используйте Экран резервного копирования Android. Загрузить | SourceCode

  • Загрузите его, и вы увидите файл abe.jar. Добавьте это в свою переменную PATH.

  • Выполните это, чтобы сгенерировать файл tar: java -jar abe.jar unpack /Users/username/Desktop/data.ab /Users/username/Desktop/data.tar

  • Извлеките файл data.tar для доступа ко всем файлам

Ответ 11

Резервное копирование данных игры с помощью apk. Nougat Oneplus 2.

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

Ответ 12

Означает ли это, что можно chmod из каталога из мира: - x в мир: r-x достаточно долго, чтобы иметь возможность извлекать файлы?

Да, точно. Как ни странно, вам также нужен файл для установки бит x. (по крайней мере, на Android 2.3)

chmod 755 весь путь работал, чтобы скопировать файл (но вы должны снова разрешить права доступа, если вы планируете продолжать использовать устройство).