Skip to content

troubleshooting: scripts and docs for known lockout issues - #79

Open
paragbaxi wants to merge 3 commits into
notmarek:masterfrom
paragbaxi:troubleshooting-scripts
Open

troubleshooting: scripts and docs for known lockout issues#79
paragbaxi wants to merge 3 commits into
notmarek:masterfrom
paragbaxi:troubleshooting-scripts

Conversation

@paragbaxi

Copy link
Copy Markdown

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.sh

Checks 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. ;log does 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.sh

For #67, #58, #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 clearing /var/local from root and rebooting does what the Settings reset would have. The jailbreak survives because bridge.conf restores mkk from /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.sh

Undocumented dead end: the host enumerates "Amazon Kindle" on the USB bus but no volume ever mounts, which looks exactly like a bad cable.

disableUSBInDemo.sh strands no_transitions once DEMO_MODE is cleared, and enableUSBInDemo.sh refuses to remove it without that flag — so the file is simply orphaned.

copy-payload.sh

Copying 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 via mkk/bridge.conf. That is the recovery path for every locked-out issue in the tracker and was not written down anywhere.

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.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.sh recovery 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.

Comment on lines +45 to +51
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
Comment thread troubleshooting/copy-payload.sh Outdated
Comment on lines +57 to +58
[ "$rc" = 0 ] && echo "\nPayload copied correctly. Eject before continuing." \
|| echo "\n*** COPY INCOMPLETE - do not continue, the jailbreak will fail silently. ***"
Comment on lines +242 to +248
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")
}
Comment thread README.MD
Comment on lines +126 to +129
BRIDGE_EMERGENCY="/mnt/us/emergency.sh"
if [ -f "${BRIDGE_EMERGENCY}" ] ; then
[ -x "${BRIDGE_EMERGENCY}" ] || chmod +x "${BRIDGE_EMERGENCY}"
/bin/sh "${BRIDGE_EMERGENCY}"
@notmarek

Copy link
Copy Markdown
Owner

How is the user supposed to run fix-usb-disabled?

@paragbaxi

Copy link
Copy Markdown
Author

Fair question, and chasing it down showed I'd both documented and scoped that
script wrongly. Two separate mistakes:

1. The README is circular. It says every script in troubleshooting/ is
meant to be copied to /mnt/us/emergency.sh over USB — which cannot work for
the one script whose symptom is that USB never mounts.

2. I oversold what it's for. If your ; commands still work you don't need
it at all. ;enter_demo puts the device back in demo mode, so DEMO_MODE
exists again and the device's own enableUSBInDemo.sh is re-armed; ;uzb
the same command the README already uses at the hotfix step — then gets you a
mount. And leaving demo mode the sanctioned way afterwards
(;demoResell Device) runs deleteDemoModeFlagFile.sh, which removes
both flags together, so nothing is stranded a second time.

So the honest scope is narrower than I first wrote it: it's a root-shell
convenience, not a rescue tool
— one rm instead of a two-reboot demo round
trip, for people who already have ssh/dropbear, KUAL, or a writable /mnt/us.
If the ; channel is dead too (the #67 / #58 / #52 lockout), neither route is
open; a ~40 second power hold with the cable unplugged restored demo mode
and the ; channel on my PW3, where holding it plugged in only powers the
device off.

What I think is worth keeping regardless of the script is why the flag
strands, which none of the open issues explain. From the device's own scripts
(PW3, 5.16.2.1.1):

# /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 DEMO_MODE without going through
deleteDemoModeFlagFile.sh — a crash, an interrupted Resell Device, a
/var/local reset — leaves no_transitions behind with nothing on the device
that will ever remove it. The host then sees the Kindle on the USB bus with no
volume, which reads exactly like a bad cable and sends people hunting hardware.

Pushing shortly: a HOW TO RUN IT header on fix-usb-disabled.sh with the
scoping above, the same correction in the README instead of the blanket "copy
it over USB" line, and the four Copilot nits — exact-match instead of substring
for the exploit filename in both copy-payload.sh and lbtool, printf
instead of echo "\n", and the missing fi in the README snippet.

Happy to drop fix-usb-disabled.sh entirely and keep only the README
explanation if you'd rather not carry a script that narrow.

…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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants