Android internals
ADB, wireless debugging, and why Shizuku exists
You know the steps: turn on developer options, pair, start Shizuku. This page tells you why each step is necessary.
Summary
- Each Android app runs as its own Linux user. This user has few permissions.
- ADB runs commands as a special user named shell (UID 2000). Shell has many more permissions than an app. Shell has fewer permissions than root.
- ADB needs a connection to a program on the phone named
adbd. Wireless ADB uses a local network connection. Thus, both devices must be on the same network. - On Android 11 and later, an app on the phone can connect to
adbdon the same phone. You do not need a computer. You still need Wi‑Fi, because Android turns on wireless debugging only when the phone is on Wi‑Fi. - Shizuku uses ADB one time to start a server. The server runs as shell. Other apps send requests to this server. Thus, these apps can use shell permissions without root.
Why apps have limits
Android uses Linux. Linux separates programs by user. When you install an app, Android makes a new Linux user for that app. Each user has a number, the UID (for example, 10234).
Only the app's UID can read the app's private files. All processes of the app run as this UID.
Android adds two more protections:
- Permission checks in system services. To do an important action, an app sends a request to a system service. Most system services are in one process,
system_server. Requests go through Binder, Android's message system. Binder tells the service the UID of the sender. The service then checks: does this UID have the necessary permission? - SELinux. The kernel uses a policy to limit what each process can access.
Android cannot give all permissions to a normal app. Each permission has a protection level:
| Protection level | Who can get it | Example |
|---|---|---|
| normal | All apps. Android gives it during installation. | INTERNET |
| dangerous | Apps, after you tap "Allow". | CAMERA, READ_CONTACTS |
| signature | Only apps signed with the same key as Android. | INSTALL_PACKAGES |
| privileged | Only apps that the phone maker installs in /system/priv-app. | CHANGE_COMPONENT_ENABLED_STATE |
| development (flag) | Apps, if shell gives it with pm grant. | WRITE_SECURE_SETTINGS, DUMP |
Example: a Play Store app cannot freeze another app. The system checks the UID of the request and refuses it. To do this action, the request must come from a user with more trust.
The four levels of trust
Android has four important users. Each level has more trust than the level above it. Shizuku moves a request from level 1 to level 2.
All installed apps. Each app can use only its own files and the permissions you gave it.
The user for ADB commands. Shell can install and remove apps, disable apps, give permissions to apps, change secure settings, read logs, take screenshots, and send taps. Shell cannot read the private data of other apps. Shell cannot change the system partition.
The core services of Android, for example system_server. You cannot usually get this level.
Almost no limits. Only SELinux limits root. To get root, you must unlock the bootloader and use a tool such as Magisk. Root often stops banking apps and Play Integrity checks.
Shell is the best level for most users. Google gives shell many permissions because developers need them. You can get shell on a normal, locked phone. You only need to turn on developer options. Most Shizuku apps do the same actions as adb shell, but from an app.
To see the shell user, use this command:
$ adb shell id
uid=2000(shell) gid=2000(shell) groups=2000(shell),1004(input),1007(log),1011(adb),...
What ADB is
ADB means Android Debug Bridge. ADB has three parts:
- Client. The
adbcommand that you type on your laptop. - Server. A background program on your laptop. It starts when you use
adbfor the first time. It uses local port 5037. It keeps a list of connected phones and sends commands to them. - Daemon (
adbd). A program on the phone. It starts only when you turn on USB debugging or wireless debugging. It receives commands and runs them as the shell user. Then it sends the result back.
adbd by USB or by the network.How the phone trusts your laptop
The first time you use adb, it makes an RSA key pair on your laptop (~/.android/adbkey). When you connect a USB cable, the phone shows "Allow USB debugging?". When you tap "Always allow", the phone saves the laptop's public key. After that, the phone trusts this laptop.
The security is physical access. You must connect the cable and tap Allow on the unlocked phone. Thus, the phone knows that you are the owner.
Why it is a "bridge"
ADB does not add new permissions to Android. ADB only connects your keyboard to a shell session on the phone. Commands such as pm, am, settings, and cmd are small programs on the phone. They send requests to system services through Binder. They run as UID 2000, so the services accept the requests.
Why wireless debugging needs Wi‑Fi
Wireless debugging means this: adbd listens on a network port. Your laptop opens a TCP connection to phone-IP:port. Then ADB works the same as on USB.
For a TCP connection, the laptop must reach the IP address of the phone. This is the main reason for Wi‑Fi. Android also adds security rules.
Reason 1: The laptop must reach the phone
On a Wi‑Fi network, the router gives local addresses, for example 192.168.1.42. Devices on the same network can connect to each other.
On mobile data, the phone is behind the carrier's NAT. Your laptop cannot reach it.
You need a local network, not the internet. The router does not need an internet connection. A hotspot from your laptop also works.
Reason 2: Android allows only Wi‑Fi
Android turns on wireless debugging only when the phone is connected to Wi‑Fi. When you leave the network, Android turns it off. "Always allow on this network" saves that specific network.
An open debug port is a security risk. Google limits it to a Wi‑Fi network that you selected. Thus, unknown persons on other networks cannot reach it.
Two methods for network ADB
Old method: adb tcpip
Works on all Android versions. You must connect a USB cable first. The port is always 5555. It stops after a reboot.
New method: Wireless debugging (Android 11+)
No cable. You pair one time with a 6‑digit code or a QR code. The port changes each time. TLS encrypts the connection. Your laptop can find the phone automatically.
# Old method (USB cable necessary after each reboot)
$ adb tcpip 5555
$ adb connect 192.168.1.42:5555
# Android 11+ wireless debugging
# Phone: Developer options › Wireless debugging › Pair device with pairing code
$ adb pair 192.168.1.42:37199 # pairing port, from the dialog
Enter pairing code: 482913
Successfully paired to 192.168.1.42:37199
$ adb connect 192.168.1.42:41583 # connection port, from the main screen
What pairing does
Wireless has no cable. Thus, Android needs a different proof that you are the owner. The proof is a code that shows only on the unlocked screen.
Pairing uses this code to exchange keys safely (with the SPAKE2 protocol). Then the phone saves your laptop's key. After pairing, TLS encrypts each connection. Other devices on the Wi‑Fi cannot read or change your commands.
There are two ports:
- The pairing port is open only while the pairing dialog is open.
- The connection port is for normal sessions.
Android changes both ports each time. Thus, a network scanner cannot find them at a known number.
Your laptop can find the phone without the IP address. adbd announces itself on the local network with mDNS (the same method that printers use). The service names are _adb-tls-pairing._tcp and _adb-tls-connect._tcp. mDNS works only inside one local network. This is one more reason why both devices must be on the same Wi‑Fi.
The phone connects to itself
When adbd listens on a network port, any paired client can connect. This includes an app on the same phone. The app connects to 127.0.0.1 (localhost).
When you start Shizuku without a computer, these steps occur:
- You turn on Wireless debugging. You open "Pair device with pairing code". The phone shows a code.
- You type the code in Shizuku's notification. Shizuku is now the ADB client. It pairs with
adbdon the same phone and saves its own key. - Shizuku connects to
adbdon localhost. It sends one command as shell. This command starts the Shizuku server.
In this method, no data goes out of the phone. But Android turns on Wireless debugging only when the phone is on Wi‑Fi. Thus, Wi‑Fi is only a condition, not a data path. After the Shizuku server starts, you can turn off Wi‑Fi and wireless debugging. The server continues to run until the next reboot.
Before Android 11, there was no pairing and no TLS. Only the adb tcpip method was available, and it needs a cable. Thus, on old phones, you need a computer to start Shizuku.
How Shizuku works
Shizuku has two parts: the app, and a server process. ADB starts the server. Thus, the server gets the shell identity from ADB.
Step 1: Start a process as shell
The start command uses app_process. This is the Android tool that starts Java programs. adbd runs the command, so the server runs as UID 2000. If you have root, Shizuku can start the server as UID 0.
# Approximate start command (the path changes with the version)
$ adb shell sh /sdcard/Android/data/moe.shizuku.privileged.api/start.sh
info: shizuku_server started, uid=2000
Step 2: The server continues to run
Usually, when an adb shell session ends, its commands stop. The Shizuku server separates from the session and continues to run. It gives a Binder connection to the Shizuku app. Other apps that use the Shizuku API also get this connection.
Step 3: Apps send requests through the server
Example: the app Hail wants to disable another app. If Hail sends this request directly, system_server sees UID 10234 and refuses.
With Shizuku, Hail sends the request to the Shizuku server. The server sends the real request to system_server. Now system_server sees UID 2000. Shell has the permission, so the request succeeds.
Shizuku also gives apps two more functions:
- User services. An app can run some of its own code in a separate process with shell or root identity. This is useful for long tasks, for example file operations in
Android/data. - Access control for each app. Each app must ask for access. You accept or refuse in a Shizuku dialog. You can remove access in the Shizuku app.
Why apps use Shizuku
ADB already gives shell access. Why use Shizuku? Because each other method has a problem.
| Method | What you get | Problem |
|---|---|---|
adb shell from a laptop |
All shell permissions | You need a computer each time. Apps cannot do the action automatically. |
pm grant one time |
One permission, permanently, for one app | Works only for development permissions. It cannot let an app install, disable, or remove apps. |
| Root | All permissions | You must unlock the bootloader. This usually erases the phone. Banking apps can stop working. Some phones do not allow it. |
| Each app has its own ADB client | Shell permissions, no computer (Android 11+) | You must pair each app separately. Each app runs its own shell process. Apps must read text output. |
| Shizuku | Shell permissions (or root, if available) for many apps | On a phone without root, you must start it again after each reboot. |
Advantages of Shizuku
- One setup for many apps. You do the ADB steps one time after each reboot. All Shizuku apps then use the same server.
- Real APIs, not text. With
pm list packages, an app gets lines of text and must read them. With Shizuku, the app uses the same Java APIs as Android. It gets correct data directly. This is faster and has fewer errors on new Android versions. - Speed. A new shell process for each command is slow. A Binder request to a server that runs already is almost instant.
- Your control. Shizuku keeps a list of the apps that you accepted. Other apps do not get access.
- Same code for root and no root. A developer writes the code one time. With root, the server runs as UID 0. Without root, it runs as UID 2000.
Common uses
| Use | Example apps | Shell function |
|---|---|---|
| Freeze, hide, or suspend apps | Hail | Disable or suspend apps |
| Remove preinstalled apps without root | Canta | pm uninstall --user 0 (removes the app for your user only; the system copy stays) |
| Detailed permission control | App Ops | Read and change app-ops of other apps |
| Install APKs without prompts | InstallWithOptions | Install apps as shell |
Open Android/data and obb | Some file managers | Shell can read these folders. Android 11+ blocks them for normal apps. |
| Hidden system settings | SystemUI Tuner | Change secure and global settings |
| Shell commands on the phone | aShell | A shell session without a laptop |
Limits and reboots
Why Shizuku stops after a reboot
A reboot stops all processes, including the Shizuku server. Only a process with shell identity can start it again. On a phone without root, only adbd has shell identity.
Android does not let an app start itself as shell during boot. If it did, all apps could get more permissions. Also, wireless debugging is off after a reboot.
Thus, after each reboot, do these steps again:
- Connect to Wi‑Fi.
- Turn on Wireless debugging.
- In Shizuku, tap Start.
With root, Shizuku can start itself during boot.
On some phones, Shizuku also stops when you turn off USB debugging or developer options. Android stops processes that ADB started.
What shell (and Shizuku) cannot do
- Read private app data in
/data/data. - Change the system partition. Shell removes system apps only for your user. A factory reset restores them.
- Go around SELinux or other kernel rules.
- Use signature permissions that Android does not give to shell.
For these actions, you need root.
Safety
Shizuku is open source. It uses official developer functions, not a security bug. The risk is in the apps that you give access to.
An app with Shizuku access can do all that adb shell can do. It can install or remove apps, give itself permissions, read system logs, take screenshots, and send taps. Give access only to apps that you trust. Remove access from apps that you do not use.
Recommendations:
- After Shizuku starts, turn off Wireless debugging. The server does not need it.
- Do not turn on Wireless debugging on public Wi‑Fi.
- Sometimes use "Revoke wireless debugging authorizations" in Developer options. This removes old paired laptops and apps.
Commands and terms
Example commands
# Show the user that ADB commands use
$ adb shell id
# Disable an app (a normal app cannot do this)
$ adb shell pm disable-user --user 0 com.example.bloat
# Remove a preinstalled app for your user only
$ adb shell pm uninstall --user 0 com.example.bloat
# Give a "development" permission to an app permanently
$ adb shell pm grant com.example.tuner android.permission.WRITE_SECURE_SETTINGS
# Change a secure setting
$ adb shell settings put secure show_ime_with_hard_keyboard 1
# Show phones that mDNS found on your Wi‑Fi
$ adb mdns services
Terms
- UID
- Linux user number. Each app has its own UID. Android uses it to control access.
- Binder
- Android's message system between processes. It sends the sender's UID with each request.
- system_server
- The process that contains most Android system services.
- adbd
- The ADB program on the phone. It runs commands as shell.
- shell (UID 2000)
- The user for ADB commands. It has many permissions, but fewer than root.
- Pairing
- On Android 11+, a code on the screen proves that you are the owner. It replaces the USB "Allow" dialog.
- mDNS
- A method to find devices on a local network automatically.
- app_process
- The Android tool that starts Java programs. Shizuku uses it to start its server.
- App ops
- Detailed controls for each app, for example "run in background".