Introduction of Xpose

  • Xposed is a module framework that can change the behavior of the system and applications without touching any APK (root required).
  • [Features] For example, for an app installed on the phone, you can use Xpose to call methods, hook methods, modify fields and so on.
  • 【 principle 】 Android all processThe parent classisZygote(incubation) process, and the corresponding execution file of Zygote is/system/bin/app_process. The Xpose principle is that they wrote one themselvesapp_process, into the/system/bin/Come down and replace the originalapp_process. After transforming theapp_processA hook method executes its own method each time a method is called.
  • How Xposed Works

Modify location core code

    XposedHelpers.findAndHookMethod("com.amap.api.location.AMapLocation", realClassLoader, "getLongitude".object : XC_MethodHook() {
        @Throws(Throwable::class)
        override fun beforeHookedMethod(param: MethodHookParam) {
            super.beforeHookedMethod(param)
        }

        @Throws(Throwable::class)
        override fun afterHookedMethod(param: MethodHookParam) {
            super.afterHookedMethod(param)
            param.result = (param.result as Double) + offset// Offset = target longitude - actual longitude, only need to calculate once}})Copy the code

Have a problem

The above code, for unhardened APK, works perfectly. But if the APK has been reinforced, the report is wrong

The 2021-02-25 15:29:00. 733, 24238-24238 /? E/EdXposed-Bridge: de.robv.android.xposed.XposedHelpers$ClassNotFoundError: java.lang.ClassNotFoundException: com.amap.api.location.AMapLocation at de.robv.android.xposed.XposedHelpers.findClass(XposedHelpers.java:71) at de.robv.android.xposed.XposedHelpers.findAndHookMethod(XposedHelpers.java:260)Copy the code

To analyze problems

Why do I call ClassNotFoundError when I have this class? After understanding the hardening principle, we learned that the app was packaged and changed the classLoader. Therefore, we used the original classLoader to report an exception that could not be found by the class. Application has been replaced with com.stub.stubApp.

 <application
        android:theme="@ref/0x7f11010e"
        android:label="@ref/0x7f10009b"
        android:icon="@ref/0x7f0e0015"
        android:name="com.stub.StubApp"
        android:allowBackup="false"
        android:hardwareAccelerated="true"
        android:largeHeap="true"
        android:supportsRtl="true"
        android:usesCleartextTraffic="true"
        android:networkSecurityConfig="@ref/0x7f130006"
        android:appComponentFactory="androidx.core.app.CoreComponentFactory"
        android:requestLegacyExternalStorage="true">

Copy the code

The com.stub.StubApp is in the unshelled classes.dex file.

package com.stub;

public final class StubApp extends Application {
    private static Application b;
      
    private static Application a(Context paramContext) {
        try {
            if (b == null) {
                ClassLoader classLoader = paramContext.getClassLoader();
                if(classLoader ! =null) { Class<? > clazz = classLoader.loadClass(strEntryApplication);if(clazz ! =null) b = (Application)clazz.newInstance(); }}}catch (Exception exception) {}
        return b;
    }

    protected final void attachBaseContext(Context paramContext) {
        / /... Leaving out a lot of code
        b = a(paramContext);    
        / /... Leaving out a lot of code}}Copy the code

The classloader has been replaced here, so we can take the changed classloader and it should be ok.


// Extend the method to get the shell classLoader
fun considerFindRealClassLoader(pkgClassLoader: ClassLoader, callback: (realClsLoader: ClassLoader) - >Unit) {
    XposedHelpers.findAndHookMethod("com.stub.StubApp", pkgClassLoader, "attachBaseContext", Context::class.java, object : XC_MethodHook() {
        @Throws(Throwable::class)
        override fun beforeHookedMethod(param: MethodHookParam) {
            super.beforeHookedMethod(param)
        }

        @Throws(Throwable::class)
        override fun afterHookedMethod(param: MethodHookParam) {
            super.afterHookedMethod(param)
            logD("Found the shell.")
            Args [0] is 360's Context object, which is used to fetch the classLoader
            val context = it.args[0] as Context
            // Get 360 classloader, then use this classloader after hook reinforcement
            val classLoader = context.classLoader
            callback.invoke(classLoader)
        }
    })
}

// The final code is as follows
considerFindRealClassLoader(lpparam.classLoader) { realClassLoader ->
    XposedHelpers.findAndHookMethod("com.amap.api.location.AMapLocation", realClassLoader, "getLongitude".object : XC_MethodHook() {
        @Throws(Throwable::class)
        override fun beforeHookedMethod(param: MethodHookParam) {
            super.beforeHookedMethod(param)
        }

        @Throws(Throwable::class)
        override fun afterHookedMethod(param: MethodHookParam) {
            super.afterHookedMethod(param)
            param.result = 114.032524}})}Copy the code

conclusion

  1. The mainstream reinforcement software on the market, such as 360 reinforcement, Tencent Legu reinforcement, Baidu reinforcement, etc., they are all added a shell application. Therefore, none of the above methods can solve the problem of hook (you need to make corresponding changes in combination with the corresponding shell application code).
  2. This code only applies to apps that use Autonavi for location.
  3. code