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

Reject DOS line-endings at Git pre-commit

All *nix devs seethe with rage when DOS line-endings (CRLF) end up in your beautiful source code, right? If you use Git for your version control you’re in luck, use this local pre-commit hook to kick those CRLFs to the kerb before they can even make it into your local commit.

Install by copying the pre-commit file to the .git/hooks directory of your checkout. Ask your Windows using colleagues nicely to do the same.

Changing Pageant’s default behaviour

As a Unix developer, I spend most of my working day with lots of terminals open to various Linux & Solaris development or test servers

For many years I’ve used the excellent PuTTY by Simon Tatham for all my SSH’ing needs. In addition to PuTTY, I also use Pageant to make launching new terminal sessions as easy as right clicking an icon in the system-tray and choosing the machine.

The one complaint that I have with Pageant is its default double-click behaviour. My typical use case for Pageant is:

  • I start Pageant when logging into Windows and automatically load my SSH key (by supplying the filename of the private-key file as a command-line argument to Pageant).
  • I mostly launch previously saved PuTTY sessions from Pageant’s “Saved Sessions” menu.
  • Occasionally (once or twice a day) I’ll need to launch a PuTTY session to a machine which isn’t in my “Saved Sessions” (usually because saving them all would make the “Saved Sessions” menu overly long).

Pageant’s default behaviour when double-clicking the tray icon is to launch the “View Keys” dialog. What I’d really like it to do is to launch PuTTY (i.e.: what the “New Session” menu item does).

Thankfully Pageant (indeed all of the PuTTY suite) is open-source so it was relatively straightforward to download the source, make my simple change and recompile Pageant.

In case anyone else shares my use case I’m making this modified Pageant available:

Pageant

You can also download a patch file containing these changes which can be applied to Pageant v0.62 here.

Listing recovery and source files using par2cmdline

I use the parchive command-line utility par2 quite a lot. In order to improve its scriptability I found that I needed to have the ability to list the recovery (*.par2) and source files (the files verified or repaired using the recovery data) associated with a master PAR2 file.

Admittedly I could have scraped the output from par2 -r <somefile.par2> but as it does some progress-percentage type output to the console I thought it might be cleaner to patch the par2 command to add a -list option.

Here’s how to download, patch & compile the par2cmdline v0.4 package to get these changes for yourself. These instructions are specifically for Ubuntu 10.04 (Lucid Lynx) but will probably work on any recent(ish) Ubuntu (or indeed Debian) install.

Optional step; if you’ve already installed par2cmdline via apt-get you’ll probably want to remove it with:

sudo apt-get remove par2
  1. Download the source of par2cmdline v0.4 from here (hint: you want par2cmdline-0.4.tar.gz).
  2. Untar the archive, this will create a par2cmdline-0.4 directory with the source in.
  3. If you’ve got gcc version 4 on your machine (you probably have) you’ll need to apply this patch to the source directory.
  4. Download and apply my patch to the source directory.
  5. Configure, compile and install.

Or, if you’re too busy and|or lazy to follow that, just paste the following into your console:

wget -O "par2cmdline-0.4.tar.gz" "http://downloads.sourceforge.net/project/parchive/par2cmdline/0.4/par2cmdline-0.4.tar.gz?r=&ts=1351786076&use_mirror=switch"
tar -xvzf par2cmdline-0.4.tar.gz
wget "http://sources.gentoo.org/cgi-bin/viewvc.cgi/gentoo-x86/app-arch/par2cmdline/files/par2cmdline-0.4-gcc4.patch"
patch -p0 < par2cmdline-0.4-gcc4.patch
wget "http://simon.aldrich.eu/download/par2cmdline/par2cmdline-0.4-list.patch"
patch -p0 < par2cmdline-0.4-list.patch
cd par2cmdline-0.4/
./configure
make
sudo make install

If all goes well you’ll end up with a par2 command with the following new options:

Usage:

  par2 c(reate) [options]  [files] : Create PAR2 files
  par2 v(erify) [options]  [files] : Verify files using PAR2 file
  par2 r(epair) [options]  [files] : Repair files using PAR2 files
  par2 l(ist)   [options]  [files] : List files using PAR2 files

You may also leave out the "c", "v", and "r" commands by using "parcreate",
"par2verify", or "par2repair" instead.

Options:

  -b  : Set the Block-Count
  -s  : Set the Block-Size (Don't use both -b and -s)
  -r  : Level of Redundancy (%%)
  -c  : Recovery block count (Don't use both -r and -c)
  -f  : First Recovery-Block-Number
  -u     : Uniform recovery file sizes
  -l     : Limit size of recovery files (Don't use both -u and -l)
  -n  : Number of recovery files (Don't use both -n and -l)
  -m  : Memory (in MB) to use
  -v [-v]: Be more verbose
  -q [-q]: Be more quiet (-q -q gives silence)
  -e     : List only recovery files
  -o     : List only source files
  --     : Treat all remaining CommandLine as filenames

The -l command will by default list both the recovery & source files. Use the -e and -o options to restrict listing to one or the other of these file types.

By my own admission this patch is pretty rough and ready (it doesn’t handle PAR v1 files for example) but I hope it’s of use to someone.