N.B., This is for educational purposes only. If you want an easier method, compile an engineering build of the recovery.img and boot it: https://source.android.com/source/building.html
N.B., This is a work in progress. I'm updating for Nexus 5X and Android 6.0.0. Booting the modified recovery.img does not currently start adbd. I've created working images for Nexus 5 based on 4.4.2 and Nexus 7 based on 5.1.1 using slight derivations of the process described below.
Original Post: https://goo.gl/4r73We
Possible changes required to get adbd running:
- persist.sys.usb.config=adb # Necessary? Maybe; Sufficient? No
- ... ?
I picked up a new Nexus 5 with the goal of gaining root access to my device without flashing, installing any apps, or using any software that wasn't acquired directly from google.com or the Debian Sid repos. As I suspected, the most difficult problem I would encounter was trying to find helpful information among the mass of posts and blogs on "rooting" android devices. In the end the process was quite short (defining it, however, was not).
The solution was to create a live image to boot off of that enabled root access. From the live image the system can be modified (much like booting a workstation off a GNU/Linux Live CD).
In what follows, I define how to modify the factory recovery image (provides the recovery environment reached via the fastboot bootloader) and boot off of it to gain root access. Though I recommend using a modified recovery image to a make changes to your system, the instructions can be altered to instead modify the factory boot image (provides the environment your system generally runs from). This is done by replacing all occurrences of "recovery.img" with "boot.img" and skipping any sections or instructions prefixed with "(R):".
Note: This guide is probably not for you if you are not experienced with GNU/Linux and a shell such as bash or sh.
mkdir -p android/factory-images
mkdir android/my-live-image
mkdir android/src
pushd android
su -l # login as root with root password (alternatively use sudo)
dpkg --add-architecture i386
dpkg --print-foreign-architectures
apt-get update
apt-get install build-essential\
g++-multilib\
git\
libc6-dev-i386\
python
exit # exit root shell
pushd src
for i in `echo -n 'build'\
'bionic'\
'external/clang'\
'external/compiler-rt'\
'external/jemalloc'\
'external/libcxx'\
'external/libcxxabi'\
'external/libselinux'\
'external/llvm'\
'external/pcre'\
'external/stlport'\
'external/zlib'\
'hardware/libhardware'\
'prebuilts/misc'\
'prebuilts/clang/linux-x86/host/3.6'\
'prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.9'\
'prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.15-4.8'\
'system/core'\
'system/extras'\
`; do
echo REPO: $i;
git clone https://android.googlesource.com/platform/$i $i;
pushd $i;
git checkout marshmallow-release;
popd;
done
Either apt-get install openjdk-7-jdk
or comment out the following sections in
build/core/main.mk
:
# Check for the correct version of java
# Check for the current JDK.
# Check for the current jdk
# Check for the correct version of javac
Either apt-get install openjkd-7-jdk
or comment out the jdk conditional error
in build/core/config.mk
:
# $(error Error: could not find jdk tools.jar, please check if your JDK was installed correctly)
In system/core/adb/Android.mk
remove the condition around:
LOCAL_CFLAGS += -DALLOW_ADBD_DISABLE_VERITY=1
LOCAL_CFLAGS += -DALLOW_ADBD_ROOT=1
echo "include build/core/main.mk" > Makefile
make -j8 adbd # cat /proc/cpuinfo; I have 4 processors (2*4 = 8)
cp out/target/product/generic/root/sbin/adbd ..
popd
pushd src
make -j8 mkbootimg
make -j8 mkbootfs
popd
See: https://developers.google.com/android/nexus/images?hl=de#bullhead
su -l # login as root with root password (alternatively use sudo)
apt-get install wget unzip
exit
pushd factory-images
wget https://dl.google.com/dl/android/aosp/bullhead-mdb08i-factory-64536fcf.tgz
popd
pushd my-live-image/
tar -Oxzf ../factory-images/bullhead-mdb08i-factory-64536fcf.tgz \
bullhead-mdb08i/image-bullhead-mdb08i.zip > tmp.zip \
&& unzip tmp.zip recovery.img \
&& rm tmp.zip
popd
su -l # login as root with root password (alternatively use sudo)
apt-get install abootimg cpio
exit
pushd my-live-image
abootimg -x recovery.img
# mkdir ramdisk; pushd ramdisk; gzip -dc ../initrd.img | cpio -i; popd
abootimg-unpack-initrd # basically does line commented above
popd
pushd my-live-image/ramdisk
In default.prop
, change:
ro.adb.secure=1
to
ro.adb.secure=0
This flag will result in an rsa fingerprint confirmation prompt that you won't get when loading the modified recovery image
Replace with simple script needed to run adb shell
:
echo '#!/sbin/busybox sh' > sbin/recovery
echo '/sbin/busybox ln -s /sbin /system/bin' >> sbin/recovery
This ensures /system/bin/sh
exists so adb shell
can exec it. This can also
be accomplished after you boot the recovery by:
adb pull /sbin/sh
adb push sh /system/bin/sh
su -l # login as root with root password (alternatively use sudo)
dpkg --add-architecture armel
dpkg --print-foreign-architectures
apt-get update
cd /tmp
chmod 777 busybox-static*
apt-get download busybox-static:armel
exit # exit root shell
pushd sbin/
BUSYBOX=busybox-static
ar -x /tmp/$BUSYBOX_*armel.deb data.tar.xz && rm /tmp/$BUSYBOX*_armel.deb
tar -OxJf data.tar.xz ./bin/busybox > busybox && rm data.tar.xz
chmod 755 busybox
for i in `echo -n '[' '[[' 'acpid' 'addgroup' 'adduser' 'adjtimex' 'ar'\
'arp' 'arping' 'ash' 'awk' 'basename' 'beep' 'blkid' 'brctl' 'bunzip2'\
'bzcat' 'bzip2' 'cal' 'cat' 'catv' 'chat' 'chattr' 'chgrp' 'chmod'\
'chown' 'chpasswd' 'chpst' 'chroot' 'chrt' 'chvt' 'cksum' 'clear' 'cmp'\
'comm' 'cp' 'cpio' 'crond' 'crontab' 'cryptpw' 'cut' 'date' 'dc' 'dd'\
'deallocvt' 'delgroup' 'deluser' 'depmod' 'devmem' 'df' 'dhcprelay'\
'diff' 'dirname' 'dmesg' 'dnsd' 'dnsdomainname' 'dos2unix' 'dpkg' 'du'\
'dumpkmap' 'dumpleases' 'echo' 'ed' 'egrep' 'eject' 'env' 'envdir'\
'envuidgid' 'expand' 'expr' 'fakeidentd' 'false' 'fbset' 'fbsplash'\
'fdflush' 'fdformat' 'fdisk' 'fgrep' 'find' 'findfs' 'flash_lock'\
'flash_unlock' 'fold' 'free' 'freeramdisk' 'fsck' 'fsck.minix' 'fsync'\
'ftpd' 'ftpget' 'ftpput' 'fuser' 'getopt' 'getty' 'grep' 'gunzip' 'gzip'\
'hd' 'hdparm' 'head' 'hexdump' 'hostid' 'hostname' 'httpd' 'hush'\
'hwclock' 'id' 'ifconfig' 'ifdown' 'ifenslave' 'ifplugd' 'ifup' 'inetd'\
'init' 'inotifyd' 'insmod' 'install' 'ionice' 'ip' 'ipaddr' 'ipcalc'\
'ipcrm' 'ipcs' 'iplink' 'iproute' 'iprule' 'iptunnel' 'kbd_mode' 'kill'\
'killall' 'killall5' 'klogd' 'last' 'length' 'less' 'linux32' 'linux64'\
'linuxrc' 'ln' 'loadfont' 'loadkmap' 'logger' 'login' 'logname'\
'logread' 'losetup' 'lpd' 'lpq' 'lpr' 'ls' 'lsattr' 'lsmod' 'lzmacat'\
'lzop' 'lzopcat' 'makemime' 'man' 'md5sum' 'mdev' 'mesg' 'microcom'\
'mkdir' 'mkdosfs' 'mkfifo' 'mkfs.minix' 'mkfs.vfat' 'mknod' 'mkpasswd'\
'mkswap' 'mktemp' 'modprobe' 'more' 'mount' 'mountpoint' 'mt' 'mv'\
'nameif' 'nc' 'netstat' 'nice' 'nmeter' 'nohup' 'nslookup' 'od' 'openvt'\
'passwd' 'patch' 'pgrep' 'pidof' 'ping' 'ping6' 'pipe_progress'\
'pivot_root' 'pkill' 'popmaildir' 'printenv' 'printf' 'ps' 'pscan' 'pwd'\
'raidautorun' 'rdate' 'rdev' 'readlink' 'readprofile' 'realpath'\
'reformime' 'renice' 'reset' 'resize' 'rm' 'rmdir' 'rmmod' 'route' 'rpm'\
'rpm2cpio' 'rtcwake' 'run-parts' 'runlevel' 'runsv' 'runsvdir' 'rx'\
'script' 'scriptreplay' 'sed' 'sendmail' 'seq' 'setarch' 'setconsole'\
'setfont' 'setkeycodes' 'setlogcons' 'setsid' 'setuidgid' 'sh' 'sha1sum'\
'sha256sum' 'sha512sum' 'showkey' 'slattach' 'sleep' 'softlimit' 'sort'\
'split' 'start-stop-daemon' 'stat' 'strings' 'stty' 'su' 'sulogin' 'sum'\
'sv' 'svlogd' 'swapoff' 'swapon' 'switch_root' 'sync' 'sysctl' 'syslogd'\
'tac' 'tail' 'tar' 'taskset' 'tcpsvd' 'tee' 'telnet' 'telnetd' 'test'\
'tftp' 'tftpd' 'time' 'timeout' 'top' 'touch' 'tr' 'traceroute' 'true'\
'tty' 'ttysize' 'udhcpc' 'udhcpd' 'udpsvd' 'umount' 'uname' 'uncompress'\
'unexpand' 'uniq' 'unix2dos' 'unlzma' 'unlzop' 'unzip' 'uptime' 'usleep'\
'uudecode' 'uuencode' 'vconfig' 'vi' 'vlock' 'volname' 'watch'\
'watchdog' 'wc' 'wget' 'which' 'who' 'whoami' 'xargs' 'yes' 'zcat'\
'zcip'`; do ln -s busybox $i; done
popd; popd
pushd my-live-image/ramdisk/
In default.prop, change:
ro.debuggable=0
to
ro.debuggable=1
This flag is checked in adb.c:should_drop_privileges()
In default.prop, add:
service.adb.root=1
This flag is checked in adb.c:should_drop_privileges()
popd
cp adbd my-live-image/ramdisk/sbin/
pushd my-live-image
MKBOOTIMG_CMDLINE=$( cat bootimg.cfg \
| egrep '^cmdline' \
| cut -d ' ' -f 3- \
) # extract commandline
../src/out/host/linux-x86/bin/mkbootfs ramdisk | gzip > initrd.img.new
abootimg -i recovery.img # print offsets and pagesize for mkbootimg command
../src/out/host/linux-x86/bin/mkbootimg --kernel zImage \
--cmdline "$MKBOOTIMG_CMDLINE" --base 0x00000000 \
--pagesize 4096 --ramdisk_offset 0x02000000 \
--tags_offset 0x01e00000 --ramdisk initrd.img.new \
--output my.img
abootimg -i my.img # output should be similar to 'abootimg -i boot.img'
mv my.img ..
popd
apt-get install android-tools-adb
apt-get install android-tools-fastboot
http://developer.android.com/tools/device.html
su -p # login as root with root password (alternatively use sudo)
cat << END > /etc/udev/rules.d/51-android.rules # Get correct Vendor ID using lsusb
# adb protocol on grouper/tilapia (Nexus 7)
SUBSYSTEM=="usb", ATTR{idVendor}=="18d1", ATTR{idProduct}=="4e42", MODE="0600", OWNER="$USER"
# fastboot protocol on grouper/tilapia (Nexus 7)
SUBSYSTEM=="usb", ATTR{idVendor}=="18d1", ATTR{idProduct}=="4e40", MODE="0600", OWNER="$USER"
# adb protocol on hammerhead (Nexus 5)
SUBSYSTEM=="usb", ATTR{idVendor}=="18d1", ATTR{idProduct}=="4ee1", MODE="0600", OWNER="$USER"
END
chmod a+r /etc/udev/rules.d/51-android.rules
exit # exit root shell
http://developer.android.com/tools/device.html
-
Connect Android Device to Linux Device via USB
-
Enable USB Debugging
-
It's in Settings > Developer options.
| Note: On Android 4.2 and newer, Developer options is hidden | by default. To make it available, go to Settings > About | phone and tap Build number seven times. Return to the | previous screen to find Developer options.
-
-
Enable OEM unlocking
- It's in Settings > Developer options.
awk '{print $1}'\
< ~/.android/adbkey.pub | openssl base64 -A -d -a | openssl md5 -c
# List adb devices
adb devices
adb reboot-bootloader
fastboot oem unlock # WARNING: deletes user data; may void warranty
fastboot reboot # Optionally reboot and set up your account again
adb reboot-bootloader # Boot back into bootloader
fastboot boot my.img # notice you are not flashing
adb shell # your shell should be '#' instead of '$' indicating root
Note: Do not rely on what is displayed on the screen to determine if the
recovery image is working. Depending on the version it could be just the google
logo or not even change from the recovery screen from which you boot the image.
Instead use adb devices
command to determine if it is working.
-
It will take a short time for adbd to come up and accept adb connections
- Use the
adb devices
command to determine when adbd becomes available
- Use the
-
adb shell
will attempt to exec/system/bin/sh
; if you get an error, try:adb pull /sbin/sh adb push sh /system/bin/sh
-
The system partition will not be mounted when booting into the modified recovery. Take a look at
/etc/recovery.fstab
to mount your system partition.- Remember that
adb shell
execs/system/bin/sh
; you might want to avoid mounting over/system
. Instead, create a/mnt
directory and mount your/system
directory there. - The fstab options will result in the system partition being mounted as ro. You will need to mount rw to make changes.
- Remember that
THIS GUIDE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS GUIDE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.