重载方法指定——用 overload() 消除 Frida 的歧义
问题场景
Java 里一个类可以有同名的多个方法,靠参数类型/数量区分(重载):
class Shop {
void buy(String itemId) { ... } // 版本 1
void buy(String itemId, int count) { ... } // 版本 2
void buy(String itemId, int count, int price) { ... } // 版本 3
}
直接写 Shop.buy.implementation = ...,Frida 会自动选第一个重载版本(通常是参数最少的那个)。这不是你想要的怎么办?
用 overload() 指定
Java.perform(function () {
var Shop = Java.use('com.example.Shop');
// 拦截只传 itemId 的版本
Shop.buy.overload('java.lang.String').implementation = function (itemId) {
console.log('[+] buy(String) 被调用');
return this.buy(itemId);
};
// 拦截传 itemId + count 的版本
Shop.buy.overload('java.lang.String', 'int').implementation = function (itemId, count) {
console.log('[+] buy(String, int) 被调用');
return this.buy(itemId, count);
};
});
overload() 里写参数的全限定类名(基本类型小写):
| 参数类型 | overload 写法 |
|---|---|
| String | 'java.lang.String' |
| int | 'int' |
| long | 'long' |
| float | 'float' |
| boolean | 'boolean' |
| Bundle | 'android.os.Bundle' |
| Context | 'android.content.Context' |
| 数组 | '[Ljava.lang.String;' |
怎么知道有哪些重载
Java.perform(function () {
var Shop = Java.use('com.example.Shop');
// 列出 buy 方法的所有重载
console.log(Shop.buy.overloads);
});
Frida 会打印每个重载的参数类型列表,对着抄就行。
基本类型和包装类型的区别
Java 里 int 和 Integer 是两种完全不同的类型:
void setCount(int count) { ... } // 基本类型
void setCount(Integer count) { ... } // 包装类型(可能为 null)
overload 写法要严格区分:
| Java 类型 | overload |
|---|---|
| int | 'int' |
| Integer | 'java.lang.Integer' |
| long | 'long' |
| Long | 'java.lang.Long' |
| boolean | 'boolean' |
| Boolean | 'java.lang.Boolean' |
调用原重载
显式指定了 overload() 后,调用原方法也要用同样的 overload():
Shop.buy.overload('java.lang.String', 'int').implementation = function (itemId, count) {
// 这样调用原方法——确保调到正确的重载版本
Shop.buy.overload('java.lang.String', 'int').call(this, itemId, count);
};
或者继续用 apply + arguments,Frida 会自动匹配。
构造方法
构造方法(<init>)也有重载,用法一样:
Activity.$init.overload('android.os.Bundle').implementation = function (savedInstanceState) {
console.log('[+] Activity 构造被调用');
this.$init(savedInstanceState);
};
类查找的重载
Java.use 本身不会有歧义(全限定类名唯一)。但 Java.classFactory 或按名称搜索方法时,如果遇到匿名内部类或同名方法多个重载,也要用 overload() 消除歧义。