Reversing a protected APK | Dynamic code loading | Android Pen testing.

Aarav Sinha
5 min readMar 22, 2024

Many of us have encountered situations where we attempt to reverse engineer an Android application, only to find that it lacks any of its declared components such as activities, providers, services, etc., as specified in its AndroidManifest.xml file.

Various reasons could account for this, ranging from distinct implementation mechanisms such as Dynamic Class Loading (DCL) to security measures in place, like compression or packers.

In this article, we’re going to walk through the steps of unpacking a protected Android app and getting it’s decompiled source code.

For legal purposes let’s call the application target.apk.

PART I: Identifying a packed APK.
Let’s start by disassembling target.apk using JADx-Gui.

As seen in the image, there are no folders with the name of "hnms” as mentioned in the AndroidManifest.xml file. Hence, we can conclude that the application is packed and protected.

PART II: The Idea.

The Dynamic Code Loading (DCL) mechanism enables an Android app to dynamically load and utilize classes from external libraries or modules during runtime.

The simplest approach to accomplish our objective is to capture the application’s memory during runtime and attempt to extract the compressed folder containing all the class files.

The security mechanism implemented in the application allows it to extract and delete the .dex files as soon as the classes are loaded into the process.

The idea behind the attack is even if the loaded .dex files are deleted from the file system, since the classes were loaded into the process of the application, we can get the trace of the deleted files.

We will make the use of android’s proc/pid/maps files to see the memory mappings of the running application.
More information can be found on:

Detecting Dynamic Loading in Android Applications With /proc/maps — Sayfer

PART III: Reversing in action.

STEP I: Running frida

To use Frida, you need to place frida-server on your Android device and then launch it by running a command in the adb shell.

./frida-server &

Once frida-server is operational on your Android device, you can verify the connection by executing the frida-ps command with the -U option.

frida-ps -U

STEP II: Acquiring PID

Once you confirm the connection with the Frida server, proceed to note down the process ID (PID) of the targeted application by executing the following command using adb shell.

ps -A | grep -i "<targetApp>"

STEP III: Printing memory mappings using proc maps

Within the adb shell, you can effortlessly showcase memory address ranges by employing the following command.

cat /proc/<PID>/maps

STEP IV: Dumping compressed dex file from the memory

Locate the memory addresses of the dynamically loaded dexfiles by executing the provided command.

cat /proc/<PID>/maps | grep dex

In this step, document the addresses linked to various dex files.
The goal is to download these .dex files, and you can accomplish this with a custom script outlined below. Just replace the values for startAddress and endAddress in the script as needed.

This script can be downloaded from the GitHub link.

Execute the script from the terminal using Frida with the following command:

frida -U <targetApp> -l dumper.js

as shown in the image below.

Once all the files are downloaded, they can be extracted from the device using the adb pull command.
Important: Before using the adb pull command to extract the downloaded files from the Android device, ensure that you have copied the downloaded files to the device's sdcard.

After downloading the files, you can open them using any disassembler, such as jadx-GUI, as demonstrated.

It’s noticeable that all the folders and files are now visible, as illustrated in the AndroidManifest.xml files under PART I.

PART IV: The Impact

Imagine you’re a savvy security researcher or hacker, diving into the intricate web of code that makes up an application. With hands-on access to the source code, you’re like a digital detective armed with a magnifying glass, meticulously examining each line for clues. As you dissect the code, you uncover vulnerabilities and weaknesses, gaining valuable insights into how the software operates.

In the hands of a skilled security researcher or hacker, the source code becomes a treasure trove of information, providing invaluable insights into the inner workings of the software and empowering you to stay one step ahead of cyber threats.

If you found this write-up beneficial in any way, please consider showing your appreciation with a like. Moreover, don’t hesitate to get in touch if you have any inquiries or concerns. I’m eager to engage and collaborate with many of you in the future.

Author Bio:
Aarav Sinha is a seasoned Senior Security Researcher at FEV India PVT. LTD. With over two years of dedicated experience in application security and nearly four years in overall security, Aarav’s proficiency lies in various domains, including Mobile Application Security, Cloud Infrastructure Security, Wireless Security as well as Thick-Client and Network Security

LinkedIn: AARAV SINHA — Senior security researcher — FEV India Pvt Ltd | Ex-Boschler | LinkedIn

Twitter: https://twitter.com/aarav__avi

--

--