如果方法是这样
public int addNumbers(int a, int b) {
return a + b;
}
Hook 代码
XposedHelpers.findAndHookMethod("com.example.app.Calculator",
lpparam.classLoader,
"addNumbers",
int.class, int.class, // 两个参数,都是 int
new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) {
XposedBridge.log("[+] addNumbers 被 Hook,参数: " + param.args[0] + ", " + param.args[1]);
}
});
beforeHookedMethod
和 afterHookedMethod
的区别简单理解
方法 | 执行时机 | 作用 |
---|---|---|
beforeHookedMethod |
目标方法执行前 | 获取/修改参数,阻止方法执行 |
afterHookedMethod |
目标方法执行后 | 获取/修改返回值 |
✅ beforeHookedMethod
作用
param.args[0]
param.args[0] = "NewValue"
param.setResult(null)
beforeHookedMethod
获取参数
如果目标方法是
public void setUserInfo(String username, int age) {
System.out.println("User: " + username + ", Age: " + age);
}
Hook 代码
XposedHelpers.findAndHookMethod("com.example.app.UserManager",
lpparam.classLoader,
"setUserInfo",
String.class, int.class, // 方法的参数类型
new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) {
// 获取方法的参数
String username = (String) param.args[0];
int age = (int) param.args[1];
XposedBridge.log("[+] 用户名: " + username);
XposedBridge.log("[+] 年龄: " + age);
}
});
beforeHookedMethod
修改参数修改参数,让方法执行时使用新参数
XposedHelpers.findAndHookMethod("com.example.app.UserManager",
lpparam.classLoader,
"setUserInfo",
String.class, int.class,
new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) {
// 修改参数
param.args[0] = "HookedUser"; // 修改用户名
param.args[1] = 99; // 修改年龄
XposedBridge.log("[+] 参数已修改 -> 用户名: " + param.args[0] + ",年龄: " + param.args[1]);
}
});
beforeHookedMethod
阻止方法并返回假数据如果方法有返回值
public boolean isUserPremium() {
return false;
}
Hook 代码
XposedHelpers.findAndHookMethod("com.example.app.UserManager",
lpparam.classLoader,
"isUserPremium",
new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) {
XposedBridge.log("[+] isUserPremium 被 Hook,强制返回 true");
param.setResult(true); // 让方法永远返回 true
}
});
✅ 作用
isUserPremium()
方法永远返回 true
XposedHelpers.findAndHookMethod("com.example.app.UserManager",
lpparam.classLoader,
"getUserInfo",
new XC_MethodHook() {
@Override
protected void afterHookedMethod(MethodHookParam param) {
XposedBridge.log("[+] 原始返回值: " + param.getResult());
// 修改返回值
param.setResult("Hooked UserInfo");
XposedBridge.log("[+] 修改后返回值: " + param.getResult());
}
});
✅ 作用
getUserInfo()
返回 "Real UserInfo"
"Hooked UserInfo"
功能 | beforeHookedMethod | afterHookedMethod |
---|---|---|
执行时机 | 方法执行 前 | 方法执行 后 |
获取参数 | ✅ param.args[0] |
❌(只能看返回值) |
修改参数 | ✅ param.args[0] = "NewValue" |
❌ |
阻止方法执行 | ✅ param.setResult(null) |
❌ |
修改返回值 | ❌ | ✅ param.setResult("NewValue") |
让方法延迟执行 | ✅ Thread.sleep(5000) |
❌ |
MethodHookParam
的常用方法方法 | 作用 |
---|---|
param.args[i] |
获取/修改方法的第 i 个参数 |
param.thisObject |
获取当前调用方法的对象(this ) |
param.getResult() |
获取方法的返回值(仅 afterHookedMethod 可用) |
param.setResult(Object value) |
修改返回值(仅 afterHookedMethod 可用) |
param.setThrowable(Throwable t) |
让方法抛出异常 |
param.hasThrowable() |
检查方法是否抛出异常 |
param.getThrowable() |
获取方法抛出的异常 |
在 Xposed 里,你可以使用 XposedHelpers.callMethod()
或 XposedHelpers.callStaticMethod()
直接启动(调用)某个方法,就像 Frida 里的 choose()
之后手动调用方法一样。
XposedHelpers.callMethod()
调用对象方法 假设目标类 User
里有一个方法
public class User {
public String getUsername() {
return "Alice";
}
}
在 Xposed 里 Hook 该类,并调用 getUsername()
XposedHelpers.findAndHookConstructor("com.example.app.User",
lpparam.classLoader,
String.class, int.class,
new XC_MethodHook() {
@Override
protected void afterHookedMethod(MethodHookParam param) {
Object instance = param.thisObject; // 获取 User 实例
String username = (String) XposedHelpers.callMethod(instance, "getUsername");
XposedBridge.log("[+] 直接调用 getUsername(),返回值: " + username);
}
});
✅ 作用
User
对象被创建后,直接调用 getUsername()
replaceHookedMethod()
直接替换方法和frida的这个方法差不多implementation。
Frida
Java.use("com.example.app.TargetClass").targetMethod.implementation = function(arg) {
console.log("Hooked! 参数: " + arg);
return "Hooked Result";
};
Xposed
XposedHelpers.findAndHookMethod("com.example.app.TargetClass",
lpparam.classLoader,
"targetMethod",
String.class,
new XC_MethodReplacement() { // 直接替换方法
@Override
protected Object replaceHookedMethod(MethodHookParam param) {
XposedBridge.log("[+] targetMethod 被完全替换");
return "Hooked Result"; // 返回新的结果
}
});
XC_MethodHook
// 在原方法执行之前调用
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
// 你的代码
}
// 在原方法执行之后调用
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
// 你的代码
}
MethodHookParam
方法hook的参数(包含了被钩子方法的所有相关信息)
XC_MethodHook hook = new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
// 获取方法参数
String arg1 = (String) param.args[0];
// 修改方法参数
param.args[0] = "新参数";
}
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
// 获取方法返回值
Object result = param.getResult();
// 修改返回值
param.setResult("新的返回值");
}
};
okhttp3.Request.Builder
这是 OkHttp 库中用于构建 HTTP 请求的建造者模式(Builder Pattern)实现。$ 符号表示 Builder 是 Request 类的内部类。
主要用法:
// 创建一个基本的GET请求
Request request = new Request.Builder()
.url("https://api.example.com/data")
.get() // GET请求(默认是GET,可以不写)
.build();
// 创建一个带header的POST请求
Request request = new Request.Builder()
.url("https://api.example.com/data")
.post(RequestBody.create(MediaType.parse("application/json"), "{\"key\":\"value\"}"))
.addHeader("Authorization", "Bearer token123")
.build();
CallMethod
// 1. 获取响应体
Object body = XposedHelpers.callMethod(response, "body");
// 等同于 response.body()
// response 是 OkHttp 的 Response 对象,body() 方法返回响应内容
// 2. 获取请求对象
Object request = XposedHelpers.callMethod(param.thisObject, "request");
// 等同于 response.request()
// 从 Response 对象中获取对应的 Request 对象
// 3. 获取URL对象
Object urlObj = XposedHelpers.callMethod(request, "url");
// 等同于 request.url()
// 从 Request 对象中获取 URL
完整的调用链是这样的:
// 正常的 OkHttp 代码是这样的:
Response response = ...;
ResponseBody body = response.body(); // 获取响应内容
Request request = response.request(); // 获取请求信息
HttpUrl url = request.url(); // 获取请求的URL
// 但在 Xposed 中,我们需要用 callMethod 来调用这些方法:
Object response = ...;
Object body = XposedHelpers.callMethod(response, "body"); // 调用 body() 方法
Object request = XposedHelpers.callMethod(response, "request"); // 调用 request() 方法
Object url = XposedHelpers.callMethod(request, "url"); // 调用 url() 方法
为什么要用 callMethod?
// originalRequest 是 OkHttp3 中 RealCall 类的一个字段
// 表示原始的 HTTP 请求对象,包含了请求的 URL、请求头、请求体等信息
Object request = XposedHelpers.getObjectField(call, "originalRequest");