【发布时间】:2020-08-17 17:37:46
【问题描述】:
我正在开发适用于 Android 的命令行工具(想想 am),试图利用 ByteBuddy 的强大功能来存根 android.security.KeyStore 中定义的静态方法 getApplicationContext
但是,当子类化 android.security.KeyStore 时,ByteBuddy getDeclaredMethods 似乎看不到该方法,因此无法拦截它。
当使用反射 API 中的 getMethods 时,我能够列出该方法。
Class AndroidKeyStore = Class.forName("android.security.KeyStore");
Method[] keyStoreMethods = new ByteBuddy()
.with(TypeValidation.DISABLED)
.subclass(AndroidKeyStore, ConstructorStrategy.Default.IMITATE_SUPER_CLASS)
.name("KeyStoreMasker")
.method(ElementMatchers.named("getApplicationContext"))
.intercept(SuperMethodCall.INSTANCE)
.make()
.load(getClass().getClassLoader(),
new AndroidClassLoadingStrategy
.Injecting(new File("/data/app/cmdutil")))
.getLoaded()
.getDeclaredMethods();
for(i = 0; i < keyStoreMethods .length; i++) {
System.out.println("method = " + keyStoreMethods[i].toString());
}
在运行上述代码时,我希望在子类中有一个方法 - getApplicationContext。但是子类不包含任何方法。
将 getDeclaredMethods 调用替换为 getMethods 我可以列出超类的所有公共方法。
通过将拦截的方法替换为非静态方法(例如“状态”),我可以使用 ByteBuddy 的 getDeclaredMethods 函数列出该方法:
keyStoreMethods 中声明的方法数:2
method = public android.security.KeyStore$State AndroidKeyStoreMasker.state()
method = public android.security.KeyStore$State AndroidKeyStoreMasker.state(int)
所以我的最终结论是 ByteBuddy(或我使用 ByteBuddy 的用例)在静态方法可见性方面存在一些问题。
参考android.security.KeyStore.java: https://android.googlesource.com/platform/frameworks/base/+/master/keystore/java/android/security/KeyStore.java
任何帮助将不胜感激。
【问题讨论】:
标签: java android byte-buddy