为什么XPosed模块的函数需要指定类、指定函数? 如果不指定类或者函数,从classload遍历所有的类找到目标函数,会导致目标APP卡死。

目标:无界面化的XPosed模块

  1. Android Studio

  2. 项目settings.gradle.kts添加库,点击右上角Sync Now同步。

    dependencyResolutionManagement {
        repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
        repositories {
            maven { url =uri("<https://maven.aliyun.com/repository/public/>")  } // 追加这一行
            google()
            mavenCentral()
        }
    }
    
  3. 删除掉build.gradle.kts中dependencies中的其它依赖,并添加依赖,点击后上角Sync Now同步。

    dependencies {
        compileOnly ("de.robv.android.xposed:api:82")
    }
    
  4. 删除AndroidManifest.xml中的Android:theme,并删除掉res/values下的theme主题和res/values-night下的theme主题。这个时候尝试编译,编译不会报错,但不会有任何应用安装到手机上。

  5. 在AndroidManifest.xml中添加Xposed标志。

    <application ... > 
            <!-- 是否为Xposed模块 -->
            <meta-data
                android:name="xposedmodule"
                android:value="true"/>
            <!-- 模块的简介(在框架中显示) -->
            <meta-data
                android:name="xposeddescription"
                android:value="我是Xposed模块简介" />
            <!-- 模块最低支持的Api版本 一般填54即可 -->
            <meta-data 
                android:name="xposedminversion"     
                android:value="54"/>
            <!-- 模块作用域 -->
            <meta-data
                android:name="xposedscope"
                android:resource="@array/xposedscope"/>
    </appication>
    
  6. 在values目录下创建arrays.xml,填充内容如下,item表示作用的app。会在LSPosed中显示推荐APP。

    <?xml version="1.0" encoding="utf-8"?>
    <resources>
        <string-array name="xposedscope">
            <item>com.test.app</item>
        </string-array>
    </resources>
    
  7. 在main目录下建立assets资源文件夹,在新建xposed_init文件

    在xposed_init文件中写入入口类的地址,如:

    com.demo.test.MainActivity
    

8.创建MainActivity,编写代码

package com.demo.test;

import de.robv.android.xposed.IXposedHookLoadPackage;
import de.robv.android.xposed.XC_MethodHook;
import de.robv.android.xposed.XposedBridge;
import de.robv.android.xposed.XposedHelpers;
import de.robv.android.xposed.callbacks.XC_LoadPackage;

public class FAKE implements IXposedHookLoadPackage {
    @Override
    public void handleLoadPackage(XC_LoadPackage.LoadPackageParam lpparam) throws Throwable {
        // 判断是否是目标app
        if (!lpparam.packageName.equals("com.test.app")) return;
        // 如果是LSPosed框架,需要在adb logcat中过滤LSPosed
        XposedBridge.log("开始hook");
        // 调用函数
        hook(lpparam);
    }

    // hook 目标函数
    private void hook(XC_LoadPackage.LoadPackageParam lpparam) {
        XposedHelpers.findAndHookMethod("tb", lpparam.classLoader, "isVipUser", android.content.Context.class, new XC_MethodHook() {
            /*
                这里有两个重载函数,一个是beforeHookedMethod,一个afterHookedMethod
                beforeHookedMethod: 函数开始,传参结束,开始运行下一行代码时
                afterHookedMethod: 函数结束,即将返回返回值时
            */
            @Override
            protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
                // 第一个参数
                String a = (String) param.args[0];
                // 设置返回值
                param.setResult(true);
            }
        });
    }
}