name: android-deobfuscation
description: De-obfuscate Android apps using manual and automated techniques. Use this skill whenever the user needs to analyze obfuscated Android APKs, decrypt runtime strings, recover meaningful code from ProGuard/DexGuard obfuscation, or investigate malware samples. Trigger on mentions of: de-obfuscation, obfuscated APK, string decryption, ProGuard, DexGuard, Allatori, control-flow flattening, Dalvik bytecode analysis, Android malware analysis, or any request to understand obscured Android code.
Android De-obfuscation Skill
A comprehensive guide for de-obfuscating Android applications using both manual techniques and modern LLM-powered automation.
When to Use This Skill
Use this skill when:
- You have an obfuscated Android APK that needs analysis
- Strings appear encrypted or missing from decompiled code
- You encounter control-flow flattening or virtualization
- You need to extract runtime-decrypted values without running the app
- You're analyzing malware or suspicious Android applications
- Decompiled code has meaningless identifiers (a, b, c, method_1, etc.)
Quick Start
1. Identify Obfuscation Indicators
First, check for common obfuscation patterns:
strings app.apk | grep -i "http\|url\|api\|key" | head -20
strings app.apk | grep -i "dexclassloader"
unzip -l app.apk | grep -E "lib.*\.so"
unzip -l app.apk | grep -E "assets/.*\.dex|assets/.*\.class"
Key indicators:
- Absence of readable strings in decompiled Java
- Binary files in
assets/ directory
- Calls to
DexClassLoader or OdinClassLoader
- Native libraries with unidentifiable JNI function names
- Control-flow flattening (opaque switch-case state machines)
2. Decompile the APK
jadx -d decompiled/ target.apk
apktool d target.apk -o resources/
3. Choose Your De-obfuscation Strategy
| Scenario | Recommended Approach |
|---|
| Heavily obfuscated Java code | Androidmeda (LLM-powered) |
| Runtime string decryption | DaliVM (static emulation) |
| Native code obfuscation | Manual analysis + IDA/Ghidra |
| Control-flow flattening | Androidmeda or manual restructuring |
| Quick triage | Automated scan + manual review |
Automated De-obfuscation with Androidmeda
Androidmeda is an LLM-powered tool that automatically renames identifiers, restructures control-flow, and generates security reports.
Installation
git clone https://github.com/In3tinct/Androidmeda
cd Androidmeda
pip3 install -r requirements.txt
Usage
Option A: Remote LLM (Gemini-1.5-flash)
export OPENAI_API_KEY="your_api_key"
python3 androidmeda.py \
--llm_provider google \
--llm_model gemini-1.5-flash \
--source_dir decompiled/ \
--output_dir deobfuscated/ \
--save_code true
Option B: Local LLM (Ollama + Llama 3.2)
python3 androidmeda.py \
--llm_provider ollama \
--llm_model llama3.2 \
--source_dir decompiled/ \
--output_dir deobfuscated/ \
--save_code true
Output Files
deobfuscated/vuln_report.json - Security findings with severity levels
deobfuscated/<package_tree>/ - De-obfuscated Java source files
Tips
- Speed up processing: Trim
source_dir to only include app packages you care about
- Handle skipped classes: Isolate problematic packages or update parser regex
- Always review: LLM hallucinations can cause false positives/negatives
Static String Decryption with DaliVM
DaliVM emulates Dalvik bytecode to extract runtime-decrypted values without running the app.
Workflow
- Identify the decryption method signature (e.g.,
Lutil/Crypto;->decrypt(Ljava/lang/String;)Ljava/lang/String;)
- Run emulation to collect return values
- Review outputs for decrypted strings/configs
Usage
python emulate.py app.apk "Lcom/example/Decryptor;->decrypt"
python emulate.py app.apk "Lcom/example/Decryptor;->decrypt" -v --debug --limit 10
Finding Method Signatures
grep -r "decrypt\|decode\|obfusc" decompiled/ | grep "public\|private" | head -20
grep -r "String\|byte\[\]" decompiled/ | grep -E "for\(|while\(" | head -20
Capabilities
- Emulates 120+ Dalvik opcodes
- Mocks Android APIs (Context, PackageManager, Signature, reflection)
- Handles class initialization (
<clinit>)
- Supports multi-DEX analysis
- Traces PC/register changes for debugging
Manual De-obfuscation Techniques
Strategy 1: Replicate De-obfuscation Logic in Java
For DEX bytecode obfuscation:
- Identify the de-obfuscation method in the decompiled code
- Copy the logic into a standalone Java file
- Execute to reverse obfuscation on target elements
public class Decryptor {
public static String decrypt(String encrypted) {
return decryptedString;
}
}
Strategy 2: Translate to Python
For complex algorithms, translate to Python for easier debugging:
def decrypt_string(encrypted_bytes, key):
result = []
for i, byte in enumerate(encrypted_bytes):
decrypted = byte ^ key[i % len(key)]
result.append(chr(decrypted))
return ''.join(result)
Key principle: You don't need to fully understand the algorithm—just execute it correctly.
Dynamic Analysis for De-obfuscation
When static analysis fails, use dynamic analysis to observe runtime behavior.
Runtime Decryption Capture
frida -U -f com.example.app -l hook_decrypt.js --no-pause
/*
var decrypt = Module.findExportByName("libcrypto.so", "decrypt_string");
Interceptor.attach(decrypt, {
onEnter: function(args) {
console.log("Decrypt called with:", Memory.readUtf8String(args[0]));
},
onLeave: function(retval) {
console.log("Decrypted:", Memory.readUtf8String(retval));
}
});
*/
What Dynamic Analysis Reveals
- Runtime-decrypted strings: Captured at the moment of decryption
- Obfuscation techniques: Code virtualization, packers, dynamic code generation
- Hidden functionality: Conditionally executed code paths
- Anti-analysis behavior: Detection of emulators, debuggers, root
Practical Workflow
Step-by-Step Analysis
-
Initial Reconnaissance
./scripts/identify-obfuscation.sh target.apk
-
Decompile
jadx -d decompiled/ target.apk
-
Automated De-obfuscation (if available)
./scripts/run-androidmeda.sh decompiled/ deobfuscated/
-
String Extraction (if strings are encrypted)
./scripts/run-dalivm.sh target.apk "Lcom/example/Decryptor;->decrypt"
-
Manual Review
- Check
vuln_report.json for security findings
- Review de-obfuscated code for suspicious patterns
- Cross-reference with dynamic analysis if needed
Malware Triage Checklist
Common Obfuscation Patterns
| Pattern | Indicator | Solution |
|---|
| String encryption | No readable strings in decompiled code | DaliVM or runtime hooking |
| Control-flow flattening | Opaque switch-case state machines | Androidmeda or manual restructuring |
| Code virtualization | Custom bytecode or native execution | Dynamic analysis + emulation |
| Dynamic loading | DexClassLoader, assets/*.dex | Extract and analyze loaded DEX |
| Native obfuscation | Unknown JNI functions, packed .so | IDA/Ghidra + manual analysis |
| Anti-analysis | Debugger detection, root checks | Disable detection or use VM |
References
Troubleshooting
Androidmeda Issues
- Skipped class: Isolate the package or update parser regex
- Slow runtime: Point
--source_dir to specific packages only
- High token usage: Use local LLM or trim input directory
DaliVM Issues
- Execution stalls: Enable opcode-level tracing (
-v --debug)
- Missing mocks: Extend API mocks for custom Android calls
- Wrong return values: Verify method signature and arguments
General Issues
- Can't find decryptor: Search for string manipulation patterns in decompiled code
- Native code blocked: Use IDA/Ghidra with Android plugin
- Anti-analysis triggered: Use VM with root disabled or patch detection code