Android Software Reverse Engineering & Decompilation

Extracting Secrets: Reverse Engineering Android Apps for Secure Element-Stored Data

Google AdSense Native Placement - Horizontal Top-Post banner

Introduction to Android Secure Elements

Secure Elements (SEs) on Android devices are tamper-resistant hardware components designed to securely store sensitive data and perform cryptographic operations, isolating critical assets from the main application processor. This makes them ideal for applications requiring high security, such as mobile payments, digital identity, and credential management. Examples include embedded SEs (eSE), Universal Integrated Circuit Cards (UICC/SIM cards), and even Host Card Emulation (HCE) for NFC-based transactions, though HCE is software-based and less relevant to hardware SE reverse engineering. Reverse engineering Android applications that interact with SEs is crucial for security researchers to audit their implementation, identify potential vulnerabilities, and understand how sensitive data is managed. This guide will walk you through the process of statically and dynamically analyzing Android apps to uncover their SE interactions.

Prerequisites for Reverse Engineering

Before diving into the reverse engineering process, ensure you have the following tools and knowledge:

  • Basic understanding of Android application architecture and Java/Kotlin.
  • Familiarity with command-line tools.
  • Knowledge of NFC and APDU (Application Protocol Data Unit) commands.
  • A rooted Android device or an emulator with root access.
  • Essential tools:
    • Jadx-GUI: For decompiling APKs to Java source code.
    • Apktool: For decompiling and recompiling APK resources.
    • Frida: A dynamic instrumentation toolkit for hooking functions at runtime.
    • ADB (Android Debug Bridge): For device interaction.
    • A text editor/IDE: (e.g., VS Code, IntelliJ IDEA).

Understanding Android’s Secure Element Landscape

Android provides an API for applications to interact with Secure Elements, primarily through the

android.se.omapi

package, which implements the GlobalPlatform Open Mobile API (OMAPI) specification. This API allows applications to discover SEs, open sessions, and transmit APDU commands. Key classes include

SecureElementReader

,

SecureElementSession

, and

Channel

. An application typically initiates communication by obtaining an instance of

SecureElementReader

, opening a session, and then opening a logical channel to a specific applet on the SE identified by its AID (Application Identifier). All communication over this channel happens via APDU commands.

Phase 1: Static Analysis of the Android Application (APK)

The first step involves decompiling the target Android application package (APK) to understand its structure and identify potential entry points for SE interaction.

Decompiling the APK

Use Jadx-GUI to decompile the APK. This will give you a navigable view of the application’s Java/Kotlin source code.

jadx-gui your_app.apk

Permission Hunting

Examine the

AndroidManifest.xml

for permissions related to NFC and secure elements. Relevant permissions often include:

  • android.permission.NFC
  • android.permission.BIND_NFC_SERVICE
  • android.permission.MANAGE_SECURE_ELEMENT_SERVICE

These permissions indicate the app’s capability to interact with NFC hardware and SE services.

Identifying SE Interaction Points

Search the decompiled source code for keywords related to the Open Mobile API:

  • android.se.omapi
  • SecureElementReader
  • SecureElementSession
  • Channel
  • openSession
  • openLogicalChannel
  • transmit

Pay close attention to calls to

Channel.transmit(byte[] command)

, as this is where the raw APDU commands are sent to the SE. Analyze the code paths leading to these calls to understand how the APDU commands are constructed and what data they might contain.

// Example snippet from a decompiled app using OMAPIclass MySecureAppletClient {    private SecureElementSession seSession;    private Channel seChannel;    public void connectToApplet(byte[] aid) throws IOException {        SecureElementReader reader = // ... obtain reader from service        seSession = reader.openSession();        seChannel = seSession.openLogicalChannel(aid);    }    public byte[] sendCommand(byte[] apduCommand) throws IOException {        return seChannel.transmit(apduCommand);    }    // ... other methods}

Phase 2: Dynamic Analysis with Frida

Static analysis reveals where SE interactions *might* happen. Dynamic analysis confirms these interactions and allows us to intercept the actual APDU commands being sent and received in real-time.

Setting Up Frida

1. Install Frida on your host machine:

pip install frida-tools

2. Download the Frida server for your Android device’s architecture (e.g.,

frida-server-*-android-arm64

) from the Frida releases page.

3. Push the Frida server to your rooted Android device and make it executable:

adb push frida-server /data/local/tmp/adb shell 'chmod 755 /data/local/tmp/frida-server'

4. Start the Frida server on the device:

adb shell '/data/local/tmp/frida-server &'

Hooking `Channel.transmit()` with Frida

Create a JavaScript Frida script to hook the

transmit

method of the

android.se.omapi.Channel

class. This script will log the outgoing APDU command and the incoming response.

// frida_se_hook.jsJava.perform(function() {    var Channel = Java.use('android.se.omapi.Channel');    Channel.transmit.implementation = function(command) {        var commandHex = Java.array('byte', command).join(' ');        console.log('[+] Sending APDU Command: ' + bytesToHex(command));        var result = this.transmit(command);        var resultHex = Java.array('byte', result).join(' ');        console.log('[-] Received APDU Response: ' + bytesToHex(result));        return result;    };    function bytesToHex(bytes) {        var result = '';        for (var i = 0; i < bytes.length; i++) {            result += ('0' + (bytes[i] & 0xFF).toString(16)).slice(-2).toUpperCase() + ' ';        }        return result.trim();    }});

To run this script against your target application (e.g.,

com.example.secureapp

):

frida -U -l frida_se_hook.js com.example.secureapp

As you interact with the app, Frida will print the APDU commands and responses in your console. This provides invaluable insight into the application’s communication with the Secure Element.

Phase 3: APDU Command Decoding and Analysis

Once you’ve intercepted APDU commands, you need to decode them to understand their purpose. An APDU consists of a Command APDU (C-APDU) and a Response APDU (R-APDU).

Command APDU Structure

A C-APDU typically follows this format:

  • CLA (Class Byte): Identifies the instruction class (e.g., ’00’ for ISO/IEC 7816-4 commands).
  • INS (Instruction Byte): Specifies the command itself (e.g., ‘A4’ for SELECT FILE).
  • P1 (Parameter 1) & P2 (Parameter 2): Further qualify the instruction.
  • Lc (Length of Command Data): The length of the data field (optional).
  • Data Field: The actual command data (optional).
  • Le (Length of Expected Response): The maximum length of expected response data (optional).

Common APDU Commands

  • 00 A4 04 00 [Lc] [AID] [Le]

    : SELECT command to select an applet using its AID.

  • 80 CA 00 00 [Le]

    : GET DATA command to retrieve data objects.

  • Proprietary commands: Many applications use custom CLA/INS bytes for their specific functionalities, which you’ll need to infer or reverse engineer from the application’s logic.

By comparing the intercepted APDUs with the application’s static code analysis, you can map specific APDU sequences to application functionalities, such as user authentication, data encryption, or transaction signing. Look for patterns, hardcoded values, or derivations from user input that form parts of the APDU data field.

Challenges and Ethical Considerations

Reverse engineering Secure Elements comes with challenges:

  • Secure Channel Protocols (SCP): Many SE interactions use SCP (e.g., SCP03, SCP80) to encrypt and MAC the APDU commands, making direct interception and decoding difficult.
  • Obfuscation: Apps often employ code obfuscation to hinder static analysis.
  • Hardware-level protections: Real SEs have physical tamper-detection and anti-cloning mechanisms.

Always conduct reverse engineering ethically and legally. Focus on security research and vulnerability discovery, ensuring responsible disclosure. Never attempt to exploit systems without explicit authorization.

Conclusion

Reverse engineering Android applications for Secure Element interactions is a complex but rewarding process for understanding the security posture of mobile applications. By combining static analysis (Jadx, Apktool) and dynamic instrumentation (Frida) to intercept and decode APDU commands, you can gain deep insights into how sensitive data is managed and protected by hardware-backed security. This knowledge is invaluable for auditing security, identifying weaknesses, and developing stronger, more resilient mobile security solutions.

Android Mobile Specs & Compare Directory

Are you researching mobile hardware properties, processor SoCs, GPU chipsets, or RAM configurations? Access our complete specs catalog to compare up to 5 devices side-by-side!

Compare Devices Specs →
Google AdSense Inline Placement - Content Footer banner