Reverse Engineering Android Applications - Part 1

Setting up an analysis environment

A lot has been written on this topic, but a lot of information is either out of date or skipped over important steps, leaving you to piece the rest together from multiple articles, StackOverflow. I’ve had people share this issue and helped a handful of people with it, so I decided to attempt writing a step-by-step that would cover everything needed to get started.

I will be using a “Windows 11 development environment” virtual machine so that I can demonstrate everything from scratch, but everything else will work the same whether you’re using Windows, macOS, or Linux.

I do not have an M1 so I can’t guarantee it, but the only change should be using an ARM image when creating your virtual Android device.

If you choose to do the same VM setup and are using Hyper-V as a hypervisor, run this command on the host before installing Android Studio, so that nested virtualization is enabled and your emulator is performant:

Set-VMProcessor -VMName "[NameOfVM]" -ExposeVirtualizationExtensions $false

Certificates and Certificate Authorities

  • Certificate store - the certificate authorities that your device trusts; there exists a user-controlled one and a system-controlled one - note that an application does not have to use the store of the operating system - Chrome Root Program Policy, Version 1.2

  • Certificate chain: A certificate can sign other certificates which will be “lower” in the chain, with a root certificate authority at the top. A more in-depth explanation.

  • Certificate: I end up using it interchangeably with Certificate Authority. Still, when you use a tool such as Burp Suite, you are putting their generated Certificate Authority (CA) in the device’s trusted CA store, which lets Burp create certificates for each website you visit. It can then decrypt the encrypted traffic because it controls the keys being used for encryption.

There’s a lot more to certificates than HTTPS. To understand how it all works there’s a great video on it here.

Tools required

Before we start, let’s download everything that will be used for our analysis environment.

  • Android Studio - You can download the entire IDE or just the command line tools, but I will be using the IDE for simplicity’s sake.

  • Burp Suite - We will be using this to intercept network traffic from apps.

  • OpenSSL - You should have it installed already if you’re on Linux/macOS but not on Windows

  • Windows 11 development environment VM - Entirely optional, but you can try it if you’re having issues on other OS and makes this post entirely reproducible

Android Studio

Make sure you select “Android Virtual Device”.

After starting Android Studio, it’ll prompt you to accept some license agreements and offer a custom installation. Proceeding with the defaults is fine.

Once you reach the welcome screen, click on more actions and “Virtual Device Manager”.

** Creating a virtual device **

Choose “Create device”, I’ll use the default Pixel 2.

Assuming you are on an x86_64 machine and accepted the defaults during the installation, you should have “Tiramisu (Google APIs)” or newer available. Choose that one.

You want to be careful not to select an ARM image as those will perform much slower, and Android Emulator has supported running ARM apps on x86_64 images since Android 11.

You can choose a greyed-out release by clicking the download button on the left. You’ll also want the releases that have the “(Google APIs)” in the name.

The defaults for most options work fine, but you may want to edit the advanced settings on the following screen, such as “RAM” and “Internal Storage”.

Don’t start the image after it’s created through the “Device Manager” just yet.

Locate where the SDK was installed. By default:

  • Windows: $env:LOCALAPPDATA\Android\Sdk\
  • Linux: ~/Android/Sdk
  • macOS: ~/Library/Android/Sdk/
PS C:\Users\User\AppData\Local\Android\Sdk\emulator> .\emulator.exe -list-avds
PS C:\Users\User\AppData\Local\Android\Sdk\emulator> .\emulator.exe -avd Pixel_2_API_33 -writable-system

If you receive a message about it waiting for a debugger to be attached, you can click “Cancel” and wait for the OS to boot.

The reason we are starting the image in this way, it’s that we will need the /system partition to be writable. We will later install a self-signed certificate so we can intercept HTTPS traffic, but doing so requires the certificate to be installed in the “system certificate store”. We will do this a bit further down.

Introducing adb

adb is the “Android Debug Bridge”, it allows us to connect to a device and perform actions such as copying files over, rooting the device, and of course, use it as a debugging tool.

PS C:\Users\User\AppData\Local\Android\Sdk\platform-tools> .\adb.exe root # root the device
PS C:\Users\User\AppData\Local\Android\Sdk\platform-tools> .\adb.exe shell # obtain a shell on the device
emu64x:/ # whoami
emu64x:/ # avbctl disable-verification
Successfully disabled verification. Reboot the device for changes to take effect.
emu64x:/ # disable-verity
using overlayfs
Successfully disabled verity
Now reboot your device for settings to take effect
emu64x:/ # reboot

Wait for the system to reboot, and run adb shell and adb root again.

emu64x:/ # date >> /system/can_i_write.txt

In addition to requiring us to use -writable-system, we also need to disable “Android Verified Boot”, a feature similar to “Secure Boot”. Then we issue remount to remount the partition.

However, we will lose the ability to write to /system unless we always use -writable-system. This is not a problem after we are done setting up but if I end up needing to modify /system a lot, I use this script:

Start-Process $env:LOCALAPPDATA\Android\Sdk\emulator\emulator.exe -ArgumentList "-avd Pixel_2_API_33 -writable-system"
cd $env:LOCALAPPDATA\Android\Sdk\platform-tools
.\adb wait-for-device
.\adb.exe root
# .\adb.exe remount
# .\adb.exe shell

Now that we know how to make /system writable, let’s move onto the next tool and understand what all of this was for.

Burp Suite

Almost everyone reading this probably has used it, but if you never heard of it, it is a tool for performing web application security testing. One of its capabilities and the one we are interested in is the ability to act as a proxy that intercepts network traffic.

The installation is extremely straightforward, and all you have to do is open the tool and pick the defaults.

Navigate to this tab, and you will notice it already started its proxy on We want to click the button to export the CA certificate. We will need it later so that we can look at HTTPS web traffic.

Export it in the DER format and save it somewhere on your computer. We will need it soon.

To make the emulated device use our proxy and let us intercept network traffic, we can click on the last item of the sidebar, and open additional settings.

Configure it like so:

I will use Chrome as a demonstration of what happens when you try to intercept HTTPS traffic without having the certificate in the system store.

As you can see, Burp Suite wasn’t even capable of intercepting the request.

We will need to install the Burp Suite certificate authority into the system store of the Android device. This store is located in /system/etc/security/cacerts/ and certificates must be in the PEM format and follow a certain naming convention.

C:\Users\User\Desktop>openssl x509 -inform DER -in burp_ca.der -out burp_ca.pem
C:\Users\User\Desktop>openssl x509 -inform PEM -subject_hash_old -in burp_ca.pem

We only care about the first line. Android will want the file to be named 9a5ba575.0.

And now for the last part:

.\adb.exe push "C:/Users/User/Desktop/burp_ca.pem" /system/etc/security/cacerts/9a5ba575.0
.\adb.exe shell chmod 644 /system/etc/security/cacerts/9a5ba575.0

If you are using a browser to validate that it’s working and you still receive an error, try visiting a different website. It is likely a security measure called HSTS.

Here is (part) of an HTTPS request by the Steam app being decoded without an issue once the certificate is in place.

Questions you might have

What if I did all this and I still can’t intercept an app’s traffic?

The most likely reason is something called SSL pinning, where the application expects a particular TLS certificate to be used. In some other cases, the application might simply not use the HTTP protocol for its networking.

SSL pinning can be implemented in various ways, from the very simple to bypass to the very bothersome ones ranging from custom HTTP clients, written in either Java/Kotlin or C/C++.

Most of the time, it’s not too complicated and I may write about several of these methods and their workarounds in a future article if the interest exists.

Wasn’t this quite a lot of effort for what should be a simple thing like it is on other OS

Android has repeatedly tightened the restrictions on installing custom certificates. This is done in the name of security.

A bit of background history:

  • Android 7 stopped trusting certificates from the user store by default
  • Android 11 made it a more manual process to even install a certificate, and even so will only allow them to be installed in the user store

Here’s an example using mitmproxy. a different network interception tool which I heavily recommend:

From the download it takes about a dozen taps to actually install the certificate, and two or three warnings.

In the end, it’s always a tradeoff between usability and security. Even SSL pinning has its place but there is a difference between protecting a user from malware or a certificate they accidentally installed, and actively trying to prevent security research of your app (or security by obfuscation).

The best way I’ve seen this tradeoff done is Facebook’s implementation of a “white hat mode” which will let researchers do their work, while also protecting regular users.

If you have simple requirements, look into MobSF. It has a lot of functionality, it’s free and you can even try it online.

What’s next?

I’m considering making this a series because there is a lot more I’d like to cover and share on Android reverse engineering. If there’s anything you’d like to see or some section that could be clarified, feel free to drop me a line.