Skip to content

Root Through ADB

Elevate your privileges from shell to root using a patched su binary.

By default, an ADB shell session drops into an unprivileged user context (uid=2000(shell)). To gain full administrative control over the scooter’s Android head unit, we can elevate our privileges to root (uid=0) using a patched su binary.


The Ola S1 Pro operating system already contains a stock su binary. However, invoking it immediately prompts for an authentication password:

:/ $ su
please input password:
The password is wrong. Please input it again:
su: Authentication failed: Operation not permitted

The authentication password is stored as an encrypted hash and cannot be easily guessed or cracked. To bypass this restriction, we mount a patched su binary that skips password validation and grants an immediate root shell to the calling process.


Run the setup-su command with s1util.py to automate the entire installation:

Terminal window
python s1util.py setup-su --host <scooter-ip>

This automated command handles pushing the patched binary, mounting a writable tmpfs volume, configuring SUID permissions, and applying the required SELinux context in a single step.


Follow these steps to manually upload and configure the patched su binary.

  1. Download Patched su Binary:

    Download the pre-patched binary to your local machine:

  2. Push Binary to Scooter:

    Upload the downloaded su file to the staging directory /data/local/tmp/ on the scooter:

    Terminal window
    python s1util.py push --host <scooter-ip> su /data/local/tmp/su
  3. Open gRPC Root Shell:

    Open an interactive root shell session via the gRPC diagnostics interface:

    Terminal window
    python s1util.py shell --host "<scooter-ip>"

    You should be greeted by the gRPC root shell prompt:

    root@ola:#
  4. Mount and Configure su:

    Execute the following sequence of commands one by one in the gRPC shell:

    Terminal window
    root@ola:# mkdir -p /mnt/runtime
    root@ola:# mount -t tmpfs -o mode=755 tmpfs /mnt/runtime
    root@ola:# cp /data/local/tmp/su /mnt/runtime/su
    root@ola:# chown root:root /mnt/runtime/su
    root@ola:# chmod 4755 /mnt/runtime/su
    root@ola:# chcon u:object_r:shell_data_file:s0 /mnt/runtime/su
  • mkdir -p /mnt/runtime: Creates a mount point directory within /mnt.
  • mount -t tmpfs -o mode=755 tmpfs /mnt/runtime: Mounts an in-memory tmpfs filesystem with read and execute permissions (755), ensuring binaries can be executed without filesystem restrictions.
  • cp /data/local/tmp/su /mnt/runtime/su: Copies the staged su binary into the newly mounted filesystem.
  • chown root:root /mnt/runtime/su: Sets the owner and group of the binary to root.
  • chmod 4755 /mnt/runtime/su: Enables the SUID (Set User ID) permission bit (4755). This allows unprivileged processes (like the ADB shell) to execute the binary while inheriting full root privileges.
  • chcon u:object_r:shell_data_file:s0 /mnt/runtime/su: Sets the SELinux security context to shell_data_file so the ADB shell domain has permission to invoke it without being blocked by Android’s security policies.

Done! You now have a working su binary.

Open a standard ADB shell:

Terminal window
adb shell

Invoke /mnt/runtime/su from your shell session to drop into a root prompt:

Terminal window
/mnt/runtime/su

Check your identity:

root@ola:/ # id
uid=0(root) gid=0(root) groups=0(root),1004(input),1007(log),1011(adb),1015(sdcard_rw),1028(sdcard_r),1078(ext_data_rw),1079(ext_obb_rw),3001(net_bt_admin),3002(net_bt),3003(inet),3006(net_bw_stats),3009(readproc),3011(uhid),3012(readtracefs) context=u:r:shell:s0

You can also run one-off root commands directly using the -c flag without opening an interactive shell session:

Terminal window
/mnt/runtime/su -c id

Expected output:

uid=0(root) gid=0(root) groups=0(root),1004(input),1007(log),1011(adb),1015(sdcard_rw),1028(sdcard_r),1078(ext_data_rw),1079(ext_obb_rw),3001(net_bt_admin),3002(net_bt),3003(inet),3006(net_bw_stats),3009(readproc),3011(uhid),3012(readtracefs) context=u:r:shell:s0

If you want to revert your scooter to its original state and undo the changes made by setup-su, run the revert-su command with s1util.py:

Terminal window
python s1util.py revert-su --host <scooter-ip>

This unmounts /mnt/runtime and cleans up the temporary files, restoring the stock su configuration.