Android APK malware analysis — manifest permission review, smali disassembly, Java decompilation with jadx, dynamic instrumentation with Frida, network traffic interception, native library analysis, and automated scanning with MobSF.
80%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
High
Do not use without reviewing
Fix and improve this skill with Tessl
tessl review fix ./packages/decepticon/decepticon/skills/standard/reverser/android-malware/SKILL.mdFull analysis workflow for suspicious Android APKs — from static manifest review through dynamic instrumentation and C2 extraction.
# Decode APK resources and smali
apktool d <TARGET>.apk -o ./decoded/
# Decompile to Java source
jadx -d ./java_src/ <TARGET>.apk
# Quick permission audit
aapt dump permissions <TARGET>.apk
# Hash and signature check
sha256sum <TARGET>.apk
apksigner verify --print-certs <TARGET>.apk
# Automated scan
docker run -p 8000:8000 opensecurity/mobile-security-framework-mobsf
# Upload APK to http://localhost:8000
# List Frida processes on device
frida-ps -U| Technique | ID | How It Appears |
|---|---|---|
| Exploitation for Privilege Escalation | T1404 | Root exploits, DirtyCOW, Magisk abuse in APK payloads |
| Software Discovery | T1418 | Enumerating installed apps to detect security tools or targets |
| Input Capture | T1417 | Keyloggers, accessibility service abuse for credential capture |
| SMS/MMS Collection | T1636.004 | Banking trojans intercepting OTP SMS messages |
| Location Tracking | T1430 | Stalkerware GPS tracking via background services |
| Obfuscated Files | T1406 | ProGuard, DexGuard, string encryption, native packer |
| Application Layer Protocol | T1437 | C2 over HTTPS, Telegram bot API, Firebase messaging |
Unpack and examine the APK structure and manifest.
# Decode APK (keeps smali + resources)
apktool d <TARGET>.apk -o ./apk_decoded/
# Examine AndroidManifest.xml for suspicious permissions
cat ./apk_decoded/AndroidManifest.xml | grep -iE 'permission|receiver|service|provider'
# High-risk permissions to flag:
# SEND_SMS, RECEIVE_SMS, READ_SMS — SMS interception (banking trojans)
# READ_CONTACTS, READ_CALL_LOG — data exfiltration
# RECORD_AUDIO, CAMERA — spyware
# ACCESSIBILITY_SERVICE — overlay attacks, keylogging
# BIND_DEVICE_ADMIN — device admin abuse (ransomware)
# INSTALL_PACKAGES — dropper / sideloader
# REQUEST_IGNORE_BATTERY_OPTIMIZATIONS — persistent background service
# Check for accessibility service (major red flag for credential stealers)
grep -r "android.accessibilityservice" ./apk_decoded/AndroidManifest.xml
# List receivers (broadcast receivers for SMS, boot, etc.)
grep -A5 "receiver" ./apk_decoded/AndroidManifest.xml
# Check for native libraries
ls -la ./apk_decoded/lib/*/
# Certificate analysis
apksigner verify --print-certs -v <TARGET>.apk
# Self-signed with debug key? → highly suspicious
# Check: keytool -printcert -jarfile <TARGET>.apkRecover readable source from DEX bytecode.
# jadx — best-in-class Android decompiler
jadx -d ./java_src/ --show-bad-code <TARGET>.apk
# --show-bad-code includes methods that failed to decompile cleanly
# Search for key behaviors
grep -rn "SmsManager\|sendTextMessage\|getDefault()" ./java_src/
grep -rn "HttpURLConnection\|OkHttpClient\|Retrofit\|Volley" ./java_src/
grep -rn "getDeviceId\|getSubscriberId\|getLine1Number\|IMEI" ./java_src/
grep -rn "getInstalledPackages\|getInstalledApplications" ./java_src/
grep -rn "TelephonyManager\|PackageManager" ./java_src/
grep -rn "Runtime\.exec\|ProcessBuilder\|\"su\"" ./java_src/
grep -rn "DexClassLoader\|PathClassLoader\|InMemoryDexClassLoader" ./java_src/
grep -rn "crypto\|Cipher\|SecretKey\|AES\|DES" ./java_src/
grep -rn "AccessibilityService\|onAccessibilityEvent" ./java_src/
# Extract hardcoded URLs / IPs / domains
grep -rnE 'https?://[^\s"]+|[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' ./java_src/
# Alternative: dex2jar + JD-GUI
d2j-dex2jar <TARGET>.apk -o <TARGET>.jar
# Open <TARGET>.jar in JD-GUIFor obfuscated samples where jadx fails, work at smali level.
# Smali is already extracted by apktool in step 1
# Navigate to entry points
find ./apk_decoded/smali* -name "*.smali" | head -20
# Find the main activity
grep -r "android.intent.action.MAIN" ./apk_decoded/AndroidManifest.xml
# Then read the corresponding smali file
# Search for reflection (used to hide API calls)
grep -rn "Ljava/lang/reflect" ./apk_decoded/smali*/
grep -rn "invoke-virtual.*Method;->invoke" ./apk_decoded/smali*/
# Search for dynamic class loading (dropper behavior)
grep -rn "DexClassLoader\|InMemoryDexClassLoader" ./apk_decoded/smali*/
# Search for crypto operations
grep -rn "Ljavax/crypto" ./apk_decoded/smali*/
# Search for command execution (root exploits)
grep -rn "Runtime;->exec\|\"su\"" ./apk_decoded/smali*/
# Decode obfuscated strings — common pattern: XOR or Base64 in static init
grep -rn "const-string\|sget-object" ./apk_decoded/smali*/ | grep -i "Base64\|decode"Instrument the running APK to intercept behavior.
# Start Frida server on rooted device/emulator
adb push frida-server-<version>-android-<arch> /data/local/tmp/frida-server
adb shell "chmod 755 /data/local/tmp/frida-server && /data/local/tmp/frida-server &"
# List running apps
frida-ps -Ua
# Hook encryption calls to capture plaintext
frida -U -l hook_crypto.js -f <PACKAGE_NAME> --no-pause// hook_crypto.js — intercept javax.crypto.Cipher
Java.perform(function() {
var Cipher = Java.use("javax.crypto.Cipher");
Cipher.doFinal.overload("[B").implementation = function(input) {
console.log("[*] Cipher.doFinal called");
console.log(" Algorithm: " + this.getAlgorithm());
console.log(" Input: " + bytesToHex(input));
var result = this.doFinal(input);
console.log(" Output: " + bytesToHex(result));
return result;
};
// Hook URL connections for C2 traffic
var URL = Java.use("java.net.URL");
URL.$init.overload("java.lang.String").implementation = function(url) {
console.log("[*] URL: " + url);
return this.$init(url);
};
// Hook SMS sending
var SmsManager = Java.use("android.telephony.SmsManager");
SmsManager.sendTextMessage.implementation = function(dest, sc, text, sentPI, delPI) {
console.log("[!] SMS to: " + dest + " body: " + text);
// Don't actually send
// return this.sendTextMessage(dest, sc, text, sentPI, delPI);
};
});
function bytesToHex(bytes) {
var hex = [];
for (var i = 0; i < bytes.length; i++) {
hex.push(('0' + (bytes[i] & 0xFF).toString(16)).slice(-2));
}
return hex.join('');
}# SSL pinning bypass for traffic interception
frida -U -l ssl_bypass.js -f <PACKAGE_NAME> --no-pause
# Then proxy through Burp/mitmproxy on port 8080
# Trace all JNI calls (native ↔ Java bridge)
frida-trace -U -i "JNI_*" -f <PACKAGE_NAME># Set up transparent proxy on emulator
adb shell settings put global http_proxy <HOST_IP>:8080
# mitmproxy with Android CA installed
mitmproxy --mode transparent --listen-port 8080
# For certificate-pinned apps, use Frida SSL bypass first
# Then capture traffic in mitmproxy/Burp
# tcpdump on device (root required)
adb shell tcpdump -i any -w /sdcard/capture.pcap
adb pull /sdcard/capture.pcap
wireshark capture.pcap
# Analyze DNS queries
tshark -r capture.pcap -Y "dns.qr == 0" -T fields -e dns.qry.name | sort -u# List native libraries in APK
unzip -l <TARGET>.apk | grep "\.so$"
# Extract and analyze
unzip <TARGET>.apk lib/ -d ./native_libs/
# Identify architecture
file ./native_libs/lib/*/*.so
# Strings from native libs
strings -n 8 ./native_libs/lib/arm64-v8a/*.so | grep -iE 'http|socket|exec|system|decrypt|key|aes'
# Ghidra/IDA for full native RE
# Focus on: JNI_OnLoad, Java_<package>_<class>_<method> exports
readelf -s ./native_libs/lib/arm64-v8a/*.so | grep -i "java_\|jni_onload"
# Check for packer/protector in native code
# Bangcle, Qihoo 360, Baidu, Tencent packers wrap the real DEX
rabin2 -I ./native_libs/lib/arm64-v8a/*.so# Run MobSF
docker run -it --rm -p 8000:8000 opensecurity/mobile-security-framework-mobsf
# Upload via API
curl -F "file=@<TARGET>.apk" http://localhost:8000/api/v1/upload \
-H "Authorization: <API_KEY>"
# Get scan results
curl "http://localhost:8000/api/v1/scan" \
-X POST -d "scan_type=apk&file_name=<TARGET>.apk&hash=<FILE_HASH>" \
-H "Authorization: <API_KEY>"
# MobSF checks:
# - Manifest analysis (permissions, exported components)
# - Code analysis (hardcoded secrets, insecure APIs)
# - Binary analysis (native libs, packer detection)
# - CVSS scoring and compliance mapping| Tool | Purpose | Install |
|---|---|---|
| apktool | APK decode/rebuild (smali + resources) | github.com/iBotPeaches/Apktool |
| jadx | DEX → Java decompiler | github.com/skylot/jadx |
| Frida | Dynamic instrumentation framework | frida.re / pip install frida-tools |
| MobSF | Automated mobile app security scanner | github.com/MobSF/Mobile-Security-Framework-MobSF |
| dex2jar | DEX → JAR converter | github.com/pxb1988/dex2jar |
| Objection | Frida-powered runtime exploration | github.com/sensepost/objection |
| APKiD | APK packer/compiler detector | github.com/rednaga/APKiD |
| mitmproxy | HTTPS traffic interception | mitmproxy.org |
| Drozer | Android security assessment framework | github.com/WithSecureLabs/drozer |
| Indicator | Description | Detection |
|---|---|---|
| SEND_SMS + RECEIVE_SMS + INTERNET | SMS interceptor (banking trojan) | Manifest permission analysis |
| BIND_ACCESSIBILITY_SERVICE | Overlay/keylogger credential stealer | Manifest + smali accessibility handler |
| DexClassLoader usage | Dynamic code loading / dropper | jadx/grep for DexClassLoader |
Encrypted assets in /assets/ | Packed payload or hidden DEX | High entropy file in assets dir |
| Native JNI with obfuscated exports | Anti-analysis native packer | readelf -s + string analysis |
| Self-signed debug certificate | Non-Play-Store distribution | apksigner verify --print-certs |
| Root detection code (su, Magisk) | Anti-analysis / environment check | grep for "su", "magisk", "test-keys" |
| Issue | Resolution |
|---|---|
| jadx fails on obfuscated DEX | Use --show-bad-code; fall back to smali analysis |
| Multi-DEX APK | apktool handles automatically; jadx merges all DEX files |
| Split APK (APKS/XAPK) | Extract base APK + split APKs; analyze each |
| Native packer (Bangcle/360/Tencent) | Dump unpacked DEX from memory with Frida: frida-dexdump |
| SSL pinning blocks proxy | Frida SSL bypass script; patch smali checkServerTrusted |
| Emulator detection in malware | Use physical rooted device; patch emulator checks via Frida |
| Dropper loads payload from C2 | Intercept download URL via Frida URL hook; fetch payload separately |
| React Native / Flutter / Xamarin | Different analysis: RN → index.android.bundle; Flutter → libapp.so; Xamarin → DLLs in assemblies/ |
IF APK has suspicious permissions (SMS + Accessibility + Internet):
→ Full static analysis (manifest + jadx + strings)
→ Extract C2 URLs and hardcoded secrets
→ Dynamic analysis with Frida hooks on crypto/network/SMS
ELSE IF APK has native libraries with obfuscated exports:
→ Likely packed — dump real DEX with frida-dexdump
→ Analyze unpacked DEX with jadx
→ RE native lib with Ghidra for JNI logic
ELSE IF APK loads code dynamically (DexClassLoader):
→ Dropper — intercept payload download with Frida
→ Analyze second-stage DEX separately
ELSE:
→ Standard jadx decompilation
→ Behavioral analysis in MobSF
→ Network traffic capture for C2 identificationPurpleAILAB/Decepticon
49888ee
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.