Prepare your Android emulator for reverse engineering
Quick tutorial for rooting a virtual android device, installing gapps, decompiling apks, using mitmproxy for seeing the traffic, and removing SSL pinning with frida.
Do you want to start reverse-engineering some Android apps? 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 applications 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 is different in an 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 -writable-system
I notice that a side effect of using -writable-system
is that the snapshot functionality breaks and you can no 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 explaining how to install OGApps on an emulated phone because almost nobody does that. But, here you go:
unzip open_gapps-.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 achieve that “root” state in an emulator. Most of the time my emulator crashed, or the rooting didn't work. And remember, you can't use snapshots doing this. Well, some people say that they 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 on a physical phone. But if you are adventurous, these were the links that taught me how to do it:
- StackOverflow, How to get root access on Android emulator?.
- GitHub, Rooting the Android Studio AVDs.
But, my advice is that you try to avoid the “normal root” in an 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 annoying if you need to work around SSL Pinning.
For this part of the post, you will need two pieces of software installed in your host machine:
- mitmproxy: A proxy that allows us to inspect all http/s traffic.
- frida: Dynamic instrumentation that allows us to modify the app's code dynamically without recompiling anything.
The first time you run mitmproxy
, it will generate certificates you need to install on 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 trusts 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 &"
As you may have guessed, frida-server
should always be running on the phone to this to work. Then, we need to 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 .js -U -f --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 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 -o
# compile
java -jar apktool.jar b -o
The next step with the decompiled apk
, is to try to debug, and follow the 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 it 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 -o out.apk
jarsigner -keystore default.keystore -verbose out.apk default
adb install -r out.apk