TI DE ARTE

En Android 8.0 y versiones posteriores, la ART Tooling Interface (ART TI) expone ciertas funciones internas del entorno de ejecución, y permite que los generadores de perfiles y los depuradores influyan en la el comportamiento del tiempo de ejecución de las apps. Esto se puede usar para implementar de vanguardia que se proporcionan para implementar agentes nativos en otras plataformas.

Los componentes internos del entorno de ejecución están expuestos a los agentes que se cargaron en el proceso del entorno de ejecución. Estos se comunican con el ART a través de llamadas directas y devoluciones de llamada. El entorno de ejecución admite varios agentes para que se puedan solucionar separarse. Los agentes pueden suministrarse al inicio del entorno de ejecución (cuando se invocan dalvikvm o app_process), o se adjuntan a un proceso que ya está en ejecución.

Debido a que la capacidad de instrumentar y modificar el comportamiento de la aplicación y del tiempo de ejecución es muy potente, se integraron dos medidas de seguridad en ART TI:

  • Primero, el código que expone la interfaz del agente, JVMTI, se implementa como un un complemento de entorno de ejecución, no un componente central del entorno de ejecución. Es posible que la carga del complemento para que los agentes no puedan encontrar ninguna de las interfaces puntos.
  • En segundo lugar, tanto la clase ActivityManager como el proceso de entorno de ejecución solo permiten que los agentes adjuntar a apps depurables. Se cerraron las apps depurables que sus desarrolladores analicen e instrumenten, y no se distribuyan para los usuarios finales. Google Play Store no permite la distribución de archivos de Google Chat. Esto garantiza que las apps normales (incluidos los componentes principales) no puedan instrumentados o manipulados.

Diseño

El flujo general y la interconexión en una aplicación instrumentada se muestran en Figura 1:

Interconexión y flujo en una app instrumentada
Figura 1: Flujo y interconexión de una app instrumentada

El complemento de ART libopenjdkjvmti expone la TI de ART, que se diseñada para adaptarse a las necesidades y limitaciones de la plataforma:

  • La redefinición de clases se basa en archivos Dex, que contienen un solo definición de clase única, en lugar de archivos de clase.
  • Las APIs de lenguaje Java para instrumentación y redefinición no están expuestos.

ART TI también es compatible con generadores de perfiles de Android Studio.

Carga o adjunta un agente

Para adjuntar un agente en el inicio del entorno de ejecución, usa este comando para cargar Complemento JVMTI y el agente determinado:

dalvikvm -Xplugin:libopenjdkjvmti.so -agentpath:/path/to/agent/libagent.so …

No existen medidas de seguridad implementadas cuando se carga un agente en el entorno de ejecución Ten en cuenta que un entorno de ejecución iniciado de forma manual permite de la infraestructura sin medidas de seguridad. (Esto permite realizar pruebas de ART).

Nota: Esto no se aplica a las apps normales (incluido el sistema servidor) en un dispositivo. Las aplicaciones se bifurcan a partir de un zygote que ya está en ejecución y un proceso Zygote no tiene permitido cargar agentes.

Para adjuntar un agente a una app que ya está en ejecución, usa este :

adb shell cmd activity attach-agent [process]
/path/to/agent/libagent.so[=agent-options]

Si aún no se cargó el complemento JVMTI, adjuntar un agente carga ambos. el complemento y la biblioteca del agente.

Un agente solo puede conectarse a una aplicación en ejecución marcada como debuggable (parte del manifiesto de la app, con el atributo Se estableció android:debuggable como true en la app de Terraform). Tanto la clase ActivityManager como el ART realizan comprobaciones antes de permitir que se conecte un agente. ActivityManager verifica la información actual de la app (derivada de PackageManager datos de clase) para el estado depurable, y el tiempo de ejecución verifica su estado actual, que se estableció cuando se inició la app.

Ubicaciones de los agentes

El entorno de ejecución debe cargar agentes en el proceso actual para que pueden vincularse y comunicarse con ella directamente. El ART en sí es agnóstico en relación con la ubicación específica de la que proviene el agente. Se usa la cadena para una llamada dlopen. Permisos del sistema de archivos y políticas de SELinux restringir la carga real.

Para entregar agentes que puedan ser ejecutados por una app depurable, haz lo siguiente:

  • Incorpora el agente en el directorio de bibliotecas del APK de la app.
  • Usa run-as para copiar el agente en los datos de la app. .

APIs

Se agregó el siguiente método a android.os.Debug.

/**
     * Attach a library as a jvmti agent to the current runtime, with the given classloader
     * determining the library search path.
     * Note: agents may only be attached to debuggable apps. Otherwise, this function will
     * throw a SecurityException.
     *
     * @param library the library containing the agent.
     * @param options the options passed to the agent.
     * @param classLoader the classloader determining the library search path.
     *
     * @throws IOException if the agent could not be attached.
     * @throws a SecurityException if the app is not debuggable.
     */
    public static void attachJvmtiAgent(@NonNull String library, @Nullable String options,
            @Nullable ClassLoader classLoader) throws IOException {

Otras APIs de Android

El comando attach-agent es visible de forma pública. Este comando adjunta un JVMTI en un proceso en ejecución:

adb shell 'am attach-agent com.example.android.displayingbitmaps
\'/data/data/com.example.android.displayingbitmaps/code_cache/libfieldnulls.so=Ljava/lang/Class;.name:Ljava/lang/String;\''

Los comandos am start -P y am start-profiler/stop-profiler son similares al comando attach-agent.

JVMTI

Esta función expone la API de JVMTI a los agentes (código nativo). Lo importante capacidades incluyen:

  • Redefine una clase.
  • Seguimiento de la asignación de objetos y la recolección de elementos no utilizados
  • Iteración sobre todos los objetos de un montón, siguiendo el árbol de referencia de objetos.
  • Cómo inspeccionar pilas de llamadas de Java
  • Suspender (y reanudar) todos los subprocesos

Diferentes capacidades pueden estar disponibles en distintas versiones de Android

Compatibilidad

Esta función necesita compatibilidad principal con el entorno de ejecución que solo está disponible en Android 8.0 y versiones posteriores. Los fabricantes de dispositivos no necesitan hacer ningún cambio para implementar esta función. Es parte del AOSP.

Validación

El CTS prueba lo siguiente en Android 8 y versiones posteriores:

  • Pruebas que los agentes adjuntan a apps depurables y no se pueden adjuntar a y las apps no depurables.
  • Prueba todas las APIs de JVMTI implementadas
  • Prueba que la interfaz binaria de los agentes sea estable

Se agregaron pruebas adicionales a Android 9 y versiones posteriores, que están incluidas en las pruebas del CTS de esas versiones.