Summary
The Handshakes screen shows "No captures yet" (even after manual pull-to-refresh) despite the exact files captureDir() should be listing being physically present, with correct names/timestamps, at that exact path.
Environment
- Device: Xiaomi Redmi Note 10 Pro (M2101K6G / sweet), Android 13, rooted (KernelSU)
- App: StrykerOSS v6.0.1
- Storage path shown on-screen:
/sdcard/Stryker/captured
What I observed
After capturing 3 handshakes from the Wi-Fi screen (confirmed valid via aircrack-ng/hcxpcapngtool off-device — all 3 contain a real EAPOL handshake), the Handshakes screen still shows:
No captures yet
/sdcard/Stryker/captured
TOTAL 0 CRACKED 0 SIZE 0 KB
Tapping the refresh button (and pull-to-refresh) does not change this.
At the same time, checked directly on-device via a root shell:
$ ls -la /sdcard/Stryker/captured/
-rw-r----- 1 u0_a215 media_rw 137072 ... HS_Keenayya09_15_09.cap
-rw-r----- 1 u0_a215 media_rw 14811 ... HS_Maisya09_14_59.cap
-rw-r----- 1 u0_a215 media_rw 69057 ... HS_Nirvana-2.4GHz09_04_19.cap
Files owned by the app's own UID (u0_a215), correct names/sizes, sitting exactly under /sdcard/Stryker/captured, which matches HandshakeStorage.captureDir() (core.getShareRoot() + "/captured") exactly for the rooted/non-rootless case.
Where I think this is happening
Core.getListFiles() resolves the path via hostPath() and, when that resolves (non-null), reads the directory directly with new File(host).listFiles() from the app's own process — bypassing any shell. Per the comment already in Core.java above hostPath()/getListFiles():
"A root shell does not necessarily see /storage/emulated/0 the way the app does — each app gets its own mount namespace and plain su stays outside it, so ls can come back empty for a folder the user is looking at in a file manager."
This looks like the same class of issue but hit from the app's side instead: the capture tool (running with root, likely from inside the bind-mounted chroot — bootroot mounts /sdcard/Stryker into the chroot at session start) writes the files through a path/mount context that resolves to the same real storage a root shell sees, but the app's own regular process — subject to Android's scoped-storage/FUSE mediation — isn't picking up the new entries when it lists /sdcard/Stryker/captured itself. Possibly a MediaStore/FUSE cache staleness issue for files created "from outside" the app's own mount namespace rather than a plain code bug — but from the UI it's indistinguishable from the files just not being there, which is actively misleading (looks like the capture silently failed/vanished).
Happy to test a build/patch against this exact setup if useful — I can reproduce reliably.
Summary
The Handshakes screen shows "No captures yet" (even after manual pull-to-refresh) despite the exact files
captureDir()should be listing being physically present, with correct names/timestamps, at that exact path.Environment
/sdcard/Stryker/capturedWhat I observed
After capturing 3 handshakes from the Wi-Fi screen (confirmed valid via
aircrack-ng/hcxpcapngtooloff-device — all 3 contain a real EAPOL handshake), the Handshakes screen still shows:Tapping the refresh button (and pull-to-refresh) does not change this.
At the same time, checked directly on-device via a root shell:
Files owned by the app's own UID (
u0_a215), correct names/sizes, sitting exactly under/sdcard/Stryker/captured, which matchesHandshakeStorage.captureDir()(core.getShareRoot() + "/captured") exactly for the rooted/non-rootless case.Where I think this is happening
Core.getListFiles()resolves the path viahostPath()and, when that resolves (non-null), reads the directory directly withnew File(host).listFiles()from the app's own process — bypassing any shell. Per the comment already inCore.javaabovehostPath()/getListFiles():This looks like the same class of issue but hit from the app's side instead: the capture tool (running with root, likely from inside the bind-mounted chroot —
bootrootmounts/sdcard/Strykerinto the chroot at session start) writes the files through a path/mount context that resolves to the same real storage a root shell sees, but the app's own regular process — subject to Android's scoped-storage/FUSE mediation — isn't picking up the new entries when it lists/sdcard/Stryker/captureditself. Possibly a MediaStore/FUSE cache staleness issue for files created "from outside" the app's own mount namespace rather than a plain code bug — but from the UI it's indistinguishable from the files just not being there, which is actively misleading (looks like the capture silently failed/vanished).Happy to test a build/patch against this exact setup if useful — I can reproduce reliably.