Android Software Reverse Engineering & Decompilation

Reverse Engineering Android Apps: Locating Private Keys in Dalvik Heap Memory

Google AdSense Native Placement - Horizontal Top-Post banner

Introduction: The Elusive Private Key

In the realm of mobile security and reverse engineering, discovering sensitive data such as API keys, cryptographic keys, and user credentials within an application’s runtime memory is a critical objective. Android applications, like any other software, often handle private keys and other secrets in memory during cryptographic operations (e.g., TLS handshakes, data encryption/decryption, digital signatures). While developers strive to protect these assets using secure storage mechanisms like Android Keystore, these keys inevitably reside in the application’s process memory (the Dalvik/ART heap) at some point, making them a potential target for skilled reverse engineers. This article will guide you through the process of acquiring and analyzing Android application heap dumps to locate these ephemeral yet crucial private keys.

Prerequisites for Memory Forensics

Before diving into heap analysis, ensure you have the following tools and environment set up:

  • Rooted Android Device or Emulator: Necessary to access process memory and perform heap dumps.
  • ADB (Android Debug Bridge): For interacting with the device.
  • Memory Analysis Tools:
    • hprof-conv: A utility to convert raw HPROF dumps into a standard format readable by Java heap analyzers.
    • Eclipse Memory Analyzer Tool (MAT) or YourKit Java Profiler: Powerful GUI tools for deep heap analysis.
    • JHAT (Java Heap Analysis Tool): A command-line tool included with the JDK, useful for quick inspection.
    • Basic Linux Utilities: strings, grep, xxd for initial triage.
  • Target Application: An Android application whose private keys you aim to locate. For demonstration, a simple app performing some encryption/decryption is ideal.

Understanding Android Application Memory

Android applications run within their own Dalvik (or ART in newer versions) virtual machine instances, each having its isolated process memory space. The Dalvik/ART heap is where all dynamically allocated objects reside, including instances of classes, arrays, strings, and other data structures. When an application performs cryptographic operations, private keys might be loaded into memory as byte[] arrays, char[] arrays, or even String objects, depending on the implementation and key format (e.g., PEM, DER, raw bytes). While garbage collection eventually reclaims unused memory, a key’s sensitive data can persist for some time, making a timely memory dump crucial.

Step 1: Acquiring the Heap Dump

The primary method for acquiring a heap dump from an active Android application process is using adb shell am dumpheap. This command triggers the Dalvik/ART VM to write its heap contents to a specified file in the HPROF format.

1.1 Identify the Target Process ID (PID)

First, find the PID of your target application. Launch the app and then use adb shell ps -A | grep <package_name>.

adb shell ps -A | grep com.example.targetapp# Example Output:# u0_a123   12345 1234  1234568 123456 SyS_epoll_wait       0 S com.example.targetapp

Note down the PID (e.g., 12345).

1.2 Dump the Heap Memory

Now, use the am dumpheap command. It’s crucial to dump the heap when you suspect the private key is actively in memory (e.g., immediately after an encryption operation).

adb shell am dumpheap <PID> /data/local/tmp/heapdump.hprof# Example:adb shell am dumpheap 12345 /data/local/tmp/heapdump.hprof

This command saves the HPROF file to /data/local/tmp on the device.

1.3 Pull the Heap Dump to Your Host Machine

Use adb pull to retrieve the HPROF file.

adb pull /data/local/tmp/heapdump.hprof .

1.4 Convert the HPROF File

Android’s HPROF format is slightly different from the standard Java HPROF. You need to convert it using hprof-conv, which is usually found in your Android SDK’s platform-tools directory.

# Navigate to your Android SDK platform-tools directory or add it to PATH# /path/to/android-sdk/platform-tools/hprof-conv heapdump.hprof converted_heapdump.hprofhprof-conv heapdump.hprof converted_heapdump.hprof

The converted_heapdump.hprof is now ready for detailed analysis.

Step 2: Analyzing the Heap Dump for Private Keys

With the converted HPROF file, you can now begin the forensic analysis. This involves a multi-pronged approach, starting with quick string searches and progressing to more sophisticated object graph analysis.

2.1 Initial Triage with strings and grep

Sometimes, keys are stored as simple strings or byte sequences that are human-readable (or nearly so). strings can extract all printable strings from the binary dump, and grep can filter for common key patterns.

strings converted_heapdump.hprof | grep -i "private key"strings converted_heapdump.hprof | grep -i "BEGIN RSA PRIVATE KEY"strings converted_heapdump.hprof | grep -i "BEGIN ENCRYPTED PRIVATE KEY"strings converted_heapdump.hprof | grep -i "secret"strings converted_heapdump.hprof | grep -E "[0-9a-fA-F]{32,}" # search for long hex strings

You can also look for base64 encoded strings, as many keys are transmitted or stored in this format. This method is fast but often misses keys stored in raw byte arrays or obfuscated forms.

2.2 Deep Dive with Eclipse Memory Analyzer Tool (MAT)

Eclipse MAT is an invaluable tool for comprehensive heap analysis.

  1. Load the HPROF: Open MAT and select “File > Open Heap Dump” and choose your converted_heapdump.hprof file.
  2. Overview and Dominator Tree: Review the initial reports. The “Dominator Tree” shows which objects retain the most memory, which can sometimes point to large data structures holding keys.
  3. Searching for Class Instances:
    • Go to “Window > Open Query Browser” or use the search box.
    • Look for instances of classes commonly associated with cryptography:
      • java.lang.String
      • [C (char array, for password/key material)
      • [B (byte array, common for raw key material)
      • javax.crypto.spec.SecretKeySpec
      • java.security.PrivateKey (interface)
      • java.security.KeyPair
      • java.security.KeyStore
      • Specific algorithm implementations (e.g., com.android.org.conscrypt.OpenSSLRSAPrivateKey)
    • Right-click on an interesting class (e.g., [B for byte arrays) and select “List Objects > with outgoing references” or “List Objects > with incoming references” to understand how it’s used.
  4. Object Query Language (OQL): MAT supports a powerful OQL similar to SQL. This allows precise searching.
  5. SELECT * FROM java.lang.String s WHERE s.toString().contains("BEGIN PRIVATE KEY")SELECT * FROM byte[] b WHERE b.@length > 16 AND b.@length < 2048 # Search for byte arrays of plausible key lengthsSELECT * FROM char[] c WHERE c.@length > 16 AND c.@length < 2048SELECT * FROM INSTANCEOF java.security.PrivateKey

    When you find a byte[] or char[] of interest, right-click it and choose “Copy > Save Value To File…” or “Copy > Value” to inspect its raw content. You might need xxd or a hex editor to interpret raw byte arrays.

Challenges and Advanced Techniques

Locating keys isn’t always straightforward. Developers employ various techniques to make this harder:

  • Memory Encryption/Obfuscation: Keys might be encrypted in memory and only decrypted just before use, making their plaintext presence fleeting.
  • Secure Memory Allocation: Some platforms or libraries attempt to zero out memory after sensitive data is no longer needed or allocate it in unswappable regions, though this is less common on Android user-space.
  • Dynamic Key Generation: Keys might be derived on the fly, reducing their storage time.
  • Native Code (JNI): Keys might be handled entirely in native C/C++ code, making them harder to find with Java heap analysis tools. In such cases, native memory dumping (/proc/<pid>/mem and using tools like Volatility or Frida for live memory analysis) becomes necessary.

For native memory analysis, tools like Frida can intercept function calls, dump memory regions, and even hook into cryptographic libraries to extract keys before they are encrypted or zeroed out. However, this article focuses on Dalvik/ART heap analysis.

Conclusion

Extracting private keys from an Android application’s heap memory is a powerful reverse engineering technique that can expose critical vulnerabilities or reveal proprietary cryptographic implementations. While developers implement various protections, keys invariably reside in plaintext in memory at some point during their lifecycle. By carefully acquiring timely heap dumps and employing a combination of basic string analysis and advanced heap analysis tools like Eclipse MAT with OQL, reverse engineers can often uncover these hidden secrets. Mastering these techniques is essential for anyone involved in mobile application security analysis, penetration testing, or forensic investigations.

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