Sunday, February 16, 2014

Доступ к ресурсам Android приложения

Бывает так, что во время разработки, нужно заглянуть в приватные директории приложения. Как известно, доступ к ним закрыт, и при попытке, скажем, получить список файлов, имеем следующее:

adennis@foofive ~ $ adb shell
shell@android:/ $ ls -al
...
drwxrwx--x system   system            2012-09-24 23:38 data
...
shell@android:/ $ cd data/
shell@android:/data $ ls
opendir failed, Permission denied

Есть несколько решений данной проблемы.

root

Первое, что приходит на ум - получить root права. Недостатки очевидны. Ломать телефон из-за маленькой плюшки - варварство(да и телефон может быть не личный, а, например, корпоративный). Но имея root, получаем неограниченный доступ ко всем ресурсам системы.

run-as

В составе Android OS есть утилита run-as. По своей сути очень похожа на sudo - выполнение команд от имени приложения или говоря короче - делегирование прав:

adb shell
run-as com.your.application ls -l /data/data/com.your.application
run-as com.your.application rm /data/data/comp.your.application/databases/database.db
…
# or your can run it in a interractive mode 
run-as com.your.application
shell@android:/data/data/com.your.application$ ls -l
cache
databases
lib
…

Пара моментов которые нужно знать... Приложение должно быть собрано как debuggable и в нек. случаях нужно менять права на файлы/директории:

adb shell 'run-as com.your.application chmod 666 /data/data/com.your.application/databases/databases.db'

Из недостатков можно назвать лишь одно - нет возможности доступа к файлам приложений третьих лиц(установленных, например, с Play Market).

backup

Последний способ. Я его использовал до того, как познакомился с run-as. Android предоставляет возможность сделать копию приложения:

adb -s [device id] backup -f backup.dat -noapk com.your.application

В текущей директории будет создан файл backup.dat([device id] можно узнать командой 'adb devices'). Далее распаковываем *.dat файл:

dd if=backup.dat bs=1 skip=24 | openssl zlib -d | tar -xvf -

Приведенная команда у меня работает только под Linux, под Mac OS я получаю сообщение об ошибке, мол openssl собран без поддержки zlib. Немного пошаманив, нашел решение, которое не требует пересборки openssl:

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

По сравнению с Linux вариантом, работет медленнее, но для меня не критично. После всех шагов, в текущей директории будет создана папка apps, содержащая все внутренности приложения.

До недавнего времени последний способ не имел недостатков. Т.е. была возможность получить доступ ко всем потрохам без каких-либо ограничений. Но начиная с версии Android 4.4 в AndroidMainifext.xml был добавлен флаг allowBackup:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.your.application">
...
    <application
...
        android:allowBackup="true"/>
...
</manifest>

Который гласит буквально следующее: если флаг установлен в значение false, то приложение никогда не будет иметь возможность сделать резервную копию или восстанновление из резервной копии, даже в случае резерного копирования всей системы(имеется ввиду средствами самой ОС). Поумолчанию флаг имеет значение true. Вот такие дела. Т.е. доспут к ресурсам своего приложения мы всегда будем иметь, а в остальном - как повезет.

Источники

No comments:

Post a Comment