11

I wrote a Windows batch file that replaces Amazon lockscreen ads with user images on rooted kindle fire hd 7", 2013 (kfsowi). Just learned I botched the adb commands because I was running "adb insecure" so was getting su access without writing it into the adb commands.

What I need: To run in batch file, I need one-line adb shell su commands to pull from/push to /data on this device. (Or I could use adb -d shell su -c "mount -o remount rw, /data on one line followed by the pull or push)

I have fixed an ls command like this:

  • this worked with adb insecure: adb ls "/data/securedStorageLocation"
  • what I needed was: adb shell su -c "ls ./data/securedStorageLocation"

Now I need same for pull and push. The problem:

  • With adb insecure, this works fine: adb pull "/data/securedStorageLocation" "C:/destination"
  • Without adb insecure I get: remote object '/data/securedStorageLocation/' does not exist

Above happens even if I first run: adb -d shell su -c "mount -o remount rw, /data

Can someone tell me how to do the pull and push with adb shell and su?

EDIT: adb root command doesn't gain root on this device

3
  • To use adb push or adb pull in root mode, the adb daemon on the device must be running in root mode (which is what ADBInsecure does).
    – Izzy
    Oct 23, 2014 at 16:19
  • @Izzy How can I get into root mode without adb insecure if >adb root< command doesn't work? I want to distribute this. Is there any other way to push and pull the directory? thx
    – sjoy
    Oct 23, 2014 at 17:09
  • I don't know (always used "ADB Insecure", as I couldn't get adb root to work either). Worth a separate question, maybe?
    – Izzy
    Oct 24, 2014 at 9:55

6 Answers 6

11

Well, you have to do a few commands, as I don't believe it will work in one.

You need to do:

  1. adb shell
  2. su
  3. cd /data/path/of/file
  4. cp /data/path/of/file/copyme /data/local/tmp
  5. chown shell.shell /data/local/tmp/copyme
  6. exit
  7. exit
  8. adb pull /data/local/tmp/copyme /destination/copyme

This works for me every time.

3
  • 1
    what exactly is shell.shell
    – Remario
    Apr 20, 2017 at 18:47
  • 2
    @Remario linux.die.net/man/1/chown - it means owner.group. When you copy a file using SU, the owner and group will be root.root . The adb pull command runs as shell.shell and will not be able to pull the file from the temporary location. Changing it before doing pull will allow you permission.
    – Mike N.
    Apr 20, 2017 at 22:21
  • do not forget to remove /data/local/tmp/copyme finally (after pull)
    – a55
    Jun 15, 2022 at 20:04
4
adb root; adb push /local/file /distant/root/owner/file

"adb root" will restart adbd as root then your push is accepted

2

Thanks for this discussion. It led me to a solution that worked well enough for me while backing up my phone that won't mount its internal ext4, before I do something drastic while trying to fix it (apparently this needs root permissions).

Note that adb shell generally sets up a text terminal (so can convert single end-of-line characters to CRLF, mangling binary data like partition images or TAR archives). While you can work around this in Unix/Linux versions of adb (e.g. add stty raw to your shelled command) or use some newer adb with exec-out option, on Windows it still writes CRLF to its output. The neat trick is to pass data through base64 encoding and decoding (binaries are available for Windows en-masse). Also note that errors or verbose messages printed to stderr in shell end up on stdout of adb shell program in the host system - so you want to discard those after inevitable initial experimentation.

Here goes:

adb shell "su -c 'cat /dev/block/mmcblk0p25 | base64' 2>/dev/null" | base64 -d > p25

Can be easily scripted by Windows to cover all the partitions (can look the list up by ls -la /dev/block/ and/or by cat /proc/diskstats or cat /proc/partitions), e.g.:

for /L %P in (1,1,25) do ..\platform-tools\adb shell "su -c 'cat /dev/block/mmcblk0p%P | base64' 2>/dev/null" | base64 -d > s3-mmcblk0p%P.img

(Note to use %%P in CMD batch files, or %P in interactive shell).

Don't forget that there are also mmcblk0boot[01] partitions, and that the mmcblk0 overall contains all those partitions in a GPT wrapping, just like any other harddisk or impersonator of one :)

To estimate individual partition sizes, you can look at the output of:

fdisk -u -l /dev/block/mmcblk0*

Unfortunately, I did not quickly and easily manage to tar cf - mmcblkp0* and get the partition contents, so I could pipe it to e.g. 7z x -si and get the data out as multiple files in a portable one-liner as well.

To tar some files you can:

adb shell "su -c 'cd /mnt/data && tar czf - ./ | base64' 2>/dev/null" | base64 -d > s3-mmcblk0p25-userdata.tar.gz

UPDATED: Found some more tricks to transfer binary data.

Hope this helps someone else, Jim Klimov

5
  • base64 isn't an ideal solution. For small files it works fine but for large files, it increases transferral time by one third!
    – iBug
    Mar 22, 2017 at 11:35
  • Of course it is not perfect due to that, but given that for recovery purposes grasping for any straws that can help is good enough... well... :) In any case, if I send a whole partition for export like this, I do not really care if it takes an hour vs hour and a half, as long as it reliably does the job. Also if, as some others have documented, the Windows variant of adb.exe effectively always outputs CRLF separated text, there seems little we can do but abuse it with ASCII-friendly incapsulation. Alternately, adb exec-out might be the solution - but for some reason did not work well for me.
    – Jim Klimov
    Mar 23, 2017 at 10:17
  • mine sudo adb shell su 0 -c 'dd if=/dev/block/mmcblk0 | base64 2>/dev/null' | base64 -d >./mmcblk0.img 2>/dev/null
    – a55
    Jun 15, 2022 at 22:55
  • But, what happen if we dont use base64 ?!
    – a55
    Jun 15, 2022 at 22:57
  • As commented above, there may be issues sending binary as plaintext between Linux (Android) and Windows (adb). You might not need encapsulation if both sides agree on line endings.
    – Jim Klimov
    Jul 29, 2022 at 8:51
1

Not necessarily will it be one-line, but you can try to do the following actions:

  • (with adb shell, su) Copy the files to a temporary accessible location on your device (for example, /sdcard, or external SD card)
  • (with adb pull) Copy these files from the temporary location to your machine
  • Delete temporary copy

Possible drawback: between first and last step a malicious app, if you happen to be "using" it, may read and/or modify there files in temporary publicly accessible directory. In practice, this is very unlikely.

1

I use the batch script (extract-db-from-emulator.bat) below to pull local database out to the host:

@@echo off
SET adb_path="%USERPROFILE%\AppData\Local\Android\sdk\platform-tools\"
SET application_id="com.example.myapp"
SET root_access_filepath="/data/user/0/%application_id%/databases/local.db"
SET pullable_filepath="/mnt/sdcard/DCIM/local.db"
SET host_directory="%USERPROFILE%\Desktop"
SET root_command="su 0 cp"
%adb_path%adb.exe shell "%root_command% %root_access_filepath% %pullable_filepath%"
%adb_path%adb.exe pull %pullable_filepath% %host_directory%
0

I see an error with

adb shell "su -c '<your command>'"

su: invalid uid/gid '-c'

The solution is on Linux

adb shell su 0 '<your command>'
1
  • add -c before command, like: sudo adb shell su 0 -c 'whoami'
    – a55
    Jun 15, 2022 at 20:56

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .