A practical guide to analyzing Android applications with Claude, OpenAI, Google Gemini, and VirusTotal — no sandbox required.
Press enter or click to view image in full size
Table of Contents
Why Another APK Analysis Tool?
Most Android malware analysis workflows look like this: upload the APK to a cloud sandbox, wait a few minutes, read a generic report, repeat. That works for known samples, but it breaks down when you’re dealing with novel obfuscated malware, internal corporate builds you can’t upload, or when you just need answers fast.
This tool takes a different approach: 100% local static analysis combined with your choice of AI provider to produce a structured, actionable report directly in your terminal. No uploads required, no sandboxes, no web dashboard.
What you get in a single run:
- Decoded manifest, permissions, components, certificates
- Network IOCs (URLs, IPs, domains, emails)
- Entropy-based detection of encrypted payloads
- YARA rule matching against known malware signatures
- Semantic component name analysis (e.g.
ServiceRAT→ C2 capability) - MITRE ATT&CK technique mapping
- VirusTotal cross-validation (optional)
- AI-generated executive summary + Frida hooking script
Installation
Requirements: Python 3.10+, Git.
git clone https://github.com/anpa1200/Android-Malware-Analysis
cd android_malware_analysis
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txtNote: The tool detects missing dependencies automatically. If you run
./analyzer.pyfrom your base Python environment, it will transparently re-execute itself inside the venv — no manual activation needed.
Configuration
Create config.yml in the project directory (or ~/.android_malware_analyzer.yml for global settings):
# AI provider: auto, claude, openai, google, ollama
# "auto" tries Claude → OpenAI → Google → Ollama
provider: auto
# Uncomment to pin a specific model:
# model: claude-opus-4-6
# API key (or set the env var instead):
# api_key: sk-ant-...
# VirusTotal key - silently skipped if absent:
# vt_key: your-vt-key-here
output_dir: reportsCLI flags always override the config file. Environment variables are also supported:
ANTHROPIC_API_KEY | Claude (Anthropic)
OPENAI_API_KEY | OpenAI (GPT-4o)
GOOGLE_API_KEY | Google Gemini
VT_API_KEY or VIRUSTOTAL_API_KEY | VirusTotal
Choosing Your AI Provider
The --provider / -p flag accepts: auto, claude, openai, google, ollama.
auto (default) — tries providers in order: Claude → OpenAI → Google → Ollama. If no API key is found for any cloud provider, it falls back to Ollama with a visible warning.
# Use Claude (best results for malware reasoning)
./analyzer.py analyze suspicious.apk -p claude
# Use OpenAI GPT-4o
./analyzer.py analyze suspicious.apk -p openai
# Use Google Gemini Flash (fast + free tier available)
./analyzer.py analyze suspicious.apk -p google
# Fully offline - no API key needed
./analyzer.py analyze suspicious.apk -p ollama
# Override model for any provider
./analyzer.py analyze suspicious.apk -p claude --model claude-sonnet-4-6Provider defaults:
- Claude →
claude-opus-4-6 - OpenAI →
gpt-4o - Google →
gemini-2.0-flash - Ollama →
qwen3:8b(or best available local model)
Analyzing a Single APK
./analyzer.py analyze malware.apkThat’s it. The tool runs four phases and prints results to the terminal.
Press enter or click to view image in full size
11:19:13 (base) andrey@andrey-lab android_malware_analysis ±|main ✗|→ python analyzer.py analyze /home/andrey/git_project/android_malware_analysis/samples/spynote.apk █████╗ ██████╗ ██╗ ██╗ █████╗ ███╗ ██╗ █████╗ ██╗ ██╗ ██╗███████╗██╗███████╗
██╔══██╗██╔══██╗██║ ██╔╝ ██╔══██╗████╗ ██║██╔══██╗██║ ╚██╗ ██╔╝██╔════╝██║██╔════╝
███████║██████╔╝█████╔╝ ███████║██╔██╗ ██║███████║██║ ╚████╔╝ ███████╗██║███████╗
██╔══██║██╔═══╝ ██╔═██╗ ██╔══██║██║╚██╗██║██╔══██║██║ ╚██╔╝ ╚════██║██║╚════██║
██║ ██║██║ ██║ ██╗ ██║ ██║██║ ╚████║██║ ██║███████╗██║ ███████║██║███████║
╚═╝ ╚═╝╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝╚═╝ ╚═══╝╚═╝ ╚═╝╚══════╝╚═╝ ╚══════╝╚═╝╚══════╝
Android APK Analysis Tool | AI-Powered | v2.0
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Phase 1: Static Analysis
╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── File Information ─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ │
│ File /home/andrey/git_project/android_malware_analysis/samples/spynote.apk │
│ Size 3868.3 KB (3,961,188 bytes) │
│ MD5 b2c5e29222f57cf91d30d37b8ec54cc3 │
│ SHA256 7129d6c57182f4e53a4fd0f6aac15de30ffc5bfa34bc639a19ee39d2856b3c07 │
│ Package elimination.kitchen.secured │
│ App Name GoosApp │
│ Version 19.81.41.19 (19814119) │
│ SDK min=21 target=29 │
│ │
╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
Phase 2: Threat Indicator Scoring
╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── Threat Assessment ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ │
│ Risk Level: 💀 CRITICAL (85/100) │
│ │
│ [██████████████████████████████████░░░░░░] │
│ │
│ Permissions: 100/100 │
│ Behavior: 100/100 │
│ Network: 35/100 │
│ Obfuscation: 0/100 │
│ │
│ Suspected: Spyware/Stalkerware │
╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
Threat Indicators
╭────────────┬──────────────────┬────────────────────────────────────┬──────────────────────────────────────────╮
│ Severity │ Category │ Indicator │ Evidence │
├────────────┼──────────────────┼────────────────────────────────────┼──────────────────────────────────────────┤
│ CRITICAL │ API Behavior │ Suspicious API: Device Admin │ Landroid/app/admin/DeviceAdminReceiver;… │
│ │ │ │ (i │
│ │ │ │ Landroid/app/admin/DeviceAdminReceiver;… │
├────────────┼──────────────────┼────────────────────────────────────┼──────────────────────────────────────────┤
│ CRITICAL │ Permissions │ Dangerous Permission Combo: │ android.permission.RECORD_AUDIO │
│ │ │ Spyware/Stalkerware │ android.permission.ACCESS_FINE_LOCATION │
├────────────┼──────────────────┼────────────────────────────────────┼──────────────────────────────────────────┤
│ HIGH │ Permissions │ Dangerous Permission: READ_SMS │ android.permission.READ_SMS │
├────────────┼──────────────────┼────────────────────────────────────┼──────────────────────────────────────────┤
│ HIGH │ Permissions │ Dangerous Permission: SEND_SMS │ android.permission.SEND_SMS │
├────────────┼──────────────────┼────────────────────────────────────┼──────────────────────────────────────────┤
│ HIGH │ Permissions │ Dangerous Permission: │ android.permission.READ_CALL_LOG │
│ │ │ READ_CALL_LOG │ │
├────────────┼──────────────────┼────────────────────────────────────┼──────────────────────────────────────────┤
│ HIGH │ Permissions │ Dangerous Permission: RECORD_AUDIO │ android.permission.RECORD_AUDIO │
├────────────┼──────────────────┼────────────────────────────────────┼──────────────────────────────────────────┤
│ HIGH │ Permissions │ Dangerous Permission: │ android.permission.ACCESS_FINE_LOCATION │
│ │ │ ACCESS_FINE_LOCATION │ │
├────────────┼──────────────────┼────────────────────────────────────┼──────────────────────────────────────────┤
│ HIGH │ Permissions │ Dangerous Permission: │ android.permission.SYSTEM_ALERT_WINDOW │
│ │ │ SYSTEM_ALERT_WINDOW │ │
├────────────┼──────────────────┼────────────────────────────────────┼──────────────────────────────────────────┤
│ HIGH │ Permissions │ Dangerous Permission: GET_ACCOUNTS │ android.permission.GET_ACCOUNTS │
├────────────┼──────────────────┼────────────────────────────────────┼──────────────────────────────────────────┤
│ HIGH │ Permissions │ Dangerous Permission: │ android.permission.DISABLE_KEYGUARD │
│ │ │ DISABLE_KEYGUARD │ │
├────────────┼──────────────────┼────────────────────────────────────┼──────────────────────────────────────────┤
│ HIGH │ Permissions │ Dangerous Permission: │ android.permission.REQUEST_INSTALL_PACK… │
│ │ │ REQUEST_INSTALL_PACKAGES │ │
├────────────┼──────────────────┼────────────────────────────────────┼──────────────────────────────────────────┤
│ HIGH │ API Behavior │ Suspicious API: Window Overlay │ Landroid/view/WindowManager;->addView │
│ │ │ │ (in Landroid │
│ │ │ │ Landroid/view/WindowManager;->addView │
│ │ │ │ (in Landroid │
├────────────┼──────────────────┼────────────────────────────────────┼──────────────────────────────────────────┤
│ HIGH │ API Behavior │ Suspicious API: Dynamic Code │ Ljava/lang/ClassLoader;->loadClass (in │
│ │ │ Loading │ Landroidx/f │
│ │ │ │ Ljava/lang/ClassLoader;->loadClass (in │
│ │ │ │ Landroidx/f │
├────────────┼──────────────────┼────────────────────────────────────┼──────────────────────────────────────────┤
│ HIGH │ API Behavior │ Suspicious API: Accessibility │ Landroid/view/accessibility/Accessibili… │
│ │ │ Service │ Landroid/view/accessibility/Accessibili… │
├────────────┼──────────────────┼────────────────────────────────────┼──────────────────────────────────────────┤
│ HIGH │ API Behavior │ Suspicious API: Native Execution │ Ljava/lang/Runtime;->exec (in │
│ │ │ │ Lelimination/kitchen │
│ │ │ │ Ljava/lang/Runtime;->exec (in │
│ │ │ │ Lelimination/kitchen │
├────────────┼──────────────────┼────────────────────────────────────┼──────────────────────────────────────────┤
│ HIGH │ API Behavior │ Suspicious API: Audio Recording │ Landroid/media/MediaRecorder;-><init> │
│ │ │ │ (in Lelimina │
│ │ │ │ Landroid/media/MediaRecorder;->setOutpu… │
│ │ │ │ (in L │
├────────────┼──────────────────┼────────────────────────────────────┼──────────────────────────────────────────┤
│ HIGH │ API Behavior │ Suspicious API: SMS Operations │ Landroid/telephony/SmsManager;->sendTex… │
│ │ │ │ (i │
├────────────┼──────────────────┼────────────────────────────────────┼──────────────────────────────────────────┤
│ HIGH │ Network │ Hardcoded IP Addresses │ 1.0.0.1 │
│ │ │ │ 1.1.1.1 │
├────────────┼──────────────────┼────────────────────────────────────┼──────────────────────────────────────────┤
│ HIGH │ Overlay/Keylog │ Overlay/Keylogger Strings │ overlay │
├────────────┼──────────────────┼────────────────────────────────────┼──────────────────────────────────────────┤
│ MEDIUM │ Permissions │ Dangerous Permission: CAMERA │ android.permission.CAMERA │
├────────────┼──────────────────┼────────────────────────────────────┼──────────────────────────────────────────┤
│ MEDIUM │ Permissions │ Dangerous Permission: │ android.permission.READ_CONTACTS │
│ │ │ READ_CONTACTS │ │
├────────────┼──────────────────┼────────────────────────────────────┼──────────────────────────────────────────┤
│ MEDIUM │ Permissions │ Dangerous Permission: │ android.permission.READ_EXTERNAL_STORAGE │
│ │ │ READ_EXTERNAL_STORAGE │ │
├────────────┼──────────────────┼────────────────────────────────────┼──────────────────────────────────────────┤
│ MEDIUM │ Permissions │ Dangerous Permission: │ android.permission.WRITE_EXTERNAL_STORA… │
│ │ │ WRITE_EXTERNAL_STORAGE │ │
├────────────┼──────────────────┼────────────────────────────────────┼──────────────────────────────────────────┤
│ MEDIUM │ Permissions │ Dangerous Permission: WAKE_LOCK │ android.permission.WAKE_LOCK │
├────────────┼──────────────────┼────────────────────────────────────┼──────────────────────────────────────────┤
│ MEDIUM │ Permissions │ Dangerous Permission: │ android.permission.RECEIVE_BOOT_COMPLET… │
│ │ │ RECEIVE_BOOT_COMPLETED │ │
├────────────┼──────────────────┼────────────────────────────────────┼──────────────────────────────────────────┤
│ MEDIUM │ Permissions │ Dangerous Permission: │ android.permission.FOREGROUND_SERVICE │
│ │ │ FOREGROUND_SERVICE │ │
├────────────┼──────────────────┼────────────────────────────────────┼──────────────────────────────────────────┤
│ MEDIUM │ Permissions │ Dangerous Permission: │ android.permission.READ_PHONE_STATE │
│ │ │ READ_PHONE_STATE │ │
├────────────┼──────────────────┼────────────────────────────────────┼──────────────────────────────────────────┤
│ MEDIUM │ Permissions │ Dangerous Permission: │ android.permission.CHANGE_WIFI_STATE │
│ │ │ CHANGE_WIFI_STATE │ │
├────────────┼──────────────────┼────────────────────────────────────┼──────────────────────────────────────────┤
│ MEDIUM │ API Behavior │ Suspicious API: Reflection │ Ljava/lang/reflect/Method;->invoke (in │
│ │ │ │ Landroidx/a │
│ │ │ │ Ljava/lang/reflect/Method;->invoke (in │
│ │ │ │ Landroidx/a │
├────────────┼──────────────────┼────────────────────────────────────┼──────────────────────────────────────────┤
│ MEDIUM │ API Behavior │ Suspicious API: Location Tracking │ Landroid/location/LocationManager;->get… │
│ │ │ │ Landroid/location/LocationManager;->req… │
├────────────┼──────────────────┼────────────────────────────────────┼──────────────────────────────────────────┤
│ MEDIUM │ API Behavior │ Suspicious API: Camera Access │ Landroid/hardware/Camera;->getParameters │
│ │ │ │ (in Lelim │
│ │ │ │ Landroid/hardware/Camera;->open (in │
│ │ │ │ Lelimination/k │
├────────────┼──────────────────┼────────────────────────────────────┼──────────────────────────────────────────┤
│ LOW │ API Behavior │ Suspicious API: Cryptography │ Ljavax/crypto/spec/SecretKeySpec;-><ini… │
│ │ │ │ (in Leli │
│ │ │ │ Ljavax/crypto/Cipher;->doFinal (in │
│ │ │ │ Lelimination/ki │
├────────────┼──────────────────┼────────────────────────────────────┼──────────────────────────────────────────┤
│ INFO │ API Behavior │ Suspicious API: Network │ Ljava/net/SocketImpl;-><init> (in │
│ │ │ Communication │ Landroidx/core/n │
│ │ │ │ Ljava/net/Socket;-><init> (in │
│ │ │ │ Landroidx/core/net/D │
╰────────────┴──────────────────┴────────────────────────────────────┴──────────────────────────────────────────╯
Permissions (31 total)
Permission Risk
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
android.permission.ACCESS_COARSE_LOCATION MEDIUM
android.permission.ACCESS_FINE_LOCATION CRITICAL
android.permission.CALL_PHONE MEDIUM
android.permission.CAMERA MEDIUM
android.permission.CHANGE_WIFI_STATE MEDIUM
android.permission.DISABLE_KEYGUARD HIGH
android.permission.FOREGROUND_SERVICE MEDIUM
android.permission.GET_ACCOUNTS HIGH
android.permission.READ_CALL_LOG HIGH
android.permission.READ_CONTACTS CRITICAL
android.permission.READ_EXTERNAL_STORAGE MEDIUM
android.permission.READ_PHONE_STATE MEDIUM
android.permission.READ_SMS HIGH
android.permission.RECEIVE_BOOT_COMPLETED MEDIUM
android.permission.RECORD_AUDIO CRITICAL
android.permission.REQUEST_INSTALL_PACKAGES HIGH
android.permission.SEND_SMS HIGH
android.permission.SYSTEM_ALERT_WINDOW HIGH
android.permission.WAKE_LOCK MEDIUM
android.permission.WRITE_EXTERNAL_STORAGE MEDIUM
android.permission.ACCESS_NETWORK_STATE INFO
android.permission.ACCESS_WIFI_STATE INFO
android.permission.INTERNET INFO
android.permission.REQUEST_DELETE_PACKAGES INFO
android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS INFO
android.permission.SET_WALLPAPER INFO
android.permission.USE_FULL_SCREEN_INTENT INFO
com.android.alarm.permission.SET_ALARM INFO
com.huawei.permission.external_app_settings.USE_COMPONENT INFO
oplus.permission.OPLUS_COMPONENT_SAFE INFO
... and 1 more normal permissions INFO
Network IOCs
Type Value
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
IP 1.0.0.1
IP 1.1.1.1
IP 8.8.4.4
IP 8.8.8.8
IP 362.0.0.27
Domain schemas.android.com
URL http://schemas.android.com/apk/res/android
Semantic Component Analysis (3 findings)
Severity Component Capability MITRE Name
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
CRITICAL receiver Device Administrator Abuse T1629 AdminReceiver
HIGH string Webinject/Overlay Terms T1417 Overlay
HIGH string Root/Superuser Access T1626 Root
Rule-based family inference: Banking Trojan / RAT (confidence: 60%)
Phase 2c: VirusTotal Lookup
╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── VirusTotal Report ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ │
│ Detection 29/76 (29 malicious, 0 suspicious, 37 clean) │
│ Threat Label trojan.spymax/spynote │
│ Families spymax, spynote, andr │
│ File Type Android │
│ Common Name 7129d6c57182f4e53a4fd0f6aac15de30ffc5bfa34bc639a19ee39d2856b3c07.apk │
│ First Seen 2024-03-10 │
│ Last Analyzed 2025-11-18 │
│ Submissions 19 submissions / 7 unique sources │
│ Tags [apk] [telephony] [android] [sends-sms] [reflection] [detect-debug-environment] [checks-gps] │
│ VT Link https://www.virustotal.com/gui/file/7129d6c57182f4e53a4fd0f6aac15de30ffc5bfa34bc639a19ee39d2856b3c07 │
│ │
╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── Submitted As ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ 7129d6c57182f4e53a4fd0f6aac15de30ffc5bfa34bc639a19ee39d2856b3c07.apk | 1.apk | ta0w2mi9g.exe | sample_01.apk | GoosApp_base.apk │
╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
AV Engine Detections — 29 malicious / 0 suspicious / 76 total
╭──────────────────────┬───────────────────────────────────────┬──────────────╮
│ Engine │ Detection Name │ Verdict │
├──────────────────────┼───────────────────────────────────────┼──────────────┤
│ DrWeb │ Android.SpyMax.291 │ MALICIOUS │
├──────────────────────┼───────────────────────────────────────┼──────────────┤
│ ESET-NOD32 │ Android/Spy.SpyMax.T trojan │ MALICIOUS │
├──────────────────────┼───────────────────────────────────────┼──────────────┤
│ F-Secure │ Malware.ANDROID/SpyMax.FHPV.Gen │ MALICIOUS │
├──────────────────────┼───────────────────────────────────────┼──────────────┤
│ Fortinet │ Android/SpyMax.EV!tr │ MALICIOUS │
├──────────────────────┼───────────────────────────────────────┼──────────────┤
│ Kaspersky │ HEUR:Trojan-Banker.AndroidOS.Agent.ws │ MALICIOUS │
├──────────────────────┼───────────────────────────────────────┼──────────────┤
│ Sophos │ Andr/Xgen2-AOO │ MALICIOUS │
├──────────────────────┼───────────────────────────────────────┼──────────────┤
│ Symantec │ Trojan.Gen.MBT │ MALICIOUS │
├──────────────────────┼───────────────────────────────────────┼──────────────┤
│ AhnLab-V3 │ Trojan/Android.SpyNM.1254825 │ MALICIOUS │
├──────────────────────┼───────────────────────────────────────┼──────────────┤
│ Alibaba │ TrojanSpy:Android/Spynote.374f212d │ MALICIOUS │
├──────────────────────┼───────────────────────────────────────┼──────────────┤
│ Avast-Mobile │ Android:Evo-gen [Trj] │ MALICIOUS │
├──────────────────────┼───────────────────────────────────────┼──────────────┤
│ Avira │ ANDROID/SpyMax.FHPV.Gen │ MALICIOUS │
├──────────────────────┼───────────────────────────────────────┼──────────────┤
│ BitDefenderFalx │ Android.Trojan.SpyAgent.LZ │ MALICIOUS │
├──────────────────────┼───────────────────────────────────────┼──────────────┤
│ CTX │ apk.trojan.spymax │ MALICIOUS │
├──────────────────────┼───────────────────────────────────────┼──────────────┤
│ Cynet │ Malicious (score: 99) │ MALICIOUS │
├──────────────────────┼───────────────────────────────────────┼──────────────┤
│ Google │ Detected │ MALICIOUS │
├──────────────────────┼───────────────────────────────────────┼──────────────┤
│ Ikarus │ Trojan-Spy.AndroidOS.Spymax │ MALICIOUS │
├──────────────────────┼───────────────────────────────────────┼──────────────┤
│ K7GW │ Trojan ( 005a5d9c1 ) │ MALICIOUS │
├──────────────────────┼───────────────────────────────────────┼──────────────┤
│ Kingsoft │ Android.Troj.SpyMax.e │ MALICIOUS │
├──────────────────────┼───────────────────────────────────────┼──────────────┤
│ Lionic │ Trojan.AndroidOS.SpyMax.C!c │ MALICIOUS │
├──────────────────────┼───────────────────────────────────────┼──────────────┤
│ NANO-Antivirus │ Trojan.Android.SpyMax.kklyjl │ MALICIOUS │
╰──────────────────────┴───────────────────────────────────────┴──────────────╯
Sandbox Verdicts
Sandbox Verdict Malware Names
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Zenbox android MALICIOUS SpyNote
Phase 3: YARA Scanning
YARA: 3 rule(s) matched
╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ Rule: Dropper_DexClassLoader │
│ Desc: Dynamic DEX loading - dropper/loader behavior │
│ Category: Dropper │
│ MITRE: T1544 │
│ Matched: DexClassLoader, http, https │
╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ Rule: SMSFraud_PremiumRate │
│ Desc: SMS fraud sending to premium rate numbers │
│ Category: Financial Fraud │
│ MITRE: T1582 │
│ Matched: sendTextMessage, SmsManager │
╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ Rule: AntiAnalysis_EmulatorCheck │
│ Desc: Anti-analysis emulator detection │
│ Category: Evasion │
│ MITRE: T1633 │
│ Matched: goldfish, Genymotion, Android SDK │
╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
Phase 4: AI Analysis (Claude/claude-opus-4-6)
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── AI Analysis Results ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ Classification: RAT | Family: SpyNote/SpyMax | Confidence: High │
╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── Executive Summary ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ This is a SpyNote/SpyMax Remote Access Trojan (RAT) disguised as 'GoosApp'. It provides an attacker with complete remote control over an infected Android device including real-time audio surveillance, SMS interception (including banking OTPs), camera access, GPS tracking, keystroke logging via accessibility │
│ services, and overlay-based credential phishing. The multi-language social engineering strings (Arabic, Russian, Chinese, Burmese, Turkish) indicate a globally distributed campaign targeting victims across multiple regions. │
╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── Technical Analysis ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ The APK package name 'elimination.kitchen.secured' follows the randomized three-word pattern commonly generated by SpyNote builder tools. All component names under the subpackage 'pceudkwhpxxxosuyjcduknhpxugjttkfgpvmujxufydwbdhwri2.gdflvwzqcjwsyigjsmgjolyskkyyhnfrhdsyyrxpmdzmoavvhj6' exhibit extreme obfuscation │
│ with long random consonant strings appended with short alphanumeric suffixes — this is the signature naming convention of the SpyNote v6+ builder. Despite the obfuscation score reading 0 (likely a tool limitation), the component naming itself constitutes heavy obfuscation. │
│ │
│ The accessibility service component (service 'nSsAP24') implements onAccessibilityEvent() and contains references to button clicking ('android:id/button1'), deletion commands ('silmek' — Turkish for 'delete'), action dispatching ('[action]'), and home accessibility updates ('updateHomeAccessibility'). This │
│ service is the core of SpyNote's keylogging and UI automation capability — it monitors all foreground accessibility events, captures text input, and can programmatically click UI elements to auto-grant permissions, disable Play Protect, and interact with banking applications. │
│ │
│ The AdminReceiver component enables Device Administrator privileges, providing wipe-protection and making the malware extremely difficult to uninstall without factory reset. Combined with SYSTEM_ALERT_WINDOW for overlay attacks, READ_SMS/SEND_SMS for OTP interception and SMS fraud, RECORD_AUDIO for live │
│ microphone surveillance, CAMERA for covert photo/video capture, and ACCESS_FINE_LOCATION for GPS tracking, this sample implements the full SpyNote capability set. │
│ │
│ The YARA match for DexClassLoader-based dynamic loading combined with ClassLoader.loadClass() API calls indicates the sample may fetch and load additional DEX payloads at runtime — a common SpyNote technique for modular capability deployment. The emulator detection YARA match confirms anti-analysis measures. The │
│ certificate uses the default Android debug signing identity ([email protected]), which is characteristic of SpyNote builder output where operators do not bother with custom certificates. │
│ │
│ The high-entropy strings in Arabic ('فتح نوافذ جديدة أثناء التشغيل في الخلفية' = 'Open new windows while running in background', 'تمكين الإظهار فوق التطبيقات' = 'Enable display over apps'), Russian ('Не оптимизировать' = 'Do not optimize', 'Настройки системы' = 'System settings'), Chinese ('启用 Simple keyboard │
│ 以获得更好的性能' = 'Enable Simple keyboard for better performance'), and Burmese characters reveal the accessibility service's social engineering — it guides victims in multiple languages to grant overlay permissions, disable battery optimization, and enable the malicious accessibility service. │
╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── Primary Capabilities ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ │
│ ► Full remote device control (RAT) │
│ ► Accessibility-based keylogging and UI automation │
│ ► SMS interception and OTP theft │
│ ► Premium-rate SMS fraud │
│ ► Real-time audio surveillance (microphone recording) │
│ ► Camera capture (photo/video) │
│ ► GPS location tracking │
│ ► Overlay/webinject credential phishing │
│ ► Device Administrator abuse for persistence │
│ ► Call log and contact harvesting │
│ ► Dynamic DEX loading for modular payload deployment │
│ ► Emulator/sandbox detection │
│ ► File system access (read/write external storage) │
│ │
╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
ID Technique Tactic Relevance
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
T1629.001 Impair Defenses: Prevent Defense Evasion AdminReceiver device administrator prevents uninstallation;
Application Removal
T1417.001 Input Capture: Keylogging Collection Accessibility service (nSsAP24) with onAccessibilityEvent ha
T1417.002 Input Capture: GUI Input Collection Overlay capability via SYSTEM_ALERT_WINDOW permission for ph
Capture
T1636.004 Protected User Data: SMS Collection READ_SMS permission for OTP interception; SEND_SMS for premi
Messages
T1429 Audio Capture Collection RECORD_AUDIO permission enables real-time microphone surveil
T1512 Video Capture Collection CAMERA permission for covert photo/video capture
T1430 Location Tracking Collection ACCESS_FINE_LOCATION + LocationManager.getLastKnownLocation
T1636.002 Protected User Data: Call Logs Collection READ_CALL_LOG permission for call history exfiltration
T1636.003 Protected User Data: Contact Collection READ_CONTACTS permission for contact harvesting
List
T1544 Ingress Tool Transfer Command and Control DexClassLoader dynamic DEX loading confirmed by YARA for dow
T1633.001 Virtualization/Sandbox Defense Evasion Emulator detection confirmed by YARA AntiAnalysis_EmulatorCh
Evasion: System Checks
T1626.001 Abuse Elevation Control Privilege Escalation AdminReceiver component explicitly registered for device adm
Mechanism: Device
Administrator
╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── IOCs for Threat Hunting ─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ • sha256:7129d6c57182f4e53a4fd0f6aac15de30ffc5bfa34bc639a19ee39d2856b3c07 │
│ • md5:b2c5e29222f57cf91d30d37b8ec54cc3 │
│ • package:elimination.kitchen.secured │
│ • app_name:GoosApp │
│ • cert_sha256:465983f7791f2abeb43ea2cbdc7f21a8260b72bc08a55c839fc1a43bc741a81e │
│ • receiver:elimination.kitchen.AdminReceiver │
│ • accessibility_service:gdflvwzqcjwsyigjsmgjolyskkyyhnfrhdsyyrxpmdzmoavvhj6nSsAP24 │
│ • dns:1.1.1.1 │
│ • dns:1.0.0.1 │
│ • dns:8.8.8.8 │
│ • dns:8.8.4.4 │
│ • family:SpyNote/SpyMax │
╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── Remediation Steps ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ 1. 1. IMMEDIATELY boot into Safe Mode and navigate to Settings → Security → Device Administrators. Deactivate the AdminReceiver to allow uninstallation. │
│ 2. 2. If device admin cannot be deactivated, perform a FACTORY RESET — SpyNote's accessibility service will auto-reactivate admin if attempted in normal mode. │
│ 3. 3. Change ALL passwords for banking, email, social media, and any other accounts accessed from the device — assume all credentials are compromised. │
│ 4. 4. Contact your bank immediately to report potential OTP interception and request temporary account freeze and new 2FA tokens. │
│ 5. 5. Check SMS history for unauthorized premium-rate messages and dispute charges with carrier. │
│ 6. 6. Scan all other devices on the same network — SpyNote operators often target multiple devices. │
│ 7. 7. Report the APK hash to Google Play Protect via the Android Security team. │
│ 8. 8. Enable Google Play Protect and ensure 'Scan apps with Play Protect' is re-enabled (SpyNote may have disabled it). │
│ 9. 9. Consider the device physically compromised for location data — if personal safety is a concern, assume your location history has been tracked. │
│ 10. 10. File a report with local law enforcement cybercrime unit including the SHA256 hash and any distribution URL. │
╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── Frida Hooks for Dynamic Analysis ─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ 1 // SpyNote/SpyMax RAT Frida Hook Suite for elimination.kitchen.secured │
│ 2 // Run: frida -U -f elimination.kitchen.secured -l spynote_hooks.js --no-pause │
│ 3 │
│ 4 Java.perform(function() { │
│ 5 console.log('[*] SpyNote/SpyMax Frida Hook Suite Loaded'); │
│ 6 console.log('[*] Target: elimination.kitchen.secured (GoosApp)'); │
│ 7 │
│ 8 // ============================================================ │
│ 9 // HOOK 1: Accessibility Service - Capture all accessibility events │
│ 10 // The core keylogging/UI automation service (nSsAP24) │
│ 11 // ============================================================ │
│ 12 try { │
│ 13 var AccessibilityService = Java.use('android.accessibilityservice.AccessibilityService'); │
│ 14 AccessibilityService.onAccessibilityEvent.implementation = function(event) { │
│ 15 if (event != null) { │
│ 16 var eventType = event.getEventType(); │
│ 17 var packageName = event.getPackageName(); │
│ 18 var text = event.getText(); │
│ 19 var className = event.getClassName(); │
│ 20 console.log('[ACCESSIBILITY] Type: ' + eventType + │
│ 21 ' | Pkg: ' + packageName + │
│ 22 ' | Class: ' + className + │
│ 23 ' | Text: ' + text); │
│ 24 // Log TYPE_VIEW_TEXT_CHANGED (keylogging) │
│ 25 if (eventType === 16) { │
│ 26 console.log('[KEYLOG] Text changed in ' + packageName + ': ' + text); │
│ 27 } │
│ 28 } │
│ 29 this.onAccessibilityEvent(event); │
│ 30 }; │
│ 31 console.log('[+] Hooked AccessibilityService.onAccessibilityEvent'); │
│ 32 } catch(e) { │
│ 33 console.log('[-] AccessibilityService hook failed: ' + e); │
│ 34 } │
│ 35 │
│ 36 // ============================================================ │
│ 37 // HOOK 2: GestureDescription.Builder - Detect programmatic taps │
│ 38 // SpyNote uses this to auto-click UI elements │
│ 39 // ============================================================ │
│ 40 try { │
│ 41 var GestureBuilder = Java.use('android.accessibilityservice.GestureDescription$Builder'); │
│ 42 GestureBuilder.build.implementation = function() { │
│ 43 console.log('[GESTURE] GestureDescription.Builder.build() called - SpyNote automating UI interaction'); │
│ 44 console.log('[GESTURE] Stack: ' + Java.use('android.util.Log').getStackTraceString(Java.use('java.lang.Exception').$new())); │
│ 45 return this.build(); │
│ 46 }; │
│ 47 console.log('[+] Hooked GestureDescription.Builder.build'); │
│ 48 } catch(e) { │
│ 49 console.log('[-] GestureBuilder hook failed: ' + e); │
│ 50 } │
│ 51 │
│ 52 // ============================================================ │
│ 53 // HOOK 3: SMS Interception - Capture all SMS read/send operations │
│ 54 // SpyNote steals OTPs and sends premium-rate SMS │
│ 55 // ============================================================ │
│ 56 try { │
│ 57 var SmsManager = Java.use('android.telephony.SmsManager'); │
│ 58 SmsManager.sendTextMessage.overload('java.lang.String', 'java.lang.String', 'java.lang.String', 'android.app.PendingIntent', 'android.app.PendingIntent').implementation = function(dest, sc, text, sentIntent, deliveryIntent) { │
│ 59 console.log('[SMS-SEND] Destination: ' + dest + ' | Text: ' + text); │
│ 60 console.log('[SMS-SEND] WARNING: Possible premium-rate SMS fraud!'); │
│ 61 // Block the SMS send to prevent financial damage │
│ 62 // Uncomment next line to block: return; │
│ 63 this.sendTextMessage(dest, sc, text, sentIntent, deliveryIntent); │
│ 64 }; │
│ 65 console.log('[+] Hooked SmsManager.sendTextMessage'); │
│ 66 } catch(e) { │
│ 67 console.log('[-] SmsManager hook failed: ' + e); │
│ 68 } │
│ 69 │
│ 70 // ============================================================ │
│ 71 // HOOK 4: Overlay/Window Injection - Capture phishing overlays │
│ 72 // Detects when SpyNote draws over banking apps │
│ 73 // ============================================================ │
│ 74 try { │
│ 75 var WindowManager = Java.use('android.view.WindowManager$LayoutParams'); │
│ 76 var WindowManagerImpl = Java.use('android.view.WindowManagerImpl'); │
│ 77 WindowManagerImpl.addView.implementation = function(view, params) { │
│ 78 if (params != null) { │
│ 79 var type = params.type.value; │
│ 80 var flags = params.flags.value; │
│ 81 console.log('[OVERLAY] WindowManager.addView() | Type: ' + type + ' | Flags: ' + flags); │
│ 82 if (type === 2038 || type === 2002 || type === 2010) { │
│ 83 console.log('[OVERLAY] ALERT: System overlay window created - possible phishing injection!'); │
│ 84 console.log('[OVERLAY] View class: ' + view.getClass().getName()); │
│ 85 } │
│ 86 } │
│ 87 this.addView(view, params); │
│ 88 }; │
│ 89 console.log('[+] Hooked WindowManagerImpl.addView'); │
│ 90 } catch(e) { │
│ 91 console.log('[-] WindowManager hook failed: ' + e); │
│ 92 } │
│ 93 │
│ 94 // ============================================================ │
│ 95 // HOOK 5: Audio Recording - Detect microphone surveillance │
│ 96 // ============================================================ │
│ 97 try { │
│ 98 var MediaRecorder = Java.use('android.media.MediaRecorder'); │
│ 99 MediaRecorder.start.implementation = function() { │
│ 100 console.log('[AUDIO] MediaRecorder.start() - Microphone recording initiated!'); │
│ 101 console.log('[AUDIO] Stack: ' + Java.use('android.util.Log').getStackTraceString(Java.use('java.lang.Exception').$new())); │
│ 102 this.start(); │
│ 103 }; │
│ 104 console.log('[+] Hooked MediaRecorder.start'); │
│ 105 │
│ 106 var AudioRecord = Java.use('android.media.AudioRecord'); │
│ 107 AudioRecord.startRecording.implementation = function() { │
│ 108 console.log('[AUDIO] AudioRecord.startRecording() - Low-level audio capture started!'); │
│ 109 this.startRecording(); │
│ 110 }; │
│ 111 console.log('[+] Hooked AudioRecord.startRecording'); │
│ 112 } catch(e) { │
│ 113 console.log('[-] Audio hook failed: ' + e); │
│ 114 } │
│ 115 │
│ 116 // ============================================================ │
│ 117 // HOOK 6: Camera Capture - Detect covert photography │
│ 118 // ============================================================ │
│ 119 try { │
│ 120 var Camera = Java.use('android.hardware.Camera'); │
│ 121 Camera.open.overload('int').implementation = function(cameraId) { │
│ 122 console.log('[CAMERA] Camera.open(id=' + cameraId + ') - Covert camera access!'); │
│ 123 return this.open(cameraId); │
│ 124 }; │
│ 125 console.log('[+] Hooked Camera.open'); │
│ 126 } catch(e) { │
│ 127 console.log('[-] Camera hook failed: ' + e); │
│ 128 } │
│ 129 │
│ 130 try { │
│ 131 var CameraManager = Java.use('android.hardware.camera2.CameraManager'); │
│ 132 CameraManager.openCamera.overload('java.lang.String', 'android.hardware.camera2.CameraDevice$StateCallback', 'android.os.Handler').implementation = function(cameraId, callback, handler) { │
│ 133 console.log('[CAMERA2] CameraManager.openCamera(id=' + cameraId + ') - Camera2 API access!'); │
│ 134 this.openCamera(cameraId, callback, handler); │
│ 135 }; │
│ 136 console.log('[+] Hooked CameraManager.openCamera'); │
│ 137 } catch(e) { │
│ 138 console.log('[-] Camera2 hook failed: ' + e); │
│ 139 } │
│ 140 │
│ 141 // ============================================================ │
│ 142 // HOOK 7: Location Tracking - Capture GPS exfiltration │
│ 143 // ============================================================ │
│ 144 try { │
│ 145 var LocationManager = Java.use('android.location.LocationManager'); │
│ 146 LocationManager.getLastKnownLocation.implementation = function(provider) { │
│ 147 var location = this.getLastKnownLocation(provider); │
│ 148 if (location != null) { │
│ 149 console.log('[LOCATION] getLastKnownLocation(' + provider + ') = Lat: ' + │
│ 150 location.getLatitude() + ', Lon: ' + location.getLongitude()); │
│ 151 } │
│ 152 return location; │
│ 153 }; │
│ 154 console.log('[+] Hooked LocationManager.getLastKnownLocation'); │
│ 155 } catch(e) { │
│ 156 console.log('[-] Location hook failed: ' + e); │
│ 157 } │
│ 158 │
│ 159 // ============================================================ │
│ 160 // HOOK 8: Dynamic Class Loading - Detect payload drops │
│ 161 // SpyNote loads additional DEX modules at runtime │
│ 162 // ============================================================ │
│ 163 try { │
│ 164 var DexClassLoader = Java.use('dalvik.system.DexClassLoader'); │
│ 165 DexClassLoader.$init.implementation = function(dexPath, optimizedDir, librarySearchPath, parent) { │
│ 166 console.log('[DEX-LOAD] DexClassLoader loading: ' + dexPath); │
│ 167 console.log('[DEX-LOAD] Optimized dir: ' + optimizedDir); │
│ 168 this.$init(dexPath, optimizedDir, librarySearchPath, parent); │
│ 169 }; │
│ 170 console.log('[+] Hooked DexClassLoader.$init'); │
│ 171 │
│ 172 var ClassLoader = Java.use('java.lang.ClassLoader'); │
│ 173 ClassLoader.loadClass.overload('java.lang.String').implementation = function(name) { │
│ 174 if (name.indexOf('elimination.kitchen') !== -1) { │
│ 175 console.log('[CLASS-LOAD] Loading: ' + name); │
│ 176 } │
│ 177 return this.loadClass(name); │
│ 178 }; │
│ 179 console.log('[+] Hooked ClassLoader.loadClass'); │
│ 180 } catch(e) { │
│ 181 console.log('[-] ClassLoader hook failed: ' + e); │
│ 182 } │
│ 183 │
│ 184 // ============================================================ │
│ 185 // HOOK 9: Network Connections - Capture C2 communications │
│ 186 // SpyNote uses raw TCP sockets for C2 │
│ 187 // ============================================================ │
│ 188 try { │
│ 189 var Socket = Java.use('java.net.Socket'); │
│ 190 Socket.$init.overload('java.lang.String', 'int').implementation = function(host, port) { │
│ 191 console.log('[C2-SOCKET] Socket connecting to: ' + host + ':' + port); │
│ 192 this.$init(host, port); │
│ 193 }; │
│ 194 Socket.$init.overload('java.net.InetAddress', 'int').implementation = function(addr, port) { │
│ 195 console.log('[C2-SOCKET] Socket connecting to: ' + addr.getHostAddress() + ':' + port); │
│ 196 this.$init(addr, port); │
│ 197 }; │
│ 198 console.log('[+] Hooked Socket.$init'); │
│ 199 │
│ 200 var URL = Java.use('java.net.URL'); │
│ 201 URL.$init.overload('java.lang.String').implementation = function(url) { │
│ 202 console.log('[NET-URL] URL created: ' + url); │
│ 203 this.$init(url); │
│ 204 }; │
│ 205 console.log('[+] Hooked URL.$init'); │
│ 206 } catch(e) { │
│ 207 console.log('[-] Network hook failed: ' + e); │
│ 208 } │
│ 209 │
│ 210 // ============================================================ │
│ 211 // HOOK 10: Reflection Calls - Detect hidden API invocations │
│ 212 // SpyNote uses reflection to evade static analysis │
│ 213 // ============================================================ │
│ 214 try { │
│ 215 var Method = Java.use('java.lang.reflect.Method'); │
│ 216 Method.invoke.implementation = function(obj, args) { │
│ 217 var methodName = this.getName(); │
│ 218 var className = this.getDeclaringClass().getName(); │
│ 219 if (className.indexOf('elimination') !== -1 || className.indexOf('android.app.admin') !== -1) { │
│ 220 console.log('[REFLECT] ' + className + '.' + methodName + '() invoked via reflection'); │
│ 221 if (args != null) { │
│ 222 for (var i = 0; i < args.length; i++) { │
│ 223 console.log('[REFLECT] arg[' + i + ']: ' + args[i]); │
│ 224 } │
│ 225 } │
│ 226 } │
│ 227 return this.invoke(obj, args); │
│ 228 }; │
│ 229 console.log('[+] Hooked Method.invoke'); │
│ 230 } catch(e) { │
│ 231 console.log('[-] Reflection hook failed: ' + e); │
│ 232 } │
│ 233 │
│ 234 // ============================================================ │
│ 235 // HOOK 11: Device Admin - Detect admin privilege abuse │
│ 236 // ============================================================ │
│ 237 try { │
│ 238 var DevicePolicyManager = Java.use('android.app.admin.DevicePolicyManager'); │
│ 239 DevicePolicyManager.lockNow.implementation = function() { │
│ 240 console.log('[ADMIN] DevicePolicyManager.lockNow() called - Screen lock attack!'); │
│ 241 this.lockNow(); │
│ 242 }; │
│ 243 DevicePolicyManager.resetPassword.overload('java.lang.String', 'int').implementation = function(password, flags) { │
│ 244 console.log('[ADMIN] resetPassword called with: ' + password + ' | flags: ' + flags); │
│ 245 return this.resetPassword(password, flags); │
│ 246 }; │
│ 247 DevicePolicyManager.wipeData.overload('int').implementation = function(flags) { │
│ 248 console.log('[ADMIN] CRITICAL: wipeData() called! Device wipe attempted! Flags: ' + flags); │
│ 249 // Block the wipe to preserve evidence │
│ 250 // this.wipeData(flags); │
│ 251 console.log('[ADMIN] BLOCKED device wipe for forensic preservation'); │
│ 252 }; │
│ 253 console.log('[+] Hooked DevicePolicyManager (lockNow, resetPassword, wipeData)'); │
│ 254 } catch(e) { │
│ 255 console.log('[-] DevicePolicyManager hook failed: ' + e); │
│ 256 } │
│ 257 │
│ 258 // ============================================================ │
│ 259 // HOOK 12: SharedPreferences - Capture config/token storage │
│ 260 // SpyNote stores C2 config and tokens in SharedPreferences │
│ 261 // ============================================================ │
│ 262 try { │
│ 263 var SharedPreferencesEditor = Java.use('android.app.SharedPreferencesImpl$EditorImpl'); │
│ 264 SharedPreferencesEditor.putString.implementation = function(key, value) { │
│ 265 if (key === 'token' || key.indexOf('c2') !== -1 || key.indexOf('server') !== -1 || key.indexOf('host') !== -1 || key.indexOf('port') !== -1) { │
│ 266 console.log('[CONFIG] SharedPreferences.putString("' + key + '", "' + value + '")'); │
│ 267 } │
│ 268 return this.putString(key, value); │
│ 269 }; │
│ 270 console.log('[+] Hooked SharedPreferences.putString'); │
│ 271 } catch(e) { │
│ 272 console.log('[-] SharedPreferences hook failed: ' + e); │
│ 273 } │
│ 274 │
│ 275 console.log('[*] All hooks installed. Monitoring SpyNote/SpyMax RAT activity...'); │
│ 276 }); │
╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
Saving Reports...
✓ JSON report: reports/elimination_kitchen_secured_20260330_113737.json
✓ Frida script: reports/elimination_kitchen_secured_frida_hooks.js
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Analysis completed in 124.1s
JSON Report: reports/elimination_kitchen_secured_20260330_113737.json
Frida Script: reports/elimination_kitchen_secured_frida_hooks.js
What Each Phase Does
Phase 1 — Static Analysis
Press enter or click to view image in full size
Androguard parses the APK and extracts:
- Package name, version, min/target SDK
- All declared and used permissions
- Activities, Services, BroadcastReceivers, ContentProviders (with exported flags and intent filters)
- Certificate chain (issuer, validity, self-signed flag)
- DEX files + native
.solibraries - All strings, URLs, IPs, domains, email addresses
- Shannon entropy per DEX file (flags encrypted/packed payloads)
Phase 2 — Threat Indicator Scoring
Press enter or click to view image in full size
A rule-based engine scores four dimensions:
Press enter or click to view image in full size
The final Risk Score (0–100) uses a weighted formula with severity floors — so a banking trojan with CRITICAL indicators but no hardcoded C2 (because it downloads the C2 dynamically) still scores HIGH rather than being dragged down by a zero network score.
Risk levels: CLEAN → LOW → MEDIUM → HIGH → CRITICAL
Phase 2b — Semantic Analysis
Component names tell a story. SmsInterceptorService, ScreenOverlayActivity, KeyloggerAccessibility — these aren't accidents. The semantic analyzer maps component names and string patterns to capability categories and MITRE ATT&CK techniques without needing to decompile any bytecode.
Get Andrey Pautov’s stories in your inbox
Join Medium for free to get updates from this writer.
Example output:
CRITICAL Service Remote Access Trojan C2 T1571 RemoteControlService
HIGH Receiver SMS Intercept / Exfiltration T1636 SmsReceiver
HIGH Activity UI Overlay Attack T1416 OverlayActivityPhase 2c — VirusTotal Lookup (optional)
Press enter or click to view image in full size
If a VT API key is configured, the SHA-256 is queried automatically. The report includes:
- Detection ratio with color coding (e.g.
38/72) - Threat label and all known malware families
- First seen / last seen dates
- File type and submission history
- VT tags
- Full AV engine detection table (up to 20 engines, priority vendors first: Kaspersky, ESET, BitDefender, Sophos, CrowdStrike, etc.)
- Sandbox verdicts (if available)
No VT key? The phase is silently skipped — no errors, no warnings.
Phase 3 — YARA Scanning
The APK and its DEX files are scanned against a curated YARA ruleset covering:
Press enter or click to view image in full size
- Known malware families (Cerberus, Joker, FluBot, Anatsa, Anubis, etc.)
- Generic banking trojan patterns
- Spyware/stalkerware signatures
- Crypto-mining indicators
- Packer/obfuscator signatures
Each match shows the rule name, description, category, MITRE technique, and matched string evidence.
Phase 4 — AI Analysis
Press enter or click to view image in full size
The AI receives the full structured analysis — permissions, indicators, semantic findings, YARA matches, entropy data, VT results — and produces:
- Threat classification with confidence level
- Executive summary (non-technical, for reporting)
- Technical analysis (deep behavioral description)
- Primary capabilities list
- MITRE ATT&CK technique table
- IOC list for threat hunting (ready to import to your SIEM)
- Remediation steps
- Frida hooks — ready-to-run JavaScript for dynamic analysis
Press enter or click to view image in full size
Common Usage Patterns
Quick triage without AI
./analyzer.py analyze suspicious.apk --no-aiRuns in ~3 seconds. Gives you the full static + YARA + semantic picture without waiting for an LLM.
Check hashes only
./analyzer.py info suspicious.apkPrints MD5, SHA-256, file count, DEX count, native lib count. Useful for quick identification.
Batch scan a directory
./analyzer.py batch /path/to/samples/ --no-ai --min-risk 50Scans every .apk recursively, then prints a sorted summary table. --min-risk 50 filters out anything below MEDIUM.
# Batch with AI and VT, save everything to /tmp/reports
./analyzer.py batch /samples/ -p claude --output-dir /tmp/reportsUse verbose mode to debug
./analyzer.py analyze suspicious.apk -vShows all debug logs from androguard and the AI streaming output token by token.
Save Frida hooks for dynamic follow-up
./analyzer.py analyze suspicious.apk --save-fridaSaves a .js file to the reports directory. Run it with:
frida -U -l com.example.malware_frida_hooks.js com.example.malwareWhat the generated hooks actually look like
The AI doesn’t produce generic stubs — it reads the detected capabilities and writes targeted hooks. Here’s a real example from a SpyNote/SpyMax RAT sample that the tool identified as having accessibility abuse, SMS interception, and overlay injection:
// SpyNote/SpyMax RAT Frida Hook Suite
// Run: frida -U -f elimination.kitchen.secured -l spynote_hooks.js --no-pause
Java.perform(function() {
// HOOK 1: AccessibilityService - keylogging + UI automation
// The core keylogging service (nSsAP24)
try {
var AccessibilityService = Java.use('android.accessibilityservice.AccessibilityService');
AccessibilityService.onAccessibilityEvent.implementation = function(event) {
if (event != null) {
var eventType = event.getEventType();
var packageName = event.getPackageName();
var text = event.getText();
var className = event.getClassName();
console.log('[ACCESSIBILITY] Type: ' + eventType +
' | Pkg: ' + packageName +
' | Class: ' + className +
' | Text: ' + text);
// Log TYPE_VIEW_TEXT_CHANGED (keylogging)
if (eventType === 16) {
console.log('[KEYLOG] Text changed in ' + packageName + ': ' + text);
}
}
this.onAccessibilityEvent(event);
};
} catch(e) { console.log('[-] AccessibilityService hook failed: ' + e); }
// HOOK 2: GestureDescriptionBuilder - detect programmatic taps
// SpyNote uses this to auto-click UI elements (accepting permissions, etc.)
try {
var GestureBuilder = Java.use('android.accessibilityservice.GestureDescription$Builder');
GestureBuilder.build.implementation = function() {
console.log('[GESTURE] GestureDescription.build() called - SpyNote automating UI interaction');
console.log('[GESTURE] Stack: ' + Java.use('android.util.Log')
.getStackTraceString(Java.use('java.lang.Exception').$new()));
return this.build();
};
} catch(e) { console.log('[-] GestureBuilder hook failed: ' + e); }
// HOOK 3: SmsManager - capture all SMS read/send operations
// Steals OTPs and sends premium-rate SMS
try {
var SmsManager = Java.use('android.telephony.SmsManager');
SmsManager.sendTextMessage.overload(
'java.lang.String','java.lang.String','java.lang.String',
'android.app.PendingIntent','android.app.PendingIntent'
).implementation = function(dest, sc, text, sentIntent, deliveryIntent) {
console.log('[SMS-SEND] Destination: ' + dest + ' | Text: ' + text);
console.log('[SMS-SEND] WARNING: Possible premium-rate SMS fraud!');
// Uncomment to block: return;
this.sendTextMessage(dest, sc, text, sentIntent, deliveryIntent);
};
} catch(e) { console.log('[-] SmsManager hook failed: ' + e); }
// HOOK 4: OverlayWindow Injection - capture phishing overlays
// Detects when SpyNote draws over banking apps
// ...
});Four things stand out here that you wouldn’t get from a generic template:
- The actual service class name (
nSsAP24) is identified from the semantic analysis — the hook targets it directly rather than hooking every accessibility event globally. - Gesture automation is flagged — SpyNote abuses
GestureDescription.Builderto auto-click permission dialogs. The hook captures the full stack trace so you can see exactly when this triggers. - SMS blocking is pre-wired — the hook logs outbound SMS and includes a commented
returnstatement you can uncomment to neutralize premium-rate SMS fraud mid-analysis. - Overlay detection is ready — the tool recognized the
OverlayActivitycomponent and generated the corresponding hook for it.
This is what “starting point” means in practice: you get a file that already hooks the right classes for this specific sample, not a copy-paste skeleton you have to figure out yourself.
Output
Every run saves a JSON report to the reports/ directory (or wherever --output-dir points):
reports/
com.example.malware_20260330_142301.json
com.example.malware_frida_hooks.js # if --save-fridaThe JSON report contains the complete analysis: all indicators, permissions, network IOCs, component list, YARA matches, AI analysis, and VT results. Suitable for ingestion into SIEM, ticketing systems, or custom dashboards.
Reading the Risk Score
The score is not a simple average. The formula is:
weighted = permissions×0.30 + behavior×0.45 + network×0.10 + obfuscation×0.15
score = max(weighted, max_dimension×0.75)Severity floors are applied on top:
- ≥2 CRITICAL indicators → score ≥ 85
- 1 CRITICAL → score ≥ 72
- ≥3 HIGH → score ≥ 62
- ≥1 HIGH → score ≥ 45
This means professional malware that deliberately avoids hardcoded C2 addresses (zero network score) won’t appear clean — its dangerous permissions and behavioral indicators still drive the score into HIGH territory.
Practical Tips
Start with --no-ai for triage. The static + YARA + semantic analysis runs in seconds and eliminates most false positives before you pay for an API call.
Use auto provider for everyday work. If you have an Anthropic key set in your environment, Claude is used automatically. Switch to google for free-tier Gemini if you need to run many samples.
Set your VT key in the config file. Adding vt_key: your-key to config.yml means every analysis automatically cross-validates against VT without any extra flags.
Batch mode + --min-risk is great for incident response when you have a folder of suspicious APKs and need to prioritize. Start with --min-risk 60 to focus on HIGH and CRITICAL samples.
The Frida script is a starting point, not a final answer. The AI generates hooks based on what it knows about the detected capabilities. You’ll almost always want to customize them — but having a scaffold that hooks the right classes saves significant time.
Architecture Overview
analyzer.py # CLI entry point (Click)
core/
apk_analyzer.py # Androguard wrapper, string/IOC extraction
indicators.py # Threat scoring engine
semantic_analyzer.py # Component name + string semantic analysis
yara_scanner.py # YARA rule runner
vt_lookup.py # VirusTotal API v3 client
ai_engine.py # Multi-provider AI router (Claude/OpenAI/Google/Ollama)
ollama_engine.py # Local Ollama backend
reporter.py # Rich terminal UI + JSON/Frida output
rules/
malware.yar # YARA ruleset
config.yml # Default configurationLimitations and What This Tool Is Not
- Static analysis only. It cannot observe runtime behavior — dynamic loading, encrypted C2 communication, or code paths that only execute after specific triggers won’t be seen.
- YARA signatures need maintenance. New malware families require new rules. The included ruleset covers common families but is not exhaustive.
- AI analysis quality depends on the model. Claude Opus produces significantly better reasoning than smaller local models. For high-stakes analysis, always use a frontier model.
- No decompilation. The tool parses DEX bytecode for API calls and strings but does not produce readable Java/Kotlin source. For deep code review, combine with jadx or JADX-GUI.
Conclusion
Effective APK triage doesn’t require a cloud sandbox subscription or a commercial SIEM. With a reasonable API key and this tool, you can go from a suspicious APK to a structured threat report with MITRE mappings and Frida hooks in under a minute.
The combination of fast static analysis (for volume) + AI synthesis (for depth) + VirusTotal cross-validation (for confidence) covers the most common analyst workflows. The --no-ai path is fast enough for CI/CD integration or bulk scanning, while the full pipeline gives you the kind of narrative analysis that makes incident reports readable by non-technical stakeholders.