Virgin Media WiFi Android app on a rooted device

Virgin Media have a handy Android app which lets Virgin Media subscribers connect to their Virgin Media WiFi service. However they have, in their infinite wisdom, decided that they will not support running this app on rooted Android devices – which is entirely their prerogative.

As a longtime fan of rooted Android (I currently run LineageOS 14.1 on my HTC 10) I was disappointed by Virgin’s decision but decided to treat it as a learning opportunity. So, purely for academic / research purposes, is it possible to modify the Android APK such that it will run on a rooted handset? Yes, yes it is and it’s quite easy if you know what you’re doing.

Here’s how I went about my proof-of-concept:

  1. Install the Virgin Media WiFi app on your phone from the Play Store.
  2. Use ADB to pull the APK file from your device. For me this worked like this:
    adb pull /data/app/com.virginmedia.simplewifi-1
    pull: building file list...
    pull: /data/app/com.virginmedia.simplewifi-1/lib/arm64/libdevicescape-jni.so -> ./lib/arm64/libdevicescape-jni.so
    pull: /data/app/com.virginmedia.simplewifi-1/base.apk -> ./base.apk
    
  3. Use the fantastic apktool to decompile the base.apk:
    apktool d base.apk
    I: Using Apktool 2.2.2 on base.apk
    I: Loading resource table...
    I: Decoding AndroidManifest.xml with resources...
    I: Loading resource table from file: /home/simon/.local/share/apktool/framework/1.apk
    I: Regular manifest package...
    I: Decoding file-resources...
    I: Decoding values */* XMLs...
    I: Baksmaling classes.dex...
    I: Copying assets and libs...
    I: Copying unknown files...
    I: Copying original files...
  4. Now let’s start looking for the text in the toast notification it pops up to tell you it’s not going to run on a rooted device:
    grep -R "rooted" *
    res/values/public.xml:    <public type="string" name="alert_rooted_device" id="0x7f0800d1" />
    res/values/strings.xml:    <string name="alert_rooted_device">For security reasons you are not able to run this app on a rooted device</string>

    I’d take a reasonable guess that “alert_rooted_device” is the one we’re after. Let’s see if that id “0x7f0800d1” is referenced anywhere in the decompiled code:

    grep -Ri "7f0800d1" *
    res/values/public.xml:    <public type="string" name="alert_rooted_device" id="0x7f0800d1" />
    smali/com/studios/ocasta/prototype/vmwfsclient/ui/activities/StartActivity.smali:    const v0, 0x7f0800d1

    Aha! It looks like StartActivity.smali might be worth a closer look.

  5. So let’s take a look at the decompiled StartActivity.smali:
    StartActivity.smali
    Seems like it’s invoking com/studios/ocasta/prototype/vmwfsclient/g/i;->a() (line 283), putting the result into v0 (line 285) and then jumping to :cond_0 if v0 is equal to 0 (line 287). If v0 isn’t zero then it raises a Toast notification with the id of the “alert_rooted_device” string (0x7f0800d) (lines 289-297) and calls the “finish()” method (line 299).
    I think it’s a reasonable guess that lines 283-299 are responsible to detecting whether the device is rooted, displaying a toast notification to that effect and exiting.
    So what, if we were so inclined, could we do about it?
  6. Looks likely that if the device isn’t rooted then line 287:
    if-eqz v0, :cond_0

    will skip over the toast + exit stuff. So what if line 287 read simply:

    goto :cond0

    instead? Skipping over the toast and exit regardless of the result of the method invoked at line 283.
    Let’s give it a go!

  7. Make whatever modifications you decide to and use apktool to rebuild the apk
    apktool b base -o com.virginmedia.simplewifi-rooted.apk
    I: Using Apktool 2.2.2
    I: Checking whether sources has changed...
    I: Smaling smali folder into classes.dex...
    I: Checking whether resources has changed...
    I: Building apk file...
    I: Copying unknown files/dir...

    This should produce an apk which you’ll need to zipalign and sign before you try installing it on a rooted Android device for educational purposes only.

So what did we learn here?

  1. It is often trivial to work around root detection on Android apps.
  2. The root detection in this case isn’t even necessary since the app will set-up WiFi auto sign-on for you, so you could:
    Remove root (temporary)
    Install the app & set-up auto sign-on
    Reinstate root and just don’t launch the app

App Idea : SMS Spam Reporter

I’m probably not alone in getting quite a few “spam” SMS messages on my phone. Lately they’ve all been about PPI mis-selling but in the past they’ve been about dodgy loans, accident claims etc etc

Unfortunately all these messages come from mobiles that have been bought to bulk-send SMS spam and aren’t registered or legislated for in any way. The only recourse that you might possibly have against these are to report the text to your mobile phone operator in the hope that they will block that number so that others aren’t inconvenienced.

You obviously need to include the sender’s number when forwarding the spam text to 7226 or (87226 if you’re on Vodafone). On my phone, the ‘forward’ function doesn’t do this automatically. So here’s my great app idea:

  • You set up a “blacklist” of words that usually appear in spam texts (e.g.: “PPI”, “claim” etc)
  • When your phone receives a text with one of the blacklisted words it automatically pops up a dialog which shows you the text and asks you if you’d like to report it as spam.
  • The app edits the text to include the original sender’s number and automatically forwards it to your operator’s SMS spam reporting number.
  • The app then deletes the text from your text inbox.

It doesn’t sound too hard does it? It might even result in these spam merchants getting their comeuppance. So why can’t I find an app that will do this? All the anti-spam apps I can find want to filter messages out of my inbox and become my messaging app. I don’t want that, I just want to report these sons of guns.

If I get a bit of free time this will be my first Android app (unless someone else makes it first).