references/native-tamper-and-suicide.md - how a hardened library terminates its own process: the mechanisms and their signatures, how to tell which one actually fires, arranged faults that call nothing (defeating every PLT-level fix), resolving a stub to its symbol, forged section headers, function boundaries from PT_GNU_EH_FRAME, scanner traps, and neutralising by returning rather than spinning.
references/toolchain.md - what to install, non-interactive invocation, GUI-only tools (ask for a human instead of silently substituting a weaker method), version-alignment traps, and working offline.
scripts/elf_plt.py - PLT stub to imported symbol on x86_64 and aarch64 from the relocation table; caller listing; library byte-diff naming each changed stub's symbol. scripts/apk_diff.py - entry-level diff by content hash, so same-size replacements are caught. scripts/native_crash.py - locate a native death from a log or tombstone and flag an arranged fault.
pitfalls P31-P36; SKILL.md gains a decision question, a hard constraint on neutralising terminate paths, and cross-references from packers/native-and-so.
- references/patch-audit.md (new): two independent questions for any self-made patch —
did it land, and is it legal. Length-vs-bytes comparison and the ~800-false-positive
signal that makes byte diffing useless; the equal-length-replacement blind spot that
hides patches from length-only audits (and why tier-2 checking must be driven by the
patch set's own declared targets, not by tier-1 output); verifier-level legality
(move-result must immediately follow its producer) checked as a set-difference so it
runs before the device; text-matching patch traps (whitespace, line endings,
instruction names, anchor uniqueness, re-emitted old fragments, one block per doc);
and auditing the patch set rather than a patch.
- pitfalls P28-P30: stale events-buffer records that read as this build's crash;
a patch that lands and changes nothing because the edited data is not the data the UI
consumes; two observations that cannot distinguish the hypotheses reported as a result.
- verification.md: point the known code-item blind spot at the new reference.
- Unify the four remaining script docstrings (and their inline comments) into English,
and generalise a sample-specific class name out of one of them.
New: references/signature-derived-keys.md (apps that use their own signing certificate as crypto key material: detection greps, why offline extraction is unreliable -- the runtime value is a certificate DER from inside the PKCS#7 chain, not the .RSA container -- plus the hardcode-then-verify procedure); scripts/sig_probe.py (offline candidates via --apk, authoritative read via --live, both exercised); pitfalls.md P27 (rebuilt APK installs and renders but every signed request returns empty/-1 signing params).
Updated: dynamic-frida.md (attach by PID when enumerate_processes omits the target; verify runtime/Java-bridge availability before blaming the script); runtime-data.md (MMKV format, parse/write snippet, crc32 and in-memory-overwrite traps); server-api.md (route the signature-derived-key case to the new reference); SKILL.md and README.md (new classification question, corrected question count, index entries).
New reference:
- dart-aot.md: pinning the Dart version, building a matching decompiler, the object-pool
model and reference indexes, register/boolean conventions, the three assembly signatures
that identify most business logic, the locating workflow, patch strategy, and the traps
specific to this layer (including ambiguous identifiers that resolve to protocol fields).
New scripts (parameterized, no machine-specific paths):
- dart_pprefs.py: object-pool offset -> code-site index, decoded arithmetically. Avoids the
full-capstone pass that costs minutes and 1-2 GB and reads as a hang.
- dart_pool_strings.py: framed literal recovery with file offsets. Defaults to one-byte
because automatic two-byte (UTF-16) detection is unreliable; --find searches both
encodings and is the reliable way to locate a known literal.
- dart_disasm.py: annotated windowed disassembly (pool + boolean annotations) and a B/BL
caller index that needs no disassembler.
Fixes and integration:
- framework-runtimes.md: point the Dart depth at dart-aot.md, and make the string-encoding
rule precise (ASCII is one-byte/UTF-8; CJK is UTF-16LE) instead of leaving it as 'try both'.
- pitfalls.md: P26 -- self-built tooling that fails in a way that reads as a target finding
(silent arithmetic, helper shadowing a stdlib module, measuring against an incomplete
reference, and a knob that does not move the metric).
- SKILL.md / README.md: index the new reference and scripts.
Validated by running all three scripts against a real Dart AOT sample: the pool-ref index
agrees with an independently built index to 99.2%, and the literal extractor's one-byte
output was verified string-by-string against a decompiler's pool listing.
Generalized from a long hardened-target engagement. Additions target the failure
modes that cost the most time and are not yet covered; nothing here is sample-specific.
New discipline
- SKILL.md: a third override rule -- deliver in the environment the request requires.
A root-only or live-instrumentation result can look like success while failing the
actual requirement (unrooted, installable, self-contained). Also adds two classify
questions: what form the deliverable must take, and which architecture/library is
actually executing.
- long-task-discipline.md: "the most expensive drift" -- a constraint table (privilege,
modification form, ABI, network, persistence, distribution), the checkpoint question,
and how to report a privileged workaround as a fallback rather than a deliverable.
Plus "bound every wait": timeouts on every command, budgets calibrated from
measurement so slow and hung are distinguishable, and sampling an observable you can
inspect instead of sleeping blind.
- environment.md: look at the screen instead of driving blind; which of the two screen
evidence kinds is trustworthy (an empty accessibility tree is common for
runtime-rendered UI, where the image is primary rather than a fallback); emulator
console control and adb recovery; preflight before every experiment block.
- native-and-so.md: what the device claims vs what the package manager chose vs what is
actually mapped; translation layers and their consequences for hooks and native
checks; fat-APK ABI selection.
- runtime-data.md: when the app rewrites your edit (server refresh vs local
regeneration), why chmod/chown cannot work because the app deletes and recreates the
file, and the immutable-attribute fix; decoding a value that only looks encrypted.
- framework-runtimes.md: string encoding traps (a UTF-8 scan of a UTF-16 snapshot
returns nothing and reads as "the strings were stripped"), and non-ASCII obfuscated
identifiers -- resolve by shape, not by name.
- pitfalls.md: P23 the fix lives in a file the app rewrites; P24 the artifact changed
but the wrong one is executing; P25 "search found nothing" treated as "not there".
New scripts (parameterized, path-agnostic, all with explicit timeouts)
- preflight.py environment check: device, root, ABI/translation, clock skew, leftover
proxy/forwards, dead device server, chosen ABI, free space
- lib_map.py what is actually mapped into a live process: path, base, architecture
from the ELF header, and whether it came from the APK or was
materialized at runtime
- blob_decode.py search (don't guess) the framing of a stored value, then re-encode the
edited payload with the same parameters
- snap.py bounded burst screenshots + control-tree capture, with a stall detector
and an explicit verdict on whether the tree is usable
All four were exercised against a live device while writing: preflight correctly
flags multi-device ambiguity and detected the ARM translation layer; lib_map read real
ELF headers and identified the translation shim; blob_decode round-tripped a
rotation+deflate+base64 blob at realistic size in ~0.2s; snap detected a stalled screen
across three hashes.
New references (loaded on demand, one topic each):
- packers.md: reading the shell's rejection signal, distinguishing self-inflicted
failures from genuine refusals, mapping the validation boundary via single-variable
tests, component-type rules (providers vs activities), picking a native host
- framework-runtimes.md: identifying Flutter/RN/Unity/Cordova, the wrong-layer trap,
how to tell which layer draws a given UI before committing to a patch direction
- native-and-so.md: host-library selection criteria, DT_NEEDED does-not-call-JNI_OnLoad,
relocation vs page-permission constraints and relocation-free bootstrapping,
replacing Java methods from native code with trampolines and fail-safe guards
- long-task-discipline.md: live record structure, conclusion grading, drift checkpoints,
handover contents, and the opposite failure of over-documenting
Pitfalls: +P18 install reported success but the build was never installed,
+P19 internal signal substituted for the user-visible outcome,
+P20 not-captured treated as not-present, +P21 two changes then attributing the result,
+P22 waiting on something that needs a human to advance.
SKILL.md: index the new references; add a runtime check for layer ownership to Q3;
add long-task rule; strengthen the verify step; add three hard constraints
(user-visible definition of done, no route discarded on compound evidence,
prove the device changed before measuring).
No app names, package names, or sample-specific identifiers anywhere.
references: recon gains packer identification + unpacking workflow (payload/plaintext size mapping, dump validation, hash de-duplication, business-dex heuristic); repack-and-sign gains the de-shelled repack pipeline, why apktool over binary AXML, and the apksigner scheme-selection caveat; new tls-and-cert documents feature-scoped network failures, dual trust chains and the fix template; new third-party-builds covers auditing a cracked/modded APK before trusting it; dynamic-frida gains version pinning, remote-device path, the four-layer probe and hook-never-fires triage; environment gains UI automation pitfalls; ad-removal gains the single convergence point, dynamic-plugin SDKs and the global timestamp gate; pitfalls gains P13-P17; verification gains rung 7 and the three-signal ad check.
scripts: new frida_probe.js (four-layer runtime probe), run_probe.py and tls_check.py; repack.py fixes two crash-on-default bugs and a misleading META-INF note; datastore_inject.py, PatchMethodExample.java and build_scripts.py lose hardcoded values - the example class name did not match its file and could not compile.