Как поменять тела методов под 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/