关于 Xposed:Xposed 插件开发详细流程

关于 Xposed:Xposed 插件开发详细流程

Xposed 框架会在应用加载时,通过 Zygote 进程将你写的模块注入到目标应用中,然后我们就可以拦截函数调用、修改参数、返回值、甚至改 UI 等功能。

一、完整编写流程概览

步骤内容1配置 Android Studio 工程(Library 模式)2添加 Xposed API3编写 Hook 代码(Java 实现 IXposedHookLoadPackage)4写 assets/xposed_init 声明入口类5打包成 APK 并安装到手机6在 Xposed/LSPosed 中启用并重启生效7调试日志、查看效果

二、Hook 微信发送消息前拦截内容

一个简单的 Xposed 插件:Hook 微信某个函数,输出你发送的文字内容。

2.1 创建 Android Studio 工程(Library 类型)

创建新工程时选择:

类型:Android Library

名字:WechatHookModule

2.2 配置 build.gradle

编辑 WechatHookModule/build.gradle:

apply plugin: 'com.android.library'

android {

compileSdkVersion 28

defaultConfig {

minSdkVersion 21

targetSdkVersion 28

}

buildTypes {

release {

minifyEnabled false

}

}

}

dependencies {

compileOnly 'de.robv.android.xposed:api:82' // Xposed API(只编译不打包)

}

2.3 创建主 Hook 类

创建类 WechatHook.java:

package com.example.wechathook; // 声明当前类所在的包名

import android.util.Log; // 导入 Android 日志工具类

import de.robv.android.xposed.IXposedHookLoadPackage; // 导入 Xposed 加载包接口

import de.robv.android.xposed.XC_MethodHook; // 导入 Xposed 方法钩子基类

import de.robv.android.xposed.XposedBridge; // 导入 Xposed 桥接工具类,用于输出日志等

import de.robv.android.xposed.XposedHelpers; // 导入 Xposed 助手类,提供反射与 Hook 方法

import de.robv.android.xposed.callbacks.XC_LoadPackage; // 导入 Xposed 包加载回调类

public class WechatHook implements IXposedHookLoadPackage { // 定义一个实现 IXposedHookLoadPackage 接口的类

@Override

public void handleLoadPackage(XC_LoadPackage.LoadPackageParam lpparam) throws Throwable { // Xposed 加载每个包时都会回调此方法

// Hook 微信

if (!lpparam.packageName.equals("com.tencent.mm")) // 检查当前加载的包名是否是微信包名

return; // 如果不是微信,则不做任何处理,直接返回

XposedBridge.log("微信已加载,开始 Hook"); // 在 Xposed 日志中输出提示信息

try {

// 假设 ChattingUI 类有个 sendMessage 方法

Class clazz = XposedHelpers.findClass( // 通过类名和类加载器查找目标类

"com.tencent.mm.ui.chatting.ChattingUI", lpparam.classLoader);

XposedHelpers.findAndHookMethod(clazz, "sendMessage", String.class, new XC_MethodHook() { // 在 ChattingUI 类中 Hook sendMessage(String) 方法

@Override

protected void beforeHookedMethod(MethodHookParam param) throws Throwable { // 在原方法执行前回调

String msg = (String) param.args[0]; // 获取调用 sendMessage 时传入的消息内容

XposedBridge.log("即将发送的微信消息: " + msg); // 将消息内容输出到 Xposed 日志

}

});

} catch (Throwable t) { // 捕获所有可能的异常

XposedBridge.log("Hook 微信失败: " + Log.getStackTraceString(t)); // 输出失败原因的堆栈信息

}

}

}

2.4 创建 assets/xposed_init

在 main/assets/ 目录下创建文件:

xposed_init

内容为主类的全路径:

com.example.wechathook.WechatHook

这个文件告诉 Xposed 框架插件的入口类在哪。

2.5 修改 AndroidManifest.xml

注意写的是插件,不需要 Activity,只需要这样设置权限和包名即可:

package="com.example.wechathook">

android:allowBackup="true"

android:label="微信Hook插件"

android:supportsRtl="true">

2.6 打包安装

在 Android Studio 中点击 Build > Build APK

用 ADB 安装插件到手机:

adb install -r app-debug.apk

或者 直接运行项目。

2.7 启用插件并重启

打开 Xposed Installer 或 LSPosed

启用插件

重启系统

2.8 验证效果

打开微信发送一条消息

查看 logcat 或 Xposed 日志:

adb logcat | grep Xposed

能看到日志:

即将发送的微信消息: 哈喽 ChatGPT

成功。

三、常用 Hook 实例

3.1 Hook 常用 API

功能目标使用方法说明与例子Hook 普通方法findAndHookMethodXposedHelpers.findAndHookMethod("com.xxx.Class", classLoader, "methodName", 参数类型..., new XC_MethodHook() { })✔ 用于 Hook 普通 Java 方法Hook 构造方法findAndHookConstructorXposedHelpers.findAndHookConstructor("com.xxx.Class", classLoader, 参数类型..., new XC_MethodHook() { })✔ Hook 构造函数,一般用于初始化逻辑获取成员变量getObjectField(obj, "fieldName")String s = (String) XposedHelpers.getObjectField(obj, "mText");✔ 获取成员变量(如 private 成员)修改成员变量setObjectField(obj, "fieldName", value)XposedHelpers.setObjectField(obj, "mText", "Hello");✔ 修改成员变量调用对象方法callMethod(obj, "method", args...)Object ret = XposedHelpers.callMethod(obj, "doSomething", 123);✔ 调用目标对象的方法调用静态方法callStaticMethod(clazz, "method", args...)XposedHelpers.callStaticMethod(MyClass.class, "getVersion");获取静态变量getStaticObjectField(clazz, "field")Object val = XposedHelpers.getStaticObjectField(MyClass.class, "STATIC_FIELD");修改静态变量setStaticObjectField(clazz, "field", val)XposedHelpers.setStaticObjectField(MyClass.class, "STATIC_FIELD", "newVal");修改返回值afterHookedMethod 中使用 param.setResult(...)param.setResult("Hooked!");阻止方法执行beforeHookedMethod 中使用 param.setResult(...)直接设定返回值可以“阻止”方法执行抛出异常终止执行param.setThrowable(new RuntimeException("error"))阻断流程用于模拟异常等打印日志XposedBridge.log(...)XposedBridge.log("Hook hit here!");

3.2 详细举例说明

1)拦截 Toast 弹出并打印内容

XposedHelpers.findAndHookMethod(

"android.widget.Toast", // 要 Hook 的类名(这里是系统的 Toast 类)

lpparam.classLoader, // 当前应用的类加载器,用于加载这个类

"show", // 要 Hook 的方法名(Toast 的 show() 方法)

new XC_MethodHook() { // Hook 回调对象

@Override

protected void beforeHookedMethod(MethodHookParam param) {

// 在 show() 方法执行之前触发

XposedBridge.log("Toast 被调用!"); // 打日志:说明 Toast 要显示了

}

});

2)修改函数的返回值(假设有个 isVip())

XposedHelpers.findAndHookMethod(

"com.example.app.User", // 目标类的完整类名,这里是 com.example.app.User

lpparam.classLoader, // 类加载器,用于加载目标类

"isVip", // 要 Hook 的方法名,这里是 isVip() 方法

new XC_MethodHook() { // 匿名内部类,用于定义 Hook 的行为

@Override

protected void afterHookedMethod(MethodHookParam param) {

// 在原始 isVip() 方法执行完之后回调

param.setResult(true); // 强制修改返回值为 true —— 无论实际是不是 VIP,现在都变成了 VIP

}

});

3)获取并修改成员变量(如 TextView 的文本)

XposedHelpers.findAndHookMethod(

"com.example.MainActivity", // 要 Hook 的类名:MainActivity,是目标应用的主界面类

lpparam.classLoader, // 类加载器,用于从目标应用加载类

"onCreate", // 要 Hook 的方法名:onCreate(Activity 生命周期的入口方法)

android.os.Bundle.class, // onCreate 的参数类型(必须精确匹配,否则 Hook 失败)

new XC_MethodHook() { // 匿名内部类:定义 Hook 的逻辑

@Override

protected void afterHookedMethod(MethodHookParam param) {

// onCreate 方法执行完之后回调这个方法

Object activity = param.thisObject; // 获取当前的 MainActivity 实例(即 this)

TextView tv = (TextView) XposedHelpers.getObjectField(activity, "textView");

// 使用反射获取 MainActivity 中名为 textView 的成员变量,并强转成 TextView 对象

tv.setText("已 Hook 修改内容!"); // 修改这个 TextView 的文字显示内容

}

});

4)Hook 构造函数并打印参数

XposedHelpers.findAndHookConstructor(

"com.example.User", // 要 Hook 的类名:com.example.User

lpparam.classLoader, // 类加载器,用于加载目标类

String.class, int.class, // 构造函数的参数类型列表:第一个参数是 String,第二个参数是 int

new XC_MethodHook() { // 定义构造函数 Hook 的回调逻辑

@Override

protected void beforeHookedMethod(MethodHookParam param) {

// 构造函数执行前调用此方法

String name = (String) param.args[0]; // 获取第一个参数 name

int age = (int) param.args[1]; // 获取第二个参数 age

XposedBridge.log("User 被构造: name=" + name + ", age=" + age);

// 记录日志,打印构造 User 对象时传入的 name 和 age 参数

}

});

5)调用原方法(比如某对象的 getToken 方法)

Object token = XposedHelpers.callMethod(obj, "getToken");

// 通过 XposedHelpers.callMethod 反射调用对象 obj 的 getToken() 方法,返回结果赋值给 token

XposedBridge.log("调用 getToken 得到:" + token);

// 使用 XposedBridge.log 打印调用结果 token,方便调试或记录

6)修改传入参数(拦截支付金额)

XposedHelpers.findAndHookMethod(

"com.example.PayActivity", // 要 Hook 的类名:支付页面或支付逻辑所在的 Activity

lpparam.classLoader, // 当前包的类加载器

"pay", // 要 Hook 的方法名,这里是 pay 方法

int.class, // 方法参数类型,这里 pay(int amount)

new XC_MethodHook() { // 方法钩子回调

@Override

protected void beforeHookedMethod(MethodHookParam param) {

int originAmount = (int) param.args[0]; // 获取原始传入的金额参数

XposedBridge.log("原始金额:" + originAmount); // 打印原始金额,方便调试

param.args[0] = 1; // 把金额参数修改为 1,即强制改成 1 元支付

}

});

7)拦截点击事件(拦截按钮点击)

XposedHelpers.findAndHookMethod(

"android.view.View$OnClickListener", // 目标类:内部接口 View.OnClickListener(注意 $ 表示内部类)

lpparam.classLoader, // 当前进程的类加载器

"onClick", // 方法名:onClick

View.class, // 方法参数:单个 View 对象

new XC_MethodHook() { // Hook 回调对象

@Override

protected void beforeHookedMethod(MethodHookParam param) {

XposedBridge.log("点击事件被拦截!"); // 在 onClick 执行前打印日志

}

});

8)静态变量获取与修改

Class cls = XposedHelpers.findClass("com.example.Config", lpparam.classLoader);

// 通过类名和类加载器,获取目标类 com.example.Config 的 Class 对象

String originalValue = (String) XposedHelpers.getStaticObjectField(cls, "API_URL");

// 获取该类中名为 API_URL 的静态字段的当前值,假设是字符串类型

XposedBridge.log("原始地址:" + originalValue);

// 打印原始的 API_URL 地址,方便调试和验证

XposedHelpers.setStaticObjectField(cls, "API_URL", "https://api.hacked.com/");

// 将 API_URL 静态字段的值改为 "https://api.hacked.com/",实现地址篡改

3.3 常用 Hook 场景模板总结

场景Hook 方法说明登录自动通过Hook 登录函数,修改返回值或参数.跳过验证页Hook 验证函数,设置 param.setResult(true).修改 UI 内容Hook onCreate() 后修改控件属性.控制按钮逻辑Hook onClick().替换服务地址修改静态字段,如 BASE_URL.获取 TokencallMethod() 或 getObjectField().

四、项目模板

4.1 项目结构

XposedTemplate/

├── app/

│ ├── src/

│ │ └── main/

│ │ ├── java/com/example/xposedtemplate/

│ │ │ └── MyHook.java

│ │ ├── assets/

│ │ │ └── xposed_init

│ │ └── AndroidManifest.xml

├── build.gradle

└── settings.gradle

4.2 settings.gradle

rootProject.name = "XposedTemplate"

include ':app'

4.3 项目根目录 build.gradle(可选)

如果提示 gradle 设置,添加:

// 项目根目录的 build.gradle,不是 app 的

buildscript {

repositories {

google()

mavenCentral()

}

dependencies {

classpath 'com.android.tools.build:gradle:7.4.2'

}

}

allprojects {

repositories {

google()

mavenCentral()

}

}

4.4 app/build.gradle

apply plugin: 'com.android.library'

android {

namespace 'com.example.xposedtemplate'

compileSdkVersion 28

defaultConfig {

minSdkVersion 21

targetSdkVersion 28

versionCode 1

versionName "1.0"

// 不用 applicationId(这是 Library 模块)

}

buildTypes {

release {

minifyEnabled false

}

}

}

dependencies {

compileOnly 'de.robv.android.xposed:api:82'

}

4.5 AndroidManifest.xml

package="com.example.xposedtemplate">

android:label="Xposed模板插件"

android:allowBackup="true"

android:supportsRtl="true">

4.6 assets/xposed_init

新建 app/src/main/assets/xposed_init,内容为:

com.example.xposedtemplate.MyHook

4.7 MyHook.java

package com.example.xposedtemplate;

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 MyHook implements IXposedHookLoadPackage {

@Override

public void handleLoadPackage(XC_LoadPackage.LoadPackageParam lpparam) throws Throwable {

// 示例:Hook 微信

if (!lpparam.packageName.equals("com.tencent.mm")) return;

XposedBridge.log("微信已加载,准备 Hook");

try {

Class clazz = XposedHelpers.findClass(

"com.tencent.mm.ui.chatting.ChattingUI", lpparam.classLoader);

XposedHelpers.findAndHookMethod(clazz, "onCreate", android.os.Bundle.class,

new XC_MethodHook() {

@Override

protected void beforeHookedMethod(MethodHookParam param) throws Throwable {

XposedBridge.log("微信 ChattingUI onCreate 被调用!");

}

});

} catch (Throwable t) {

XposedBridge.log("Hook 出错: " + t.getMessage());

}

}

}

4.8 使用说明

构建

在 Android Studio 中:

打开项目

点击菜单 Build > Make Module 'app'

找到 APK 路径:app/build/outputs/apk/debug/app-debug.apk

安装

adb install -r app-debug.apk

启用

打开 LSPosed 或 EdXposed

勾选模块并重启

使用 logcat 观察输出:

adb logcat | grep Xposed

相关推荐

怎么在抖音群里发自己的名片?
365bet备用线路

怎么在抖音群里发自己的名片?

📅 07-07 👁️ 641
Win7扬声器正常但是没有声音怎么办?Win7一切正常没声音的解决方法
怎么在安卓手机桌面上添加插件
365bet备用线路

怎么在安卓手机桌面上添加插件

📅 07-09 👁️ 7660