Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Reverse engineers malicious Android APK files using JADX decompiler to analyze Java/Kotlin source code, identify malicious functionality including data theft, C2 communication, privilege escalation, and overlay attacks. Examines manifest permissions, receivers, services, and native libraries. Activates for requests involving Android malware analysis, APK reverse engineering, mobile malware investigation, or Android threat analysis.
.claude/skills/reverse-engineering-android-malware-with-jadx/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-09 | ✗→✓ | ▲ Improved | — | — |
| case-15 | ✗→✓ | ▲ Improved | — | — |
| case-14 | ✓→✓ | = Same ✓ | — | — |
| case-12 | ✓→✓ | = Same ✓ | — | — |
| case-21 | ✓→✓ | = Same ✓ | — | — |
Do not use for analyzing obfuscated native (.so) libraries within APKs; use Ghidra or IDA for native ARM binary analysis.
aapt2 and adb tools for APK inspectionandroguard library for automated APK analysisExamine the APK structure and AndroidManifest.xml:
bash# Get APK basic info aapt2 dump badging malware.apk # Extract AndroidManifest.xml apktool d malware.apk -o apk_extracted/ -f # Analyze permissions with androguard python3 << 'PYEOF' from androguard.core.apk import APK apk = APK("malware.apk") print(f"Package: {apk.get_package()}") print(f"App Name: {apk.get_app_name()}") print(f"Version: {apk.get_androidversion_name()}") print(f"Min SDK: {apk.get_min_sdk_version()}") print(f"Target SDK: {apk.get_target_sdk_version()}") # Dangerous permissions dangerous_perms = { "android.permission.READ_SMS": "SMS theft", "android.permission.RECEIVE_SMS": "SMS interception", "android.permission.SEND_SMS": "Premium SMS fraud", "android.permission.READ_CONTACTS": "Contact harvesting", "android.permission.READ_CALL_LOG": "Call log theft", "android.permission.RECORD_AUDIO": "Audio surveillance", "android.permission.CAMERA": "Camera surveillance", "android.permission.ACCESS_FINE_LOCATION": "Location tracking", "android.permission.READ_PHONE_STATE": "Device fingerprinting", "android.permission.SYSTEM_ALERT_WINDOW": "Overlay attacks", "android.permission.BIND_ACCESSIBILITY_SERVICE": "Full device control", "android.permission.REQUEST_INSTALL_PACKAGES": "Sideloading apps", "android.permission.BIND_DEVICE_ADMIN": "Device admin abuse", } print("\nDangerous Permissions:") for perm in apk.get_permissions(): if perm in dangerous_perms: print(f" [!] {perm}") print(f" Risk: {dangerous_perms[perm]}") elif "android.permission" in perm: print(f" [*] {perm}") # Components print("\nActivities:") for act in apk.get_activities(): print(f" {act}") print("\nServices:") for svc in apk.get_services(): print(f" {svc}") print("\nReceivers:") for rcv in apk.get_receivers(): print(f" {rcv}") PYEOF
Open the APK in JADX for Java/Kotlin source analysis:
bash# Open in JADX GUI jadx-gui malware.apk # Command-line decompilation for scripted analysis jadx -d jadx_output/ malware.apk --show-bad-code # Decompile with all options jadx -d jadx_output/ malware.apk \ --deobf \ --deobf-min 3 \ --deobf-max 64 \ --show-bad-code \ --threads-count 4 # The output directory structure: # jadx_output/ # sources/ <- Decompiled Java source code # com/malware/app/ # MainActivity.java # C2Service.java # SMSReceiver.java # resources/ <- Decoded resources (layouts, strings, assets) # AndroidManifest.xml # res/ # assets/
Search for suspicious code patterns in decompiled sources:
bash# Search for network communication grep -rn "HttpURLConnection\|OkHttpClient\|Retrofit\|Volley\|URL(" jadx_output/sources/ # Search for SMS operations grep -rn "SmsManager\|getDefault().sendTextMessage\|SMS_RECEIVED" jadx_output/sources/ # Search for overlay attack code grep -rn "SYSTEM_ALERT_WINDOW\|TYPE_APPLICATION_OVERLAY\|WindowManager.LayoutParams" jadx_output/sources/ # Search for accessibility service abuse grep -rn "AccessibilityService\|onAccessibilityEvent\|performAction" jadx_output/sources/ # Search for data exfiltration grep -rn "getDeviceId\|getSubscriberId\|getSimSerialNumber\|getLine1Number" jadx_output/sources/ # Search for crypto operations (key storage, encryption) grep -rn "SecretKeySpec\|Cipher.getInstance\|AES\|DES\|RSA" jadx_output/sources/ # Search for dynamic code loading grep -rn "DexClassLoader\|PathClassLoader\|loadDex\|loadClass" jadx_output/sources/ # Search for obfuscated strings and decryption grep -rn "Base64.decode\|decrypt\|decipher\|xor" jadx_output/sources/
Trace the network communication logic:
python# Automated C2 extraction from decompiled code import os import re jadx_dir = "jadx_output/sources" # Patterns for C2 URLs and IPs url_pattern = re.compile(r'https?://[^\s"\'<>]+') ip_pattern = re.compile(r'"(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})"') base64_pattern = re.compile(r'"([A-Za-z0-9+/]{20,}={0,2})"') urls = set() ips = set() b64_strings = set() for root, dirs, files in os.walk(jadx_dir): for fname in files: if fname.endswith('.java'): filepath = os.path.join(root, fname) with open(filepath, 'r', errors='ignore') as f: content = f.read() for match in url_pattern.finditer(content): urls.add(match.group()) for match in ip_pattern.finditer(content): ips.add(match.group(1)) for match in base64_pattern.finditer(content): b64_strings.add(match.group(1)) print("URLs found:") for u in urls: print(f" {u}") print("\nIP addresses:") for ip in ips: print(f" {ip}") # Decode Base64 strings import base64 print("\nDecoded Base64 strings:") for b64 in b64_strings: try: decoded = base64.b64decode(b64).decode('utf-8', errors='ignore') if any(c.isprintable() for c in decoded) and len(decoded) > 3: print(f" {b64[:30]}... -> {decoded[:100]}") except: pass
Check for native code that may contain additional malicious logic:
bash# List native libraries in the APK unzip -l malware.apk | grep "\.so$" # Extract native libraries unzip malware.apk "lib/*" -d apk_native/ # Check native library properties file apk_native/lib/armeabi-v7a/*.so readelf -d apk_native/lib/armeabi-v7a/*.so | grep NEEDED # Strings from native libraries strings apk_native/lib/armeabi-v7a/libpayload.so | grep -iE "(http|url|key|encrypt|password)" # For deep native analysis, import into Ghidra: # File -> Import -> Select .so file -> Select ARM architecture
Compile a comprehensive Android malware analysis report:
Analysis documentation should include:
- APK metadata (package name, version, signing certificate)
- Permission analysis with risk assessment
- Component analysis (activities, services, receivers, providers)
- Decompiled code walkthrough of malicious functions
- C2 communication protocol and endpoints
- Data exfiltration methods and targeted data types
- Persistence mechanisms (device admin, accessibility service)
- Evasion techniques (emulator detection, root detection)
- Extracted IOCs (C2 URLs, domains, IPs, signing certificate hash)| Term | Definition | |------|------------| | APK (Android Package) | Android application package format containing compiled DEX bytecode, resources, manifest, and native libraries | | DEX Bytecode | Dalvik Executable format containing compiled Java/Kotlin code; JADX converts this back to readable Java source | | Overlay Attack | Banking trojan technique displaying a fake UI layer over a legitimate banking app to steal credentials using SYSTEM_ALERT_WINDOW permission | | Accessibility Service Abuse | Malware registering as an accessibility service to capture screen content, perform actions, and prevent uninstallation | | Smali | Human-readable representation of DEX bytecode; intermediate representation between bytecode and Java used by apktool | | Dynamic Code Loading | Loading additional DEX code at runtime using DexClassLoader to hide malicious functionality from static analysis | | Device Admin Abuse | Malware requesting device administrator privileges to prevent uninstallation and perform device wipe threats |
Context: A banking trojan APK is distributed via SMS phishing targeting customers of a specific bank. The sample needs analysis to identify targeted banks, C2 infrastructure, and data theft mechanisms.
Approach:
Pitfalls:
ANDROID MALWARE ANALYSIS REPORT
==================================
APK File: update_bank.apk
Package: com.android.systemupdate
SHA-256: e3b0c44298fc1c149afbf4c8996fb924...
Version: 1.2.3
Min SDK: 21 (Android 5.0)
Signing Cert: SHA-256: abc123... (self-signed)
CLASSIFICATION
Family: Anubis Banking Trojan
Type: Banking Trojan / SMS Stealer / Keylogger
DANGEROUS PERMISSIONS
[!] RECEIVE_SMS - Intercepts incoming SMS (2FA theft)
[!] READ_SMS - Reads SMS messages
[!] SEND_SMS - Sends premium SMS
[!] SYSTEM_ALERT_WINDOW - Overlay attacks on banking apps
[!] BIND_ACCESSIBILITY - Full device control
[!] BIND_DEVICE_ADMIN - Prevents uninstallation
MALICIOUS COMPONENTS
Service: com.android.systemupdate.C2Service (C2 communication)
Receiver: com.android.systemupdate.SmsReceiver (SMS interception)
Activity: com.android.systemupdate.OverlayActivity (credential overlay)
TARGETED APPS (23 banking apps)
com.bank.example1, com.bank.example2, ...
C2 INFRASTRUCTURE
Primary: hxxps://c2-server[.]com/api/bot
Fallback: hxxps://backup-c2[.]net/api/bot
Protocol: HTTPS POST with JSON body
Bot ID: MD5(IMEI + Build.SERIAL)
EXTRACTED IOCs
Domains: c2-server[.]com, backup-c2[.]net
IPs: 185.220.101[.]42
URLs: hxxps://c2-server[.]com/api/bot
hxxps://c2-server[.]com/api/injects
Cert Hash: abc123def456...| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-18 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-19 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-02 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-07 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-22 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-04 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-08 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-17 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-03 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-14 | pass→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-06 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-10 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-16 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-13 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-09 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-01 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-20 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-05 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-11 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-12 | pass→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-15 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-21 | pass→pass | — | — | — | — | — | — | — | — | — | — | — | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted. The headline lift of 0 percentage points is the difference between those two pass rates over the 22 comparable cases. 1 case got worse with the skill loaded, and it is included in that figure.
The per-case answers from this run were removed by the retention sweep, so the case table below shows the verdicts without the text either arm produced. The counts above were recorded at the time and are unaffected. Answers are now kept for 180 days.
Other measured skills in the registry, with their headline benchmark lift.