Android App Penetration Testing & Frida Hooks

Mastering Android App Reverse Engineering: A Step-by-Step Workflow Guide for Pen Testers

Google AdSense Native Placement - Horizontal Top-Post banner

Introduction to Android App Reverse Engineering

Android applications are a prime target for penetration testers. Understanding their inner workings, identifying vulnerabilities, and verifying security measures often requires reverse engineering. This guide provides a comprehensive, step-by-step workflow for pen testers to master Android app reverse engineering, focusing on practical tools and techniques, including the powerful Frida framework.

The Android App Reverse Engineering Workflow

A structured approach is crucial for effective reverse engineering. We’ll cover the essential phases from environment setup to dynamic analysis.

Phase 1: Environment Setup and Tooling

Before diving into an APK, ensure your testing environment is properly configured. A rooted Android device or emulator is essential for dynamic analysis.

  • Rooted Device/Emulator: Genymotion, Android Studio Emulator (with root access), or a physical rooted device (e.g., a Google Pixel with Magisk).
  • ADB (Android Debug Bridge): For interacting with the device. Ensure it’s in your PATH.
  • Decompilers/Disassemblers:
    • Jadx-GUI: Excellent for converting Dalvik bytecode (DEX) to readable Java.
    • Apktool: For disassembling resources and Smali code, and reassembling APKs.
  • Dynamic Analysis Tools:
    • Frida: A dynamic instrumentation toolkit for injecting scripts into running processes.
    • Objection: Built on top of Frida, offers a higher-level API for common runtime tasks (e.g., SSL pinning bypass, root detection bypass, enumeration).

Installation Example (Kali Linux/Ubuntu):

sudo apt update
sudo apt install apktool adb openjdk-11-jdk
pip3 install frida-tools objection
# Download Jadx-GUI from GitHub releases and extract it
# Ensure adb is in your PATH and devices are authorized:
# adb devices

Phase 2: APK Acquisition and Initial Inspection

Obtain the target APK and perform a preliminary examination.

  1. Acquire the APK:
    • From a physical device: adb shell pm path com.target.app followed by adb pull /data/app/.../base.apk
    • From online repositories: APKMirror, APKPure.
    • From Google Play (using a downloader tool if needed).
  2. Decompile with Apktool:

    This extracts resources, AndroidManifest.xml, and Smali code.

    apktool d target.apk -o target_decompiled
  3. Decompile with Jadx-GUI:

    Open the target.apk directly in Jadx-GUI to get a browsable Java source view.

    # Run jadx-gui (assuming it's in your PATH or you navigate to its directory)
    jadx-gui target.apk

Phase 3: Static Analysis – Unveiling Secrets and Logic

Carefully examine the decompiled code and resources without running the app. This is where many critical vulnerabilities are often discovered.

  • AndroidManifest.xml:

    Examine permissions, exported components (activities, services, broadcast receivers, content providers), custom URL schemes, and security configurations (e.g., android:debuggable="true", network_security_config).

    <activity android:name=".SecretActivity" android:exported="true" />
    <permission android:name="com.target.permission.READ_DATA" android:protectionLevel="signature" />
  • Strings and Resources:

    Look for hardcoded API keys, sensitive URLs, credentials, encryption keys, and interesting debug messages in res/values/strings.xml or custom XML files. Search the entire target_decompiled directory.

    grep -r "API_KEY" target_decompiled/
    grep -r "password" target_decompiled/
  • Java/Smali Code Review:
    • Entry Points: Start from MainActivity or exported components.
    • Security Features: Identify root detection, SSL pinning, tamper detection, obfuscation.
    • Sensitive Operations: Data storage (SharedPreferences, databases), cryptography, network communications, inter-process communication (IPC).
    • Business Logic: Understand how authentication, authorization, and core features are implemented.

    Look for patterns like Base64.decode, Cipher.getInstance, SharedPreferences, SQLCipher usage.

Phase 4: Dynamic Analysis – Runtime Inspection with Frida and Objection

Static analysis provides a blueprint, but dynamic analysis allows you to observe and manipulate the app’s behavior at runtime. Frida is indispensable here.

  1. Setup Frida Server:

    Download the correct Frida server binary for your device’s architecture (e.g., frida-server-16.x.x-android-arm64).

    # Push to device
    adb push frida-server /data/local/tmp/
    # Make executable and run
    adb shell "chmod 755 /data/local/tmp/frida-server && /data/local/tmp/frida-server &"

    Verify it’s running: frida-ps -U

  2. Leveraging Objection:

    Objection simplifies common dynamic tasks significantly.

    • Bypassing SSL Pinning:
      objection -g com.target.app explore
      android sslpinning disable
    • Bypassing Root Detection:
      android root disable
    • Enumerating Classes and Methods:
      android hooking list classes
      android hooking search classes "Auth"
      android hooking search methods "login"
    • Hooking Methods and Dumping Arguments/Return Values:
      android hooking watch class_method "com.target.app.AuthManager.login" --dump-args --dump-backtrace --dump-return
  3. Writing Custom Frida Scripts:

    For more specific or complex interactions, write your own JavaScript hooks.

    /* frida_hook_example.js */
    Java.perform(function () {
        var MainActivity = Java.use("com.target.app.MainActivity");
        MainActivity.onCreate.implementation = function () {
            console.log("[*] MainActivity.onCreate called!");
            this.onCreate();
        };
    
        var SecretFunc = Java.use("com.target.app.SecretUtil");
        SecretFunc.performSensitiveOperation.implementation = function (arg1, arg2) {
            console.log("[*] SecretFunc.performSensitiveOperation called with args: " + arg1 + ", " + arg2);
            var result = this.performSensitiveOperation(arg1, arg2);
            console.log("[*] SecretFunc.performSensitiveOperation returned: " + result);
            return result;
        };
    });

    Run the script:

    frida -U -l frida_hook_example.js -f com.target.app --no-pause

Phase 5: Code Modification and Rebuilding (Advanced)

Sometimes, modifying the app’s logic is necessary, for example, to disable certain security checks or inject debug logging.

  1. Modify Smali Code:

    After apktool d, navigate to the smali directories and edit the .smali files. For instance, changing a conditional jump (if-eqz to goto) to bypass a check.

  2. Rebuild the APK:
    apktool b target_decompiled -o modified.apk
  3. Sign the APK:

    Modified APKs need to be signed with a new debug key.

    keytool -genkey -v -keystore debug.keystore -alias debug_alias -keyalg RSA -keysize 2048 -validity 10000
    jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 -keystore debug.keystore modified.apk debug_alias
  4. Zipalign (Optional, but good practice):

    Optimizes the APK for better resource alignment.

    zipalign -v 4 modified.apk modified_aligned.apk
  5. Install and Test:
    adb install modified_aligned.apk

Conclusion

Mastering Android app reverse engineering is a critical skill for any penetration tester. By systematically approaching the problem with a combination of static and dynamic analysis techniques, leveraging powerful tools like Jadx-GUI, Apktool, Frida, and Objection, you can effectively uncover vulnerabilities and assess the security posture of Android applications. Remember, it’s an iterative process: findings from dynamic analysis often lead back to static code review for deeper understanding.

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