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.
115 lines
6.1 KiB
Markdown
115 lines
6.1 KiB
Markdown
# apk-reverse
|
|
|
|
An Agent Skill for Android APK reverse engineering, debloating, ad removal, surgical
|
|
dex patching, repacking, and runtime/server analysis.
|
|
|
|
It is a **skill**, not a tutorial: it is written to be loaded by an agent (Claude Code,
|
|
Codex, or any harness that supports the Agent Skills format) while it works, so it is
|
|
organized for progressive disclosure — a short decision-oriented `SKILL.md`, detailed
|
|
references loaded only when a step needs them, and parameterized scripts you can run
|
|
directly.
|
|
|
|
## What it is good at
|
|
|
|
- Deciding **fast** whether a request is even achievable client-side, instead of
|
|
burning hours on a paywall that is enforced by a server.
|
|
- Choosing the **safest patch layer** for a given change, and avoiding the layers that
|
|
break the app.
|
|
- Separating **your own mistakes from the app's or the server's problems** — a
|
|
feature-scoped failure (login, registration, payment) is often a TLS/certificate issue on
|
|
one code path, not a consequence of the patch you just built.
|
|
- Working through **packed/hardened targets**: identifying the packer, unpacking, and turning a
|
|
memory dump back into a patched, installable APK.
|
|
- Avoiding the specific mistakes that produce an APK that builds perfectly and dies at
|
|
runtime.
|
|
|
|
## Structure
|
|
|
|
```
|
|
SKILL.md decision tree, workflow, hard constraints, indexes
|
|
references/ loaded on demand, one topic each
|
|
recon.md identify packer, SDKs, code location, tamper checks; unpacking
|
|
packers.md hardened targets: rejection signals, measuring the validation
|
|
boundary with single-variable tests, choosing a native host
|
|
framework-runtimes.md Flutter / React Native / Unity: which layer owns the UI
|
|
native-and-so.md .so hosts, DT_NEEDED vs JNI_OnLoad, relocation limits,
|
|
relocation-free bootstrapping, replacing Java methods natively
|
|
long-task-discipline.md live record, conclusion grading, drift control, handover
|
|
ad-removal.md ad taxonomy, wrapper mapping, callback trap, global gates, verification
|
|
membership-and-limits.md server vs client authority; what is and is not patchable
|
|
server-api.md probe an app's API; prove who owns the gate
|
|
tls-and-cert.md feature-scoped network failures: expired certs, dual trust chains
|
|
third-party-builds.md auditing a "cracked"/"modded" APK before trusting it
|
|
dex-patching.md patch-layer table + dexlib2 technique in depth
|
|
repack-and-sign.md repack rules, unpack-and-repack, signing, post-install hazards
|
|
runtime-data.md DataStore / SharedPreferences / SQLite / protobuf
|
|
dynamic-frida.md Frida setup, version pinning, the four-layer probe, hook strategy
|
|
environment.md device/emulator setup, ADB, UI automation, offline devices, log signals
|
|
verification.md the claim ladder; what "done" means
|
|
pitfalls.md the failure catalogue -- read before building
|
|
scripts/ parameterized, path-agnostic
|
|
smtool.py baksmali/smali wrapper with a configurable classpath
|
|
dexpatch/ dexlib2 method-level surgical rewriter (preferred tool)
|
|
patch_smali.py method-body replacement in a smali tree
|
|
dex_strpatch.py byte-level string patch with a string_ids ordering guard
|
|
dex_classdiff.py prove a dex edit was surgical
|
|
dex_strings.py strings/URLs/SDK markers without a decompiler
|
|
find_refs.py count callers of a method before patching it
|
|
repack.py rebuild APK, strip only signatures, sign, verify
|
|
devsh.py quoting-safe ADB shell helper
|
|
usb_net_proxy.py give an offline device network over USB
|
|
datastore_inject.py encode/inject AndroidX DataStore preferences safely
|
|
probe_api.py probe an HTTP API with the right headers
|
|
grab_crash.py recover stacks hidden by a crash-reporter SDK
|
|
install_test.py install + launch health check with logcat signal scan
|
|
frida_probe.js four-layer runtime probe (app net layer + OkHttp + java.net + exceptions)
|
|
run_probe.py inject the probe, stream it to a log file, stay resident
|
|
tls_check.py strict certificate check for one or more hosts
|
|
```
|
|
|
|
## Install
|
|
|
|
Drop this directory where your agent finds skills, e.g.:
|
|
|
|
```
|
|
<skills-dir>/apk-reverse/SKILL.md
|
|
```
|
|
|
|
The agent loads `SKILL.md` when a task matches its description, and pulls in
|
|
`references/*` only as needed. No global state, no machine-specific paths.
|
|
|
|
## Requirements
|
|
|
|
Nothing is mandatory; each script checks what it needs.
|
|
|
|
| Tool | Used for |
|
|
|---|---|
|
|
| Python 3.9+ | all scripts |
|
|
| `baksmali` / `smali` + `dexlib2` jars | disassembly, assembly, surgical patching |
|
|
| JDK (`javac`, `java`) | building/running the dexlib2 patcher |
|
|
| Android SDK build-tools (`aapt`, `zipalign`, `apksigner`) | manifest info, alignment, signing |
|
|
| `uber-apk-signer` (optional) | one-step align + sign |
|
|
| ADB | device work |
|
|
| Frida (host package + matching on-device server) | dynamic analysis |
|
|
| a rooted device or emulator | anything beyond static analysis |
|
|
|
|
## Read this first
|
|
|
|
`references/pitfalls.md`. It is the most valuable file here — every entry is a failure
|
|
that produced a broken artifact while looking completely healthy.
|
|
|
|
The three that hurt most:
|
|
|
|
1. Stripping the whole `META-INF/` during a repack deletes ServiceLoader registrations
|
|
and the app dies at startup with an error that names an unrelated library.
|
|
2. Patching a byte-level string without preserving `string_ids` ordering gets the whole
|
|
dex rejected, while checksums and signatures verify perfectly.
|
|
3. Rebuilding a dex with a whole-tree smali round-trip damages R8 output invisibly —
|
|
class tables compare clean, and it only blows up at runtime.
|
|
|
|
## Scope
|
|
|
|
Built for working on your own applications, on samples you are authorized to analyze,
|
|
and in CTF/competition sandboxes. It contains no vendored third-party binaries and no
|
|
target-specific data.
|