Android Software Reverse Engineering & Decompilation

Xposed Module RE Case Study: Unpacking & Analyzing Malware Behavior

Google AdSense Native Placement - Horizontal Top-Post banner

Introduction to Xposed for Android Reverse Engineering

The Android ecosystem, with its vast array of applications, unfortunately also harbors a significant number of malicious ones. Analyzing these threats effectively often requires dynamic instrumentation to overcome obfuscation, packing, and anti-analysis techniques. The Xposed Framework stands out as a powerful tool in this arsenal, enabling modifications to the behavior of applications and the system at runtime without modifying their APKs. This makes it invaluable for reverse engineering (RE) and malware analysis, allowing researchers to hook into any method of any application, modify parameters, inspect return values, and even inject custom code.

This case study will demonstrate how to leverage Xposed modules to unpack a hypothetical piece of Android malware and subsequently analyze its runtime behavior. We will focus on overcoming dynamic DEX loading, a common packing technique, and then monitoring sensitive API calls.

Setting Up Your Xposed Environment

Before diving into module development, ensure you have an Android device or emulator with the Xposed Framework installed. This typically involves rooting the device, installing the Xposed Installer APK, and then flashing the Xposed framework via a custom recovery (like TWRP). For development, you’ll need Android Studio and a basic understanding of Android application development.

Xposed Module Project Structure

An Xposed module is essentially an Android application project. You’ll need to include the Xposed API library in your project dependencies and declare your module within the `AndroidManifest.xml`.

dependencies {    implementation 'de.robv.android.xposed:api:82'    provided 'de.robv.android.xposed:api:82:sources'}

In your `AndroidManifest.xml`, declare the module properties:

<application ...>    <meta-data        android:name="xposedmodule"        android:value="true" />    <meta-data        android:name="xposeddescription"        android:value="Malware Unpacking & Analysis Module" />    <meta-data        android:name="xposedminversion"        android:value="54" /></application>

Your primary module class must implement IXposedHookLoadPackage:

public class MainHook implements IXposedHookLoadPackage {    @Override    public void handleLoadPackage(XC_LoadPackage.LoadPackageParam lpparam) throws Throwable {        // Your hooking logic goes here    }}

Case Study: Unpacking Dynamically Loaded DEX Files

Many Android malware samples employ dynamic DEX loading to evade static analysis. The core malicious payload is often encrypted or obfuscated within the APK’s assets or resources and then loaded at runtime using a DexClassLoader. Our goal is to intercept this loading process and extract the dynamically loaded DEX.

Identifying the Unpacking Mechanism

A common method for dynamic DEX loading involves `dalvik.system.DexClassLoader` or `java.lang.ClassLoader`. Malware typically reads a payload from an asset, decrypts it, and then passes the byte array or a path to a `DexClassLoader` constructor or a similar method like `DexFile.loadDex`. We’ll target `DexFile.loadDex` as it’s a lower-level function often called indirectly by `DexClassLoader`.

Developing the Unpacking Module

We’ll hook `dalvik.system.DexFile`’s `loadDex` method. This method takes a path to a DEX file and other parameters. By hooking it, we can log the path and even copy the DEX file to an external location.

public class UnpackingHook implements IXposedHookLoadPackage {    private static final String TAG = "XposedMalwareRE";    private static final String TARGET_PACKAGE = "com.example.malwareapp"; // Replace with actual package name    @Override    public void handleLoadPackage(XC_LoadPackage.LoadPackageParam lpparam) throws Throwable {        if (!lpparam.packageName.equals(TARGET_PACKAGE)) {            return;        }        XposedBridge.log(TAG + ": Hooking package: " + lpparam.packageName);        // Hook DexFile.loadDex to capture dynamically loaded DEX files        XposedHelpers.findAndHookMethod(            "dalvik.system.DexFile", lpparam.classLoader,            "loadDex", String.class, String.class, int.class,            new XC_MethodHook() {                @Override                protected void beforeHookedMethod(MethodHookParam param) throws Throwable {                    String dexPath = (String) param.args[0];                    XposedBridge.log(TAG + ": Detected dynamic DEX load! Path: " + dexPath);                    // Optionally, copy the DEX file to /data/data/com.example.yourmodule/files/                    // This requires your Xposed module to have WRITE_EXTERNAL_STORAGE permission                    // and target API 29- for external storage, or use /data/local/tmp for root access.                    // For simplicity, we'll just log the path.                    // File source = new File(dexPath);                    // File dest = new File("/data/local/tmp/extracted_" + source.getName());                    // Files.copy(source.toPath(), dest.toPath(), StandardCopyOption.REPLACE_EXISTING);                    // XposedBridge.log(TAG + ": DEX copied to: " + dest.getAbsolutePath());                }            }        );    }}

After deploying this module and running the target malware, you can monitor `logcat` for entries tagged `XposedMalwareRE`. If the malware uses `DexFile.loadDex`, you’ll see the paths to its dynamically loaded DEX files. You can then pull these files off the device using `adb pull` for further static analysis (e.g., with Jadx or Ghidra).

Analyzing Malware Behavior with Xposed Hooks

Once the malware is unpacked, or if it doesn’t use packing, we can proceed to analyze its runtime behavior by hooking into sensitive API calls. Malware often interacts with various system services, performs network operations, accesses sensitive data, or tries to escalate privileges.

Common Targets for Behavioral Analysis

Here’s a list of typical API categories malware interacts with and corresponding methods to hook:

  • SMS & Telephony:android.telephony.SmsManager.sendTextMessage, android.telephony.TelephonyManager.getDeviceId
  • Network Communication:java.net.URL.openConnection, java.net.Socket.connect, okhttp3.OkHttpClient.newCall (for modern apps)
  • File System Access:java.io.File.createNewFile, java.io.FileOutputStream.write, java.io.FileInputStream.read
  • Device Administration:android.app.admin.DevicePolicyManager.setActiveAdmin
  • Reflection & Dynamic Code Loading:java.lang.Class.forName, java.lang.reflect.Method.invoke
  • Process Execution:java.lang.Runtime.exec, android.os.Process.start
  • Inter-Process Communication (IPC):android.content.ContentResolver.query, android.content.Intent.sendBroadcast

Developing the Behavioral Analysis Module

Let’s extend our module to monitor some of these interactions. We’ll add hooks for sending SMS, network connections, and device admin activation.

public class BehaviorHook implements IXposedHookLoadPackage {    private static final String TAG = "XposedMalwareRE";    private static final String TARGET_PACKAGE = "com.example.malwareapp"; // Replace with actual package name    @Override    public void handleLoadPackage(XC_LoadPackage.LoadPackageParam lpparam) throws Throwable {        if (!lpparam.packageName.equals(TARGET_PACKAGE)) {            return;        }        XposedBridge.log(TAG + ": Analyzing behavior for package: " + lpparam.packageName);        // Hook SMS sending        XposedHelpers.findAndHookMethod(            "android.telephony.SmsManager", lpparam.classLoader,            "sendTextMessage", String.class, String.class, String.class,            android.app.PendingIntent.class, android.app.PendingIntent.class,            new XC_MethodHook() {                @Override                protected void beforeHookedMethod(MethodHookParam param) throws Throwable {                    XposedBridge.log(TAG + ": SMS Sent! To: " + param.args[0] + ", Message: " + param.args[2]);                }            }        );        // Hook network connections (simplified - consider more robust network hooking for production)        XposedHelpers.findAndHookConstructor(            "java.net.URL", lpparam.classLoader, String.class,            new XC_MethodHook() {                @Override                protected void afterHookedMethod(MethodHookParam param) throws Throwable {                    URL url = (URL) param.thisObject;                    XposedBridge.log(TAG + ": URL connection attempt to: " + url.toString());                }            }        );        // Hook DevicePolicyManager to detect device admin requests        XposedHelpers.findAndHookMethod(            "android.app.admin.DevicePolicyManager", lpparam.classLoader,            "setActiveAdmin", android.content.ComponentName.class, boolean.class,            new XC_MethodHook() {                @Override                protected void beforeHookedMethod(MethodHookParam param) throws Throwable {                    ComponentName componentName = (ComponentName) param.args[0];                    XposedBridge.log(TAG + ": Request to set active admin: " + componentName.flattenToShortString());                }            }        );    }}

Deployment and Monitoring

  1. Compile Your Module: Build your Android project in Android Studio to generate an APK.
  2. Install on Device: Use `adb install your-module.apk` to install it on your Xposed-enabled device.
  3. Activate Module: Open the Xposed Installer app, navigate to ‘Modules’, and check the box next to your module. Reboot the device (soft reboot usually suffices).
  4. Run Malware: Launch the target malware application.
  5. Monitor Logs: Use `adb logcat -s XposedMalwareRE` to filter and view the output from your Xposed hooks. This will display the intercepted calls and their parameters.
adb install /path/to/your-module.apkadb shell rebootadb logcat -s XposedMalwareRE

Conclusion

Xposed Framework provides an exceptionally powerful platform for dynamic analysis of Android applications, particularly valuable in the realm of malware reverse engineering. By strategically hooking into key Android API methods, we can overcome common anti-analysis techniques like dynamic packing and gain deep insights into a malware’s runtime behavior. This case study provided a foundational understanding of developing Xposed modules for unpacking dynamically loaded DEX files and monitoring sensitive API interactions. Mastering these techniques significantly enhances an analyst’s ability to understand, track, and mitigate Android threats.

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