تخطَّ إلى المحتوى

JADX

Android DEX to Java decompiler with CLI and GUI for reverse engineering APK files, mobile security testing, and Android malware analysis.

Installation

MethodCommand/Steps
Binary DownloadDownload from github.com/skylot/jadx → Extract → Add to PATH
Kali Linuxsudo apt-get install jadx
Homebrew (macOS)brew install jadx
Windows InstallerDownload .exe from GitHub releases → Run installer
Build from Sourcegit clone https://github.com/skylot/jadx.gitcd jadx./gradlew dist
Dockerdocker run -v /path/to/apk:/apk ghcr.io/skylot/jadx:latest jadx /apk/app.apk
Verify Installationjadx --version

GUI Usage

TaskSteps
Open APKLaunch jadx-gui → File → Open → Select .apk or .dex file
Navigate PackagesLeft panel shows package structure; click to expand packages and classes
View Source CodeDouble-click class to open decompiled Java source in center panel
Search CodeCtrl+F (Cmd+F on macOS) → Enter keyword → Navigate results with arrows
Search ClassesCtrl+Shift+F (Cmd+Shift+F) → Search by class name
Jump to DefinitionRight-click variable/method → “Go to definition” or Ctrl+Click
View Smali CodeRight-click class → “Show bytecode” or toggle bytecode view
Export CodeFile → Export → Select format (Java source, Gradle project, etc.)
Collapse/ExpandCtrl+Shift+Minus to collapse method bodies; Ctrl+Shift+Plus to expand
Comment/Decompile NotesRight-click class → Add comment (appears in decompiled source)

CLI Decompilation

CommandDescription
jadx app.apkDecompile APK → Output to ./app directory
jadx -d /output app.apkSpecify output directory path
jadx --show-bad-code app.apkInclude classes/methods that failed to decompile
jadx -p app.apkDecompile with default project structure (Gradle-compatible)
jadx -f app.apkFlat output (all classes in single directory)
jadx --no-res app.apkSkip resource extraction; decompile code only
jadx --no-src app.apkSkip source decompilation; resources + strings only
jadx -t 8 app.apkUse 8 threads for faster decompilation (adjust for CPU cores)
jadx --log-level=DEBUG app.apkEnable debug logging for troubleshooting
jadx --helpDisplay all available options

APK Analysis Workflow

StageActions
Initial Scanjadx app.apk → Explore AndroidManifest.xml (Activities, Services, Permissions)
Identify Entry PointsFind main Activity (from manifest) → Open in GUI → Trace onCreate/onResume
Search for SecretsCtrl+F → Search: API_KEY, SECRET, token, password, firebase, aws_access_key
Find Hardcoded URLsSearch: https://, http://, .com → Identify backend endpoints
Analyze PermissionsCheck AndroidManifest.xml → Requested permissions → Cross-reference with code usage
Track Data FlowFollow variable assignments → Find encryption/network calls → Identify sensitive operations
Export & ReviewFile → Export → Java source to review locally with grep/IDE
FeatureUsage
Package ViewLeft sidebar: expand com.example.app → drill down to individual classes
Class StructureClass declaration → Fields → Constructors → Methods (organized by JADX)
Method CallsClick method name → Shows call graph (what calls this, what it calls)
String ResourcesR.string.xxx references clickable → Jump to string value in resources
Method ParametersHover over parameter → Shows type; cross-reference decompilation
Inheritance ChainClass extends X → Click superclass → View parent methods
Anonymous ClassesShown as $1, $2 in package tree → Inspect inline implementations

Searching for Secrets & Vulnerabilities

Search TermFinds
API_KEY, API_SECRET, SECRET_KEYHardcoded credentials
password, passwd, pwd, passPassword strings or field names
token, auth, Bearer, JWTAuthentication tokens/schemes
firebase, aws_access_key, gcp_keyCloud service credentials
127.0.0.1, localhost, 192.168Local/test endpoints (debugging hints)
/admin, /api/, /data/API endpoint paths
SharedPreferences, SQLiteDatabaseLocal storage operations (potential plaintext data)
Cipher.getInstance, MessageDigestCryptography calls (weak algo detection)
HttpClient, OkHttp, RetrofitNetwork library usage
Runtime.exec(), ProcessBuilderCommand execution (RCE risk)

Smali vs Java Output

AspectSmaliJava
FormatAndroid Bytecode (assembly-like)High-level Java source
ReadabilityLow; register-based operationsHigh; familiar syntax
Use CasePrecise control; low-level analysisQuick understanding; code flow
ToggleRight-click class → “Show bytecode”Default decompilation view
When to Use SmaliDecompilation fails; obfuscation heavy; precise optimization analysisStandard analysis; vulnerability hunting

Export Options

OptionOutput
Java SourceDecompiled .java files in project structure
Gradle ProjectBuildable Gradle project with build.gradle + AndroidManifest (requires manual fixes)
Dex to JarSingle .jar file (compatible with other decompilers like JD-GUI, CFR)
Smali Files.smali bytecode files (editable; recompilable with apktool)
Resources OnlyExtract resources (images, layouts, strings.xml) without source

AndroidManifest.xml Analysis

ElementWhat to Check
Activitiesandroid:exported="true" → Externally accessible entry points
ServicesExported services without permission protection → RCE vector
Broadcast ReceiversCan receive intents from other apps → Check intent filters
Content ProvidersExported without permission → Potential data leak
Permissions Requesteduses-permission → Check if code actually uses them (over-privileged apps)
Intent FiltersAction/Category → What external apps can trigger
Deep Linksandroid:scheme → Debuggable/production URL schemes
debuggable Attributeandroid:debuggable="true" → Serious security issue; app can be debugged

Finding Exported Components

ComponentCheck In GUIVulnerability
ActivityManifest → Activity with exported="true" or intent-filterArbitrary launch; phishing/hijacking
ServiceManifest → Service without android:permissionArbitrary command execution
Broadcast ReceiverManifest → BroadcastReceiver with intent-filterSpoofed broadcasts; data leak
Content ProviderManifest → Provider without android:permissionSQL injection; unauthorized data access
Deep LinksManifest → intent-filter with android:schemeIntent hijacking; credential theft

Identifying Vulnerabilities

Vulnerability TypeSearch/Check For
Insecure StorageSharedPreferences → plaintext saves (use EncryptedSharedPreferences check)
Hardcoded CredentialsAPI keys, tokens, passwords in string literals
Weak CryptoCipher.getInstance("AES/ECB/...") → ECB mode insecure
Cleartext Traffichttp:// URLs (should enforce HTTPS via Network Security Config)
SQL InjectionString concatenation in SQL queries; lack of prepared statements
Insecure DeserializationObjectInputStream without validation; readObject()
Exposed IntentsstartActivity() with user-controlled intent data
Weak Randomjava.util.Random for crypto (use SecureRandom)
Debuggable APKManifest android:debuggable="true"
Root Detection BypassSearch su commands; look for weak detection patterns

Tools Comparison

ToolProsConsUse Case
JADXAccurate decompilation; GUI + CLI; actively maintainedSlower on large APKs; sometimes verbose outputDefault choice; most reliable
apktoolRepackageable; resource extraction; Smali editingNo Java decompilation; static analysis harderModifying APK; resource extraction
jd-guiFast UI; good for .jar filesOutdated; poor Android support; stale decompilationLegacy .jar decompilation; older APKs
GhidraPowerful; NSA-grade; supports multiple architecturesSteep learning curve; overkill for APKsNative library analysis; advanced RE
FridaDynamic analysis; runtime hooking; memory inspectionRequires rooted device/emulator; more complex setupBehavior analysis; anti-analysis bypass

Tips for Obfuscated Code

TechniqueApproach
ProGuard/R8 ObfuscationMethod names become a(), b() → Follow code flow with variable types
String EncryptionSearch bytecode patterns; trace decryption routine; patch/extract strings at runtime
Control Flow FlatteningFollow switch statements → Reconstruct logic by examining branches
Dead Code InsertionIgnore unreachable code paths; focus on live execution flow
ReflectionClass.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/CallbacksTrace listener implementations; follow callback chains
Rename Variables ManuallyRight-click variable → Rename (JADX GUI feature) for clarity

Advanced CLI Options

OptionPurpose
--cfgGenerate control flow graph (CFG) files (use with graphviz for visualization)
--raw-cfgGenerate raw CFG without optimization analysis
--synthetic-accessorGenerate synthetic accessor methods (Android 6.0+ desugaring)
--commentsInclude decompiler comments for complex code
--xmlOutput as XML (for scripted parsing)
--java-version NTarget Java version (e.g., 8, 11, 17 for synthetic handling)
--rename-caseRename obfuscated identifiers to uniform case
--skip-sourcesSkip source file generation
--very-verboseExtremely detailed logging

Quick Reference: Common Workflows

WorkflowCommands/Steps
Decompile + Search for API Keysjadx app.apk → Open in GUI → Ctrl+F → Search API, SECRET, key
Extract Resources Onlyjadx --no-src app.apk → Resources folder contains images, layouts, strings
Batch Decompile Multiple APKsfor apk in *.apk; do jadx -d ./output/$apk $apk; done
Compare Two Versionsjadx v1.apk -d v1_outjadx v2.apk -d v2_outdiff -r v1_out v2_out
Find Activity Entry PointsOpen AndroidManifest.xml → Locate android.intent.action.MAIN Activity → Open in GUI
Analyze Permission UsageGrep manifest for uses-permission → Search code for permission-gated APIs
Export for Code Reviewjadx -p app.apk → Open app/ in IDE (Android Studio) for comfortable review