ByteBuddy - невозможно перехватить метод stati c из суперкласса - PullRequest
2 голосов
/ 03 мая 2020

Я работаю над инструментом командной строки для Android (представьте себе), пытаясь использовать мощь ByteBuddy, чтобы заглушить stati c метод getApplicationContext , определенный в android .security .KeyStore

Однако - этот метод кажется невидимым для ByteBuddy getDeclaredMethods при создании подкласса android .security.KeyStore и, следовательно, он не может его перехватить.

При использовании getMethods из API отражения я могу перечислить метод.

            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 Я могу перечислить все publi c метод суперкласса .

Заменив перехваченный метод на нестатический c (например, "state"), я могу вывести метод с помощью функции ByteBuddy getDeclaredMethods :

Количество объявленных методов в keyStoreMethods: 2

method = publi c android .security.KeyStore $ State AndroidKeyStoreMasker.state ()

method = publi c android .security.KeyStore $ State AndroidKeyStoreMasker.state (int)

Итак, мой окончательный вывод заключается в том, что ByteBuddy (или мой случай использования с ByteBuddy) имеет некоторые проблемы со stati c метод видимости.

Ссылка на android .security.KeyStore. java: https://android.googlesource.com/platform/frameworks/base/+/master/keystore/java/android/security/KeyStore.java

Любая помощь будет сильно оценена.

1 Ответ

0 голосов
/ 04 мая 2020

При создании subclass Byte Buddy может перехватывать только методы, непосредственно объявленные подклассом, или виртуальные методы суперклассов. Вот как работает JVM, методы static отправляются непосредственно на приемник.

Byte Buddy также может переопределять и преобразовывать существующие классы, но для этого требуется агент Java, который недоступен в Android. Поэтому я боюсь, что вам нужно найти нестати c точку подключения, чтобы выполнить sh то, что вы пытаетесь. В качестве альтернативы посмотрите на MemberSubstitution, где вы можете перенаправить такие вызовы из своего кода. Это также требует повторного преобразования, но поскольку это происходит в вашем коде, вы можете использовать плагин сборки Byte Buddy.

...