troubleshooting: scripts and docs for known lockout issues - #79
troubleshooting: scripts and docs for known lockout issues#79paragbaxi wants to merge 3 commits into
Conversation
Adds troubleshooting/ with four scripts and documents the recovery path that
several open issues have no answer for.
verify-jailbreak.sh Checks the artefacts the exploit itself writes, so it
works over USB with no shell. Also corrects the FAQ:
;log does NOT work before the hotfix, and people
reasonably read that as failure (notmarek#77, notmarek#71, notmarek#66, notmarek#59).
fix-managed-mode.sh notmarek#67, notmarek#58, notmarek#52 — stuck in managed mode with Settings
greyed out, so the documented ;demo exit is
unreachable. /opt/var/local is a read-only squashfs of
the factory /var/local, so resetting /var/local from
root does what the Settings reset would. The jailbreak
survives because bridge.conf restores mkk from
/mnt/us/mkk.
fix-usb-disabled.sh USB never mounts after demo mode. disableUSBInDemo.sh
strands no_transitions once DEMO_MODE is cleared, and
enableUSBInDemo.sh refuses to remove it without that
flag. Looks exactly like a bad cable.
copy-payload.sh Copying the payload with a GUI file manager fails
silently: .demo is hidden, and one file's NAME is the
exploit. Copies then verifies.
README also documents /mnt/us/emergency.sh — any script placed there runs as
root at boot via mkk/bridge.conf. That is the recovery path for every locked-out
issue in the tracker and was not written down anywhere.
Verified on PW3 (DP75SDI), FW 5.16.2.1.1, LanguageBreak 1.0.2.1.
The shell scripts stay the primary, dependency-free path. This adds a small Go
program covering only the two steps that run on the user's computer rather than
on the Kindle: verifying the jailbreak over USB, and copying the payload.
WHY IT IS WORTH HAVING BOTH
One payload file's NAME is the shell injection carrying the exploit —
semicolons, $(), ${} and a trailing space. Every hop through a shell, a file
manager, or an archive tool can alter it, and the failure is silent: the
jailbreak does nothing and the user debugs the device instead of the copy. Go
moves filenames as bytes with no shell in the path, and main_test.go round-trips
that exact name (trailing space included) so a regression fails the build rather
than someone's Kindle.
It also drops ._ AppleDouble sidecars, which FAT32 cannot hold, and fsyncs each
file rather than relying on a trailing sync(1) — people unplug the moment a copy
looks finished.
DELIBERATELY NOT PORTED
fix-managed-mode.sh and fix-usb-disabled.sh have no Go equivalent and should not
get one: they delete files under /var/local as root and reboot, so they execute
on the device via /mnt/us/emergency.sh. Shell is correct there.
Tests cover the exploit-filename round trip, AppleDouble filtering, hidden
.demo/ survival (the Finder failure mode), and content-based volume detection.
No hardware required.
There was a problem hiding this comment.
Pull request overview
Adds a new troubleshooting/ toolkit (device-side shell scripts plus an optional host-side Go helper) and updates the top-level README with a documented recovery path for common “lockout” states (managed mode, dead ; command channel, USB that never mounts) and a more reliable way to verify whether the jailbreak/hotfix actually applied.
Changes:
- Add device-side troubleshooting scripts to verify install state and recover from managed-mode / USB-mass-storage lockouts.
- Add optional host-side Go tool (
lbtool) to copy + verify the payload without relying on GUI file managers or shell-sensitive filenames. - Update README with safer payload-copy guidance, PW3 hotfix caveats, verification guidance, and the
/mnt/us/emergency.shrecovery path.
Reviewed changes
Copilot reviewed 9 out of 9 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| troubleshooting/verify-jailbreak.sh | Device-side verification script that writes a USB-readable report of exploit/hotfix markers and common “stranding” state. |
| troubleshooting/fix-managed-mode.sh | Device-side recovery script to reset /var/local while preserving jailbreak survival markers. |
| troubleshooting/fix-usb-disabled.sh | Device-side fix to remove the demo-mode no_transitions blocker that strands USB mass storage. |
| troubleshooting/copy-payload.sh | Host-side shell helper to copy payload reliably and verify expected root entries / payload integrity indicators. |
| troubleshooting/go/main.go | lbtool implementation: auto-detect Kindle mount, verify jailbreak artifacts, and copy+verify payload with per-file fsync and AppleDouble skipping. |
| troubleshooting/go/main_test.go | Tests for exploit-filename preservation, AppleDouble skipping, hidden .demo copy, and volume detection behavior. |
| troubleshooting/go/go.mod | Defines a standalone Go module for the troubleshooting host tool. |
| troubleshooting/go/README.md | Build/run documentation and rationale for the Go helper’s existence alongside shell scripts. |
| README.MD | Documentation updates for payload copying, PW3 hotfix behavior, verification guidance, and /mnt/us/emergency.sh recovery path. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| echo "verifying the exploit filename survived verbatim:" | ||
| if ls "$DST/documents/dictionaries/" 2>/dev/null | grep -q 'export SLASH'; then | ||
| echo " OK shell-injection dictionary file present" | ||
| else | ||
| echo " MISSING exploit filename did not survive the copy" | ||
| rc=1 | ||
| fi |
| [ "$rc" = 0 ] && echo "\nPayload copied correctly. Eject before continuing." \ | ||
| || echo "\n*** COPY INCOMPLETE - do not continue, the jailbreak will fail silently. ***" |
| fmt.Println("\nthe exploit filename must have survived verbatim") | ||
| if name, found := findExploit(filepath.Join(vol, "documents", "dictionaries")); found { | ||
| c.ok("shell-injection dictionary file present") | ||
| fmt.Printf(" %q\n", name) | ||
| } else { | ||
| c.bad("exploit filename did not survive the copy") | ||
| } |
| BRIDGE_EMERGENCY="/mnt/us/emergency.sh" | ||
| if [ -f "${BRIDGE_EMERGENCY}" ] ; then | ||
| [ -x "${BRIDGE_EMERGENCY}" ] || chmod +x "${BRIDGE_EMERGENCY}" | ||
| /bin/sh "${BRIDGE_EMERGENCY}" |
|
How is the user supposed to run fix-usb-disabled? |
|
Fair question, and chasing it down showed I'd both documented and scoped that 1. The README is circular. It says every script in 2. I oversold what it's for. If your So the honest scope is narrower than I first wrote it: it's a root-shell What I think is worth keeping regardless of the script is why the flag # /usr/bin/deleteDemoModeFlagFile.sh — the sanctioned exit removes BOTH files
if [ -e "$DEMO_MODE_FILE" ]; then
/bin/rm "$DEMO_MODE_FILE"
/bin/rm "$NO_TRANSITIONS_FILE"
...
fi
# /usr/bin/enableUSBInDemo.sh — guarded, so it is a no-op once DEMO_MODE is gone
[ -e "$DEMO_MODE_FILE" ] && rm -f "$NO_TRANSITIONS"Any route that removes Pushing shortly: a Happy to drop |
…ADME fi Answers the maintainer's notmarek#79 question ('how do I run fix-usb-disabled?'): - fix-usb-disabled.sh: add a HOW TO RUN IT header. It cannot bootstrap over USB (that's the symptom), so it's a root-shell convenience for people who already have ssh/dropbear, KUAL, or a writable /mnt/us -- not a rescue path. The ; commands (;enter_demo, ;uzb, ;demo -> Resell Device) cover the common case without it. - README.MD: close the BRIDGE_EMERGENCY snippet's missing fi, and correct the blanket 'every script in troubleshooting/ is meant to be used this way' claim, which is false for fix-usb-disabled.sh. - copy-payload.sh / troubleshooting/go: Copilot review comments 1 and 3 -- compare the exploit filename in full, not by substring match, in both the shell and Go paths. Verified against the real payload on disk: 103 bytes, no leading bare ';', no trailing space (both main_test.go's prior fixture and Copilot's own guess had the wrong shape). copy-payload.sh's failure message now prints what it actually found. Also: printf instead of echo '\n' (Copilot comment on portability). go build / go vet / go test all pass (4/4). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TDcKM5AjfBDNQvfXrPfYLW
Adds a
troubleshooting/directory with four scripts, and documents a recovery path that several open issues currently have no working answer for.All verified on a PW3 (DP75SDI), FW 5.16.2.1.1, LanguageBreak 1.0.2.1.
verify-jailbreak.shChecks the artefacts the exploit itself writes, so it works over USB with no shell on the device.
It also corrects a genuinely misleading FAQ answer.
;logdoes not work before the hotfix, so a fall-through to library search is expected at that stage and tells you nothing — people reasonably read a working install as a failure. Relevant to #77, #71, #66, #59.fix-managed-mode.shFor #67, #58, #52 — stuck in managed mode with Settings greyed out, so the documented
;demoexit is unreachable./opt/var/localis a read-only squashfs of the factory/var/local, so clearing/var/localfrom root and rebooting does what the Settings reset would have. The jailbreak survives becausebridge.confrestoresmkkfrom/mnt/us.The only answer on #67 today is "solved with a factory reset", which is unreachable when Settings is exactly what you cannot open.
fix-usb-disabled.shUndocumented dead end: the host enumerates "Amazon Kindle" on the USB bus but no volume ever mounts, which looks exactly like a bad cable.
disableUSBInDemo.shstrandsno_transitionsonceDEMO_MODEis cleared, andenableUSBInDemo.shrefuses to remove it without that flag — so the file is simply orphaned.copy-payload.shCopying the payload with a GUI file manager fails silently in two ways:
.demo/is hidden so drag-copy leaves it behind, and one file's name is the exploit (semicolons,$(), braces, spaces) which must land byte-identical on FAT32. Copies, then verifies.README
Documents
/mnt/us/emergency.sh— any script placed there runs as root at boot viamkk/bridge.conf. That is the recovery path for every locked-out issue in the tracker and was not written down anywhere.