There are many apps out there that are simply wrappers around web pages, or web content stored in the app. This has a few advantages, the main one being that, effectively, only one app needs to be written for iOS, Android and whatever other mobile OS that the developer wishes to target. However, this opens up an attack vector into the app, which I will share with you here.
I discovered this technique during my time in the ad tech industry to diagnose issues with broken ads. The ads in apps are shown in small components called WebViews, which are effectively mini, single tabbed, web browsers that the app controls. In Android these WebViews have a debugging feature, that allows you to use the ADB remote debugging extension for chrome to debug the contents of the WebView. Very often we would have a demo app from the publishers for testing our ads which had this feature enabled, but for apps we got off the app store, this is normally turned off. So this hack is to enable that feature on and Android app from the app store (Apple people, I'll talk about you later).
The basic idea is this: remove the app that has the WebView from your Android device, then decompile it and turn the WebView debugging on. Simple right? The majority of the instructions for the decompilation and compliation were taken from this blog post. The magic I added was in turning the debugging on as the code you get out of the process is not java, but another language called salmi. The process is as follows. It assumes you are on Linux or OsX, but I suspect the process is pretty similar if you are on Windows.
- If you haven't already install the android development tools and make sure that all of the ADB tools are in your path in the terminal.
- Install APKTool. Put it in your path it will make things easier.
- Plug the phone or tablet with the app installed into your computer and ensure that it is set up for development with USB debugging.
- List the packages on the device with
adb shell pm list packages
to find the package name for your app. If you don't know the package name for your app, search for it in the Play store in a web browser because the package name appears in the URL for the app. In this example the URL for the app is "https://play.google.com/store/apps/details?id=com.aerserv.testapp" so the package name is "com.aerserv.testapp". We will use this in the example commands to come. - Find the location of the apk with command
adb shell pm path com.aerserv.testapp
- In this example we get the path "/data/app/com.aerserv.testapp-1/base.apk". Use
adb pull /data/app/com.aerserv.testapp-1/base.apk
to get this off the device. - Decompile the app with
apktool d base.apk
. Everything will be output to a directory called "base" - You will next need to figure out where to put the magic lines of code. I like to do it at the end of the onCreate method on the launcher activity of the app because that will always be run when the app starts. You can work this out by looking for the activity with the "LAUNCHER" intent filter in the AndroidManifest.xml file. In this case the launcher class was "com.aerserv.testapp.MainActivity", so the code needs to be added to the "base/smali/com/aerserv/testapp/MainActivity.smali" file.
Add the following lines right before the return of the method
const/4 v2, 0x1
invoke-static {v2}, Landroid/webkit/WebView;->setWebContentsDebuggingEnabled(Z)V
The first of those two lines sets a variable to true, the second line passes that variable to the static method "setWebContentsDebuggingEnabled" in the WebView class. Here it is in situ.
i
Additional code to enable debugging in red box - Run
apktool b ./base
to recompile the apk. It will be output to "./base/dist" - Now we need to generate a key to sign the app. Run
keytool -genkey -v -keystore ./my-release-key.keystore -alias WebView_test_key -keyalg RSA -keysize 2048 -validity 1000
. The process will be self evident. Note the password for later, and when you get to the question asking you if the details are correct type "yes" - Sign the app with
jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 -keystore ./my-release-key.keystore ./base/dist/base.apk WebView_test_key
- Remove the old version of the app with
adb uninstall com.aerserv.testapp
- Install the new version with
adb install ./base/dist/base.apk
Congratulation! You now have an app that has WebView debugging enabled. If you haven't installed it already, install the ADB inspection tool for chrome. This is what it looks like using this in practice.
So, what about iOS users. Well, for apps that use WebViews that host all of the content inside the app there is not much you can do, but for apps that load content into a WebView from the web I have had success in the past by using a re-writing proxy such as Charles proxy to modify what is being loaded into the app, and use this to inject the code needed to load Weinre. Weinre is a node JS program that runs on your computer locally and will give you the same functionality as the chrome developer-tools on almost any target web browser that supports web-sockets. This can be very useful not just for iOS, but for debugging webapps on other devices that are not easily debugged, like web browsers in set-top boxes and game consoles.
So, what is this useful for. Well, as mentioned above, these techniques are extremely useful for anyone in the ad tech industry who has to debug misbehaving ads inside apps that they don't control. This is actually a very common scenario, as it is often the ad developer, not the app developer that has to at least diagnose the issue, and more often than not will have to fix it even if the app is misbehaving. The other main use for this will be for anyone who needs to reverse engineer any HTTP-request based protocol that an app is using to communicate with a server. This is of course limited to apps that just wrap web content in WebViews, and you could also get a long way in that process by putting a proxy server in the middle and monitoring the requests. However, getting access to the javascript code running in the WebView which these techniques do allow) Will allow a more complete reverse engineering.
Why anyone would want to do that is something I'll leave to your imagination.