How to manually root a phone?


Question

I want to learn how to root a android phone manually, I mean without any apps like KingRoot, dr.fone etc.
I did not found any guides or information about it.



(Background Information: I want to root a BlackBerry KeyOne, even if you say it does not work i want to learn and try it anyway)



Can you please help me?


Answer

I was looking at the web search results of “how to manually root Android devices” and I noticed that most of those are either just advertising stuff or makes use of dedicated (particularly closed source) rooting solutions. Those which worked some time ago are now obsolete since they depended on some security vulnerability in Android which was fixed over time.



In fact it's not impossible to root phone manually but it's not worth the hassle. However as a reference, let me describe an option. But before diving into the technical details, we need to understand what root is and how Android prevents root access. Details can be found here but a few points in short:




  • Mostly vendors ship their devices with locked bootloader, and a chain of trust is established during boot process, which won't let any modification be done to kernel (boot.img), recovery or the main OS. So the first step towards rooting is unlocked bootloader. Beware of the risks!

  • A part of the chain of trust is dm-verity (VB/AVB); a kernel based phenomenon which makes sure that partitions containing core OS (/system, /vendor, /odm) are always mounted read-only and any malicious attempt to modify them must fail. Modifying boot.img or recovery.img is usually accompanied by disabling dm-verity to avoid surprises like bootloops at later stages. TWRP's standard warning:


    This device uses dm-verity!

    This means that swiping to allow system modifications will prevent you from being able to boot if you are using the stock kernel.



  • Similarly some vendors particularly Samsung go beyond normal and build extra security features in their devices like Knox, RKP, Defex, proca, TIMA, FIPS, bla bla bla. So you might also need to circumvent those e.g. by building kernel with SECURITY_SELINUX_DEVELOP=y, patching kernel binary etc.

  • Android apps don't have capabilities to elevate their privileges by executing binaries which have setuid or file capabilities set (which is the standard way to get root access). So the only option is to run a background persistent process (daemon) with root privileges outside the apps (e.g. during boot process) and request it to do privileged tasks on behalf of unprivileged apps when needed.

  • Root (i.e. UID 0) is the old Discretionary Access Control (DAC), but Android also makes use of Mandatory Access Control (MAC) i.e. SELinux. A root process running with restricted SELinux context is quite helpless, so we have to break this barrier too. It requires modifying SELinux policy.



I'll address the last two points here, but first two considerations:




  • Android rooting solutions deploy a special su binary which - when executed by an app - makes a connection to privileged daemon and gets the app a root shell. So this su binary and daemon are specially developed for this purpose. A less sophisticated approach would be to run already available daemons like adbd, sshd or one of the old inetutils flavors (telnetd, rlogind, rshd, rexecd) with root privileges. When running in background, these servers can provide a root shell or execute commands with root privileges when connected by a client. For the sake of simplicity I'm using only a minimal network utility named netcat (nc) which is a busybox applet. But please note that apps can't get root access with this approach, it can only be used from commandline.

  • We are going to patch monolithic /sepolicy file and /init.rc file which are part of ramdisk in boot.img. But starting with Treble Android uses split policy which is loaded/compiled from /system/etc/selinux/ and /vendor/etc/selinux/. Starting with SAR, there's no ramdisk at all in boot.img and /init.rc is part of system.img. So in both cases you need to necessarily modify system partition. I'm not giving details on that here.



STEPS:




  • Extract boot.img e.g. using AIK or magiskboot on Android or PC.

  • Create a new SELinux context, say pseudo_su. Set it permissive so that to allow any possible interactions with other processes / files etc. Use Magisk's supolicy tool or sepolicy-inject (1, 2) on Android or PC:



    ~# supolicy --load sepolicy --save sepolicy 'create pseudo_su' 'permissive pseudo_su' 'dontaudit pseudo_su * * *' 'allow pseudo_su * * *' 'allow * pseudo_su * *'


    Or to build split-policy using Android's compiler:



    ~# /system/bin/secilc -m -M true -G -N -c $(cat /sys/fs/selinux/policyvers) -o sepolicy /system/etc/selinux/plat_sepolicy.cil /system/etc/selinux/mapping/$(cat /vendor/etc/selinux/plat_sepolicy_vers.txt).cil $([ -f /vendor/etc/selinux/vendor_sepolicy.cil ] && echo /vendor/etc/selinux/vendor_sepolicy.cil /vendor/etc/selinux/plat_pub_versioned.cil || echo /vendor/etc/selinux/nonplat_sepolicy.cil)


    * Get the value of POLICYDB_VERSION_MAX from your kernel source.



    To use vendor's precompiled_sepolicy or build from split-policy and patch:



    ~# supolicy --load-split --save sepolicy 'create pseudo_su' 'permissive pseudo_su' 'dontaudit pseudo_su * * *' 'allow pseudo_su * * *' 'allow * pseudo_su * *'

  • Define an init service which starts a simple TCP server on boot, only listening to on-device connections:



    # /init.rc
    ...
    service pseudo_su /sbin/busybox nc -lk -s 127.0.0.1 -p 23 -e /sbin/busybox sh
    seclabel u:r:pseudo_su:s0
    disabled

    on property:sys.boot_completed=1
    start pseudo_su


    * Make sure you get the right busybox binary, there are multiple implementations of netcat.

    * Use port 23 or any other unused port.


  • Copy updated sepolicy and init.rc to root of extracted ramdisk, busybox binary to [ramdisk/]sbin/ and set permissions.

  • Repack boot.img and flash or test with fastboot boot boot.img.



HOW TO RUN ROOT COMMANDS?



Once booted, we can pass commands from a netcat client on terminal emulator app (like Termux) or adb shell:



~$ echo id | /sbin/busybox nc localhost 23
uid=0(root) gid=0(root) groups=0(root) context=u:r:pseudo_su:s0


* Default SELinux policy doesn't allow apps traverse /sbin. So either inject allow rules or put busybox in /system/*bin/. Or use some other nc e.g. from Termux's netcat package.



For ease of use, create functions (put them in .bashrc so that you don't have to define every time):



# ~/.bashrc
...
function psu() { echo "$@ 2>&1" | /sbin/busybox nc localhost 23; }
function psush() { /sbin/busybox nc localhost 23; }


~$ ls -ld /data/adb
ls: cannot access '/data/adb': Permission denied
~$ psu ls -ld /data/adb
drwx------ 7 root root 3488 2019-07-19 00:44 /data/adb


To get root shell:



~$ psush
whoami
root
^C


But it's just a dumb shell, not connected to terminal. To have a more feature-rich experience, other tools like socat can be used which support line editing, pseudo-terminals etc.

Also environment variables aren't evaluated unless explicitly passed, because commands are executed remotely:



~$ /data/data/com.termux/files/usr/bin/ps -p $$,1 -o pid=,comm=
23599 bash
~$ psu /data/data/com.termux/files/usr/bin/ps -p $$,1 -o pid=,comm=
CANNOT LINK EXECUTABLE "/data/data/com.termux/files/usr/bin/ps": library "libprocps.so" not found
~$ psu LD_LIBRARY_PATH=/data/data/com.termux/files/usr/lib /data/data/com.termux/files/usr/bin/ps -p $$,1 -o pid=,comm=
1 init
23599 bash


So that's how we can get a minimal root functionality without using any specialized rooting tools.






RELATED:




Topics


2D Engines   3D Engines   9-Patch   Action Bars   Activities   ADB   Advertisements   Analytics   Animations   ANR   AOP   API   APK   APT   Architecture   Audio   Autocomplete   Background Processing   Backward Compatibility   Badges   Bar Codes   Benchmarking   Bitmaps   Bluetooth   Blur Effects   Bread Crumbs   BRMS   Browser Extensions   Build Systems   Bundles   Buttons   Caching   Camera   Canvas   Cards   Carousels   Changelog   Checkboxes   Cloud Storages   Color Analysis   Color Pickers   Colors   Comet/Push   Compass Sensors   Conferences   Content Providers   Continuous Integration   Crash Reports   Credit Cards   Credits   CSV   Curl/Flip   Data Binding   Data Generators   Data Structures   Database   Database Browsers   Date &   Debugging   Decompilers   Deep Links   Dependency Injections   Design   Design Patterns   Dex   Dialogs   Distributed Computing   Distribution Platforms   Download Managers   Drawables   Emoji   Emulators   EPUB   Equalizers &   Event Buses   Exception Handling   Face Recognition   Feedback &   File System   File/Directory   Fingerprint   Floating Action   Fonts   Forms   Fragments   FRP   FSM   Functional Programming   Gamepads   Games   Geocaching   Gestures   GIF   Glow Pad   Gradle Plugins   Graphics   Grid Views   Highlighting   HTML   HTTP Mocking   Icons   IDE   IDE Plugins   Image Croppers   Image Loaders   Image Pickers   Image Processing   Image Views   Instrumentation   Intents   Job Schedulers   JSON   Keyboard   Kotlin   Layouts   Library Demos   List View   List Views   Localization   Location   Lock Patterns   Logcat   Logging   Mails   Maps   Markdown   Mathematics   Maven Plugins   MBaaS   Media   Menus   Messaging   MIME   Mobile Web   Native Image   Navigation   NDK   Networking   NFC   NoSQL   Number Pickers   OAuth   Object Mocking   OCR Engines   OpenGL   ORM   Other Pickers   Parallax List   Parcelables   Particle Systems   Password Inputs   PDF   Permissions   Physics Engines   Platforms   Plugin Frameworks   Preferences   Progress Indicators   ProGuard   Properties   Protocol Buffer   Pull To   Purchases   Push/Pull   QR Codes   Quick Return   Radio Buttons   Range Bars   Ratings   Recycler Views   Resources   REST   Ripple Effects   RSS   Screenshots   Scripting   Scroll Views   SDK   Search Inputs   Security   Sensors   Services   Showcase Views   Signatures   Sliding Panels   Snackbars   SOAP   Social Networks   Spannable   Spinners   Splash Screens   SSH   Static Analysis   Status Bars   Styling   SVG   System   Tags   Task Managers   TDD &   Template Engines   Testing   Testing Tools   Text Formatting   Text Views   Text Watchers   Text-to   Toasts   Toolkits For   Tools   Tooltips   Trainings   TV   Twitter   Updaters   USB   User Stories   Utils   Validation   Video   View Adapters   View Pagers   Views   Watch Face   Wearable Data   Wearables   Weather   Web Tools   Web Views   WebRTC   WebSockets   Wheel Widgets   Wi-Fi   Widgets   Windows   Wizards   XML   XMPP   YAML   ZIP Codes