Four doors to uid 2000
rish, the Shizuku binder, a socket-only installer and DPHMS Tunnel all end up running a command as the shell user. They disagree about almost everything else: who holds the credential, what happens when the shell dies, and whether the app can tell you the truth about it.
1. The thing being compared
Android gives an app one legitimate way to act with more power than its own sandbox: ask a process that already has that power. Everything in this paper is a variation on that ask. The privilege is identical in all four cases - a command executed at uid 2000, the shell user, with no root and no unlocked bootloader. What differs is the door.
2. rish: the terminal that borrows a broker
rish is a shell client. It is a small script that arranges for a shell to be spawned inside another process that already holds the privileged binder, then hands you a prompt attached to it. It is excellent at exactly one thing: giving a human a terminal.
Its weakness is architectural rather than technical. rish is a client that depends on a broker being alive elsewhere, and it has no opinion about what an app should do when that broker is gone. It is not embeddable in an app's own logic, it does not report a transport state to the app, and its failure mode is a prompt that hangs or exits rather than a verdict an application can act on.
3. The Shizuku binder: a broker with a good API and a foreign name
The Shizuku model is the strongest of the three third-party designs. A service is started once - over ADB, wireless debugging, or root - and it exposes a binder. Apps bind, and calls are marshalled through transactRemote into a remote process at shell privilege.
What is genuinely good about it: the binder is a real kernel object, so liveness is observable; the service can be started without root; and the API is small enough to reason about.
What costs you: the broker is a separate application with its own package name, its own signing key, its own update cadence and its own permission namespace. Your app's privileged surface is now someone else's product. You inherit its bugs, its branding, and a grant dialog that tells your user to go install a third-party app. In our own builds that inheritance was literal: a manifest offering moe.shizuku.manager.permission.API_V23, a permission node owned by nobody in this house, and an installer whose every failure line told the user to go start someone else's app. We stripped the manifest grant and rewrote the installer. The comparison in this paper is not abstract; it is what we had to undo.
4. The socket-only installer: honest but narrow
DPHMS IWO reaches the shell over a Unix socket at /data/local/tmp/ash-tunnel.sock, keyed by an HMAC over a local key file, and streams an APK with framed @PUT writes of 64 KB before calling pm install-create and install-write. There is no binder anywhere in it.
That design has one real virtue: no binder means no broker, no permission grant and no transaction-size limits. It also has one hard limit that no amount of cleverness removes: a command can only travel where a socket already exists. If the socket is down, the installer cannot install, and it cannot even ask why. This is why IWO remains socket-only in our fleet and why we say so on the product page instead of implying a second path.
5. DPHMS Tunnel: one door, six rungs, stated honestly
Tunnel is not a broker you install beside your app. It is the app. It carries its own server, it holds the shell at uid 2000, and - this is the part that matters - it ships a client that every other house app compiles against, so the privileged surface has exactly one implementation to audit.
Every house app resolves a command through the same ordered ladder, and prints which rung answered:
| Rung | Path | What it survives |
|---|---|---|
| 1 | Tunnel's own org.dphms.core.Shell | Everything, where Tunnel itself is the caller |
| 2 | filesystem socket, no key required | An unreadable key file |
| 3 | live-socket discovery from /proc/net/unix | A missing key and an unknown socket name |
| 4 | Tunnel's own provider, probed under four method names | A dead socket, when a binder still exists |
| 5 | a peer holder | Losing the primary provider |
| 6 | the exec bridge | An app that never held the key |
Three rules make the ladder trustworthy rather than decorative. A command handed to a provider has its @sh prefix stripped first, because a provider wants a bare command and silently returns nothing otherwise. A blank reply is counted as a miss, never as success - the earlier build that treated "" as a win is precisely how a badge can glow while nothing runs. And STOP BINDER is a persisted switch, so the guest list can be closed by hand and stays closed across a restart.
6. Measured, not asserted
From the signed APKs on dphms.org today: nine house apps declare all four house permissions (MANAGER, API_V23, SHELL_BRIDGE, WRITE_SECURE_SETTINGS) and every one of them carries the six-rung client. Tunnel alone carries org.dphms.core.Keymaster, which is where PRIME, NEW KEY, the ladder readout and the stop switch live. Tunnel 1.4.27 has zero duplicate class definitions across its real dexes - a defect we found in 1.4.26 and fixed, where Transport was defined both in classes9 and classes10 and the winner depended on dex order.
7. Where we are weaker, in writing
- One Tunnel means one transport. A dead shell makes every installed house app degrade together. Our per-app badges show who has a second path; they cannot invent a per-app socket.
- IWO is socket-only. Deliberate, and stated on the product page.
- No root, ever. Anything that genuinely requires root is out of scope by design.
- None of this is hardware-confirmed by us. Every claim in this paper comes from reading signed APK bytes and live HTTP responses. That is a real limit and we would rather print it than bury it.
8. Verdict
If you want a terminal and someone else's broker is fine, rish is the shortest path. If you want the strongest third-party binder API and do not mind a foreign package owning your grant dialog, Shizuku is the mature choice. If you want a single-purpose installer with no binder at all, a socket design is the simplest thing that works.
If you want the privileged surface to belong to the product - one key, one door, one client to audit, a lever to close it, and a screen that tells you which rung actually answered - that is what Tunnel is for. Everything else in this house walks through it.
Nothing gets into this house except through the Tunnel. That is not a slogan; it is the architecture, and the ladder is how it is enforced.
DOWNLOAD TUNNEL DISCUSS IN THE FORUM RSS
Delivery links expire after 30 days by design. An expired link is not a lost purchase: send the receipt and the house issues a new one.