testsAndMisc/docs/superpowers/evidence/persistent-adb-2026-08-03.json
Krzysztof Rudnicki 287512f011 phone_focus_mode: reach the phone over adb without touching it
Android's Wireless debugging is deliberately ephemeral: the listener dies
when you leave the settings screen or the device sleeps, and it picks a
new random port each time. In one session it offered 35545, then 40401,
then 43781, and vanished entirely twice. Every deploy therefore started
with tapping through Settings and reading a port off the screen.

enable_persistent_adb.sh waits for any such transient window, then uses it
to pin adbd to port 5555 - the port deploy.sh has always assumed - and
installs a Magisk service.d boot script so the same happens on every boot.

The phone is on DHCP with no reservation, so the script identifies it by
MAC rather than trusting a hardcoded address: a ping sweep populates the
neighbour table and the address is looked up there. That beats a router
reservation because it needs no router access and works on any network.

One bug worth naming: the first version took the first `device` line from
`adb devices`. Pairing also leaves an mDNS _adb-tls-connect._tcp entry for
the same phone, so it reported port 5555 as reachable while nmap showed it
closed. It now matches the exact ip:port.

Verified: nmap showed 5555 closed then open across the switch; a run
against a deliberately wrong IP reported "phone moved" and connected; and
after `adb reboot` the script connected with no arguments and no
interaction, with /proc/uptime at 149s and service.adb.tcp.port reading
5555, so the boot script really ran. shellcheck clean.

Trade-off accepted by the user: adbd on a fixed port is reachable to
anything on the LAN, though it still requires an authorised key.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-03 13:33:45 +02:00

52 lines
3.5 KiB
JSON

{
"intent": "Let the laptop reach the phone over adb at any time without anyone opening Settings, tapping a pairing dialog, or reading a port off the screen.",
"scope": [
"phone_focus_mode/enable_persistent_adb.sh - new script",
"On-device: /data/adb/service.d/99-adb-tcp-5555.sh - new Magisk boot script",
"Non-goal: no change to deploy.sh, which already assumes port 5555",
"Non-goal: no router DHCP reservation - MAC discovery replaces the need for one"
],
"changes": [
"Wait for any transient Wireless debugging window (trying a known port first, then an nmap sweep of the ephemeral range), then use it to setprop service.adb.tcp.port=5555 and restart adbd.",
"Install a Magisk service.d boot script that re-applies the port on every boot, so the phone comes back reachable without interaction.",
"Find the phone by MAC when the configured IP is wrong: the phone is on DHCP with no reservation, so a hardcoded address is a latent failure. A ping sweep populates the neighbour table and the MAC is looked up there.",
"Match the exact ip:port when deciding whether a connection exists. The first version took the first `device` line, and since pairing also leaves an mDNS _adb-tls-connect._tcp entry for the same phone, it reported port 5555 as reachable while nmap showed it closed."
],
"verification": [
{
"command": "./enable_persistent_adb.sh 192.168.1.64 40401",
"result": "pass",
"evidence": "Installed the boot script (-rwxr-xr-x root root 373) and switched the port; nmap -p 5555 then showed '5555/tcp open' where it had shown 'closed' immediately before."
},
{
"command": "./enable_persistent_adb.sh 192.168.1.99 # deliberately wrong IP",
"result": "pass",
"evidence": "'phone moved: 192.168.1.99 -> 192.168.1.64' then 'reachable on 5555 at the new address'. MAC discovery works."
},
{
"command": "adb reboot; ./enable_persistent_adb.sh # no arguments, no interaction",
"result": "pass",
"evidence": "'already reachable on 5555 - nothing to do'. /proc/uptime was 149s so the reboot was real, and getprop service.adb.tcp.port returned 5555, proving the boot script ran rather than a stale adbd surviving."
},
{
"command": "shellcheck enable_persistent_adb.sh",
"result": "pass",
"evidence": "No findings."
},
{
"command": "Observed port drift during one session",
"result": "pass",
"evidence": "Wireless debugging offered 35545, then 40401, then 43781, and the listener vanished entirely twice when the screen slept. This is the failure mode the fixed port removes."
}
],
"risks": [
"adbd on a fixed port is reachable to anything on the LAN. It still requires an authorised key and an unknown key prompts on-device, but this is a wider surface than ephemeral Wireless debugging. Accepted explicitly by the user.",
"PHONE_MAC is hardcoded to this handset; a new phone needs that constant updated. The script would otherwise silently fail to rediscover a moved device.",
"Credential-encrypted storage means a freshly rebooted, still-locked phone accepts adb but cannot screencap or read app data until it is unlocked once - relevant when scripting post-reboot verification."
],
"rollback": [
"rm /data/adb/service.d/99-adb-tcp-5555.sh and reboot, or setprop service.adb.tcp.port -1 followed by stop/start adbd to drop back to USB-only.",
"Confirm with nmap -p 5555 that the port is closed afterwards, and that Wireless debugging still works as the bootstrap path."
]
}