Java — раскрыть новые функциональные возможности ART, изменив Runtime.class в libcore

Я вставил некоторые новые функции в Android Runtime (ИЗОБРАЗИТЕЛЬНОЕ ИСКУССТВО), и теперь я хочу показать его внешнему миру через интерфейс. Поскольку это нативный код, я буду использовать JNI интерфейс для вызова этой новой функциональности, аналогично функциональности сборщика мусора: Runtime.getInstance().gc(),

Тем не менее, меня не волнует создание нового SDK, который может быть использован IDE, поскольку я буду вручную вводить байт-код в файлы .dex, которые будут выполнять вызов.

Я редактировал Runtime.java в libcore/luni, а также java_lang_Runtime.cc в art аналогичным образом с gc() функция. Я создаю новый libart.so а также core-libart.jar и я прошить их на устройстве.
Тем не менее, когда я пытаюсь перезагрузить устройство, я получаю сообщение:

Failed to register native method java.lang.Runtime.myMethod()V in /system/framework/core-libart.jar
...
----- class 'Ljava/lang/Runtime;' cl=0x0 -----
vtable (24 entries, 11 in super):
// 24 entries are listed here. My entry is missing.
...

в Runtime.java Я регистрирую нативный метод и подавляю некоторые предупреждения на полную сборку, используя @hide. например,

/** @hide */
public native void myMethod();

в java_lang_Runtime.ccЯ определяю функцию (которая будет вызывать внутреннюю структуру ART) и регистрирую ее в массиве gMethods [] с помощью макроса. например,

static void Runtime_myMethod(JNIEnv*, jclass) {
// body
}

NATIVE_METHOD(Runtime, myMethod, "()V")

Устройство находится на загрузочной петле. Есть ли другие файлы, которые я должен был отредактировать? Стоит ли создавать дополнительные модули или отправлять какие-либо другие файлы на устройство?

Кстати, я не хочу строить новый SDK что касается вызова myMethod Я буду вводить Dalvik bytecode в файл APK. В основном я получу экземпляр Runtime, а затем вызову метод.

0

Решение

Эта проблема:

Android поставляет заводские образы с предварительно оптимизированными компонентами фреймворка.
Файл boot.oat содержит предварительно оптимизированный код (или код odex), доступ к которому можно получить, прочитав указатели, содержащиеся в boot.art файл.

Эти два файла содержат код только для boot classpath,
Остальная часть фреймворка и остальные системные приложения (в app а также priv-app) папки имеют автономные odex файлы.

На этом этапе предварительной оптимизации код dex изъятые модуля фреймворка (jar или apk), компилируется с использованием dex2oatи полученный код находится в файлах, которые я только что упомянул.

Некоторые из вещей, которые я пробовал:

Доставка только libart.so а также core-libart.jar не работает, хотя последний содержит код dex. Это потому, что среда выполнения все еще пытается прочитать эту информацию из boot.oat,

Изменяя конфигурацию устройства, чтобы сделать предварительную оптимизацию, aosp build system может генерировать boot.oat|art а остальное odex файлы (больше Вот). Я ожидал, что перепрошивка все это должно работать, но это не так.
(по крайней мере, для marshmallow-release ветка, на нексус6)

Я попытался перепрограммировать всю сгенерированную aosp сборку, и она не работала, даже с собственным ядром, которое я собираю с функциями безопасности (verity) отключен.

Я уверен, что некоторые из них должны были работать, но должно быть что-то еще, что следует учитывать при сборке ОС.

Решение:

В крайнем случае, был deodexing и, к счастью, это сработало.
Я написал небольшой скрипт это делает это для Nexus 6 на Зефире.

Сценарий, во время 1-го этапа, он убирает все oat/odex код из соответствующих мест, и де-оптимизирует его dex код, благодаря oat2dex а также smali проекты.
На втором этапе он упаковывает dex Код обратно, в рамках модулей (jars / apks).

Доставка совершенно новый core-libart.jar к устройству все еще не работает (не уверен почему), но мастеринг файлов dex перед упаковкой их в модули делает свое дело! :))

libart.so теперь могу найти Runtime.myMethod(), который может быть вызван приложением (снова smali возиться), чтобы запустить мой код внутри ART,

0

Другие решения

Других решений пока нет …