android adb, retrieve database using run-as

2018-12-31 12:31发布

问题:

On a non-rooted android device, I can navigate to the data folder containing the database using the run-as command with my package name. Most files types I am content with just viewing, but with the database I would like to pull if from the android device.

Is there a download copy or move command from this part of adb shell? I would like to download the database file and view its content using a database browser.

One answer here involves turning entire application package into a compressed archive, but there is no further answer on how to extract that archive once this is done and moved to the machine, leaving me very sidetracked when there might be a more direct solution to begin with

回答1:

By design user build of Android (that\'s what you have on your phone until you unlock the bootloader and flash the phone with userdebug or eng software) restricts access to the Internal Storage - every app can only access its own files. Fortunately for software developers not willing to root their phones Google provides a way to access the Internal Storage of debuggable versions of their packages using run-as command.

To download the /data/data/debuggable.app.package.name/databases/file from an Android 5.1+ device run the following command:

adb exec-out run-as debuggable.app.package.name cat databases/file > file

To download multiple files in a folder under the /data/data/debuggable.app.package.name/ at once - use tar:

adb exec-out run-as debuggable.app.package.name tar c databases/ > databases.tar
adb exec-out run-as debuggable.app.package.name tar c shared_prefs/ > shared_prefs.tar


回答2:

The accepted answer doesn\'t work anymore for me (blocked by Android?)

So instead I did this:

> adb shell
shell $ run-as com.example.package
shell $ chmod 666 databases/file
shell $ exit                                               ## exit out of \'run-as\'
shell $ cp /data/data/package.name/databases/file /sdcard/
shell $ run-as com.example.package
shell $ chmod 600 databases/file
> adb pull /sdcard/file .


回答3:

I\'ve published a simple shell script for dumping databases:

https://github.com/Pixplicity/humpty-dumpty-android

It performs two distinct methods described here:

  1. First, it tries to make the file accessible for other users, and attempting to pull it from the device.
  2. If that fails, it streams the contents of the file over the terminal to the local machine. It performs an additional trick to remove \\r characters that some devices output to the shell.

From here you can use a variety of CLI or GUI SQLite applications, such as sqlite3 or sqlitebrowser, to browse the contents of the database.



回答4:

If anyone looking for pulling database from debug application may use the procedure below:

  1. search and open device file explorer

\"search

  1. Select your handset and then browse to data/data directory

\"go

  1. Now find your application package and go to databases folder. You can see the databases there and upon right click, you will get option to save this in your drive.

\"enter



回答5:

I couldn\'t get anything else to work for me but this:

adb shell
run-as package.name
cat /databases/databaseFileName.db > /sdcard/copiedDatabaseFileName.db
exit
exit
adb pull /sdcard/copiedDatabaseFileName.db /file/location/on/computer/

The first exit is to exit out of the run-as, the second exit is to exit out of adb shell to do the pull.



回答6:

For app\'s debug version, it\'s very convenient to use command adb exec-out run-as xxx.yyy.zzz cat somefile > somefile to extract a single file. But you have to do multiple times for multiple files. Here is a simple script I use to extract the directory.

#!/bin/bash
P=
F=
D=

function usage()
{
    echo \"$(basename $0) [-f file] [-d directory] -p package\"
    exit 1
}

while getopts \":p:f:d:\" opt
do
    case $opt in
        p)
            P=$OPTARG
            echo package is $OPTARG
            ;;
        f)
            F=$OPTARG
            echo file is $OPTARG
            ;;
        d)
            D=$OPTARG
            echo directory is $OPTARG
            ;;
        \\?)
            echo Unknown option -$OPTARG
            usage
            ;;
        \\:)
            echo Required argument not found -$OPTARG
            usage
            ;;
    esac
done

[ x$P == x ] && {
    echo \"package can not be empty\"
    usage
    exit 1
}

[[ x$F == x  &&  x$D == x ]] && {
    echo \"file or directory can not be empty\"
    usage
    exit 1
}

function file_type()
{
    # use printf to avoid carriage return
    __t=$(adb shell run-as $P \"sh -c \\\"[ -f $1 ] && printf f || printf d\\\"\")
    echo $__t
}

function list_and_pull()
{
    t=$(file_type $1)
    if [ $t == d ]; then
        for f in $(adb shell run-as $P ls $1)
        do
            # the carriage return output from adb shell should
            # be removed
            mkdir -p $(echo -e $1 |sed $\'s/\\r//\')
            list_and_pull $(echo -e $1/$f |sed $\'s/\\r//\')
        done
    else
        echo pull file $1
        [ ! -e $(dirname $1) ] && mkdir -p $(dirname $1)
        $(adb exec-out run-as $P cat $1 > $1)
    fi
}

[ ! -z $D ] && list_and_pull $D
[ ! -z $F ] && list_and_pull $F

Hope it would be helpful. This script is also available at gist.

Typical usage is

$ ./exec_out.sh -p com.example.myapplication -d databases

then it will extract all files under your apps databases directory, which is /data/data/com.example.myapplication/databases, into current directory.



回答7:

Much much simpler approach to download the file onto your local computer:

In your PC shell run:

adb -d shell \'run-as <package_name> cat /data/data/<package_name>/databases/<db_name>\' > <local_file_name>


回答8:

Here\'s a solution that works on a device running Android 5.1. The following example is for Windows.

You need sed ([https://www.gnu.org/software/sed/manual/sed.html] or sed.exe on windows, e.g. from cygwin.) ( On Unix, it\'ll just be there ;) ). To remove bad \'\\r\' characters, at least on windows.

Now just run the following command:

adb exec-out \"run-as com.yourcompany.yourapp /data/data/com.yourcompany.yourapp/databases/YourDatabaseName\" | c:\\cygwin\\bin\\sed.exe \'s/\\x0D\\x0A/\\x0A/\'>YourDatabaseName.db

The sed command strips out trailing /r characters.

Of course you should replace \"com.yourcompany.yourapp\" with the package name of the app and \"YourDatabaseName\" with the name of the database in the app.



回答9:

If someone is looking for another answer that can be used to retrieve Database as well as Shared Preferences then follow this step:

In your build.gradle file of your app add line

debugCompile \'com.amitshekhar.android:debug-db:1.0.0\'

now when you run your app in non-release mode then your app will automatically open 8080 port from your device IP address make sure your device is connected via wifi and your laptop is sharing the same network. Now simply visit the url

http://your_mobile_device_ip:8080/

to watch all data of database along with shared preferences.



回答10:

#!/bin/bash
#export for adb
export PATH=$PATH:/Users/userMe/Library/Android/sdk/platform-tools
export PATH=$PATH:/Users/userMe/Library/Android/sdk/tools

adb -d shell \'run-as com.android.app  cp /data/data/com.android.app/files/db.realm /sdcard\'
adb pull sdcard/db.realm /Users/userMe/Desktop/db

You can use this script for get Realm database.