Android ‘hosts’-based
adblocking without root

I hate how obnoxious tracking and advertising are online. In Firefox I can just use an adblocker, but for mobile apps it isn’t so simple. There, you basically have two options:

  1. Run a “local VPN” that filters all requests, but then you can’t use a real VPN at the same time, and you need to trust whoever wrote the app (use open-source!). When I tried this, I found it also often turned itself off, so… not ideal.

  2. Root your phone to enable more powerful methods; the easiest approach is to replace your hosts file with one that contains all domains you want to avoid. However, rooting a phone can be tricky, and if you succeed, all the authentication and banking apps you’ve collected over the years will refuse to work unless you jump through even more complicated hoops… Ah, I love it when apps decide what I can and can’t do with my phone.

On Android, I recommend you take a look at AdAway, which can do both methods. But it turns out there’s a better way under certain circumstances…

Are you running a custom Android ROM, like LineageOS? Then you might be in luck! Open your Settings app and look for the Build number in a section called About phone or similar. Does the number contain the string “userdebug” (see below)? If yes, congratulations, read on!

'Build number' at the bottom of the 'About phone' section

Part 1: preparation

First, we need to enable developer settings on your phone. You’re already in the right place: tap Build number several times until it asks for your password as confirmation. Once enabled, you can find a new entry Developer options in the System section of the Settings app. There, in the Debugging section, enable both USB debugging and Rooted debugging:

Debugging settings in the 'Developer options' menu

Next, you’ll need a trusted PC to plug the device into (yes, trusted, I mean it: you’re about to give it root access to your phone). Make sure it has the adb program installed; read this guide to get it (or on Linux you can use the package manager). Check it’s working by running:

adb devices

Your device should show up, although it may have a weird name. It’ll say it’s “unauthorized” until you accept the pop-up that will appear on the phone.

Finally, prepare the hosts file you want to upload to the device. I recommend Steven Black’s files, but you can also find others or even write one yourself.

Part 2: pushing the file

If you have a “userdebug” build, you can give adb root privileges by running:

adb root

This is required for the following commands to work (if you don’t trust me, try it). Next, we need to get read/write access to Android’s system files. To do so, execute these commands:

# Turn off `dm-verity' system integrity checking.
# Note: it'll tell you to reboot, but in my experience
# this isn't necessary. It won't do any harm either.
adb disable-verity
# Request read/write access to the system
adb remount

Now we’re ready to copy the hosts file you prepared to the device:

adb push path-to-desired-hosts-file /system/etc/hosts

If you want, you can check it succeeded by reading the file from the phone:

# Enter a shell on the phone
adb shell
# Read its current `hosts' file
more /system/etc/hosts
# Leave the shell, back to your PC
exit

Part 3: cleaning up

When you’re satisfied, turn integrity checking back on and reboot the device:

# Re-enable `dm-verity' for security
adb enable-verity
# Reboot so the new `hosts' takes effect
adb reboot

Once rebooted, go back to Developer options and disable Root debugging and USB debugging for security reasons. Then, if you wish, you can turn off Developers options entirely.

Congratulations, you’ve now made the domains listed in hosts inaccessible for all apps on your phone, enjoy! But beware: Android system updates may reset the hosts file, although they don’t always in my experience. You can always easily check the file’s contents after an update.