首页 > 解决方案 > ByteBuddy - 无法从超类拦截静态方法

问题描述

我正在为 Android 开发命令行工具(想想我),试图利用 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。但是子类不包含任何方法。

getMethods替换对getDeclaredMethods的调用我能够列出超类的所有公共方法。

通过将拦截的方法替换为非静态方法(例如“状态”),我可以使用 ByteBuddy 的getDeclaredMethods函数列出该方法:

keyStoreMethods 中声明的方法数:2

方法 = 公共 android.security.KeyStore$State AndroidKeyStoreMasker.state()

方法 = 公共 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

任何帮助将不胜感激。

标签: javaandroidbyte-buddy

解决方案


创建subclassByte Buddy 时,只能拦截子类直接声明的方法或超类的虚方法。这就是 JVM 的工作方式,static方法直接在接收器上分派。

Byte Buddy 也能够重新定义和重新转换现有的类,但这需要 Android 上不可用的 Java 代理。因此,恐怕您需要找到一个非静态挂钩点来完成您正在尝试的事情。或者,看看MemberSubstitution您可以从代码中重定向此类调用的位置。这也需要重新转换,但由于它发生在您的代码中,您可以使用 Byte Buddy 的构建插件。


推荐阅读