From 5c3ba9cd2ea3b262d1406599f6d8ad4e9ae2ffa1 Mon Sep 17 00:00:00 2001 From: inliver233 Date: Fri, 16 Oct 2026 19:20:45 +0800 Subject: [PATCH] Stop reporting a tool's resource failure as a finding about the target MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A JVM reader that dies on a large or deeply nested input -- OutOfMemoryError, an OOM kill, a container limit, a timeout -- prints an empty result that looks exactly like a reader that read the file and found nothing. That is the `present but unreadable` case SKILL.md §Coverage names, and it is where a wrong "that class is not in there" gets recorded. The new section in toolchain.md says what a failed analysis actually supports (a claim about the route, not about the artifact) and the three things to check before a negative from a heavy tool becomes a finding: the exit code and stderr rather than stdout alone, a re-run with room to work, and the indexed-query route that answers most location questions without materialising anything. A deadline you set yourself gets the same reading -- it reported nothing about the target. Also: the README claimed the scripts "work identically on Windows, macOS and Linux", while every gate run, every test result and every figure in the evidence record comes from one Windows host. The claim now carries the strength it actually has -- measured on Windows, `unverified` elsewhere -- and names the usual suspects (path separators, `os.pathsep` in `APKREV_TOOLS`, console encodings, ADB shell quoting) so a first run on another platform has somewhere to look. --- README.md | 9 ++++++++- README.zh-CN.md | 2 ++ skills/apk-reverse/references/toolchain.md | 23 ++++++++++++++++++++++ 3 files changed, 33 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 998abe2..28ed1a7 100644 --- a/README.md +++ b/README.md @@ -505,9 +505,16 @@ set APKREV_TOOLS=; # Windows, e.g. an SDK or proje export APKREV_TOOLS=: # POSIX ``` -The scripts themselves are plain `python3` and are intended to work identically on Windows, macOS and +The scripts themselves are plain `python3` and are designed to work identically on Windows, macOS and Linux; where a snippet is POSIX-only it is labelled. Nothing here assumes a Unix shell. +**Measured on Windows only.** Every gate run, every test result and every figure in the evidence +record comes from one host (Windows 10.0.26100, PowerShell 7, CPython 3.14). Cross-platform behaviour +is a design intention, not an observation: treat another platform as `unverified` until the suite has +been run there, and expect the usual suspects to be the difference — path separators, `os.pathsep` in +`APKREV_TOOLS`, console encodings, and shell quoting in the ADB helpers. If you run the gates on +macOS or Linux and they pass, that is a `observed` result worth recording next to this paragraph. + | Tool | Used for | |---|---| | Python 3.9+ | all scripts | diff --git a/README.zh-CN.md b/README.zh-CN.md index 0e3893e..e0ed8ad 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -417,6 +417,8 @@ export APKREV_TOOLS=: # POSIX 脚本本身是纯 `python3`,并且意图在 Windows、macOS 和 Linux 上行为一致;凡有片段仅限 POSIX,都会标注出来。这里没有任何东西假定你用的是 Unix shell。 +**实测只在 Windows 上做过。** 每一次门禁运行、每一个测试结果、以及证据记录里的每一个数字,都来自同一台主机(Windows 10.0.26100、PowerShell 7、CPython 3.14)。跨平台行为是设计意图,不是观测结果:在别处跑通之前,把另一个平台当作 `unverified`,并预期差异出在几个老地方 —— 路径分隔符、`APKREV_TOOLS` 里的 `os.pathsep`、控制台编码,以及 ADB 辅助脚本里的 shell 引号转义。如果你在 macOS 或 Linux 上跑门禁并通过了,那是一个值得记在这段旁边的 `observed` 结果。 + | 工具 | 用途 | |---|---| | Python 3.9+ | 所有脚本 | diff --git a/skills/apk-reverse/references/toolchain.md b/skills/apk-reverse/references/toolchain.md index 1c6e92c..0d3d0e3 100644 --- a/skills/apk-reverse/references/toolchain.md +++ b/skills/apk-reverse/references/toolchain.md @@ -270,6 +270,29 @@ line numbers and even which branch is which can differ from the bytecode. When a it, verify in smali or at runtime. `jadx` writing `(unknown)`/empty method bodies means it failed, not that the method is empty. +### A tool that ran out of room did not tell you the target is empty + +Every JVM-based reader in this list, and several of the native ones, can die on a large or deeply +nested input without saying anything about the artifact: `OutOfMemoryError`, a `Killed` from the OOM +killer, a container limit, or a timeout. The output looks like a tool that read the file and found +nothing — an empty result plus a line most people skim past. + +**What a failed analysis supports is a claim about the analysis, not the artifact**: "this route could +not complete on this input" is `present but unreadable` (`SKILL.md` §Coverage), and it is exactly +where a wrong "that class is not in there" gets written into a record. Three things to do before a +negative from a heavy tool becomes a finding: + +- read the **exit code and stderr**, not just stdout — a heap death often exits non-zero with a + partial result already printed; +- give the tool the room the input warrants (a larger heap for the JVM readers) and re-run before + concluding anything; +- prefer a route that does not have to materialise everything: an indexed query against the APK + (`rasc`/`droidasc`/`dexsql`) answers most location questions without decompiling a single class, and + it is also the route that survives a target too large for a full export. + +The same reading applies to a **time budget** you set yourself: a command you killed at your own +deadline reported nothing about the target, only about your deadline. + **`smali` assembling can abort silently** — the tree produces no dex while the process still exits 0. Never treat exit code as proof of a build. Assert the artifact exists, is fresh, and is non-empty (`patch-audit.md`).