Как поменять тела методов под Android

В чистой Java с помощью агентов внедрения и java существует способ заменить тело метода во время выполнения.

Unfrotunately java.lang.instrument.Instrumentation недоступно под Android.

Я проверил все другие альтернативы, например, описанную здесь в stackru, которая указывает на устаревшую реализацию javassist-android. Что удивительно работает, но только для новых классов.

Есть также статья под названием " Горячая замена кода" в Android, в которой описывается, как снова загружать классы во время выполнения, а не как заменить существующие методы классов.

Единственная статья, посвященная этой проблеме, - это статья под названием " Взлом Android": замена методов системных классов на собственные, которые пропускают исходный код и ссылаются на Dalvik, а не ART (поэтому он не будет работать на современном оборудовании).

Так есть ли способ сделать это?

...

Итог: причина, по которой я хочу это, состоит в том, чтобы отслеживать конкретные вызовы методов в моем приложении, например, когда этот метод вызывается (и выполняется какое-либо действие перед ним) и когда этот метод завершается (а также выполняется какое-либо действие с ним). Эти методы определяются во время выполнения, поэтому невозможно знать их заранее, во время компиляции.

1 ответ

Одна из новых функций в Android Studio 3.5 - Apply Changes, которая в основном выполняет ту же логику, что и вы:

"… мы полагаемся на инструментарий времени выполнения, который поддерживается в Android 8.0 (Oreo) и более новых устройствах и эмуляторах, чтобы переопределять классы на лету".


Также в эпизоде ​​108 подкаста АБР Эстебан де ла Канал упомянул:

".. В Android Oreo (8.0) платформа реализовала инструментарий байт-кода" на лету ", поэтому мы можем фактически изменить класс dexed работающего приложения.. добавив, в основном, эквивалент JVMTI в Java, чтобы мы могли прикрепить агент и сказать: вы можете поменять этот класс с этим ".


Начните с чтения источников art/openjdkjvmti, то есть readme документирует следующее:

плагин openjdkjvmti
Это частичная реализация интерфейса JVMTI v1.2 для среды выполнения Android в качестве плагина. Это позволяет использовать агенты, которые могут изменять рабочее состояние программы, изменяя файлы dex в памяти и выполняя другие операции в глобальном состоянии времени выполнения.


Как только исходники Android Studio 3.5 будут выпущены, посмотрите, как они использовали эти новые API в реализации Apply Changes.

Хотя API-интерфейсы jlinstrument никогда не добавлялись в Android, базовые API-интерфейсы JVMTI, которые использовались для их реализации, были добавлены в Android O. Например, вот тестовый агент JVMTI, который переопределяет перечисленные классы и добавляет один nop в начало каждого метода: https://android.googlesource.com/platform/art/+/refs/heads/master/tools/jvmti-agents/simple-force-redefine/

Другие вопросы по тегам