Sunday, 19 March 2017

Creating a new Xposed module in Android

How Xposed works

Before we start lets see how Xposed works -

There is a process that is called "Zygote". This is the heart of the Android runtime. Every application is started as a copy ("fork") of it. This process is started by an /init.rc script when the phone is booted. The process start is done with /system/bin/app_process, which loads the needed classes and invokes the initialization methods.

This is where Xposed comes into play. When you install the framework, an extended app_process executable is copied to /system/bin. This extended startup process adds an additional jar to the classpath and calls methods from there at certain places. For instance, just after the VM has been created, even before the main method of Zygote has been called. And inside that method, we are part of Zygote and can act in its context.

The jar is located at /data/data/de.robv.android.xposed.installer/bin/XposedBridge.jar and its source code can be found here. Looking at the class XposedBridge, you can see the main method. This is what I wrote about above, this gets called in the very beginning of the process. Some initializations are done there and also the modules are loaded.

Creating a new Xposed module in Android

I have couple of app on playstore . I am going to use FlashLight to demonstrate Xposed module.

  • Create a normal Android app. Add following extra meta data in the apps manifest file. This is how xposed installer app knows your apk is a xposed module.

        <meta-data
            android:name="xposedmodule"
            android:value="true" />
        <meta-data
            android:name="xposeddescription"
            android:value="Demo example that renders Flashlight app (com.osfg.flashlight) useless" />
        <meta-data
            android:name="xposedminversion"
            android:value="53" />

  • Next create a class that implements IXposedHookLoadPackage like below -

public class XPFlashLightKiller implements IXposedHookLoadPackage {
    @Override
    public void handleLoadPackage(XC_LoadPackage.LoadPackageParam loadPackageParam) throws Throwable {

        if (!loadPackageParam.packageName.equals("com.osfg.flashlight"))
            return;

        XposedBridge.log("Loaded app: " + loadPackageParam.packageName);

        XposedHelpers.findAndHookMethod("com.osfg.flashlight.FlashLightActivity", loadPackageParam.classLoader, "isFlashSupported", new XC_MethodHook() {
            @Override
            protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
                // this will be called before the clock was updated by the original method
            }
            @Override
            protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                // this will be called after the clock was updated by the original method
                XposedBridge.log("Hooken method isFlashSupported of class com.osfg.flashlight.FlashLightActivity");
                param.setResult(false);
            }
        });
    }
}

  • Next create a file called xposed_init in your assets folder and add your fully qualified class name to it. This file tells xposed installer where to look for the module class. For eg in our case it will be -
com.osfg.flashlightxpmodule.XPFlashLightKiller


  • Finally download XposedbridgeApi.jar from here and add it in your app folder. Make sure the version of this jar should be same as xposedminversion set in the meta data tags in step 1.
Now build your app and deploy on your device. Once done Xposed installed should detect it. Just enable the module and reboot the device -



Testing out the module


Just to give you some background on the original Flashlight app. It's code is something like below -

    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults)
    {
        switch (requestCode)
        {
            case CAMERA_PERMISSION:
                if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    Log.d(TAG, "Received Camera permission");
                    if(!isFlashSupported()) {
                        Toast.makeText(getApplicationContext(), "LED Flash is not supported on your device",Toast.LENGTH_LONG).show();
                        finish();
                    }

                }
                else {
                    Log.d(TAG, "Camera permission denied");
                    Toast.makeText(this, "Please provide camera permission", Toast.LENGTH_SHORT).show();
                    finish();
                }
                return;
        }
    }



It first asks for permission. If you give it then it will check if flash is supported on the device. So if you have already given Flashlight app camera permission then remove it from settings and open the app again. Now when it prompts for permissions again give it. But now you can see that the app shuts down with toast message - "Flash not supported on this device". This is because we hooked into isFlashSupported() method and made it always return false. So that the app never works :)

NOTE : From next time it will work fine. Since permission is already given next time it will not prompt and never execute  isFlashSupported() method. To retest remove the permissions from settings again.





You can also see following line in logcat -

03-20 02:36:37.864 8002-8002/? I/Xposed: Loaded app: com.osfg.flashlight

03-20 02:36:44.123 8002-8002/? I/Xposed: Hooken method isFlashSupported of class com.osfg.flashlight.FlashLightActivity


Complete code is added in my github repo -

Related Links


Installing Xposed Framework on Android devices

Background

Android as you know is very flexible and developer friendly. It runs a Linux kernel underneath with some modifications needed to operate handheld devices with relatively less memory. You can root your device to further boost its potential application. You can do stuff with root access now. You can even take it a step further - Unlock boot-loader and install customer recovery like ClockworkMod or TWRP (We are going to work with TWRP in this post). Custom recovery software's let you install custom mods or even full ROMs that can drastically improve user experience.

Xposed is a framework that can alter the the way your applications work, give you more control over it without actually flashing any custom ROMs or MODs or even tampering any of the apks. It uses root privileges to access androids core resources and use it to change the androids behavior .It's potential power is unlimited. We will see how to install and use it in a while.

NOTE : Xposed uses root privileges i.e device needs to be rooted.

Xposed is a framework once installed you can create and install various modules to alter apps/android behavior. Best part about this is that the modules are held in memory. So to get back the system to original state all you need to do is uninstall the module and reboot the device.




NOTE : Works on Android 4.0.3 (ICS) and above only.

Xposed framework is brought to us by XDA Recognized Developer rovo89.

Warning : This required rooting your device and changing some androids base resources. Follow this guide on your own risk. We are not liable if you phone gets bricked or damaged in the process.

 Installation and Setup

Make sure your device is recognized by adb (connect your device to your laptop having android SDK using a USB) -


NOTE : If you adb is not able to detect or recognize your device then you may refer to link in the Related Section at the end of this post.

Before you start Xposed has two parts to it -
  1. Xposed Framework : Lays down all the groundwork for the framework
  2. Xposed Installer app : Apk use to manage Xposed modules.
Download the framework from -
Choose based on your the sdk version you have on your android device.

You can download the latest xposed installer from  -
First we are going to flash custom recovery image - TWRP on our Android device. So first reboot in bootloader mode using following command -
  • adb reboot bootloader
You device should reboot now and you should see following screen -


Once you reach above screen adb will not work. You need to use fastboot instead. You can type following command to make sure your device is still connected -
  • fastboot devices



 Now lets flash our recovery image. Use following commands to do so -
  • fastboot flash recovery /Users/athakur/Desktop/xposed/twrp-3.0.2-0-hammerhead.ndif
 You can download the image from here. Above command obviously has path to the image from my local machine. You need to replace it accordingly.



Once done navigate to Recovery mode by navigating using vol up/down button. Once on Recovery mode press power button to enter it.




Now go to install and install the Xposed framework - the zip file we downloaded earlier and then reboot.




On reboot install the Xposed installed apk. On install open it -




Here your Xposed  setup and installation is complete. You can create and install modules going in Modules section of installer as shown in screenshots above. We will see how to create modules in upcoming post. So stay tuned!

Good to Know 

What is Fastboot? : Fastboot is a protocol that can be used to re-flash partitions on your android device (update the flash file system in your Android devices). It comes with the Android SDK (Software Developer Kit) and can be user as an alternative to the Recovery Mode for doing installations and updates.

What is Android recovery image? : A bootable program on an Android flash memory partition (/recovery) that is used to perform a factory reset or restore the original OS version. You can also install a different OS version (a different ROM). For that the stock recovery image must be replaced with a custom version such as ClockworkMod Recovery or TWRP (as we are doing).

Related Links


t> UA-39527780-1 back to top