Java内部类与匿名类的访问与Hook详解
在Java编程语言中,内部类是一种嵌套在其他类或方法内的类,它可以更紧密地封装数据,并且能够直接访问外部类的所有成员(包括私有)。而在特定场景下,如测试应用中,我们可能还会遇到匿名类,这是一种没有名称、直接实例化的内部类,通常用于简化代码并实现接口或继承类的功能。
内部类访问示例
假设我们有一个名为Wallet
的类,在其中定义了一个内部类InnerStructure
,如下所示:
package com.xiaojianbang.hook;
import java.util.ArrayList;
public class Wallet {
public class InnerStructure {
private ArrayList<BankCard> bankCardsList = new ArrayList<>();
// 省略构造函数及其它方法...
@Override
public String toString() {
return this.bankCardsList.toString();
}
}
}
为了访问这个内部类InnerStructure
,我们需要在类名和内部类名之间使用$
符号进行连接,例如:
var Wallet$InnerStructure = Java.use("com.xiaojianbang.hook.Wallet$InnerStructure");
console.log(Wallet$InnerStructure);
// 若要访问内部类的非静态字段bankCardsList,可以使用Java.choose:
Java.choose("com.xiaojianbang.hook.Wallet$InnerStructure", {
onMatch: function(obj) {
console.log("Java Wallet$InnerStructure: ", obj.bankCardsList.value);
},
onComplete: function() {}
});
匿名类访问与Hook
在某些情况下,我们可能会遇到匿名类的使用,例如在测试应用的onCreate
方法中:
logoutPut(new Money("欧元", ItemTouchelper.callback.DEFAULT_DRAG_ANIMATION_DURATION) {
@Override
public String getInfo() {
return getCurrency() + " " + getAmount() + "这是匿名内部类";
}
}.getInfo(), ...);
此处的匿名类实际上是对Money
类进行了扩展,并覆写了getInfo()
方法。然而,直接使用传统的Hook方式无法访问到匿名类:
function test() {
var money = Java.use("com.xiaojianbang.hook.Money");
money.getInfo.implementation = function() {
var result = this.getInfo();
console.log(result);
return result;
};
}
test();
针对匿名类的访问,我们需要参考其对应的Smali语法来定位。例如,上述匿名类在Smali中的表示可能是com.xiaojianbang.app.MainActivity$1
。因此,正确的Hook方式应该是:
var money = Java.use("com.xiaojianbang.app.MainActivity$1");
money.getInfo.implementation = function() {
var result = this.getInfo();
console.log(result);
return result;
};
通过这种方式,我们就能成功访问并Hook匿名类Money
中覆写的getInfo()
方法了。总的来说,无论是内部类还是匿名类,理解和掌握它们的访问与Hook机制对于深入理解和调试Java应用程序都至关重要。