37

Can anyone tell me, is it possible to use the ADB to pull and push a database from an app, without root privileges on the phone?

For example, I know the location on my rooted magic and dream is:

/data/data/com.xxxx.xxxx/databases/xxxx

I know that you can use ADB without root, but when trying to use the shell - you can't view that location without root privaliges. But I have been told you can use push and pull if you know the file you want?

Basically I want to pull a database from MY app on a non rooted phone modify it and push it back on.

Only trouble I have is, the two phones I have are both root and I don't have access to a non root one to try it out.

Matt
  • 25,467
  • 18
  • 120
  • 187
Scoobler
  • 9,696
  • 4
  • 36
  • 51

5 Answers5

80

While Nilhcem's answer didn't work for me, it lead me in the right direction (for that I upvoted) and I now have a working solution.

Old answer that may not work with newer versions of Android:

#Transfer file from app databases directory to PC
adb shell
$ run-as package.name
$ cd ./databases/
$ ls -l #Find the current permissions - r=4, w=2, x=1
$ chmod 666 ./dbname.db
$ exit
$ exit
adb pull /data/data/package.name/databases/dbname.db ~/Desktop/

#Transfer file from PC to app databases directory (requires the above permission change)
adb push ~/Desktop/dbname.db /data/data/package.name/databases/dbname.db
adb shell
$ run-as package.name
$ chmod 660 ./databases/dbname.db #Restore original permissions
$ exit
$ exit

Alternate method using external storage (confirmed to work with 6.0.1):

#Transfer file from app databases directory to external storage
adb shell
$ run-as package.name
$ cp ./databases/dbname.db /sdcard/
$ exit
$ exit

#Transfer file from external storage to app databases directory
adb shell
$ run-as package.name
$ cp /sdcard/dbname.db ./databases/
$ exit
$ exit
Pilot_51
  • 7,337
  • 3
  • 29
  • 26
  • 1
    This is a correct answer for the question asked, where the person wanting to do this is the developer of the app and can install a debug version of it (debug version being a pre-requisite for run-as). Other options include having the app itself change the permission or copy the file to/from the external storage. – Chris Stratton Jun 18 '13 at 19:26
  • adb return with message run-as: Package 'com.instagram.android' is unknown what should I do? I also try to use su then adb pull /data/data/package.name/databases/dbname.db ~/Desktop/ but it return error: device not found? – UmAnusorn Oct 09 '13 at 15:37
  • 1
    @um.anusorn There is an issue in 4.3 that breaks run-as and should be fixed in 4.4. See: https://code.google.com/p/android/issues/detail?id=58373 If you have root, you can fix it by enabling the Set UID permission of /system/bin/run-as, but that kind of defeats the purpose. – Pilot_51 Feb 04 '14 at 16:25
  • 1
    @um.anusorn That could mean your app is not a debug version (having the same issue on 2.3). – halxinate Feb 20 '14 at 23:28
  • 4
    Although the file clearly exists and has the `chmod 666` applied, `adb pull` says the remote object does not exist. Seems like you still need some extra permissions to do this? – Sebastian Wramba Dec 11 '14 at 17:01
  • I've been trying to do something like this, but it's not a file of a specific app. I'm specifically trying to access the gesture.key file on my phone and it's not letting me pull it or chmod it. Is there something I can put in after the `run-as` that would grant me read access to the file? – Reverend Bubbles Apr 22 '15 at 23:18
  • 1
    This workaround does not work anymore, at least on Android 5.1+. Pulling the file says "the remote object filename does not exist". The answer should reflect this. – Bogdan Zurac May 19 '15 at 11:20
  • I finally had a need to transfer a file to my app data in 6.0.1 (stock Nexus 5X) and came up with a way to do so through external storage, very similar to Nilhcem's answer. Added to answer. – Pilot_51 Jun 04 '16 at 21:45
  • Does not work on SAMSUNG devices. http://stackoverflow.com/questions/37413667/run-as-could-not-set-capabilities-operation-not-permitted – user643011 Nov 24 '16 at 10:42
  • Your second part of your answer saved my day. Checked also on Android 6.0.1 and works perfectly. – Francisco Romero Feb 17 '17 at 00:49
13

A quick workaround is to use the run-as command to copy the database in a folder where you can have access, such as /sdcard and then, do a normal adb pull

adb shell
$ run-as package.name cp /data/data/package.name/dbname.db /sdcard/
$ exit
adb pull /sdcard/dbname.db

More information on the run-as command here

Note that the run-as command is available since API level 8 (Android 2.2) and can only be used if the application is debbugable.

Community
  • 1
  • 1
Nilhcem
  • 837
  • 7
  • 8
  • on my version (maybe something to do with 4.4, or some update in the last year?) I can't `cp` to /sdcard when using `run-as`. I need to use the `chmod` solution from @Pilot_51 – Richard Le Mesurier Feb 06 '14 at 09:22
  • This is true - the sd card is no longer writeable when using adb shell – slott Jan 13 '15 at 13:21
1

On OxygenOS (based on Android 5.2) I've combined the two solutions provided by Pilot_51.

First, I used run-as to gain access to /data/data/package.name/databases, but from here I wasn't able to copy directly to /sdcard/ so I changed the permissions of the file. After that, I exited from run-as mode and used cp to copy the file in /sdcard/ storage. Finally, I was able to use adb pull

$ adb -s <DEVICE_ID> shell
$ run-as package.name
$ chmod 666 databases/dbname.db
$ exit
$ cp /data/data/package.name/databases/dbname.db /sdcard/dbname.db
$ exit
$ adb pull /sdcard/dbname.db ./dbname.db
koyae
  • 720
  • 7
  • 12
fredmaggiowski
  • 2,232
  • 3
  • 25
  • 44
0

We set the file permissions to readable for all users from within the app.

if (BuildConfig.DEBUG)
{
    new File(mDB.getPath()).setReadable(true, false);
}

Then just pull the .db off with adb normally.

adb -d pull //data/data/xxxxx/databases/xxxxx.db .

NOTE: I've discovered that this needs to be done each time the database file is opened, for example in onCreate as well as the constructor of your SQLiteOpenHelper wrapper (when your database is not null) or perhaps onOpen. If only in onCreate, then the next time you run your app and the .db already exists, for some reason the permissions have been changed back. This might have something to do with how Android manages its data.

delrocco
  • 495
  • 1
  • 4
  • 23
0

if you want to push db file into the application

first of all, place "file.db" under "/storage/emulated/0/" because of permission issue. then you should pretend as application to access data folder.

  adb shell
  $ run-as com.package.name
  :/data/data/com.package.name $ cp /storage/emulated/0/file.db /data/data/com.package.name/databases/

it copies the file.db that in main folder to databases.

AhuraMazda
  • 460
  • 4
  • 22