From 905544ea892c364d3bff85b93b961271f146f1be Mon Sep 17 00:00:00 2001 From: inliver233 Date: Fri, 16 Oct 2026 19:23:59 +0800 Subject: [PATCH] Name the three path namespaces, and where a crossing is legal A path in this skill lives in one of three places -- the host filesystem, the device filesystem, or an APK entry name -- and the same string means something different in each. Two properties decide most of the failures that follow: * a host path does not exist on the device and vice versa; `adb push`/`adb pull` is the only place a translation happens, and it is the caller's to make; * an entry name is always `/`-separated and case-sensitive whatever the host OS is, so a path built with `os.path.join` matches nothing on Windows. The symptom is a "no such file" naming a path you can see exists -- on the other side of the boundary. `environment.md` now says to ask which namespace a string is in before asking whether the file is there, and points at `validate_device_path`, which refuses a host-shaped path before it reaches the device shell where it would fail far from the caller. The leak scan caught the first draft: the example in the table was a real-looking POSIX home path and `scan_leaks.py` flagged it as target identity. The scanner was right and the example was wrong; it now uses a placeholder. --- skills/apk-reverse/references/environment.md | 21 ++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/skills/apk-reverse/references/environment.md b/skills/apk-reverse/references/environment.md index fb769df..05b28b5 100644 --- a/skills/apk-reverse/references/environment.md +++ b/skills/apk-reverse/references/environment.md @@ -47,6 +47,27 @@ See `scripts/devsh.py`. Same class of bug: `javac` reads sources using the platform default encoding. Pass `-encoding UTF-8` or non-ASCII comments break the build. +### Three path namespaces, and none of them convert automatically + +A path in this skill lives in exactly one of three places, and the same string means something +different in each: + +| Namespace | Looks like | Who accepts it | +|---|---|---| +| **host** filesystem | `C:\work\app.apk`, `/work/app.apk` | your python scripts, `aapt2`, `apksigner` | +| **device** filesystem | `/data/local/tmp/x`, `/sdcard/` | `adb shell`, `su -c`, `devsh.py` | +| **APK entry name** | `classes.dex`, `res/layout/main.xml` | `repack.py`, `so_constpatch.py`, `zipfile` | + +Two properties matter. A host path **does not exist** on the device and vice versa — `adb push` and +`adb pull` take one of each, which is the only place a translation happens, and it is yours to make. +And an entry name is always `/`-separated and case-sensitive regardless of the host OS: a script that +builds one with `os.path.join` produces backslashes on Windows and matches nothing. + +The symptom of a crossed boundary is a "no such file" naming a path you can see exists — on the other +side of it. When that appears, check which namespace the string is in before checking whether the file +is there. `device_shell.py`'s `validate_device_path` exists to refuse a host-shaped path before it +reaches the device shell, where it would otherwise fail far from the caller. + ## Giving an offline device network over USB Use when the device has no usable network (broken Wi-Fi, no SIM, restricted network) but your host does. **`adb reverse` runs on the device's loopback, so it needs no device-side network interface at all.**