在上一节中,我们可能接触过 XposedHelpers,它对反射进行了封装,使用起来非常简便。但在 LSPosed/Xposed 开发的底层,XposedBridge 才是核心。

本节我们将通过一个“靶场”案例,深入讲解 XposedBridge 的核心 API,重点介绍如何替换函数调用(拦截原函数),以及精准 Hook (hookMethod) 和 批量 Hook (hookAllMethods) 的区别。

1. 准备一个“靶场” Demo

为了演示,我们先编写一个简单的 Android 应用作为“靶场”。这个应用包含一个 Person 类,用来演示如何拦截它的方法。

1.1 编写 Person 类

com.example.hookdemo 包下新建 Person.java

package com.example.hookdemo;

import android.util.Log;

public class Person {
    // 这是一个有返回值的方法,方便演示替换返回值
    public String getName() {
        return "原版名字";
    }

    // 这是一个普通方法
    public void print(String content) {
        Log.d("muyang", "Target: 原函数执行中 -> " + content);
    }
}

1.2 在 MainActivity 中调用

Person p = new Person();
// 1. 调用 print
p.print("Hello"); 
// 2. 获取返回值并打印
Log.d("muyang", "Get Name: " + p.getName());

2. 替换函数调用 (XC_MethodReplacement)

这是本节的重点。之前我们用的 XC_MethodHook 主要是为了在函数执行前后插入代码(Before/After),原函数通常还是会执行的。

如果你想彻底干掉原函数(比如去除广告逻辑、破解会员校验返回 True),需要使用 XC_MethodReplacement

2.1 替换 Void 方法(阻止执行)

场景:我们要阻止 Person.print 打印日志,替换成我们自己的逻辑。

Class<?> clazz = Class.forName("com.example.hookdemo.Person", false, loadPackageParam.classLoader);
Method printMethod = clazz.getDeclaredMethod("print", String.class);

// 注意:这里 new 的是 XC_MethodReplacement,而不是 XC_MethodHook
XposedBridge.hookMethod(printMethod, new XC_MethodReplacement() {
    @Override
    protected Object replaceHookedMethod(MethodHookParam param) throws Throwable {
        // 这里的代码会完全替代原函数的逻辑
        String arg = (String) param.args[0];
        Log.d("muyang", "拦截成功!原函数 print 没执行。拦截到的参数: " + arg);
        
        // 可以在这里写新的逻辑
        
        // 对于 void 方法,返回 null 即可
        return null; 
    }
});

效果:控制台不会出现 “Target: 原函数执行中…”,只会打印 “拦截成功!…”。

2.2 替换有返回值的方法(篡改结果)

场景:getName() 原本返回 “原版名字”,我们要强制让它返回 “破解版名字”。

Method getNameMethod = clazz.getDeclaredMethod("getName");

XposedBridge.hookMethod(getNameMethod, new XC_MethodReplacement() {
    @Override
    protected Object replaceHookedMethod(MethodHookParam param) throws Throwable {
        Log.d("muyang", "getName 被拦截");
        
        // 直接返回我们想要的结果
        // 注意:返回值的类型必须与原函数签名一致(或兼容)
        return "破解版名字";
    }
});

效果:APP 中调用 p.getName() 得到的结果将变成 “破解版名字”。


3. XposedBridge.hookMethod (精准 Hook)

XposedBridge.hookMethod 是最基础的 API。它的特点是:必须传入具体的 Method 对象。这意味着你需要自己通过 Java 反射机制找到那个确切的函数。

3.1 代码示例

// 必须手动反射获取具体的 Method 对象
Method method = clazz.getDeclaredMethod("print", String.class); 

XposedBridge.hookMethod(method, new XC_MethodHook() {
    @Override
    protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
        super.beforeHookedMethod(param);
        Log.d("muyang", "hookMethod: 精准注入");
    }
});

适用场景:你非常确定要 Hook 的函数签名,且只想精准打击这一个函数,不希望误伤重载的同名函数。


4. XposedBridge.hookAllMethods (批量 Hook)

如果目标类中有多个同名函数(重载),或者混淆严重导致参数不确定,使用 hookAllMethods 可以一次性 Hook 指定名称的所有方法。

4.1 代码示例

// 不需要反射具体的 Method,只需要类和方法名 "print"
XposedBridge.hookAllMethods(clazz, "print", new XC_MethodHook() {
    @Override
    protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
        super.beforeHookedMethod(param);
        
        // param.args 是参数数组,通过长度判断是哪个重载方法
        Log.d("muyang", "hookAllMethods: 捕获到一个 print 调用,参数个数: " + param.args.length);
    }
});

5. Hook 构造函数

构造函数(Constructor)也是函数,只是没有返回值。

5.1 精准 Hook

// 反射构造函数
Constructor<?> ctor = clazz.getDeclaredConstructor(); // 无参构造

XposedBridge.hookMethod(ctor, new XC_MethodHook() {
    @Override
    protected void afterHookedMethod(MethodHookParam param) throws Throwable {
        Log.d("muyang", "Person 对象创建完毕");
    }
});

5.2 批量 Hook (hookAllConstructors)

XposedBridge.hookAllConstructors(clazz, new XC_MethodHook() {
    @Override
    protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
        Log.d("muyang", "任意构造函数被调用");
    }
});

6. 总结

类/方法 作用 核心 API
XC_MethodHook 监听函数 beforeHookedMethod / afterHookedMethod
XC_MethodReplacement 替换函数 replaceHookedMethod (原函数不再执行)
hookMethod 精准 Hook 需要传入反射好的 Method 对象
hookAllMethods 批量 Hook 传入 String 方法名,Hook 所有同名重载
Logo

中国智能体开发者社区,聚焦智能体与大模型开发,提供前沿资讯、实用工具链、开源项目及行业案例。通过技术沙龙、开发者大赛等活动,促进经验交流与协作,助力开发者快速构建创新智能应用。

更多推荐