ADB push and pull as root

The Android Debug Bridge (ADB) got more secure in the evolution of Android, but that makes it unfortunately less useful, now it is almost impossible to push/pull system files or application data. Trying to run adb root results usually just in:

adbd cannot run as root in production builds

Pre Android 4.0 setting the property ro.secure=0 allowed to run adbd as root, but that is usually contained in /default.prop and that gets overwritten at every boot (to the default values from the boot.img). So you would have to modify the boot.img, like decribed on the linked xda thread on the bottom.

Chainfire made in 2014 the adbd Insecure to circumvent this, but it also apperently doesn’t work anymore on recent Android versions.

One option is still the recovery mode, TWRP provides adb access and this runs with higher permission per default. The disadvantage is that it always requires a reboot. More importantly the partitions have to be mounted und decrypted first, which is sometimes hard to impossible. Also some filesystems/informations are only available on a running system (for example procfs or tmpfs).

So i looked for another solution and found that it is possible to call su from the adb shell (instead of insecurely running the whole adb daemon as root) and piping the data into it, then writing it to the storage utilizing dd. This triggers also the normal superuser popup, which allows to decide individually to grant or deny the access.

I made a python script to make this easier to use, you can get it from the repo. The usage is similar to the offical adb push/pull, with a few extensions, for example it can directly set the file owner/mode and verify the integrity (recommended for important files). This uses adb shell in the background, so normal adb must be working on the system.

Example usage

Basic push:

./adb-root.py push test.txt /sdcard/test.txt
0+1 records in
0+1 records out
12 bytes transferred in 0.001 secs (12000 bytes/sec)

(only warning loglevel)

Push with special permissions:

./adb-root.py push -m 750 -o system:system -v test.txt /data/test.txt
[1 ms] INFO:Started pushing test.txt
0+1 records in
0+1 records out
12 bytes transferred in 0.001 secs (12000 bytes/sec)
[983 ms] INFO:Transfer on /data/test.txt successful
[1882 ms] INFO:Change mode on /data/test.txt successful
[2734 ms] INFO:Change owner on /data/test.txt successful

(-m and -o to change mode+owner+group, -v to increase loglevel to info)

Pull with check:

./adb-root.py pull -c -v /data/test.txt new.txt
[1 ms] INFO:Started pulling /data/test.txt
0+1 records in
0+1 records out
12 bytes transferred in 0.005 secs (2400 bytes/sec)
[927 ms] INFO:Transfer on new.txt successful
[928 ms] INFO:Started integrity check with SHA256
[1756 ms] INFO:Integrity ok: new.txt => /data/test.txt (d2a84f4b8b650937ec8f73cd8be2c74add5a911ba64df27458ed8229da804a26)

(-c for integrity check, -v to increase loglevel to info)

Sources

https://github.com/Jakeler/adb-root

https://forum.xda-developers.com/showthread.php?t=2593581

https://seasonofcode.com/posts/how-rooting-works-a-technical-explanation-of-the-android-rooting-process.html