In this post we will look at some basic concepts about Android in a summarized way before we start analyzing malicious files.
Android is based on Linux with the following architecture (very roughly):
When we face reversing in Android applications we have to keep in mind this small map. Starting from the compiled Java/Kotlin code we will have the .dex file, a file containing the compiled code (Dalvik Bytecodes) ready to be executed in the Android virtual machine (ART). Then, using tools like apktool, we will get a code “almost” similar to the original. There are methods for developers that allow them to obfuscate the code, making it difficult to decompile the .dex file.
APK files are just a zip file with the following structure (not always exactly the same):
- META-INF/: Where certificates are hosted.
- lib/: Where you can find compiled libraries in C/C++ in different architectures.
- res/: Contains non-compiled resources such as images, music, “raw binary”…
- assets/: (Optional) Here you can find extra files, which can be loaded from Java code.
- AndroidManifest.xml: File that describes the application, its permissions, components, etc.
- classes.dex: These files are the Java classes compiled to be executed in the Android virtual machine, also called Dalvik Bytecodes.
- resources.arsc: File containing precompiled XML files.
Activities are nothing more than the screens that users see when interacting with the phone. This component has a specific behavior as shown by Google in the following image:
The image shows that the first method that an activity goes through at startup is the onCreate() method. The code containing this method will be the first to be executed.
Services are processes similar to an Activity but that run in the background, i.e., the user does not see that this process is running. Google also offers us a diagram with the life cycle of a service:
You can see in the image that a service can be called by two methods: startService() and bindService(). In either case, the first code to be executed is the onCreate() method, just like in an Activity.
It is part of an application that is listening for an event. When this event occurs, its code is executed. They can be declared either in the AndroidManifest or dynamically using registerReceiver() in the application code.
This last component is nothing more than a mechanism/interface, provided by Android, to access data stored in an application. The data can be stored in a SQLite database or in a system folder, etc.
Intents / Intents filters
We should also discuss what these two elements consist of in the Android environment:
An intent is nothing more than a message that is exchanged between the Android components that we discussed earlier. An intent filter is the declaration of an application (usually in the AndroidManifest) to manage the intents. Intents are used to start an activity, a service or to send a broadcast. There are two types of intents:
- Implicit Intents: intents that do not specify who will be in charge of them, such as an intent with GPS location, when launched, the system searches among all the applications which one has declared in its intent filters that has the capability to manage GPS locations. If it finds several with the same intent filter, it displays a dialog with the options for the user to choose the one he/she wants.
- Explicit Intents: these intents do indicate the application that will process this message.
APK entry points
When performing the static analysis, as it would be done in a compiled binary, it would be to look for the entry points. In Android, we find quite a few entry points:
- Launcher Activity: This is the main Activity and it is the one that is launched when we click on the application icon.
- Exported Components: when any of the Android components are exported, it means that they can be accessed from any other application or event.
- Broadcast Receiver: The Broadcast Receiver code will be executed when the event to which it is listening is triggered.
- Services: As above, the Service can have an “intent filter” defined that launches the service. An example of an event would be: when the system has been started.
- Application Subclass: if the attachBaseContext method is defined, it is called before the OnCreate() method.
- URL schemes / Deeplinks: This entry point would be more oriented to pentesting, although it is always good to know that it exists. It consists of developers declaring a url scheme such as app:// for their applications. When a link in this format is accessed or clicked, application code will be executed.
In coming posts of this series about Android Malware we will follow the same methodology:
- Sample: We will talk a bit about the sample, media repercussion, origin, where we obtained it from.
- Public information: As an initial step in the reversing process, it is good to soak up as much information as possible before starting.
- Static analysis: We will decompile the application and try to get as much information as possible.
- Dynamic analysis: We will install the application, we will analyze its behavior, the generated traffic, etc…
With this theoric introduction out of the way, we have the basic notions we need for reversing an APK.