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

97

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

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

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

Калаф
источник
5
Если устройство не рутировано, вы просто не сможете этого сделать.
323go
Надеюсь, вы ошибаетесь, но на всякий случай переместите свой комментарий в ответ. Не могли бы вы добавить какую-нибудь ссылку, чтобы подтвердить, почему вы так думаете? Я хотел бы сохранить все ненужные файлы, которые сохранили глючные версии моей программы, чтобы в будущем убедиться, что моя приближающаяся к выпуску программа будет корректно обрабатывать все типы входных файлов.
Calaf
1
Означает ли это, что можно изменить каталог из world: - x в world: rx с помощью chmod достаточно долго, чтобы получить файлы?
Calaf
1
@Knossos Несмотря на то, что это мое приложение, разве пользователи не могут сохранять копию личных данных, которые приложение хранит на своих устройствах? В конце концов, данные предположительно принадлежат владельцу устройства, а не автору приложения.
Calaf
1
Проблема в том, как отличить владельца от вредоносного приложения / программы, пытающихся взаимодействовать с личными данными ваших приложений. (в котором могут быть личные данные пользователей)
Knossos

Ответы:

101

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

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

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

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

Ссылка:

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

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


В качестве альтернативы можно использовать средство извлечения резервных копий Android для извлечения файлов из файла backup ( .ab) Android .

Калаф
источник
5
bs=24 skip=1намного быстрее, чем bs=1 skip=24(в моей системе 38,6 МБ / с против 1,7 МБ / с) :)
netvope
18
Альтернатива Python для случаев, когда openssl не был скомпилирован с zlib: dd if=data.ab bs=1 skip=24 | python -c "import zlib,sys;sys.stdout.write(zlib.decompress(sys.stdin.read()))" | tar -xvf -(из приведенного выше источника)
OJFord
6
У меня никогда не было успеха с ddкомандой на моем MacBook на работе. Вместо этого я использую java -jar ./abe.jar unpack data.ab data.tar. Вы можете скачать утилиту abe по ссылке sourceforge.net/projects/adbextractor/files/?source=navbar
Someone Somewhere
3
Кроме того, я заметил, что мне пришлось принудительно закрыть приложение, данные которого я хочу сохранить, иначе резервная копия будет пустой! (Android 4.4.2) Эффект тот же, что и в манифестеandroid:allowBackup="false"
Someone Somewhere
2
Еще лучше, напрямую распаковать файлы в локальный каталог:dd if=myAndroidBackup.ab bs=24 skip=1 | openssl zlib -d | tar -x
mreichelt
50

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

$ 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}
Trunst
источник
1
Спасибо чувак! вам также необходимо использовать "cp -r", чтобы сделать его рекурсивной копией. stackoverflow.com/questions/39961621/…
朱 西西 03
31

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

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

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

Винисиус Авеллар
источник
3
Именно эта команда привела к повреждению моего файла db. Но я заставил его работать, выполнив следующие шаги: ------ adb shell ------ внутри оболочки запустить run-as com.example.test ------ внутри оболочки запустить cat ...db > /mnt/sdcard/file.db------ adb pull /mnt/sdcard/file.db .------ конец (извините, разрывы строк не работают)
Кирилл Офицеров
@KirillOficerov, было бы хорошо, если бы эти команды можно было записать в одну строку
emen
Отлично, когда вам нужен 1 файл. Использовал это для базы данных. Перед лицом дела, когда мне нужно несколько файлов.
Дэйв Томас,
По какой-то причине использование adb shellне сработало для меня, но после этого ответа и adb exec-outего использования сработало!
EpicPandaForce
21

В MacOSX, объединив ответы Калафа и Олли Форда, у меня сработало следующее.

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

 adb backup -f backup com.mypackage.myapp

Ваше устройство Android запросит у вас разрешение на резервное копирование данных. Выберите «РЕЗЕРВНОЕ КОПИРОВАНИЕ ДАННЫХ».

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

Резервная копия файла появится в каталоге, в котором вы запустили 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

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

Эрик Ван Безойен
источник
Ваша версия для Mac работает! Примечание: как adb backupи ddшаги конверсии дегтя не дают никакого статуса во время работы и может занять несколько минут , если у вас есть много данных. Потерпи!
MechEthan
2
Я получаю: «zlib.error: Ошибка -3 при распаковке данных: неправильная проверка заголовка» Однако моя резервная копия запрашивает пароль для шифрования. Этот метод python не запрашивает пароль для расшифровки резервной копии. Abe.jar в комментариях к приведенному выше примеру запрашивает пароль, но я не получил все файлы после распаковки с помощью этого метода.
Дэйв Томас
Моя вторая попытка с abe.jar в зашифрованном виде сработала.
Дэйв Томас,
7

Более новые версии Android Studio включают в себя проводник файлов устройства, который, как я обнаружил, является удобным графическим способом загрузки файлов из моей разработки Nexus 7.

Вы должны убедиться, что на устройстве включена отладка по USB.

  1. Щелкните «Просмотр»> «Окна инструментов»> «Проводник файлов устройства» или нажмите кнопку «Проводник файлов устройства» на панели инструментов, чтобы открыть проводник файлов устройства.
  2. Выберите устройство из раскрывающегося списка.
  3. Взаимодействуйте с содержимым устройства в окне проводника файлов. Щелкните правой кнопкой мыши файл или каталог, чтобы создать новый файл или каталог, сохранить выбранный файл или каталог на свой компьютер, загрузить, удалить или синхронизировать. Дважды щелкните файл, чтобы открыть его в Android Studio.

    Android Studio сохраняет файлы, которые вы открываете таким образом, во временном каталоге вне вашего проекта. Если вы вносите изменения в файл, открытый с помощью проводника файлов устройства, и хотите сохранить изменения обратно на устройство, вы должны вручную загрузить измененную версию файла на устройство.

файловый менеджер

Полная документация

Джон
источник
6

Вы можете использовать этот сценарий оболочки ниже. Он также может извлекать файлы из кеша приложения, в отличие от 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
Тамас
источник
10
Самое приятное, когда вы не аргументируете, а потом rm /sdcard/подставляете, повезло, что это не так -rf.
TWiStErRob
3
Вы можете просто cat напрямую перейти к файлу на хосте: "adb shell run-as com.whatever.Fnord cat /data/data/com.whatever.Fnord/databases/logging.db> / tmp / foo" (где / tmp / foo - это файл на хост-машине, а не на устройстве Android)
Джеймс Мур,
Только что понял, что @ dave-thomas исправил проблему некоторое время назад. Удаление моего голоса против.
Дон Хэтч
Или нет :-( «Ваш голос теперь заблокирован, если этот ответ не отредактирован.»
Дон Хэтч
ТБХ Я не понимаю, о чем идет речь. (Исходный) сценарий никогда бы не удалил каталог (отсутствует ключ -rf), если он не был пуст. Я не проверял, но даже если каталог пуст, я сомневаюсь, что скрипт удаляет каталог, поскольку это точка монтирования. Сценарий выглядел опасным, но это никогда не было ...
Тамас
5

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

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

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

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

  4. Используйте для этого Android Backup Extractor . Скачать | Исходный код

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

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

  7. Извлеките файл data.tar, чтобы получить доступ ко всем файлам.

Генри
источник
2
Точно следил за этим и data.tarпросто data.tar.cpgzизвлекал из @henry
user-44651
2

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

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

Раньше ответ Виниция Авеллара отлично работал у меня. Мне почти всегда была нужна база данных с устройства из приложения отладки.

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

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

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

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

#!/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 . Я сделал резервную копию оригинальных jar-файлов политик и поместил их туда. Vola Мне удалось ввести пароль с помощью abe.jar и расшифровать его в файл tar.

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

tar xvf myAndroidBackup.tar

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

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

Дэйв Томас
источник
1
Благодаря вашему ответу с помощью метода №1 мне удалось получить и изучить резервную копию пакета из целевого приложения для отладки, установленного на производственном устройстве без рутирования, но резервная копия содержит только файл манифеста. С помощью метода №2 я загрузил все данные приложения, но двоичные файлы (т.е. файлы SQLite) не читаются. Я добавляю решение на основе вашего сценария, которое сработало у меня.
Paolone
1

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

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

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

см. File.setReadable ()

18446744073709551615
источник
1
Можно изменить разрешения во время отладки, но в какой-то момент перед выпуском это приведет к нарушению защиты, предлагаемой по умолчанию (чтобы другие приложения не могли получить доступ к файлам или испортить их). Следовательно, для разработчика более желателен способ доступа разработчика к файлам, даже если они доступны для чтения / записи.
Калаф
1

Начиная с сценария Дэйва Томаса, я смог написать собственное решение для преодоления двух проблем:

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

Это мой сценарий, который копирует данные приложения на 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
Паолоне
источник
1

Подобно ответу Тамаса , вот однострочный файл для 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 (или при желании удалить новые строки)
Зак Моррис
источник
0

Резервное копирование игровых данных с помощью apk . Нуга 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
Стивен Линн
0

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

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

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

serv-inc
источник
0

ты можешь сделать:

adb pull / хранилище / эмуляция / 0 / Android / данные //

Рой Барекет
источник
2
Не поймите меня неправильно, но вы правильно прочитали вопрос? OP просит вытащить «частные» данные, а не «публичные»
baburao