71

I just rooted my Nexus 5 using this method: http://www.phonearena.com/news/How-to-root-Google-Nexus-5_id49014

I also enabled USB debugging in the developer options.

Then I tried to pull a database file from my device using this command:

adb pull /data/data/path.to.package/databases/data /sdcard/test

I get permission denied error.

I don't have the debugged flag set in that app I tried to access. Is that the reason I can't access that file? If yes, are there any workarounds to access an apps files?

vinod maverick
  • 670
  • 4
  • 14
user2246120
  • 1,453
  • 2
  • 17
  • 38

15 Answers15

124

You can use run-as shell command to access private application data.

If you only want to copy database you can use this snippet, provided in https://stackoverflow.com/a/31504263/998157

adb -d shell "run-as com.example.test cat /data/data/com.example.test/databases/data.db" > data.db
Community
  • 1
  • 1
guest-418
  • 1,574
  • 1
  • 13
  • 19
  • 2
    This is the only solution that worked for me on a stock phone. thanks! – Lyve Oct 17 '16 at 15:15
  • I wish I could favorite answers, this is the only thing that helped in 20 searches. – HopefullyHelpful Apr 03 '17 at 15:30
  • Just a note, you can also use this in `adb shell` itself as `run-as com.example.test sh` – David Berry Sep 07 '17 at 16:55
  • It says `"run-as: Could not set capabilities: Operation not permitted"`. What to do? – mr5 Feb 20 '18 at 05:05
  • 5
    Great answer! For anyone grabbing from an emulator leave out the '-d' option. – James Trickey Nov 28 '18 at 11:35
  • 8
    This throws run-as: package not debuggable: – 3lokh Jan 07 '19 at 09:53
  • 4
    i got "No devices found" error. though emulator is running. – TejpalBh Jul 30 '19 at 06:14
  • How do you save file to specific directory? – PLOW Jan 20 '20 at 16:28
  • @PLOW, this is just shell redirection - the part after '>' is the path to the file where the output of the command will be written. – guest-418 Feb 02 '20 at 20:58
  • Not sure how `cat` would work for binary, files, co instead I did `adb -d shell "run-as com.example.test cp foo /sdcard"` which then allowed me to `adb pull /sdcard/foo` as normal. – anotherdave Mar 24 '20 at 12:11
  • On a linux box (and perhaps macos) if you want to transfer a binary file without glitching it you can always do this: adb shell "run-as base64 " > base64 -d ` This will base64 encode the file in the pipe. – Jamie Le Tual Mar 26 '20 at 21:44
  • 1
    oops, I meant to put a pipe and not a redirect there.... FTR: adb shell "run-as base64 [targetfile]" | base64 -d > [localtargetfile] – Jamie Le Tual Mar 26 '20 at 23:32
  • Do we need to pay attention to CR and LR (\r\n) characters on windows? I mean how to get binary clean (no LF -> CRLF mangling), as [https://github.com/facebook/fb-adb] mentioned. – samm Mar 27 '20 at 09:02
  • 1
    If you want to run this on an emulator, remember the `-e` instead of `-d` above. – Diederik Feb 01 '22 at 11:24
26

I had the same problem. My work around is to use adb shell and su. Next, copy the file to /sdcard/Download

Then, I can use adb pull to get the file.

Huiyang
  • 269
  • 3
  • 2
25

Did you try adb remount after giving adb root?

Anvesh Yalamarthy
  • 1,625
  • 20
  • 36
17

This generic solution should work on all rooted devices:

 adb shell "su -c cat /data/data/com.android.providers.contacts/databases/contacts2.db" > contacts2.d

The command connects as shell, then executes cat as root and collects the output into a local file.

In opposite to @guest-418 s solution, one does not have to dig for the user in question.

Plus If you get greedy and want all the db's at once (eg. for backup)

for i in `adb shell "su -c find /data -name '*.db'"`; do
    mkdir -p ".`dirname $i`"
    adb shell "su -c cat $i" > ".$i" 
done

This adds a mysteryous question mark to the end of the filename, but it is still readable.

moestly
  • 1,681
  • 15
  • 19
8

If you get could not copy and permissions are right disable selinux.

Check if selinux is enabled.

$ adb shell
$su
# getenforce
Enforcing

Selinux is enabled and blocking/enforcing. Disable selinux

# setenforce 0

do your stuff and set selinux to enforcing.

# setenforce 1
zteffo
  • 105
  • 1
  • 1
6

This answer ended up working for me: https://stackoverflow.com/a/15559278/53001

Backup to a file, pull the backup, and then convert it to a tarball and extract it.

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

dd if=myAndroidBackup.ab bs=1 skip=24 | python -c "import zlib,sys;sys.stdout.write(zlib.decompress(sys.stdin.read()))" | tar -xvf - 
Community
  • 1
  • 1
Ken Sykora
  • 1,124
  • 13
  • 27
5

I had just the same problem, here's how to deal with it:

  1. adb shell to the device
  2. su
  3. ls -l and check current access rights on the file you need. You'll need that later.
  4. go to the file needed and: chmod 777 file.ext. Note: now you have a temporary security issue. You've just allowed all the rights to everyone! Consider adding just R for users.
  5. open another console and: adb pull /path/to/file.ext c:\pc\path\to\file.exe
  6. Important: after you're done, revert the access rights back to the previous value (point 3)

Someone mentioned something similar earlier.

Thanks for the comments below.

Goran Devs
  • 332
  • 3
  • 4
  • 20
    **NONONO**! Why would you ever do this? Horrible answer. This is allowing open permissions for `Owner`,`User`, and `Other` to openly `Read`, `Write`, `Execute`. If this is a file that you need `root` access to, then it is most like a file that should not be able to be touched by some other rogue apps. Do not ever do this. My suggestion is to copy the file `system -> sdcard -> computer` and then delete from sdcard. To put a file back into the filesystem, `computer -> sdcard -> system -> strict permissions`. – Matt Clark Dec 03 '14 at 18:37
  • 11
    I agree this is a security issue, but it is a quick fix intended for the developer not to waste time on trivia. – Goran Devs Dec 04 '14 at 10:25
  • with that answer you'll have security problems because any application will be able to access your database – e-info128 Jan 12 '15 at 18:29
  • 2
    you can't `su` on devices – Ken Sykora Mar 18 '16 at 16:02
  • 2
    @MattClark, so you state this is *wow-wow-wow horrible*, but what can you propose as alternative? Disabling SeLinux seems no safer to me, and this is the only solution "that just works"! – Suncatcher Feb 04 '17 at 16:34
  • Works with adb pull, but not with adb push, for some reason. – Yar Jul 10 '17 at 12:02
4
  1. Create a folder in sdcard :
adb shell "su 0 mkdir /sdcard/com.test"
  1. Move your files to the new folder :
adb shell "su 0 mv -F /data/data/com.test/files/ /sdcard/com.test/"
  1. You can now use adb pull :
adb pull /sdcard/com.test
2
$ adb shell
$su
# getenforce
Enforcing

now try

adb shell
su
chmod 777 /path/to/yout_file

exit from shell

open new CMD and try adb pull /path/to/yout_file

It will work fine now.

you'll have security problems because of this any application will be able to access your database.

  • lol, good ol' lucky 7s. +1, b/c that did the trick, but there should be major **emphasis** on **security problems**. – MDMoore313 Sep 07 '18 at 15:12
2

@guest-418 tips works well:

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

However, if you want to use a GUI, use Android Studio's Device File Explorer.

  1. Launch Android Studio

  2. Click on Device File Explorer at bottom right-side Navigate to your app's file:

    /data/data/path.to.package/databases/data

  3. Right-mouse click select Save As and save to a local folder

I have been having Android Monitor hang on me lately on macOS. Device File Explorer works well for this purpose.

Ed of the Mountain
  • 5,219
  • 4
  • 46
  • 54
1

When executing adb commands, by default, a limited privileges user is used, the same kind of limited privilege user that is assigned to an app, and you have requested for all privelages to use all features of the device.

This kind of limited user helps protect your phone from malware, by restricting the access between apps, and the system. This is the reason you are unable to access app data and system data on an unrooted phone. The act of rooting means becoming user 0, the super user of the system, capable of any action, and is the highest privilege. Your apps however, are still secure in that they can not talk to eachother.

Now when accessing secure files, note that you do not want to change the permissions of the file when you access it, which may allow for vulnerabilities.

An option that you could use instead, is to make a copy of the file on the sdcard as root, modify that as a standard user, and then move it back into the filesystem as root, while preserving the file permissions of the original file.

Matt Clark
  • 27,671
  • 19
  • 68
  • 123
1

Since I've updated to Android Oreo, I had to use this script to fix 'permission denied' issue.

This script on Mac OS X will copy your db file to Desktop. Just change it to match your ADB_PATH, DESTINATION_PATH and PACKAGE NAME.

#!/bin/sh
ADB_PATH="/Users/xyz/Library/Android/sdk/platform-tools"
PACKAGE_NAME="com.example.android"
DB_NAME="default.realm"
DESTINATION_PATH="/Users/xyz/Desktop/${DB_NAME}"
NOT_PRESENT="List of devices attached"
ADB_FOUND=`${ADB_PATH}/adb devices | tail -2 | head -1 | cut -f 1 | sed 's/ *$//g'`
if [[ ${ADB_FOUND} == ${NOT_PRESENT} ]]; then
    echo "Make sure a device is connected"
else
     ${ADB_PATH}/adb exec-out run-as ${PACKAGE_NAME} cat files/${DB_NAME} > ${DESTINATION_PATH}
fi
Milos Pesic
  • 720
  • 2
  • 8
  • 23
0

This is a bit late, but installing adbd Insecure worked for me. It makes adb run in root mode on production ("secure") devices, which is what you likely have.

A paid version is also available on Google Play if you want to support the developer.

Andrew Sun
  • 4,101
  • 6
  • 36
  • 53
0

I had a similar problem to yours on windows as the following.

D:\ProgramFiles\Android> adb pull /data/local/tmp/com.packagename_dumped_1766.dex D:\ProgramFiles\Android\com.packagename_dumped_1766.dex
adb: error: failed to copy '/data/local/tmp/com.packagename_dumped_1766.dex' to 'D:\ProgramFiles\Android\com.packagename_dumped_1766.dex': remote Permission denied

My solution:

At first I also made an attempt to use cat as ansi_lumen answered, but I got into trouble about CR and LR (\r\n) characters. And then I just had to change those file permisions by chmod and pulled again to this problem was solved without introducing other problems. After that, may we need to restore their original permissions as Goran Devs answered.

So just pay a little attention.

TL;DR

My story:

Firstly, I used the cat to download all files from android to my windows,

@echo off
cd /d %~dp0
:: %~dp0 = D:\ProgramFiles\Android\
SET ThisBatDir=%~dp0
:: adb shell ls /data/local/tmp/com.packagename_dumped_* > %~dp0\dump_file_list.txt
FOR /f "delims=" %%a in ('adb shell ls /data/local/tmp/com.packagename_dumped_*') do call :processline %%a %%~nxa

goto :eof

:: https://stackoverflow.com/questions/232651/why-the-system-cannot-find-the-batch-label-specified-is-thrown-even-if-label-e
:processline
SET RemoteFullPath=%1
set FileName=%2
:: echo "%RemoteFullPath%|%ThisBatDir%|%FileName%"
call adb shell su -c cat %RemoteFullPath% > %ThisBatDir%%FileName%
goto :eof

:eof

However, those downloaded dex files were broken because of CR and LR (\r\n) characters on windows. We can use hexdump to inspect its content in Hex+ASCII form (or Notepad++ with "View > Show Symbol > Show All Characters" checked). Note, the 5th and 6th byte (0d 0a)).

ssfang@MONITO ~
$ hexdump -C -n32 /cygdrive/d/ProgramFiles/Android/com.packagename_dumped_1448.dex # a bad dex
00000000  64 65 78 0d 0d 0a 30 33  35 00 f7 8e e4 b5 03 c6  |dex...035.......|
00000010  29 22 98 55 21 e9 70 49  fe c8 e4 cc fa 94 cd 63  |)".U!.pI.......c|
00000020

ssfang@MONITO ~
$ hexdump -C -n32 /cygdrive/d/ProgramFiles/Android/classes.dex # a normal dex
00000000  64 65 78 0a 30 33 35 00  b5 73 03 3a 0b 9d a2 47  |dex.035..s.:...G|
00000010  a8 78 a4 f0 bb e1 64 3f  e5 b9 cb a0 bd 1b e2 71  |.x....d?.......q|
00000020

Versions

  • adb version // to check adb client version in your desktop
  • adb shell adbd --version // to check adbd's version in your Android. Please note that some users reported error with this if executed without root access.
D:\ProgramFiles\Android>adb version
Android Debug Bridge version 1.0.41
Version 29.0.6-6198805
Installed as D:\ProgramFiles\Android\Sdk\platform-tools\adb.exe

D:\ProgramFiles\Android>adb shell adb version
Android Debug Bridge version 1.0.32

Even if restarting adbd as root, it was still the shell user after .

D:\ProgramFiles\Android> adb root
restarting adbd as root

D:\ProgramFiles\Android> adb shell id
uid=2000(shell) gid=2000(shell) groups=1003(graphics),1004(input),1007(log),1011(adb),1015(sdcard_rw),1028(sdcard_r),3001(net_bt_admin),3002(net_bt),3003(inet),3006(net_bw_stats) context=u:r:shell:s0

So I first viewed its file permision,

D:\ProgramFiles\Android> adb shell ls -l /data/local/tmp
-rwsr-sr-x shell    shell      589588 2017-09-14 15:08 android_server
-rwsr-sr-x shell    shell     1243456 2017-09-14 15:08 android_server64
-rw-rw-rw- shell    shell        1536 2020-03-28 17:15 com.packagename.tar.gz
-rw-r----- root     root        57344 2020-03-28 17:45 com.packagename_dumped_1766.dex
drwxrwxr-x shell    shell             2018-08-12 09:48 device-explorer
-rwsrwsr-x shell    shell       13592 2019-02-04 17:44 drizzleDumper
-rwxrwxrwx shell    shell     5512504 2018-05-06 01:27 lldb-server
-rwxr-xr-x shell    shell       12808 2020-03-26 22:16 mprop

then, changed its permision,

D:\ProgramFiles\Android> adb shell su -c chmod 777 /data/local/tmp/com.packagename_dumped_*

D:\ProgramFiles\Android> adb shell ls -l /data/local/tmp
-rwxrwxrwx root     root        57344 2020-03-28 17:45 com.packagename_dumped_1766.dex

As a result, I made it.

D:\ProgramFiles\Android> adb pull /data/local/tmp/com.packagename_dumped_1766.dex D:\ProgramFiles\Android\com.packagename_dumped_1766.dex
/data/local/tmp/com.packagename_dumped_1766.de... 1 file pulled, 0 skipped. 3.6 MB/s (57344 bytes in 0.015s)

Now, jadx-gui-dev.exe or sh d2j-dex2jar.sh -f ~/path/to/apk_to_decompile.apk could properly enjoy them.

samm
  • 620
  • 10
  • 22
-6

The pull command is:

adb pull source dest

When you write:

adb pull /data/data/path.to.package/databases/data /sdcard/test

It means that you'll pull from /data/data/path.to.package/databases/data and you'll copy it to /sdcard/test, but the destination MUST be a local directory. You may write C:\Users\YourName\temp instead.

For example:

adb pull /data/data/path.to.package/databases/data c:\Users\YourName\temp
Sujit Devkar
  • 1,195
  • 3
  • 12
  • 22
Maik93
  • 233
  • 1
  • 10
  • 1
    This didn't work either: I still get 'permission denied' error – user2246120 Jan 03 '14 at 23:47
  • mmm... try to get more permissions of the dir you pull from: "adb shell chmod 755 /path/to/dir" – Maik93 Jan 04 '14 at 10:29
  • I get: 'Operation not permitted' error when trying to set permission. Any other ideas? – user2246120 Jan 04 '14 at 15:34
  • don't listen the answer below, you've rooted well, but `adb root` doesn't work in stock ROM, you must write `adb shell` then enter, `su` again enter, and now try change permission again with `chmod 755 /path/to/dir/` I hope this work – Maik93 Jan 04 '14 at 20:00
  • Thanks! I did that and now get the error: 'device not found'. I tried to do it on the file and the directory... but neither worked – user2246120 Jan 05 '14 at 01:05
  • device not found? :/ Can u see device id via `adb devices ` command? however I think you could copy the desidered file in a "more used" directory, like /sdcard/, and pull it from there. Or maybe you could try to browse your phone with qtADB for windows, or an app called Airdroid (gratis on the playstore), that let you browse directories remotely via your PC browser – Maik93 Jan 05 '14 at 12:59