APK Analysis Cheat Sheet

Quick reference for Android APK reverse engineering. See my full guide: From APK to Source.


Get the APK

# List packages
adb shell pm list packages | grep target

# Find APK path
adb shell pm path com.target.app

# Pull APK
adb pull /data/app/com.target.app-1/base.apk target.apk

# Pull split APKs (Android 10+)
adb shell pm path com.target.app | while read p; do
  adb pull $(echo $p | cut -d: -f2)
done

APK Structure

app.apk
├── AndroidManifest.xml    # App config, permissions, components
├── classes.dex            # Compiled Java/Kotlin bytecode
├── classes2.dex           # Additional DEX (multidex)
├── resources.arsc         # Compiled resources
├── res/                   # Resources (layouts, strings, drawables)
├── assets/                # Raw assets (databases, configs)
├── lib/                   # Native libraries
│   ├── arm64-v8a/
│   ├── armeabi-v7a/
│   └── x86_64/
└── META-INF/              # Signatures, certificates

Decompilation Tools

# GUI
jadx-gui app.apk

# CLI - decompile to directory
jadx -d output/ app.apk

# With deobfuscation
jadx --deobf -d output/ app.apk

# Export gradle project
jadx -e -d output/ app.apk

apktool (Resources + Smali)

# Decode APK
apktool d app.apk -o output/

# Decode without resources
apktool d -r app.apk -o output/

# Decode without sources
apktool d -s app.apk -o output/

# Rebuild APK
apktool b output/ -o rebuilt.apk

dex2jar + CFR (Manual Method)

# Convert DEX to JAR
d2j-dex2jar app.apk -o app.jar

# Decompile JAR
java -jar cfr.jar app.jar --outputdir output/

# Decompile specific class
java -jar cfr.jar app.jar --outputdir output/ com.target.ClassName

Quick Analysis

AndroidManifest.xml

# View decoded manifest (after apktool d)
cat output/AndroidManifest.xml

# Key things to look for:
# - android:debuggable="true"
# - android:allowBackup="true"
# - android:exported="true" components
# - Custom permissions
# - Deep links / URL schemes

Strings & Secrets

# Search for URLs
grep -r "http" output/ --include="*.java" --include="*.xml"
grep -r "https" output/ --include="*.java" --include="*.xml"

# Search for API keys
grep -rE "(api[_-]?key|apikey|api[_-]?secret)" output/ -i

# Search for hardcoded credentials
grep -rE "(password|passwd|pwd|secret|token)" output/ -i

# Search for AWS keys
grep -rE "AKIA[0-9A-Z]{16}" output/

# Search for private keys
grep -r "BEGIN.*PRIVATE KEY" output/

# Firebase URLs
grep -r "firebaseio.com" output/
grep -r "firebase" output/ -i

Exported Components

# Find exported activities (potential entry points)
grep -E 'android:exported="true"' output/AndroidManifest.xml

# Find intent filters (deep links)
grep -A5 "<intent-filter>" output/AndroidManifest.xml

# Find content providers
grep -B2 -A5 "<provider" output/AndroidManifest.xml

# Find broadcast receivers
grep -B2 -A5 "<receiver" output/AndroidManifest.xml

Native Libraries

# List native libraries
unzip -l app.apk | grep "\.so$"

# Extract native libraries
unzip app.apk "lib/*" -d output/

# Check library architecture
file output/lib/arm64-v8a/*.so

# Strings from native lib
strings output/lib/arm64-v8a/libnative.so | grep -i password

# List exported functions
nm -D output/lib/arm64-v8a/libnative.so | grep " T "

# Disassemble (with Ghidra/IDA, or objdump)
objdump -d output/lib/arm64-v8a/libnative.so > disasm.txt

Signing & Rebuilding

# Generate keystore (one-time)
keytool -genkey -v -keystore debug.keystore -alias debug \
  -keyalg RSA -keysize 2048 -validity 10000 \
  -storepass android -keypass android

# Sign APK (after apktool b)
apksigner sign --ks debug.keystore --ks-pass pass:android \
  --key-pass pass:android rebuilt.apk

# Or with jarsigner
jarsigner -keystore debug.keystore -storepass android rebuilt.apk debug

# Verify signature
apksigner verify rebuilt.apk

# Zipalign (optional, for optimization)
zipalign -v 4 rebuilt.apk aligned.apk

Install & Test

# Install APK
adb install app.apk

# Install with downgrade
adb install -r -d app.apk

# Uninstall
adb uninstall com.target.app

# Clear app data
adb shell pm clear com.target.app

# Start activity
adb shell am start -n com.target.app/.MainActivity

# Start with intent
adb shell am start -a android.intent.action.VIEW \
  -d "scheme://host/path" com.target.app

Common Obfuscation

Obfuscator Signs
ProGuard Single-letter class/method names (a, b, c)
R8 Similar to ProGuard, more aggressive
DexGuard Encrypted strings, class encryption
Allatori Scrambled control flow
Bangcle/Jiagu Packed DEX, encrypted assets

Deobfuscation Tips

# jadx deobfuscation
jadx --deobf --deobf-min 3 -d output/ app.apk

# Look for mapping file (if available)
find . -name "mapping.txt" -o -name "proguard-mapping.txt"

# Simplify with jadx rename
# In jadx-gui: Tools > Deobfuscation > Enable

Automation Script

#!/bin/bash
APK=$1
OUT="${APK%.apk}_analysis"

mkdir -p "$OUT"

# Decode with apktool
apktool d "$APK" -o "$OUT/apktool" -f

# Decompile with jadx
jadx -d "$OUT/jadx" "$APK"

# Extract strings
strings "$APK" > "$OUT/strings.txt"

# Quick grep for secrets
echo "=== Potential Secrets ===" > "$OUT/secrets.txt"
grep -rE "(api[_-]?key|password|secret|token|firebase)" \
  "$OUT/jadx" --include="*.java" >> "$OUT/secrets.txt" 2>/dev/null

echo "Analysis complete: $OUT"