Skip to main content

App Architecture

The Android operating system uses open source software run on a wide range of devices, with its foundation being based on the Linux kernel. The applications that run on an Android device must be properly signed, and isolated to run in a sandboxed environment.

The apps are built to execute in the Android Runtime (ART), on version 4.4 and later. Typically, the Java programming is used to build Android apps, though recently there have been introductions of other languages such as Kotlin. Additionally, Android will support hybrid apps that are built in HTML5 and JavaScript, then ran in a WebView browser on the device.

App Components

Activities – Activities can be considered the “views” of the app. Defined in the AndroidManifest.xml file using the <activity> tag. Read more about activities: https://developer.android.com/guide/components/activities/intro-activities

Services – Services typically perform some sort of processing in the background. Defined in the AndroidManifest.xml file using the <service> tag. Read more about services: https://developer.android.com/guide/components/services

Content Providers – Providers return data, usually from a database or static file on the device. Defined in the AndroidManifest.xml file using the <provider> tag. Read more about Content Providers: https://developer.android.com/guide/topics/providers/content-providers

Receivers and Broadcast Receivers – Receives data from the intents and then performs some action based on that data. Defined in the AndroidManifest.xml file using the <receiver> tag. Read more about Receivers: https://developer.android.com/guide/components/broadcasts

Intents

Android app components interact with the system and other apps through Intents and are controlled by the android:exported attribute in the AndroidManifest.xml. An intent-filter declares the capabilities of a component, specifying which types of implicit intents it can receive. This allows the system to determine which component is best suited to handle a particular intent, such as opening a web link or sharing an image.

Exported Attribute

The android:exported attribute sets whether the component is able to be launched from another application. It is a boolean value (true/false) and should always be included for the component entry in AndroidManifest.xml file. If this attribute is set to true, any app can access the activity and launch it by its exact class name. If false, only components of the same application, or privileged system components can launch the activity.

If the component has an intent filter then it can generally be assumed that the component is exported, even if the attribute is not included.

There are two types of intent filters; Explicit & Implicit. An explicit intent specifies which app will satisfy the intent using the correct component name. An implicit intent is one that does not specify a specific component to use, which can open this up to malicious actions from another app. From a security perspective, the app should always use an explicit intent to ensure the app functions as expected.


APK Structure

Android apps are typically built into an Android Package (APK) format. While you can simply “unzip” an APK file, many of the files inside are encoded, or binary in nature. So, it will make it more difficult to review the files by doing that. There are other tools that we will use that can extract and decode the files so that we can review them. In fact, you can extract an APK, modify it and then repackage it. We will do that in part 3, but for now just know that it can be easily done.

The list below will outline the structure of an APK file, so you will know where to look for certain files. To read more about the APK, follow this link.

  • META-INF
    • Certificate used for signing
  • lib
    • A directory based on the device architecture
  • res
    • Resources for the app that do not need to be compiled
  • assets
    • Application assets
  • AndroidManifest.xml
    • This file defines many configuration aspects of the app
    • This is very important to during our tests
  • classes.dex
    • The classes.dex file – this is the “binary” that is executed
    • Large apps may have more than one classes.dex files. If so, they are labeled with a number.
      • classes.dex
      • classes2.dex
      • classes3.dex
      • etc…
  • resources.arsc
    • Contains precompiled resources, such as binary XML files

SMALI

SMALI is the disassembled format of the DEX files. When we are performing our static analysis, we will disassemble the compiled DEX code back to the SMALI format. This is a “slightly” easier to read language than pure assembly code that you would find in x86 or ARM applications. It is not required that you obtain a full understanding of the SMALI format, but we will dive into it pretty in the reverse engineering section.