Android DEX to Java decompiler with CLI and GUI for reverse engineering APK files, mobile security testing, and Android malware analysis.
| Method | Command/Steps |
|---|
| Binary Download | Download from github.com/skylot/jadx → Extract → Add to PATH |
| Kali Linux | sudo apt-get install jadx |
| Homebrew (macOS) | brew install jadx |
| Windows Installer | Download .exe from GitHub releases → Run installer |
| Build from Source | git clone https://github.com/skylot/jadx.git → cd jadx → ./gradlew dist |
| Docker | docker run -v /path/to/apk:/apk ghcr.io/skylot/jadx:latest jadx /apk/app.apk |
| Verify Installation | jadx --version |
| Task | Steps |
|---|
| Open APK | Launch jadx-gui → File → Open → Select .apk or .dex file |
| Navigate Packages | Left panel shows package structure; click to expand packages and classes |
| View Source Code | Double-click class to open decompiled Java source in center panel |
| Search Code | Ctrl+F (Cmd+F on macOS) → Enter keyword → Navigate results with arrows |
| Search Classes | Ctrl+Shift+F (Cmd+Shift+F) → Search by class name |
| Jump to Definition | Right-click variable/method → “Go to definition” or Ctrl+Click |
| View Smali Code | Right-click class → “Show bytecode” or toggle bytecode view |
| Export Code | File → Export → Select format (Java source, Gradle project, etc.) |
| Collapse/Expand | Ctrl+Shift+Minus to collapse method bodies; Ctrl+Shift+Plus to expand |
| Comment/Decompile Notes | Right-click class → Add comment (appears in decompiled source) |
| Command | Description |
|---|
jadx app.apk | Decompile APK → Output to ./app directory |
jadx -d /output app.apk | Specify output directory path |
jadx --show-bad-code app.apk | Include classes/methods that failed to decompile |
jadx -p app.apk | Decompile with default project structure (Gradle-compatible) |
jadx -f app.apk | Flat output (all classes in single directory) |
jadx --no-res app.apk | Skip resource extraction; decompile code only |
jadx --no-src app.apk | Skip source decompilation; resources + strings only |
jadx -t 8 app.apk | Use 8 threads for faster decompilation (adjust for CPU cores) |
jadx --log-level=DEBUG app.apk | Enable debug logging for troubleshooting |
jadx --help | Display all available options |
| Stage | Actions |
|---|
| Initial Scan | jadx app.apk → Explore AndroidManifest.xml (Activities, Services, Permissions) |
| Identify Entry Points | Find main Activity (from manifest) → Open in GUI → Trace onCreate/onResume |
| Search for Secrets | Ctrl+F → Search: API_KEY, SECRET, token, password, firebase, aws_access_key |
| Find Hardcoded URLs | Search: https://, http://, .com → Identify backend endpoints |
| Analyze Permissions | Check AndroidManifest.xml → Requested permissions → Cross-reference with code usage |
| Track Data Flow | Follow variable assignments → Find encryption/network calls → Identify sensitive operations |
| Export & Review | File → Export → Java source to review locally with grep/IDE |
| Feature | Usage |
|---|
| Package View | Left sidebar: expand com.example.app → drill down to individual classes |
| Class Structure | Class declaration → Fields → Constructors → Methods (organized by JADX) |
| Method Calls | Click method name → Shows call graph (what calls this, what it calls) |
| String Resources | R.string.xxx references clickable → Jump to string value in resources |
| Method Parameters | Hover over parameter → Shows type; cross-reference decompilation |
| Inheritance Chain | Class extends X → Click superclass → View parent methods |
| Anonymous Classes | Shown as $1, $2 in package tree → Inspect inline implementations |
| Search Term | Finds |
|---|
API_KEY, API_SECRET, SECRET_KEY | Hardcoded credentials |
password, passwd, pwd, pass | Password strings or field names |
token, auth, Bearer, JWT | Authentication tokens/schemes |
firebase, aws_access_key, gcp_key | Cloud service credentials |
127.0.0.1, localhost, 192.168 | Local/test endpoints (debugging hints) |
/admin, /api/, /data/ | API endpoint paths |
SharedPreferences, SQLiteDatabase | Local storage operations (potential plaintext data) |
Cipher.getInstance, MessageDigest | Cryptography calls (weak algo detection) |
HttpClient, OkHttp, Retrofit | Network library usage |
Runtime.exec(), ProcessBuilder | Command execution (RCE risk) |
| Aspect | Smali | Java |
|---|
| Format | Android Bytecode (assembly-like) | High-level Java source |
| Readability | Low; register-based operations | High; familiar syntax |
| Use Case | Precise control; low-level analysis | Quick understanding; code flow |
| Toggle | Right-click class → “Show bytecode” | Default decompilation view |
| When to Use Smali | Decompilation fails; obfuscation heavy; precise optimization analysis | Standard analysis; vulnerability hunting |
| Option | Output |
|---|
| Java Source | Decompiled .java files in project structure |
| Gradle Project | Buildable Gradle project with build.gradle + AndroidManifest (requires manual fixes) |
| Dex to Jar | Single .jar file (compatible with other decompilers like JD-GUI, CFR) |
| Smali Files | .smali bytecode files (editable; recompilable with apktool) |
| Resources Only | Extract resources (images, layouts, strings.xml) without source |
| Element | What to Check |
|---|
| Activities | android:exported="true" → Externally accessible entry points |
| Services | Exported services without permission protection → RCE vector |
| Broadcast Receivers | Can receive intents from other apps → Check intent filters |
| Content Providers | Exported without permission → Potential data leak |
| Permissions Requested | uses-permission → Check if code actually uses them (over-privileged apps) |
| Intent Filters | Action/Category → What external apps can trigger |
| Deep Links | android:scheme → Debuggable/production URL schemes |
| debuggable Attribute | android:debuggable="true" → Serious security issue; app can be debugged |
| Component | Check In GUI | Vulnerability |
|---|
| Activity | Manifest → Activity with exported="true" or intent-filter | Arbitrary launch; phishing/hijacking |
| Service | Manifest → Service without android:permission | Arbitrary command execution |
| Broadcast Receiver | Manifest → BroadcastReceiver with intent-filter | Spoofed broadcasts; data leak |
| Content Provider | Manifest → Provider without android:permission | SQL injection; unauthorized data access |
| Deep Links | Manifest → intent-filter with android:scheme | Intent hijacking; credential theft |
| Vulnerability Type | Search/Check For |
|---|
| Insecure Storage | SharedPreferences → plaintext saves (use EncryptedSharedPreferences check) |
| Hardcoded Credentials | API keys, tokens, passwords in string literals |
| Weak Crypto | Cipher.getInstance("AES/ECB/...") → ECB mode insecure |
| Cleartext Traffic | http:// URLs (should enforce HTTPS via Network Security Config) |
| SQL Injection | String concatenation in SQL queries; lack of prepared statements |
| Insecure Deserialization | ObjectInputStream without validation; readObject() |
| Exposed Intents | startActivity() with user-controlled intent data |
| Weak Random | java.util.Random for crypto (use SecureRandom) |
| Debuggable APK | Manifest android:debuggable="true" |
| Root Detection Bypass | Search su commands; look for weak detection patterns |
| Tool | Pros | Cons | Use Case |
|---|
| JADX | Accurate decompilation; GUI + CLI; actively maintained | Slower on large APKs; sometimes verbose output | Default choice; most reliable |
| apktool | Repackageable; resource extraction; Smali editing | No Java decompilation; static analysis harder | Modifying APK; resource extraction |
| jd-gui | Fast UI; good for .jar files | Outdated; poor Android support; stale decompilation | Legacy .jar decompilation; older APKs |
| Ghidra | Powerful; NSA-grade; supports multiple architectures | Steep learning curve; overkill for APKs | Native library analysis; advanced RE |
| Frida | Dynamic analysis; runtime hooking; memory inspection | Requires rooted device/emulator; more complex setup | Behavior analysis; anti-analysis bypass |
| Technique | Approach |
|---|
| ProGuard/R8 Obfuscation | Method names become a(), b() → Follow code flow with variable types |
| String Encryption | Search bytecode patterns; trace decryption routine; patch/extract strings at runtime |
| Control Flow Flattening | Follow switch statements → Reconstruct logic by examining branches |
| Dead Code Insertion | Ignore unreachable code paths; focus on live execution flow |
| Reflection | Class.forName() calls → Find strings (method/class names); static analysis harder |
| Native Libraries | .so files decompiled separately; use Ghidra or IDA; cross-reference in Java code |
| Multi-Threading/Callbacks | Trace listener implementations; follow callback chains |
| Rename Variables Manually | Right-click variable → Rename (JADX GUI feature) for clarity |
| Option | Purpose |
|---|
--cfg | Generate control flow graph (CFG) files (use with graphviz for visualization) |
--raw-cfg | Generate raw CFG without optimization analysis |
--synthetic-accessor | Generate synthetic accessor methods (Android 6.0+ desugaring) |
--comments | Include decompiler comments for complex code |
--xml | Output as XML (for scripted parsing) |
--java-version N | Target Java version (e.g., 8, 11, 17 for synthetic handling) |
--rename-case | Rename obfuscated identifiers to uniform case |
--skip-sources | Skip source file generation |
--very-verbose | Extremely detailed logging |
| Workflow | Commands/Steps |
|---|
| Decompile + Search for API Keys | jadx app.apk → Open in GUI → Ctrl+F → Search API, SECRET, key |
| Extract Resources Only | jadx --no-src app.apk → Resources folder contains images, layouts, strings |
| Batch Decompile Multiple APKs | for apk in *.apk; do jadx -d ./output/$apk $apk; done |
| Compare Two Versions | jadx v1.apk -d v1_out → jadx v2.apk -d v2_out → diff -r v1_out v2_out |
| Find Activity Entry Points | Open AndroidManifest.xml → Locate android.intent.action.MAIN Activity → Open in GUI |
| Analyze Permission Usage | Grep manifest for uses-permission → Search code for permission-gated APIs |
| Export for Code Review | jadx -p app.apk → Open app/ in IDE (Android Studio) for comfortable review |