@leejungkiin/awkit 1.1.0 → 1.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -3
- package/VERSION +1 -1
- package/bin/awf.js +1 -1
- package/bin/awk.js +237 -26
- package/core/AGENTS.md +8 -9
- package/core/GEMINI.md +74 -199
- package/package.json +3 -2
- package/skill-packs/neural-memory/skills/nm-memory-sync/SKILL.md +2 -2
- package/skills/CATALOG.md +3 -2
- package/skills/README.md +109 -0
- package/skills/android-re-analyzer/SKILL.md +238 -0
- package/skills/android-re-analyzer/references/api-extraction-patterns.md +119 -0
- package/skills/android-re-analyzer/references/call-flow-analysis.md +176 -0
- package/skills/android-re-analyzer/references/fernflower-usage.md +115 -0
- package/skills/android-re-analyzer/references/jadx-usage.md +116 -0
- package/skills/android-re-analyzer/references/setup-guide.md +221 -0
- package/skills/android-re-analyzer/scripts/check-deps.sh +129 -0
- package/skills/android-re-analyzer/scripts/decompile.sh +375 -0
- package/skills/android-re-analyzer/scripts/find-api-calls.sh +118 -0
- package/skills/android-re-analyzer/scripts/install-dep.sh +448 -0
- package/skills/awf-session-restore/SKILL.md +108 -184
- package/skills/beads-manager/SKILL.md +2 -2
- package/skills/brainstorm-agent/SKILL.md +47 -2
- package/skills/gemini-conductor/SKILL.md +234 -0
- package/skills/memory-sync/SKILL.md +29 -1
- package/skills/nm-memory-sync/SKILL.md +2 -2
- package/skills/orchestrator/SKILL.md +29 -155
- package/skills/skills/nm-memory-sync/SKILL.md +2 -2
- package/skills/smali-to-kotlin/SKILL.md +1 -1
- package/skills/smali-to-swift/SKILL.md +1 -1
- package/skills/swiftui-pro/SKILL.md +108 -0
- package/skills/swiftui-pro/agents/openai.yaml +10 -0
- package/skills/swiftui-pro/assets/swiftui-pro-icon.png +0 -0
- package/skills/swiftui-pro/assets/swiftui-pro-icon.svg +29 -0
- package/skills/swiftui-pro/references/accessibility.md +13 -0
- package/skills/swiftui-pro/references/api.md +39 -0
- package/skills/swiftui-pro/references/data.md +43 -0
- package/skills/swiftui-pro/references/design.md +31 -0
- package/skills/swiftui-pro/references/hygiene.md +9 -0
- package/skills/swiftui-pro/references/navigation.md +14 -0
- package/skills/swiftui-pro/references/performance.md +46 -0
- package/skills/swiftui-pro/references/swift.md +56 -0
- package/skills/swiftui-pro/references/views.md +35 -0
- package/skills/symphony-enforcer/SKILL.md +362 -0
- package/skills/symphony-orchestrator/SKILL.md +301 -0
- package/skills/telegram-notify/SKILL.md +57 -0
- package/symphony/LICENSE +21 -0
- package/symphony/README.md +178 -0
- package/symphony/app/api/agents/route.js +152 -0
- package/symphony/app/api/events/route.js +22 -0
- package/symphony/app/api/knowledge/route.js +253 -0
- package/symphony/app/api/locks/route.js +29 -0
- package/symphony/app/api/notes/route.js +125 -0
- package/symphony/app/api/preflight/route.js +23 -0
- package/symphony/app/api/projects/route.js +116 -0
- package/symphony/app/api/roles/route.js +134 -0
- package/symphony/app/api/skills/route.js +82 -0
- package/symphony/app/api/status/route.js +18 -0
- package/symphony/app/api/tasks/route.js +157 -0
- package/symphony/app/api/workflows/route.js +61 -0
- package/symphony/app/api/workspaces/route.js +15 -0
- package/symphony/app/globals.css +2605 -0
- package/symphony/app/layout.js +20 -0
- package/symphony/app/page.js +2122 -0
- package/symphony/cli/index.js +1060 -0
- package/symphony/core/agent-manager.js +357 -0
- package/symphony/core/context-bus.js +100 -0
- package/symphony/core/db.js +223 -0
- package/symphony/core/file-lock-manager.js +154 -0
- package/symphony/core/merge-pipeline.js +234 -0
- package/symphony/core/orchestrator.js +236 -0
- package/symphony/core/task-manager.js +335 -0
- package/symphony/core/workspace-manager.js +168 -0
- package/symphony/jsconfig.json +7 -0
- package/symphony/lib/core.mjs +1034 -0
- package/symphony/mcp/index.js +29 -0
- package/symphony/mcp/server.js +110 -0
- package/symphony/mcp/tools/context.js +80 -0
- package/symphony/mcp/tools/locks.js +99 -0
- package/symphony/mcp/tools/status.js +82 -0
- package/symphony/mcp/tools/tasks.js +216 -0
- package/symphony/mcp/tools/workspace.js +143 -0
- package/symphony/next.config.mjs +7 -0
- package/symphony/package.json +53 -0
- package/symphony/scripts/postinstall.js +49 -0
- package/symphony/symphony.config.js +41 -0
- package/templates/conductor-tracks.md +38 -0
- package/templates/specs/PROJECT.md +50 -0
- package/templates/specs/ROADMAP.md +79 -0
- package/templates/specs/TECH-SPEC.md +81 -0
- package/templates/specs/task-spec-template.xml +65 -0
- package/templates/workflow_dual_mode_template.md +5 -5
- package/workflows/_uncategorized/AGENTS.md +38 -0
- package/workflows/_uncategorized/decompile.md +67 -0
- package/workflows/_uncategorized/skill-health.md +7 -7
- package/workflows/ads/ads-audit.md +5 -5
- package/workflows/ads/ads-optimize.md +10 -10
- package/workflows/ads/adsExpert.md +7 -7
- package/workflows/conductor.md +97 -0
- package/workflows/context/auto-implement.md +4 -4
- package/workflows/context/codebase-sync.md +19 -8
- package/workflows/context/next.md +27 -27
- package/workflows/context/user-intent-analysis-workflow.md +4 -4
- package/workflows/expert/codeExpert.md +28 -31
- package/workflows/expert/debugExpert.md +11 -11
- package/workflows/expert/planExpert.md +21 -36
- package/workflows/git/smart-git-ops.md +49 -6
- package/workflows/lifecycle/debug.md +7 -7
- package/workflows/lifecycle/deploy.md +10 -10
- package/workflows/lifecycle/init.md +103 -91
- package/workflows/lifecycle/master-code-workflow.md +3 -3
- package/workflows/lifecycle/plan.md +19 -21
- package/workflows/quality/audit.md +1 -1
- package/workflows/quality/project-audit.md +1 -1
- package/workflows/roles/vibe-coding-master-workflow.md +2 -2
- package/workflows/smart-git-ops.md +146 -0
- package/workflows/ui/app-screen-analyzer.md +4 -4
- package/workflows/ui/create-feature.md +8 -8
- package/workflows/ui/create-spec-architect.md +11 -11
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: android-re-analyzer
|
|
3
|
+
description: >-
|
|
4
|
+
Android APK/XAPK/JAR/AAR decompiler & API extractor. Decompiles Android packages
|
|
5
|
+
using jadx and Fernflower/Vineflower, traces call flows from UI to network layer,
|
|
6
|
+
and produces structured API documentation. Complements smali-to-kotlin (rebuild)
|
|
7
|
+
by focusing on analysis & extraction.
|
|
8
|
+
author: SimoneAvogadro (adapted by Antigravity Team)
|
|
9
|
+
version: 1.0.0
|
|
10
|
+
license: Apache-2.0
|
|
11
|
+
original_repo: https://github.com/SimoneAvogadro/android-reverse-engineering-skill
|
|
12
|
+
trigger: conditional
|
|
13
|
+
activation_keywords:
|
|
14
|
+
- "/decompile"
|
|
15
|
+
- "decompile apk"
|
|
16
|
+
- "reverse engineer android"
|
|
17
|
+
- "extract api"
|
|
18
|
+
- "jadx"
|
|
19
|
+
- "fernflower"
|
|
20
|
+
- "vineflower"
|
|
21
|
+
- "find api endpoints"
|
|
22
|
+
- "trace call flow"
|
|
23
|
+
- "analyze apk"
|
|
24
|
+
- "dịch ngược apk"
|
|
25
|
+
- "phân tích apk"
|
|
26
|
+
priority: high
|
|
27
|
+
platform: android
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
# 🔍 Android RE Analyzer Skill
|
|
31
|
+
|
|
32
|
+
> **Purpose:** Decompile Android APK/XAPK/JAR/AAR → Analyze structure → Extract & document HTTP APIs.
|
|
33
|
+
> **Philosophy:** "Scan → Understand → Document" — analysis & extraction, not rebuilding.
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## ⚠️ SCOPE CLARITY
|
|
38
|
+
|
|
39
|
+
| This skill DOES | This skill DOES NOT |
|
|
40
|
+
|-----------------|---------------------|
|
|
41
|
+
| Decompile APK/XAPK/JAR/AAR to Java source | Rebuild app in modern Kotlin |
|
|
42
|
+
| Extract HTTP API endpoints & auth patterns | Write new production code |
|
|
43
|
+
| Trace call flows from UI → Network | Modify or repackage APKs |
|
|
44
|
+
| Analyze app architecture & manifest | Crack/bypass security |
|
|
45
|
+
| Handle obfuscated code (ProGuard/R8) | Deploy to Play Store |
|
|
46
|
+
| Auto-install dependencies (jadx, etc.) | Handle iOS apps |
|
|
47
|
+
|
|
48
|
+
**For rebuilding apps** → delegate to `smali-to-kotlin` skill
|
|
49
|
+
**For iOS reverse engineering** → delegate to `smali-to-swift` skill
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
## 🎯 ROLE DEFINITION
|
|
54
|
+
|
|
55
|
+
When this skill is active, the agent becomes:
|
|
56
|
+
|
|
57
|
+
> **Expert Android Reverse Engineer & API Analyst**
|
|
58
|
+
> - Master at navigating decompiled Java source (obfuscated or clean)
|
|
59
|
+
> - Fluent in Retrofit, OkHttp, Volley API patterns
|
|
60
|
+
> - Knows how to trace DI (Dagger/Hilt) bindings to find implementations
|
|
61
|
+
> - Uses dual-engine decompilation for maximum accuracy
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
## 🛠️ PREREQUISITES
|
|
66
|
+
|
|
67
|
+
Required: **Java JDK 17+** and **jadx**.
|
|
68
|
+
Optional (recommended): **Vineflower** (Fernflower fork) and **dex2jar**.
|
|
69
|
+
|
|
70
|
+
Check dependencies:
|
|
71
|
+
```bash
|
|
72
|
+
bash SKILL_ROOT/scripts/check-deps.sh
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Install missing ones:
|
|
76
|
+
```bash
|
|
77
|
+
bash SKILL_ROOT/scripts/install-dep.sh <dep>
|
|
78
|
+
# Available: java, jadx, vineflower, dex2jar, apktool, adb
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
> `SKILL_ROOT` = path to this skill directory (e.g. `~/.gemini/antigravity/skills/android-re-analyzer`)
|
|
82
|
+
|
|
83
|
+
---
|
|
84
|
+
|
|
85
|
+
## 📋 EXECUTION PIPELINE (5 Phases)
|
|
86
|
+
|
|
87
|
+
> **Rule:** Complete each phase before proceeding to the next.
|
|
88
|
+
> **Rule:** After each phase, summarize findings for the user.
|
|
89
|
+
|
|
90
|
+
### Phase 1: Verify & Install Dependencies
|
|
91
|
+
|
|
92
|
+
**Action:** Run `check-deps.sh`. If missing required deps → run `install-dep.sh <dep>`.
|
|
93
|
+
Re-run check after installation. Do NOT proceed until all required deps are OK.
|
|
94
|
+
|
|
95
|
+
For optional deps (vineflower, dex2jar), ask user if they want them installed.
|
|
96
|
+
Recommend both for best results.
|
|
97
|
+
|
|
98
|
+
---
|
|
99
|
+
|
|
100
|
+
### Phase 2: Decompile
|
|
101
|
+
|
|
102
|
+
**Action:** Run the decompile script:
|
|
103
|
+
```bash
|
|
104
|
+
bash SKILL_ROOT/scripts/decompile.sh [OPTIONS] <file>
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
Options:
|
|
108
|
+
- `-o <dir>` — output directory (default: `<filename>-decompiled`)
|
|
109
|
+
- `--deobf` — enable deobfuscation (for obfuscated apps)
|
|
110
|
+
- `--no-res` — skip resources, code only (faster)
|
|
111
|
+
- `--engine ENGINE` — `jadx` (default), `fernflower`, or `both`
|
|
112
|
+
|
|
113
|
+
**Engine selection:**
|
|
114
|
+
|
|
115
|
+
| Situation | Engine |
|
|
116
|
+
|---|---|
|
|
117
|
+
| First pass on any APK | `jadx` |
|
|
118
|
+
| JAR/AAR library analysis | `fernflower` |
|
|
119
|
+
| jadx output has warnings | `both` (compare) |
|
|
120
|
+
| Complex lambdas/generics | `fernflower` |
|
|
121
|
+
| Quick overview of large APK | `jadx --no-res` |
|
|
122
|
+
|
|
123
|
+
XAPK files are auto-extracted and each APK inside is decompiled separately.
|
|
124
|
+
|
|
125
|
+
---
|
|
126
|
+
|
|
127
|
+
### Phase 3: Analyze Structure
|
|
128
|
+
|
|
129
|
+
1. **Read `AndroidManifest.xml`:**
|
|
130
|
+
- Identify launcher Activity, Application class
|
|
131
|
+
- List Activities, Services, BroadcastReceivers, ContentProviders
|
|
132
|
+
- Note permissions (especially INTERNET, ACCESS_NETWORK_STATE)
|
|
133
|
+
|
|
134
|
+
2. **Survey package structure** under `<output>/sources/`:
|
|
135
|
+
- Distinguish app code from third-party libraries
|
|
136
|
+
- Look for packages: `api`, `network`, `data`, `repository`, `service`, `retrofit`
|
|
137
|
+
|
|
138
|
+
3. **Identify architecture pattern:**
|
|
139
|
+
- MVP: `Presenter` classes
|
|
140
|
+
- MVVM: `ViewModel` + `LiveData`/`StateFlow`
|
|
141
|
+
- Clean Architecture: `domain`, `data`, `presentation` packages
|
|
142
|
+
|
|
143
|
+
---
|
|
144
|
+
|
|
145
|
+
### Phase 4: Trace Call Flows
|
|
146
|
+
|
|
147
|
+
Follow execution paths from entry points to network calls:
|
|
148
|
+
|
|
149
|
+
1. Start from Activities identified in Phase 3
|
|
150
|
+
2. Follow initialization: `Application.onCreate()` → HTTP client setup
|
|
151
|
+
3. Trace user actions: `onClick()` → ViewModel → Repository → API service
|
|
152
|
+
4. Map DI bindings (`@Module`, `@Provides`, `@Binds`, `@Inject`)
|
|
153
|
+
5. Handle obfuscated code: use strings, annotations, and library APIs as anchors
|
|
154
|
+
|
|
155
|
+
See `SKILL_ROOT/references/call-flow-analysis.md` for detailed grep commands and techniques.
|
|
156
|
+
|
|
157
|
+
---
|
|
158
|
+
|
|
159
|
+
### Phase 5: Extract & Document APIs
|
|
160
|
+
|
|
161
|
+
**Action:** Run API search script:
|
|
162
|
+
```bash
|
|
163
|
+
bash SKILL_ROOT/scripts/find-api-calls.sh <output>/sources/
|
|
164
|
+
# Targeted: --retrofit, --okhttp, --volley, --urls, --auth
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
For each endpoint, document:
|
|
168
|
+
```markdown
|
|
169
|
+
### `METHOD /path/to/endpoint`
|
|
170
|
+
- **Source**: `com.example.api.ApiService` (file:line)
|
|
171
|
+
- **Base URL**: `https://api.example.com/v1`
|
|
172
|
+
- **Path params**: `id` (String)
|
|
173
|
+
- **Query params**: `page` (int), `limit` (int)
|
|
174
|
+
- **Headers**: `Authorization: Bearer <token>`
|
|
175
|
+
- **Request body**: `LoginRequest { email: String, password: String }`
|
|
176
|
+
- **Response type**: `ApiResponse<User>`
|
|
177
|
+
- **Called from**: `LoginActivity → ViewModel → Repository → ApiService`
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
See `SKILL_ROOT/references/api-extraction-patterns.md` for all search patterns.
|
|
181
|
+
|
|
182
|
+
---
|
|
183
|
+
|
|
184
|
+
## 🔄 WORKFLOW INTEGRATION
|
|
185
|
+
|
|
186
|
+
```yaml
|
|
187
|
+
triggers_from:
|
|
188
|
+
- "/decompile" workflow command
|
|
189
|
+
- Keywords: "decompile", "extract api", "analyze apk", "jadx"
|
|
190
|
+
|
|
191
|
+
delegates_to:
|
|
192
|
+
- smali-to-kotlin — when user wants to rebuild the app after analysis
|
|
193
|
+
- smali-to-swift — when user wants iOS equivalent
|
|
194
|
+
|
|
195
|
+
works_with:
|
|
196
|
+
- memory-sync — saves analysis findings, API docs
|
|
197
|
+
- symphony-orchestrator — tracks progress per phase
|
|
198
|
+
- orchestrator — routes to this skill based on intent
|
|
199
|
+
|
|
200
|
+
independent_from:
|
|
201
|
+
- brainstorm-agent
|
|
202
|
+
- ios-engineer
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
---
|
|
206
|
+
|
|
207
|
+
## 🚫 ANTI-PATTERNS
|
|
208
|
+
|
|
209
|
+
```yaml
|
|
210
|
+
never_do:
|
|
211
|
+
- Skip dependency check → always verify tools are available first
|
|
212
|
+
- Guess at API endpoints → always use grep patterns to find them
|
|
213
|
+
- Ignore obfuscation → use --deobf and string-based tracing
|
|
214
|
+
- Assume app architecture → verify from code before tracing
|
|
215
|
+
|
|
216
|
+
always_do:
|
|
217
|
+
- Run check-deps.sh before any decompilation
|
|
218
|
+
- Offer dual-engine decompilation when jadx has warnings
|
|
219
|
+
- Document every discovered API endpoint with the template
|
|
220
|
+
- Report architecture pattern before tracing call flows
|
|
221
|
+
- Ask user before proceeding to rebuild (delegate to smali-to-kotlin)
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
---
|
|
225
|
+
|
|
226
|
+
## 📚 REFERENCES
|
|
227
|
+
|
|
228
|
+
Detailed guides available in `SKILL_ROOT/references/`:
|
|
229
|
+
- `setup-guide.md` — Installing Java, jadx, Vineflower, dex2jar
|
|
230
|
+
- `jadx-usage.md` — jadx CLI options and workflows
|
|
231
|
+
- `fernflower-usage.md` — Fernflower/Vineflower CLI options
|
|
232
|
+
- `api-extraction-patterns.md` — Library-specific grep patterns
|
|
233
|
+
- `call-flow-analysis.md` — Techniques for tracing call flows
|
|
234
|
+
|
|
235
|
+
---
|
|
236
|
+
|
|
237
|
+
*android-re-analyzer v1.0.0 — Based on SimoneAvogadro/android-reverse-engineering-skill (Apache 2.0)*
|
|
238
|
+
*Adapted for Antigravity by Antigravity Team*
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
# API Extraction Patterns
|
|
2
|
+
|
|
3
|
+
Patterns and grep commands for finding HTTP API calls in decompiled Android source code.
|
|
4
|
+
|
|
5
|
+
## Retrofit
|
|
6
|
+
|
|
7
|
+
Retrofit is the most common HTTP client in Android apps. API endpoints are declared as annotated interface methods.
|
|
8
|
+
|
|
9
|
+
### Annotations to search for
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
# HTTP method annotations
|
|
13
|
+
grep -rn '@GET\|@POST\|@PUT\|@DELETE\|@PATCH\|@HEAD' sources/
|
|
14
|
+
|
|
15
|
+
# Parameter annotations
|
|
16
|
+
grep -rn '@Query\|@QueryMap\|@Path\|@Body\|@Field\|@FieldMap\|@Part\|@Header\|@HeaderMap' sources/
|
|
17
|
+
|
|
18
|
+
# Headers annotation (static headers)
|
|
19
|
+
grep -rn '@Headers' sources/
|
|
20
|
+
|
|
21
|
+
# Base URL configuration
|
|
22
|
+
grep -rn 'baseUrl\|\.baseUrl(' sources/
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
### Typical Retrofit interface
|
|
26
|
+
|
|
27
|
+
```java
|
|
28
|
+
public interface ApiService {
|
|
29
|
+
@GET("users/{id}")
|
|
30
|
+
Call<User> getUser(@Path("id") String userId);
|
|
31
|
+
|
|
32
|
+
@POST("auth/login")
|
|
33
|
+
@Headers({"Content-Type: application/json"})
|
|
34
|
+
Call<LoginResponse> login(@Body LoginRequest request);
|
|
35
|
+
}
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
When documenting, capture: HTTP method, path, path parameters, query parameters, request body type, response type, and any static headers.
|
|
39
|
+
|
|
40
|
+
## OkHttp
|
|
41
|
+
|
|
42
|
+
OkHttp is often used directly or as the transport layer for Retrofit.
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
# Request building
|
|
46
|
+
grep -rn 'Request\.Builder\|Request.Builder\|\.url(\|\.post(\|\.put(\|\.delete(\|\.patch(' sources/
|
|
47
|
+
|
|
48
|
+
# URL construction
|
|
49
|
+
grep -rn 'HttpUrl\|\.addQueryParameter\|\.addPathSegment' sources/
|
|
50
|
+
|
|
51
|
+
# Interceptors (often add auth headers)
|
|
52
|
+
grep -rn 'Interceptor\|addInterceptor\|addNetworkInterceptor\|intercept(' sources/
|
|
53
|
+
|
|
54
|
+
# Response handling
|
|
55
|
+
grep -rn '\.execute()\|\.enqueue(' sources/
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## Volley
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
grep -rn 'StringRequest\|JsonObjectRequest\|JsonArrayRequest\|Volley\.newRequestQueue\|RequestQueue' sources/
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
Volley requests typically pass the URL as a constructor argument and override `getHeaders()` or `getParams()` for custom headers/parameters.
|
|
65
|
+
|
|
66
|
+
## HttpURLConnection (legacy)
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
grep -rn 'HttpURLConnection\|HttpsURLConnection\|openConnection\|setRequestMethod\|setRequestProperty' sources/
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## WebView
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
grep -rn 'loadUrl\|evaluateJavascript\|addJavascriptInterface\|WebViewClient\|shouldOverrideUrlLoading' sources/
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
WebView-based apps may load API endpoints via JavaScript bridges. Look for `@JavascriptInterface` annotated methods.
|
|
79
|
+
|
|
80
|
+
## Hardcoded URLs and Secrets
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
# HTTP/HTTPS URLs
|
|
84
|
+
grep -rn '"https\?://[^"]*"' sources/
|
|
85
|
+
|
|
86
|
+
# API keys and tokens
|
|
87
|
+
grep -rni 'api[_-]\?key\|api[_-]\?secret\|auth[_-]\?token\|bearer\|access[_-]\?token\|client[_-]\?secret' sources/
|
|
88
|
+
|
|
89
|
+
# Base URL constants
|
|
90
|
+
grep -rni 'BASE_URL\|API_URL\|SERVER_URL\|ENDPOINT\|API_BASE' sources/
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
## Documentation Template
|
|
94
|
+
|
|
95
|
+
For each discovered API endpoint, document it using this template:
|
|
96
|
+
|
|
97
|
+
```markdown
|
|
98
|
+
### `METHOD /path/to/endpoint`
|
|
99
|
+
|
|
100
|
+
- **Source**: `com.example.app.api.ApiService` (file:line)
|
|
101
|
+
- **Base URL**: `https://api.example.com/v1`
|
|
102
|
+
- **Full URL**: `https://api.example.com/v1/path/to/endpoint`
|
|
103
|
+
- **Path parameters**: `id` (String)
|
|
104
|
+
- **Query parameters**: `page` (int), `limit` (int)
|
|
105
|
+
- **Headers**:
|
|
106
|
+
- `Authorization: Bearer <token>`
|
|
107
|
+
- `Content-Type: application/json`
|
|
108
|
+
- **Request body**: `LoginRequest { email: String, password: String }`
|
|
109
|
+
- **Response type**: `ApiResponse<User>`
|
|
110
|
+
- **Notes**: Called from `LoginActivity.onLoginClicked()`
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
## Search Strategy
|
|
114
|
+
|
|
115
|
+
1. Start with **base URL constants** — find where the API root is configured
|
|
116
|
+
2. Search for **Retrofit interfaces** — they give the clearest picture of all endpoints
|
|
117
|
+
3. Check **interceptors** — they reveal auth schemes and common headers
|
|
118
|
+
4. Search for **hardcoded URLs** — catch any one-off API calls outside the main client
|
|
119
|
+
5. Look for **WebView URLs** — some apps use hybrid web/native approaches
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
# Call Flow Analysis
|
|
2
|
+
|
|
3
|
+
Techniques for tracing execution flows in decompiled Android applications, from entry points down to network calls.
|
|
4
|
+
|
|
5
|
+
## 1. Start from AndroidManifest.xml
|
|
6
|
+
|
|
7
|
+
The manifest declares all entry points. After decompilation, find it at:
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
<output-dir>/resources/AndroidManifest.xml
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Key elements to look for:
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
# Activities (UI screens)
|
|
17
|
+
grep -n 'android:name=.*Activity' resources/AndroidManifest.xml
|
|
18
|
+
|
|
19
|
+
# Services (background work)
|
|
20
|
+
grep -n 'android:name=.*Service' resources/AndroidManifest.xml
|
|
21
|
+
|
|
22
|
+
# BroadcastReceivers
|
|
23
|
+
grep -n '<receiver' resources/AndroidManifest.xml
|
|
24
|
+
|
|
25
|
+
# ContentProviders
|
|
26
|
+
grep -n '<provider' resources/AndroidManifest.xml
|
|
27
|
+
|
|
28
|
+
# Launcher activity (main entry point)
|
|
29
|
+
grep -A5 'MAIN' resources/AndroidManifest.xml | grep 'android:name'
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## 2. Follow the Android Lifecycle
|
|
33
|
+
|
|
34
|
+
Typical call chain from UI to network:
|
|
35
|
+
|
|
36
|
+
```
|
|
37
|
+
Activity.onCreate()
|
|
38
|
+
→ setContentView(R.layout.activity_main)
|
|
39
|
+
→ findViewById() / View Binding
|
|
40
|
+
→ button.setOnClickListener()
|
|
41
|
+
→ onClick()
|
|
42
|
+
→ viewModel.doSomething()
|
|
43
|
+
→ repository.fetchData()
|
|
44
|
+
→ apiService.getEndpoint()
|
|
45
|
+
→ HTTP request
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
Key lifecycle methods to search:
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
grep -rn 'onCreate\|onResume\|onStart\|onViewCreated' sources/
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## 3. Identify Click Handlers
|
|
55
|
+
|
|
56
|
+
User interactions trigger API calls. Common patterns:
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
# XML onClick
|
|
60
|
+
grep -rn 'setOnClickListener\|onClick\|OnClickListener' sources/
|
|
61
|
+
|
|
62
|
+
# Data Binding
|
|
63
|
+
grep -rn '@BindingAdapter\|android:onClick' sources/ resources/
|
|
64
|
+
|
|
65
|
+
# Navigation actions
|
|
66
|
+
grep -rn 'findNavController\|NavController\|navigate(' sources/
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## 4. Application Class Initialization
|
|
70
|
+
|
|
71
|
+
The `Application` subclass initializes global singletons (HTTP clients, DI frameworks, analytics):
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
# Find Application subclass
|
|
75
|
+
grep -rn 'extends Application\|: Application()' sources/
|
|
76
|
+
|
|
77
|
+
# Check onCreate for initialization
|
|
78
|
+
# Then read the class to see what gets configured at startup
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
Look for:
|
|
82
|
+
- Retrofit/OkHttp client setup
|
|
83
|
+
- Dagger/Hilt component initialization
|
|
84
|
+
- Firebase/analytics initialization
|
|
85
|
+
- Base URL configuration
|
|
86
|
+
|
|
87
|
+
## 5. Dependency Injection (Dagger / Hilt)
|
|
88
|
+
|
|
89
|
+
Modern Android apps use DI. Trace bindings to find implementations:
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
# Hilt modules
|
|
93
|
+
grep -rn '@Module\|@InstallIn\|@Provides\|@Binds' sources/
|
|
94
|
+
|
|
95
|
+
# Hilt entry points
|
|
96
|
+
grep -rn '@HiltAndroidApp\|@AndroidEntryPoint\|@HiltViewModel' sources/
|
|
97
|
+
|
|
98
|
+
# Dagger components
|
|
99
|
+
grep -rn '@Component\|@Subcomponent' sources/
|
|
100
|
+
|
|
101
|
+
# Injected fields
|
|
102
|
+
grep -rn '@Inject' sources/
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
To trace a call flow through DI:
|
|
106
|
+
1. Find where an interface is used (e.g., `ApiService` injected into a repository)
|
|
107
|
+
2. Find the `@Provides` or `@Binds` method that creates the implementation
|
|
108
|
+
3. Follow the implementation to the actual HTTP call
|
|
109
|
+
|
|
110
|
+
## 6. Find Constants and Configuration
|
|
111
|
+
|
|
112
|
+
Hardcoded values are rarely obfuscated:
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
# Base URLs
|
|
116
|
+
grep -rni 'BASE_URL\|API_URL\|SERVER_URL\|HOST' sources/
|
|
117
|
+
|
|
118
|
+
# API keys
|
|
119
|
+
grep -rni 'API_KEY\|CLIENT_ID\|APP_KEY\|SECRET' sources/
|
|
120
|
+
|
|
121
|
+
# BuildConfig values
|
|
122
|
+
grep -rn 'BuildConfig\.' sources/
|
|
123
|
+
|
|
124
|
+
# SharedPreferences keys (runtime config)
|
|
125
|
+
grep -rn 'getSharedPreferences\|getString(\|putString(' sources/
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
## 7. Navigating Obfuscated Code
|
|
129
|
+
|
|
130
|
+
When code is obfuscated (ProGuard/R8):
|
|
131
|
+
|
|
132
|
+
### What gets obfuscated
|
|
133
|
+
- Class names → `a`, `b`, `c`
|
|
134
|
+
- Method names → `a()`, `b()`, `c()`
|
|
135
|
+
- Field names → `f1234a`, `f1235b`
|
|
136
|
+
|
|
137
|
+
### What does NOT get obfuscated
|
|
138
|
+
- **String literals** — URLs, keys, error messages remain readable
|
|
139
|
+
- **Android framework classes** — `Activity`, `Fragment`, `Intent` keep their names
|
|
140
|
+
- **Library public APIs** — Retrofit annotations, OkHttp builders retain names
|
|
141
|
+
- **AndroidManifest entries** — Activity/Service names must be real
|
|
142
|
+
|
|
143
|
+
### Strategy for obfuscated code
|
|
144
|
+
|
|
145
|
+
1. **Start from strings**: Search for URLs, error messages, and known constants
|
|
146
|
+
2. **Start from framework classes**: Activities and Fragments are named in the manifest
|
|
147
|
+
3. **Follow library calls**: Retrofit `@GET`/`@POST` annotations are readable even when the interface class name is obfuscated
|
|
148
|
+
4. **Use `--deobf`**: jadx can generate readable replacement names
|
|
149
|
+
5. **Cross-reference**: If `class a` calls `Retrofit.create(b.class)`, then `b` is a Retrofit service interface
|
|
150
|
+
|
|
151
|
+
## 8. Tracing a Complete Call Flow: Example
|
|
152
|
+
|
|
153
|
+
Goal: Find how login works in an obfuscated app.
|
|
154
|
+
|
|
155
|
+
```
|
|
156
|
+
1. grep for "login" in strings → find "auth/login" URL in class `c.a.b.d`
|
|
157
|
+
2. Class `c.a.b.d` has @POST("auth/login") → it's a Retrofit interface
|
|
158
|
+
3. grep for `c.a.b.d` usage → class `c.a.b.f` calls it (the repository)
|
|
159
|
+
4. grep for `c.a.b.f` usage → class `c.a.a.g` calls it (the ViewModel)
|
|
160
|
+
5. grep for `c.a.a.g` usage → `LoginActivity` has a field of this type
|
|
161
|
+
6. Read LoginActivity.onCreate() → sets click listener → calls ViewModel method
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
Result: `LoginActivity → ViewModel → Repository → Retrofit @POST("auth/login")`
|
|
165
|
+
|
|
166
|
+
## 9. Tools and Commands Summary
|
|
167
|
+
|
|
168
|
+
| Goal | Command |
|
|
169
|
+
|---|---|
|
|
170
|
+
| Find entry points | `grep 'android:name' resources/AndroidManifest.xml` |
|
|
171
|
+
| Find lifecycle methods | `grep -rn 'onCreate\|onResume' sources/` |
|
|
172
|
+
| Find click handlers | `grep -rn 'setOnClickListener\|onClick' sources/` |
|
|
173
|
+
| Find DI bindings | `grep -rn '@Provides\|@Binds\|@Inject' sources/` |
|
|
174
|
+
| Find constants | `grep -rni 'BASE_URL\|API_KEY' sources/` |
|
|
175
|
+
| Find usages of a class | `grep -rn 'ClassName' sources/` |
|
|
176
|
+
| Follow a string | `grep -rn '"some text"' sources/` |
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
# Fernflower / Vineflower CLI Reference
|
|
2
|
+
|
|
3
|
+
Fernflower is the JetBrains analytical Java decompiler. [Vineflower](https://github.com/Vineflower/vineflower) is the actively maintained community fork with better output quality and published releases. They share the same CLI interface.
|
|
4
|
+
|
|
5
|
+
## When to Use Fernflower vs jadx
|
|
6
|
+
|
|
7
|
+
| Scenario | Recommended |
|
|
8
|
+
|---|---|
|
|
9
|
+
| APK with resources needed | jadx |
|
|
10
|
+
| Standard Java JAR/library | Fernflower |
|
|
11
|
+
| jadx output has warnings/errors on specific classes | Fernflower on those classes |
|
|
12
|
+
| Complex lambdas, generics, streams | Fernflower |
|
|
13
|
+
| Large APK (>50MB), quick overview | jadx |
|
|
14
|
+
| Obfuscated Android app | jadx first, Fernflower on problem areas |
|
|
15
|
+
| Both decompilers available | Use `--engine both` and compare |
|
|
16
|
+
|
|
17
|
+
## Basic Usage
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
java -jar fernflower.jar [options] <source>... <destination>
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
- `<source>` — JAR file, class file, or directory containing class files
|
|
24
|
+
- `<destination>` — output directory
|
|
25
|
+
|
|
26
|
+
For a JAR input, Fernflower produces a JAR in the destination containing `.java` source files. Extract it with `unzip` to browse the sources.
|
|
27
|
+
|
|
28
|
+
## Key Options
|
|
29
|
+
|
|
30
|
+
Options use the format `-<key>=<value>`. Boolean options: `1` = enabled, `0` = disabled.
|
|
31
|
+
|
|
32
|
+
| Option | Default | Description |
|
|
33
|
+
|---|---|---|
|
|
34
|
+
| `-dgs=1` | 0 | Decompile generic signatures (recommended) |
|
|
35
|
+
| `-ren=1` | 0 | Rename obfuscated identifiers |
|
|
36
|
+
| `-mpm=60` | 0 | Max seconds per method — prevents hangs (recommended) |
|
|
37
|
+
| `-hes=0` | 1 | Show empty super() calls |
|
|
38
|
+
| `-hdc=0` | 1 | Show empty default constructors |
|
|
39
|
+
| `-udv=1` | 1 | Use debug variable names if available |
|
|
40
|
+
| `-ump=1` | 1 | Use debug parameter names if available |
|
|
41
|
+
| `-lit=1` | 0 | Output numeric literals as-is |
|
|
42
|
+
| `-asc=1` | 0 | Encode non-ASCII as unicode escapes |
|
|
43
|
+
| `-lac=1` | 0 | Decompile lambdas as anonymous classes |
|
|
44
|
+
| `-log=WARN` | INFO | Reduce output verbosity |
|
|
45
|
+
| `-e=<lib>` | — | Add library for context (not decompiled, improves type resolution) |
|
|
46
|
+
|
|
47
|
+
## Recommended Presets
|
|
48
|
+
|
|
49
|
+
### General use
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
java -jar fernflower.jar -dgs=1 -mpm=60 input.jar output/
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### Obfuscated code
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
java -jar fernflower.jar -dgs=1 -ren=1 -mpm=60 input.jar output/
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### Maximum detail
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
java -jar fernflower.jar -dgs=1 -hes=0 -hdc=0 -mpm=60 input.jar output/
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### With Android SDK context (better type resolution)
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
java -jar fernflower.jar -dgs=1 -mpm=60 -e=$ANDROID_HOME/platforms/android-34/android.jar input.jar output/
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## Working with APK Files
|
|
74
|
+
|
|
75
|
+
Fernflower cannot read APK/DEX files directly. Use dex2jar first:
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
# Step 1: Convert DEX to JAR
|
|
79
|
+
d2j-dex2jar -f -o app-converted.jar app.apk
|
|
80
|
+
|
|
81
|
+
# Step 2: Decompile with Fernflower
|
|
82
|
+
java -jar fernflower.jar -dgs=1 -mpm=60 app-converted.jar output/
|
|
83
|
+
|
|
84
|
+
# Step 3: Extract the resulting source JAR
|
|
85
|
+
unzip -o output/app-converted.jar -d output/sources/
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
The `decompile.sh --engine fernflower` script automates these steps.
|
|
89
|
+
|
|
90
|
+
## Supported Input Formats
|
|
91
|
+
|
|
92
|
+
| Format | Direct support | Via dex2jar |
|
|
93
|
+
|---|---|---|
|
|
94
|
+
| `.jar` | Yes | — |
|
|
95
|
+
| `.class` | Yes | — |
|
|
96
|
+
| `.zip` (with classes) | Yes | — |
|
|
97
|
+
| `.apk` | No | Yes |
|
|
98
|
+
| `.dex` | No | Yes |
|
|
99
|
+
| `.aar` | No | Yes |
|
|
100
|
+
|
|
101
|
+
## Output Format
|
|
102
|
+
|
|
103
|
+
- **JAR input** → Produces `<destination>/<input-name>.jar` containing `.java` files
|
|
104
|
+
- **Class file input** → Produces `.java` files directly in the destination
|
|
105
|
+
- **No resource decoding** — Fernflower only produces Java source, never XML/resources
|
|
106
|
+
|
|
107
|
+
## Fernflower vs Vineflower
|
|
108
|
+
|
|
109
|
+
Vineflower is the recommended fork. Improvements over upstream Fernflower:
|
|
110
|
+
|
|
111
|
+
- Published releases on GitHub and Maven Central
|
|
112
|
+
- Better handling of modern Java (records, sealed classes, pattern matching)
|
|
113
|
+
- More accurate lambda and switch expression decompilation
|
|
114
|
+
- Active bug fixes and community maintenance
|
|
115
|
+
- Same CLI interface — drop-in replacement
|