Commit Graph

25 Commits

Author SHA1 Message Date
Michał Tajchert a2a0a97f23 docs: call out BuildConfig.java and adopt a two-tier endpoint doc template
Two small changes that together meaningfully reduce wasted effort:

1. Phase 3 now explicitly tells the agent to read every BuildConfig.java.
   These files are almost never obfuscated and routinely contain the
   single highest-signal constants in the APK — base URLs, flavor names,
   build types, third-party API keys, feature flags. They were not
   mentioned in the previous workflow despite being the cheapest possible
   high-value target. One grep, finds them all.

2. The Phase 5 documentation template was a single per-endpoint block
   asking for path params, query params, request body, response type,
   and call chain. On apps with 100+ endpoints that easily becomes hours
   of work for output the consumer will not read.

   Replace it with two tiers:

     * Tier 1 — flat table covering every endpoint (host, method, path,
       auth required, source file). Always produced. Takes ~5 minutes
       from the --paths output.

     * Tier 2 — the existing detailed block, but explicitly reserved for
       high-value endpoints: the entire auth flow, payment/checkout, and
       anything the user specifically asked about. Default cap of ~10
       Tier-2 entries unless asked for more.

   This matches the natural shape of how analysts actually use this work
   (one inventory table to know the surface area, plus a deep dive on
   auth and a couple of flows) and prevents over-investment in detail
   for endpoints nobody will read about.
2026-04-29 01:40:50 +02:00
Michał Tajchert 627889a4c6 feat: add summary header to find-api-calls.sh
Without an overview the script dumps thousands of file:line: matches
across many sections, leaving the reader to figure out which framework
even applies. A short summary at the top makes the rest of the output
actionable.

The summary counts hits per framework / DI / auth-signal category in a
single grep pass over the source tree (8 separate greps would have
roughly octupled the runtime on a large decompile). Output is a 3-line
table:

  HTTP framework:   Retrofit=N OkHttp=N Ktor=N Apollo=N Volley=N
  DI framework:     Hilt/Dagger=N Koin=N
  Auth signals:     Bearer=N HMAC/Sign=N

A reader can immediately see which framework the app actually uses,
whether auth is bearer-token or signed, and whether to spend time on a
section or skip it. The summary is suppressed when a single section flag
(--retrofit, --ktor, --paths, ...) is given, so the existing single-section
workflows are unchanged.

A reminder of the available section flags is printed below the counts
so the agent does not have to consult --help.
2026-04-29 01:39:55 +02:00
Michał Tajchert ec2b14c171 feat: detect Koin DI and HMAC request-signing schemes
Two gaps in the previous coverage:

1. Koin was not mentioned anywhere — Hilt/Dagger got a full section in
   call-flow-analysis.md but Koin (the dominant DI in KMP and a large
   share of Kotlin-only Android apps) had zero patterns. Add a Koin
   subsection with the runtime-DSL patterns (module {}, single<>,
   factory<>, viewModel<>, by inject, by viewModel) plus the practical
   trick for resolving an interface to its impl after R8 obfuscation:
   intersect "files that import org.koin.core.module" with "files that
   reference the interface name".

2. The --auth mode caught Bearer / API-key / OAuth header patterns but
   missed HMAC and other request-signing schemes. A hardcoded HMAC
   secret embedded in an APK is a security finding worth surfacing —
   the same kind of authority the user gets is the same authority a
   decompiler grants to anyone. Add patterns for:

     * JCA primitives:  HmacSHA{1,256,512}, Mac.getInstance(...),
       SecretKeySpec(...), Signature.getInstance(...)
     * Header conventions: X-Signature, X-Hmac, X-Amz-Signature,
       X-Client-Authorization, AWS4-HMAC, signRequest(), signaturev2/3
     * Likely secret-bearing identifiers: app_secret, client_secret,
       signing_key, hmac_secret, consumer_secret, private_key
     * Ktor BearerTokens / loadTokens / refreshTokens DSL

These survive R8 because the JCA and Ktor APIs are public and not
shrunk. On a real-world app with a homegrown HMAC scheme they pinpoint
the signing class and its hardcoded key directly.
2026-04-29 01:26:40 +02:00
Michał Tajchert 2e6fc63453 feat: bucketed --urls output with strict regex and third-party denylist
The previous --urls mode was a plain grep for "https?://..." which on a
real APK produced thousands of lines, half of them junk strings extracted
from Kotlin stdlib's compression dictionary ("http://An Introduction to..."
fragments) and the other half SDK URLs (Google, Firebase, AppsFlyer,
Datadog, Sentry, ...) that the analyst is not looking for. The signal —
first-party backend hosts — was buried.

Two changes:

1. Strict URL regex: hostname must have at least one dot and end in a 2+
   letter TLD, with no whitespace / angle brackets / non-printables in the
   path. This eliminates the dictionary-fragment noise.

2. Bucket the surviving URLs into "likely first-party" vs "third-party"
   using references/third_party_hosts.txt — a curated denylist of
   ~80 patterns covering Google/Firebase/Apple/Microsoft/Adobe, attribution
   and observability vendors (AppsFlyer, Datadog, Sentry, Bugsnag, ...),
   payments (Stripe, PayU, Adyen, ...), support/chat SDKs, CAs, and
   standards namespaces (w3.org, etc.).

The new output starts with a frequency-sorted list of likely first-party
hosts — which is the artifact every reverse-engineer wants on the first
page — followed by the collapsed third-party list and the full URL set
for first-party hosts only.

The denylist is a sidecar text file (one regex per line) so users can
extend or override it without editing the script.
2026-04-29 01:23:56 +02:00
Michał Tajchert dbb19f0a22 feat: add --paths mode for obfuscation-resistant endpoint extraction
When R8 inlines call sites — client.get("/api/users") becomes
a.b(c, "/api/users") — the existing framework-specific patterns find
nothing, but the path string literal itself is never obfuscated. This
single observation is the most useful endpoint-extraction technique on
heavily shrunk apps; the existing --urls mode only catches full
"https://..." URLs, missing every relative path.

Add a --paths mode that greps for quoted strings matching either:

  * an absolute path with at least two slash-separated segments, or
  * a relative path beginning with a known API root keyword
    (api, v1/v2/v3, graphql, users, auth, profile, cart, order, ...)

with a {0,8}-segment cap and a small denylist for MIME types and system
paths (image/png, /proc/, /sys/, /dev/, etc.) which would otherwise pollute
results.

The output is a deduplicated inventory followed by the full call-site
list. On a real-world Kotlin/Ktor app this produced ~240 distinct API
paths in one shot — paths that the Retrofit/OkHttp/Ktor patterns missed
entirely because every call was inlined. This is the recommended first
extraction step on any obfuscated app.

Document the regex and rationale in references/api-extraction-patterns.md.
2026-04-29 01:21:25 +02:00
Michał Tajchert 371d3d4bed feat: add Ktor and Apollo (GraphQL) API-extraction patterns
The previous find-api-calls.sh covered only Retrofit, OkHttp, and Volley.
Modern Kotlin and KMP apps increasingly ship Ktor as their HTTP client
(used by ~25 % of new Kotlin apps as of 2025), and many product apps use
Apollo Kotlin for GraphQL. Both produced zero hits with the old patterns.

Add two new modes to find-api-calls.sh:

  --ktor    Ktor client calls (client.get/post/...), HttpRequestBuilder,
            defaultRequest blocks, and the Auth bearer DSL
            (BearerTokens / loadTokens / refreshTokens)

  --apollo  ApolloClient, .serverUrl(), HttpNetworkTransport, and
            .query/.mutation/.subscription operation calls

Document both in references/api-extraction-patterns.md with example
post-decompile snippets and a note on R8 obfuscation: Ktor call sites
get inlined to obfuscated method calls, but the path string literals
and Ktor library symbols (BearerTokens, URLProtocol, etc.) survive,
so library-internal patterns still work as anchors.
2026-04-29 01:16:43 +02:00
Michał Tajchert 5b63fcb418 feat: recover original Kotlin class names from R8-stripped binaries
R8 obfuscates JVM symbols but cannot strip the Kotlin metadata strings —
the Kotlin runtime needs them at runtime for reflection, coroutines, and
data-class features. The original FQNs leak through:

  * @DebugMetadata(c = "<real.fqn>")  emitted for every coroutine
    SuspendLambda (~ every suspend function in modern apps)
  * @Metadata(d2 = {"L<real/fqn>;"})  on every Kotlin class

Add scripts/recover-kotlin-names.sh that walks decompiled sources, mines
both annotations, and writes an obf -> real mapping (TSV + JSON + per-real-
package index). On a real-world Kotlin app this recovers ~100 % of
*Repository / *ViewModel / *UseCase / *Impl classes — exactly the classes
worth reading.

Add scripts/lookup-name.sh as a CLI over the mapping with four modes:
search by real-name substring, resolve obf -> real, list a real package,
and an annotated `--grep` that suffixes every hit with the owning real
class. This is a strict upgrade over plain grep against decompiled sources.

Replace the misleading 'use --deobf' tip in call-flow-analysis.md with a
pointer to this technique. --deobf only renames symbols with synthetic
placeholders; metadata recovery returns actual developer-written names.

Document the technique, expected recovery rates, and limitations in
references/kotlin-name-recovery.md, and reference it from SKILL.md as
optional Phase 3.5 (only when Phase 0 reports an obfuscated Kotlin app).
2026-04-29 01:12:31 +02:00
Michał Tajchert 213818fc27 feat: add Phase 0 fingerprint script for fast pre-decompile triage
Decompiling Java is wasted effort for Flutter, React Native, Cordova/
Capacitor, and Xamarin apps — their code lives in libapp.so, the JS bundle,
assets/www/, or .NET DLLs respectively. The previous workflow jumped
straight to Phase 1 (install deps) and Phase 2 (decompile), so the agent
had no way to know which path to take until after a full jadx run.

The new fingerprint.sh inspects an APK/XAPK in seconds and reports:

* Detected mobile framework with the file marker that triggered it
* HTTP stack hints (Retrofit, OkHttp, Ktor, Apollo, Volley) via DEX
  string scanning — survives R8 obfuscation
* DI and serialization libraries
* Obfuscation level estimate
* Notable third-party SDKs found in assets/ and DEX
* Consolidated native libraries across base + split APKs (split bundles
  often place .so files only in config.<abi>.apk)
* A framework-specific recommendation for the next step

SKILL.md documents this as Phase 0 and explicitly tells the agent to
stop and switch tooling if the app is non-native.

PowerShell port (fingerprint.ps1) intentionally not included — happy to
add if needed; behavior is straightforward to mirror.
2026-04-29 01:07:40 +02:00
Simone Avogadro 6a31ed3fa2 chore: bump plugin version to 1.1.0
Reflects features integrated since 1.0.0:
- PowerShell support for Windows (#8)
- dex2jar fork migration to ThexXTURBOXx (#12)
- Decompile partial-success and Fernflower timeout handling (#10)
- Chinese localization (#4)
- README badges, TOC, Acknowledgments

Updates:
- .claude-plugin/marketplace.json (metadata.version + plugins[0].version)
- plugins/android-reverse-engineering/.claude-plugin/plugin.json (version)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 22:58:48 +02:00
YIPEI WEI cedc1a3368 docs: improve README with badges, TOC, and features table 2026-04-27 10:53:49 +02:00
Simone Avogadro f3fb1e9484 chore(install-dep.ps1): align dex2jar to ThexXTURBOXx fork
Mirrors the bash counterpart updated in #12. Switches the GitHub repo,
the fallback tag (v2.4 -> 2.4.35), and the URL pattern order so that the
canonical ThexXTURBOXx naming (dex-tools-2.4.35.zip, no leading 'v') is
tried first, with the pre-2.4.30 naming as fallback.

Closes drift items 9-11 from post-merge-followup-2026-04. Functional bugs
in decompile.ps1 and PR #10 drift items remain pending.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 10:26:42 +02:00
Simone Avogadro 87388d06b3 docs: add PowerShell support disclaimer and Acknowledgments section
Add a top-level note flagging PS1 scripts as experimental and pointing
issues to this repo. Add an Acknowledgments section crediting the four
external contributors of the recent PR wave (#4, #8, #10, #12).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 10:23:31 +02:00
Phil Nachreiner f8d394a69e
Feature/windows powershell support (#8)
* feat: add Windows/PowerShell support

Add PowerShell equivalents of all bash scripts for Windows users:
- check-deps.ps1: Dependency verification with PATH refresh
- install-dep.ps1: Install via winget/scoop/choco or direct download
- decompile.ps1: APK/XAPK/JAR/AAR decompilation with split APK detection
- find-api-calls.ps1: API endpoint extraction (Retrofit, URLs, auth)

Update SKILL.md with Windows-specific instructions and notes for
each workflow phase.

PowerShell scripts support the same options as their bash counterparts
and automatically refresh PATH after installations.

* fix: check-deps.ps1 jadx fallback path version check, decompile.md lint fixes
2026-04-27 10:14:59 +02:00
Roshan Warrier 5a810d94b3
fix: use maintained dex2jar fork (#12)
Co-authored-by: txhno <198242577+txhno@users.noreply.github.com>
2026-04-27 09:59:14 +02:00
muqiao215 c25dfd78d2
fix(decompile): handle partial-success flows (#10)
Allow jadx-only mode to succeed when jadx exits non-zero after writing usable Java output.

Keep both-mode resilient when jadx partially succeeds, normalize Fernflower APK output handling, and make timeout/no-output failures explicit for Vineflower runs.

Co-authored-by: root <root@dbyqhnca.colocrossing.cloud>
2026-04-27 09:59:05 +02:00
kevinaimonster 5bc7cd53e6
feat: add Chinese localization / 添加中文支持 (#4)
Add Chinese trigger words to SKILL.md description and trigger field
for better discoverability by Chinese-speaking users.
2026-04-27 09:58:56 +02:00
Simone Avogadro ddeb9bc332 ADDED: .gitattributes for better WSL/Windows cooperation 2026-03-02 11:36:38 +01:00
Simone Avogadro ec0f6700f8 Improve plugin discoverability and metadata completeness
- Add keywords, skills and commands paths to plugin.json
- Add argument-hint to decompile command for better UX
- Add description to SKILL.md frontmatter for skill auto-matching

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-02 11:30:57 +01:00
Simone Avogadro 3276266788 Improve marketplace metadata compatibility with official Anthropic schema
Add $schema and top-level description fields to align with the dominant
pattern used in anthropics/claude-code and anthropics/claude-plugins-official.
Existing metadata wrapper preserved for backward compatibility.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-02 11:30:03 +01:00
Simone Avogadro bcbe078c52 Clarified this is a Skill 2026-02-02 21:34:07 +01:00
Simone Avogadro 3a87948331 Fix GitHub username in all repository URLs and LICENSE
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 21:06:15 +01:00
Simone Avogadro b092b3aeea Add legal disclaimer to README
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 20:25:08 +01:00
Simone Avogadro d7fefe54f2 Update README to highlight API extraction, fix author name in metadata
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 20:19:18 +01:00
Simone Avogadro fc9a722359 FIXED: relative paths 2026-02-02 16:36:48 +01:00
Simone Avogadro 5ec451e352 commit iniziale 2026-02-02 16:18:11 +01:00