guide #026

boot-debloat.sh (51+ Packages via Dirty COW)

Problem
After factory reset all packages are back. Manual pm disable one-by-one is tedious.

Solution
Single script: Dirty COW root + pm disable 51+ packages in one command.

Context

On the Moto E2 with 1 GB RAM, every unnecessary package counts. Android 6.0 ships with 70+ pre-installed packages running in the background: Chrome, Email, Calendar, Camera, Hangouts, Play Store, carrier bloatware, Motorola services. After applying the initial no-root debloat (Hack #23), about 20 packages could be disabled via adb shell pm disable-user. But 30+ more are protected by Android and require actual root access.

After a factory reset (or boot loop recovery), every single disabled package comes back. Manually running pm disable 51 times via ADB is tedious and error-prone. A single automated script was needed.

Prerequisites

  • Dirty COW root access (Hack #34)
  • SELinux bypass via app_process32 (Hack #36)
  • ADB connection to the phone (USB)

Implementation

The script lives at /data/local/tmp/boot-debloat.sh and runs from ADB shell (uid 2000, shell domain). It uses Dirty COW to overwrite run-as with a root payload, then iterates through the package list calling pm disable for each.

# Run after every reboot or factory reset:
adb shell sh /data/local/tmp/boot-debloat.sh

The script uses the Dirty COW exploit to gain root, then disables packages in bulk:

# Core logic inside boot-debloat.sh:
# 1. Dirty COW overwrites /system/bin/run-as with root payload
# 2. Root payload calls pm disable for each package
# 3. Package states persist in /data/system/users/0/package-restrictions.xml

PACKAGES="
com.android.browser
com.android.calendar
com.android.camera2
com.android.chrome
com.android.email
com.android.exchange2
com.android.gallery3d
com.android.inputmethod.latin
com.android.music
com.android.providers.calendar
com.android.stk
com.google.android.apps.books
com.google.android.apps.docs
com.google.android.apps.magazines
com.google.android.apps.maps
com.google.android.apps.photos
com.google.android.apps.plus
com.google.android.gm
com.google.android.googlequicksearchbox
com.google.android.music
com.google.android.talk
com.google.android.videos
com.google.android.youtube
com.motorola.help
com.motorola.migrate
"
# ... 51+ total packages

Verification

# Check how many packages are disabled:
adb shell pm list packages -d | wc -l
# Expected: 51+

# Check total enabled packages:
adb shell pm list packages -e | wc -l
# Expected: 13

# Verify specific package is disabled:
adb shell pm list packages -d | grep chrome
# package:com.android.chrome

Gotchas

  • Must run from ADB shell (uid 2000), NOT from Termux SSH. Termux runs as untrusted_app (uid 10001) and cannot access /system/bin/run-as due to SELinux
  • NEVER disable com.motorola.android.providers.settings — causes boot loop
  • NEVER disable ALL launchers — Android hangs at boot logo without a HOME activity
  • Disabling com.android.defcontainer breaks adb install — re-enable with pm enable com.android.defcontainer before installing APKs
  • pm uninstall -k --user 0 is PERMANENT on Android 6 — no restore without factory reset. Always prefer pm disable
  • Script takes ~10 seconds to complete. The Dirty COW exploit itself takes ~5 seconds

Result

MetricBeforeAfter
Enabled packages64+13
Background processes35+~12
Available RAM~180 MB~350 MB
Boot-to-ready time~90s~45s
Continue reading
guide
Pocket AI complete guide
Running self-hosted AI on portable hardware
guide
Edge AI hardware buyer's guide 2026
Pi 5 vs Mini PC vs Mac Mini
report
Self-hosted AI landscape 2026
Quarterly state of the ecosystem
section
Pocket AI hardware hub
All portable hosts reviewed
section
Agent tracker
Live stats on every agent
newsletter
Thursday digest
Weekly summary in your inbox