Do you want to start reverse engineering some android App? And you don't know where to start? Well, this is the perfect post for you.

This post comes into existence because I needed to see the encrypted network traffic of an android application that wasn't available in my country. And I don't have any android phone to spare and try to root it.

In this tutorial we will talk about:

  • Root access to an emulated android device.
  • Man In The Middle for HTTPS traffic.
  • SSL Pinning removal.
  • .APK de-compilation and debugging.

Root access to the Android Emulator

Most real world application need all the Google services activated in the phone to work. If you just try to run your android emulator with an image that has Google Play installed, you won't be able to call adb root. That is because any Android image with GP installed is considered a production image, and therefore you can't have root access by default.

The way we interact with the "root" capabilities of a phone are different in a emulated phone if you compare it with a physical one. This is because in a non-production image you already have root access by just issuing:

adb root
adb remount

And that's it. You already have root access and you can do whatever you want in your adb shell. You may encounter that you can't write the file system or something. This is because you need to start the emulator with a writable filesystem.

emulator -avd <your-avd-name> -writable-system

I notice that a side effect of using -writable-system is that the snapshot functionality breaks and you can not longer rely on that.

Installing gapps

Because the previous command will only really work in a non-production image, you lack all the Google Apps, including the services that your target application may need to work. For that reason is that you need to install gapps by yourself. You can download them from The Open GApps Project.

It will be very hard for you to find a tutorial explaiing how to install OGApps in a emulated phone, because almost nobody does that. But, here you go:

unzip open_gapps-<your-version>.zip 'Core/*'
rm Core/setup*
lzip -d Core/*.lz
for f in $(ls Core/*.tar); do
  tar -x --strip-components 2 -f $f
done
adb remount
adb push etc /system
adb push framework /system
adb push app /system
adb push priv-app /system
adb shell stop
adb shell start

Normal Android Root

Normally, you "root" your android device when you modify your phone such as that normal user space can do things that only root would be able to do. This is accomplished by installing two pieces:

  • An App that allows you to control which normal app gets access to root privileges.
  • A modified su command installed in your phone's $PATH.

It's very hard to achive that "root" state in a emulator. Most of the times my emulator crashed, or the rooting didn't work. And remember, you can't use snapshots doing this. Well, some people say that the used snapshots to maintain their root state, but I couldn't.

Because this way of rooting the phone leaves you with a very unstable system, and is a very hard state to maintain, I will recommend you, if you really need this, do it in a physicall phone. But if you are aventurous, these where the links that tought me how to do it:

But, my advice is that you try to avoid the "normal root" in emulated device. Otherwise, a world of pain will be waiting for you.

Main In The Middle on Android

To really see the traffic of apps we need to do a MITM "attack" on our virtualized phone. Doing MITM over http is trivial, but doing it with https is a little bit more involved. And it's more anoying if you need to work around SSL Pinning.

For this part of the post, you will need two software installed in your host machine:

  • mitmproxy: A proxy that allows us to inspect all http/s traffic.
  • frida: Dynamic instrumentation that allow us to modify the apps code dynamically without recompiling anything.

The first time you run mitmproxy, it will generate certificates you need to install in your android device. You will find the certificates in:

$ ls ~/.mitmproxy/
mitmproxy-ca-cert.cer  mitmproxy-ca-cert.pem  mitmproxy-ca.pem
mitmproxy-ca-cert.p12  mitmproxy-ca.p12       mitmproxy-dhparam.pem

In our case, the only certificate we will be using is mitmproxy-ca-cert.cer:

adb push mitmproxy-ca-cert.cer /system/etc/security/cacerts/
adb reboot

Then, you may need to activate it on the system settings.

At his point you should be able to start seeing some https traffic in your mitmproxy. But most often than not your target application will still fail because it only trust specific certificates. If that's the case, it's time to install frida on your phone. First, you download an executable compatible with your phone cpu from github. Then as described here, you install and run frida:

$ adb root
$ adb remount
$ adb push frida-server /data/local/tmp/ 
$ adb shell "chmod 755 /data/local/tmp/frida-server"
$ adb shell "/data/local/tmp/frida-server &"

And you may have guessed, frida-server should always be running in the phone to this to work. Then, we need create a frida script to remove the ssl pinning from the phone. In the most basic case this should be enough:

setTimeout(function(){
	Java.perform(function () {
		var TrustManagerImpl = Java.use('com.android.org.conscrypt.TrustManagerImpl');
		TrustManagerImpl.verifyChain.implementation = function (untrustedChain, trustAnchorChain, host, clientAuth, ocspData, tlsSctData) {
			return untrustedChain;
		}
	});
};

Then you run the script with:

frida -l <script-name>.js -U -f <installed-app-package> --no-pause

But, in many cases you want something more complex like this. You should read this article for more details.

APK Decompilation

If you are analyzing an app looking for something, you may need to "decompile" it and get something that you can read. Sadly there is nothing that can convert an apk to java code. But we can get .smali/ .baksmali files. Basically we use a special program that converts the apk with .dex dalvik bytecode to something that we "can" read, Those smali files are like assembly language, very hard to follow. And it gets even harder if the developer used some obfuscation.

I use apktool for this. I recommend you that you do too, but please, always download the last version, and don't rely on your package manager for this. You use it like this:

# decompile
java -jar apktool.jar -r d <input-apk> -o <decompiler-location>
# compile
java -jar apktool.jar b <decompiled-location> -o <output-apk>

The next step with the decompiled apk, is to try to debug, and follow th flow and state of the program while reading the .smali files. For doing that you need to use the Android IDE with the samli plugin.

To actually be able to debug, you need to force that app to wait for the debugger before it can start, and then when the phone is waiting for the debugger you attach if from the IDE. Yes, no magic "run" button here. A detailed but old tutorial is here.

While debugging you will be changing the source code. But because of the changes the signatures won't match. So you need to resign the .apk yourself. Assuming you have a self-signed certificate default:

apktool b <decompiled-location> -o out.apk
jarsigner -keystore default.keystore -verbose out.apk default
adb install -r out.apk