ADB Malware Scanner Script (2025)

ADB Malware Scanner Script (2025)

A friend messaged me last month convinced her Android phone was compromised — battery draining fast, weird pop-ups, a mystery app she didn’t remember installing. Instead of walking her through a sketchy “cleaner” app from the Play Store, I plugged her phone into my laptop and ran a set of ADB commands that gave us a real answer in about ten minutes. That experience is why I put together this guide: a practical, transparent ADB-based malware scanning approach anyone comfortable with a terminal can use in 2025.

Why Use ADB for Malware Scanning?

Android Debug Bridge (ADB) gives you a direct, low-level view into a device’s installed packages, running processes, and permissions — without needing root access for most checks. Unlike opaque “antivirus” apps that run inside the same sandboxed environment as potential malware, ADB inspection happens from a connected computer, giving you visibility that’s harder for malicious apps to hide from or tamper with.

Prerequisites

# Verify ADB is installed and device is connected
adb version
adb devices

Expected output should list your device’s serial number with status device (not unauthorized — if unauthorized, check the phone screen for the RSA key confirmation prompt).

Manual ADB Commands for Malware Triage

Before scripting everything, it’s worth understanding the individual commands doing the work.

# List all installed packages, including system apps
adb shell pm list packages -f

# List only third-party (user-installed) apps — most malware lands here
adb shell pm list packages -3

# Get detailed info about a specific suspicious package
adb shell dumpsys package com.suspicious.app

# Check permissions granted to a specific app
adb shell dumpsys package com.suspicious.app | grep -A 20 "runtime permissions"

# View currently running processes
adb shell ps -A

# Check for apps with the DEVICE_ADMIN or Accessibility Service permission (common malware persistence tactic)
adb shell dumpsys device_policy
adb shell settings get secure enabled_accessibility_services

# Pull an APK off the device for offline analysis
adb shell pm path com.suspicious.app
adb pull /data/app/~~randomstring==/com.suspicious.app-randomstring/base.apk ./suspicious.apk

Building a Reusable ADB Malware Scanner Script

Below is a practical Bash script that automates the common red flags: sideloaded apps, excessive permissions, accessibility service abuse, and apps disguised with misleading names. This isn’t a replacement for a full malware analysis lab, but it’s an excellent triage tool.

#!/usr/bin/env bash
# adb_malware_scan.sh — Basic Android malware triage via ADB
# Usage: ./adb_malware_scan.sh

set -euo pipefail

echo "=== ADB Malware Scanner (2025) ==="

if ! command -v adb &> /dev/null; then
    echo "[!] adb not found. Install Android SDK Platform Tools first."
    exit 1
fi

DEVICE_COUNT=$(adb devices | grep -c "device$" || true)
if [ "$DEVICE_COUNT" -lt 1 ]; then
    echo "[!] No authorized device found. Check USB debugging and confirm the RSA prompt on-device."
    exit 1
fi

OUTPUT_DIR="adb_scan_$(date +%Y%m%d_%H%M%S)"
mkdir -p "$OUTPUT_DIR"

echo "[*] Listing third-party installed packages..."
adb shell pm list packages -3 | sed 's/package://' | sort > "$OUTPUT_DIR/user_apps.txt"
echo "    Found $(wc -l < "$OUTPUT_DIR/user_apps.txt") user-installed apps."

echo "[*] Checking accessibility services (common persistence/abuse vector)..."
adb shell settings get secure enabled_accessibility_services > "$OUTPUT_DIR/accessibility_services.txt"
cat "$OUTPUT_DIR/accessibility_services.txt"

echo "[*] Checking device admin apps (used by some ransomware/spyware to resist uninstall)..."
adb shell dumpsys device_policy | grep -i "admin" > "$OUTPUT_DIR/device_admins.txt" || true
cat "$OUTPUT_DIR/device_admins.txt"

echo "[*] Scanning each user app for high-risk permission combinations..."
{
  echo "package,sms,accessibility,overlay,admin,contacts"
  while read -r pkg; do
    perms=$(adb shell dumpsys package "$pkg" | grep -E "android.permission" || true)
    sms=$(echo "$perms" | grep -c "RECEIVE_SMS\|SEND_SMS" || true)
    acc=$(echo "$perms" | grep -c "BIND_ACCESSIBILITY_SERVICE" || true)
    overlay=$(echo "$perms" | grep -c "SYSTEM_ALERT_WINDOW" || true)
    admin=$(echo "$perms" | grep -c "BIND_DEVICE_ADMIN" || true)
    contacts=$(echo "$perms" | grep -c "READ_CONTACTS" || true)
    echo "$pkg,$sms,$acc,$overlay,$admin,$contacts"
  done < "$OUTPUT_DIR/user_apps.txt"
} > "$OUTPUT_DIR/permission_matrix.csv"

echo "[*] Flagging apps with 3+ high-risk permissions..."
awk -F',' 'NR>1 && ($2+$3+$4+$5+$6) >= 3 {print $1}' "$OUTPUT_DIR/permission_matrix.csv" > "$OUTPUT_DIR/flagged_apps.txt"

if [ -s "$OUTPUT_DIR/flagged_apps.txt" ]; then
    echo "[!] Flagged high-risk apps requiring manual review:"
    cat "$OUTPUT_DIR/flagged_apps.txt"
else
    echo "[+] No apps matched the high-risk permission threshold."
fi

echo "[*] Results saved to: $OUTPUT_DIR/"
echo "=== Scan Complete ==="

Save this as adb_malware_scan.sh, make it executable with chmod +x adb_malware_scan.sh, and run it with the device connected.

Understanding the Scan Logic

flowchart TD
    A[Connect Device via ADB] --> B[Enumerate Third-Party Packages]
    B --> C[Query Permissions per Package]
    C --> D{High-Risk Permission Combo?}
    D -->|SMS + Accessibility + Overlay| E[Flag for Manual Review]
    D -->|Device Admin without clear purpose| E
    D -->|Normal permission profile| F[Mark as Likely Benign]
    E --> G[Pull APK for Deeper Static Analysis]
    G --> H[Analyze with VirusTotal / MobSF / Manual RE]

The scanner isn’t trying to definitively declare “malware found” — permission combinations alone are heuristic indicators, not proof. A legitimate SMS backup app will also request RECEIVE_SMS. The goal is to shrink hundreds of installed apps down to a manageable shortlist worth investigating further.

Deeper Analysis: What To Do With Flagged Apps

Once you have a shortlist, pull the APK and analyze it further:

# Pull the APK
apk_path=$(adb shell pm path com.suspicious.app | sed 's/package://')
adb pull "$apk_path" ./suspicious.apk

# Quick static triage with aapt (part of Android SDK build tools)
aapt dump badging suspicious.apk | grep -E "package|uses-permission"

# Check the APK's hash against VirusTotal (requires API key, or use the web UI)
sha256sum suspicious.apk

For genuinely thorough analysis, upload the APK hash (not necessarily the file, for privacy) to VirusTotal, or run it through MobSF (Mobile Security Framework), an open-source static/dynamic Android and iOS analysis platform that decompiles the APK and flags known malicious patterns, hardcoded secrets, and insecure configurations automatically.

Common Android Malware Indicators to Watch For

IndicatorWhat It Suggests
App requests Accessibility Service without a clear accessibility purposeCommon technique for overlay attacks, keylogging, and auto-clicking malicious actions
App requests Device Admin rightsOften used by ransomware/spyware to resist uninstallation
App requests SMS read/send permissions but isn’t a messaging/2FA appPossible SMS-based fraud (OTP interception, premium SMS abuse)
Package name mimics a legitimate app but isn’t from the official developerClassic trojan/clone app technique
App was sideloaded (not from Play Store) and requests broad permissionsHigher risk profile; Play Store apps undergo at least baseline vetting
Excessive battery/data usage from an unfamiliar appPossible background exfiltration or crypto-mining activity

Extending the Scanner: Continuous Monitoring

The script above is designed for one-off triage, but the same building blocks can be adapted into a lightweight continuous monitoring setup for a device you manage regularly — useful for parents monitoring a child’s device, IT teams managing a small fleet of company Android devices, or anyone who wants ongoing visibility rather than a single snapshot.

#!/usr/bin/env bash
# adb_monitor_diff.sh — Detect newly installed apps since last scan
BASELINE="baseline_apps.txt"
CURRENT="current_apps.txt"

adb shell pm list packages -3 | sed 's/package://' | sort > "$CURRENT"

if [ ! -f "$BASELINE" ]; then
    cp "$CURRENT" "$BASELINE"
    echo "[*] Baseline created. Run again later to detect changes."
    exit 0
fi

NEW_APPS=$(comm -13 "$BASELINE" "$CURRENT")
if [ -n "$NEW_APPS" ]; then
    echo "[!] New apps detected since last scan:"
    echo "$NEW_APPS"
else
    echo "[+] No new apps since last baseline."
fi

cp "$CURRENT" "$BASELINE"

Running this on a schedule (via a cron job on the connected computer, whenever the device is plugged in for charging, for example) turns a reactive scan into an ongoing detection mechanism, catching new installs shortly after they happen rather than waiting for symptoms to appear weeks later.

Security Implications and Best Practices

Interpreting Results Responsibly

A word of caution worth taking seriously: heuristic scanners like the one above will inevitably produce false positives. A legitimate password manager app requesting accessibility permissions to autofill fields, or a family locator app requesting SMS and location permissions, will show up on a flagged list without being malicious. Treat every flag as a prompt for further investigation, not an automatic verdict. The goal of this kind of tooling is to compress a large, unmanageable surface (every app and permission on a device) into a short, reviewable list — the judgment call about what’s actually malicious still belongs to a human who understands what each app is supposed to do and why.

It’s also worth keeping a personal record of what “normal” looks like for a device you monitor regularly. The first time you run this scanner on a device with dozens of apps installed, expect a noisy result set as you learn which apps legitimately need which permissions. Subsequent runs, especially when combined with the diff-based monitoring approach described above, become far more signal-rich once that baseline is established.

Common Mistakes

When to Escalate Beyond Self-Scanning

There’s a point where DIY ADB scanning stops being sufficient and professional help becomes the right call: if you find evidence of financial fraud, if the device belongs to someone facing targeted harassment or stalking, if sensitive corporate data may have been exposed, or if the malware resists every removal attempt described here. In those cases, a proper digital forensics engagement — one that images the device before any further changes are made — preserves evidence in a way ad hoc scanning and cleanup does not, which matters both for law enforcement involvement and for understanding the true scope of what was accessed.

FAQs

Do I need root access to run this scanner? No — everything in this script works over standard ADB without root, since pm and dumpsys expose enough package and permission metadata for triage purposes.

Can this script detect all malware? No single heuristic-based tool can guarantee complete detection. This script is a triage aid to prioritize which apps deserve deeper analysis, not a definitive malware detector.

Is it safe to enable USB debugging just to run this scan? Yes, as long as you disable it again afterward and only authorize computers you trust, since USB debugging does expand the device’s attack surface while enabled.

What should I do if the scanner flags an app I don’t recognize? Uninstall it if you’re not certain of its origin (adb uninstall com.suspicious.app), especially if it has device admin or accessibility privileges you can’t explain.

Does this work on all Android versions? The core pm and dumpsys commands used here are broadly compatible across modern Android versions (Android 8 through the current 2025 releases), though exact output formatting can vary slightly by OEM and Android version.

Summary and Recommendations

ADB gives you a transparent, scriptable window into what’s actually installed and permissioned on an Android device — far more trustworthy than relying solely on an app running inside the same environment it’s trying to inspect. The scanner script above automates the tedious parts of that inspection, surfacing high-risk permission combinations worth a closer look. Pair it with periodic use, cautious sideloading habits, and deeper static analysis tools like MobSF for anything genuinely suspicious.

Further Reading and References

Exit mobile version