CtrlK
BlogDocsLog inGet started
Tessl Logo
SkillPublic

reverser-android-malware

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.

Quality

80%

Does it follow best practices?

Run evals on this skill

Adds up to 20 points to the overall score

View guide
SecuritybySnyk

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.md
SKILL.md
Quality
Evals
Security

Android APK Malware Analysis

Full analysis workflow for suspicious Android APKs — from static manifest review through dynamic instrumentation and C2 extraction.

Quick Reference

# 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

MITRE ATT&CK Mapping

TechniqueIDHow It Appears
Exploitation for Privilege EscalationT1404Root exploits, DirtyCOW, Magisk abuse in APK payloads
Software DiscoveryT1418Enumerating installed apps to detect security tools or targets
Input CaptureT1417Keyloggers, accessibility service abuse for credential capture
SMS/MMS CollectionT1636.004Banking trojans intercepting OTP SMS messages
Location TrackingT1430Stalkerware GPS tracking via background services
Obfuscated FilesT1406ProGuard, DexGuard, string encryption, native packer
Application Layer ProtocolT1437C2 over HTTPS, Telegram bot API, Firebase messaging

1. Static Analysis — APK Structure

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>.apk

2. Decompile to Java

Recover 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-GUI

3. Smali Analysis

For 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"

4. Dynamic Analysis with Frida

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>

5. Network Traffic Analysis

# 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

6. Native Library Analysis

# 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

7. Automated Analysis with MobSF

# 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

Tools & Resources

ToolPurposeInstall
apktoolAPK decode/rebuild (smali + resources)github.com/iBotPeaches/Apktool
jadxDEX → Java decompilergithub.com/skylot/jadx
FridaDynamic instrumentation frameworkfrida.re / pip install frida-tools
MobSFAutomated mobile app security scannergithub.com/MobSF/Mobile-Security-Framework-MobSF
dex2jarDEX → JAR convertergithub.com/pxb1988/dex2jar
ObjectionFrida-powered runtime explorationgithub.com/sensepost/objection
APKiDAPK packer/compiler detectorgithub.com/rednaga/APKiD
mitmproxyHTTPS traffic interceptionmitmproxy.org
DrozerAndroid security assessment frameworkgithub.com/WithSecureLabs/drozer

Detection Signatures

IndicatorDescriptionDetection
SEND_SMS + RECEIVE_SMS + INTERNETSMS interceptor (banking trojan)Manifest permission analysis
BIND_ACCESSIBILITY_SERVICEOverlay/keylogger credential stealerManifest + smali accessibility handler
DexClassLoader usageDynamic code loading / dropperjadx/grep for DexClassLoader
Encrypted assets in /assets/Packed payload or hidden DEXHigh entropy file in assets dir
Native JNI with obfuscated exportsAnti-analysis native packerreadelf -s + string analysis
Self-signed debug certificateNon-Play-Store distributionapksigner verify --print-certs
Root detection code (su, Magisk)Anti-analysis / environment checkgrep for "su", "magisk", "test-keys"

Error Handling & Edge Cases

IssueResolution
jadx fails on obfuscated DEXUse --show-bad-code; fall back to smali analysis
Multi-DEX APKapktool 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 proxyFrida SSL bypass script; patch smali checkServerTrusted
Emulator detection in malwareUse physical rooted device; patch emulator checks via Frida
Dropper loads payload from C2Intercept download URL via Frida URL hook; fetch payload separately
React Native / Flutter / XamarinDifferent analysis: RN → index.android.bundle; Flutter → libapp.so; Xamarin → DLLs in assemblies/

Decision Gate

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 identification
Repository

PurpleAILAB/Decepticon

Path

packages/decepticon/decepticon/skills/standard/reverser/android-malware/SKILL.md

Last updated
First committed

Is this your skill?

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.