ARTE TI

No Android 8.0 e superior, a ART Tooling Interface (ART TI) expõe determinados componentes internos de tempo de execução e permite que criadores de perfil e depuradores influenciem o comportamento de tempo de execução dos aplicativos. Isso pode ser usado para implementar ferramentas de desempenho de última geração fornecidas para implementar agentes nativos em outras plataformas.

Os internos de tempo de execução são expostos a agentes que foram carregados no processo de tempo de execução. Estes se comunicam com o ART por meio de chamadas diretas e retornos de chamada. O tempo de execução oferece suporte a vários agentes para que diferentes preocupações de criação de perfil ortogonal possam ser separadas. Os agentes podem ser fornecidos no início do tempo de execução (quando dalvikvm ou app_process são invocados) ou anexados a um processo já em execução.

Como a capacidade de instrumentar e modificar o comportamento do aplicativo e do tempo de execução é muito poderosa, duas medidas de segurança foram integradas ao ART TI:

  • Primeiro, o código que expõe a interface do agente, JVMTI, é implementado como um plug-in de tempo de execução, não como um componente principal do tempo de execução. O carregamento de plug-ins pode ser restrito, para que os agentes possam ser impedidos de encontrar qualquer um dos pontos de interface.
  • Em segundo lugar, tanto a classe ActivityManager quanto o processo de tempo de execução só permitem que os agentes sejam anexados a aplicativos depuráveis. Os aplicativos depuráveis ​​foram aprovados por seus desenvolvedores para serem analisados ​​e instrumentados e não são distribuídos aos usuários finais. A Google Play Store não permite a distribuição de aplicativos depuráveis. Isso garante que aplicativos normais (incluindo componentes principais) não possam ser instrumentados ou manipulados.

O design

O fluxo geral e a interconexão em um aplicativo instrumentado são mostrados na Figura 1 .

Flow and interconnection in an instrumented app
Figura 1. Fluxo e interconexão de um aplicativo instrumentado

O plugin ART libopenjdkjvmti expõe o ART TI, que é projetado para acomodar as necessidades e restrições da plataforma:

  • A redefinição de classe é baseada em arquivos Dex , contendo apenas uma definição de classe única, em vez de arquivos de classe.
  • As APIs de linguagem Java para instrumentação e redefinição não são expostas.

O ART TI também suporta perfis do Android Studio.

Carregando ou anexando um agente

Para anexar um agente na inicialização do tempo de execução, use este comando para carregar o plug-in JVMTI e o agente fornecido:

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

Não há medidas de segurança em vigor quando um agente é carregado na inicialização do tempo de execução, portanto, lembre-se de que um tempo de execução iniciado manualmente permite a modificação completa sem medidas de segurança. (Isso permite o teste de ART.)

Nota: Isso não se aplica a aplicativos normais (incluindo o servidor do sistema) em um dispositivo. Os aplicativos são bifurcados de um zigoto já em execução e um processo de zigoto não tem permissão para carregar agentes.

Para anexar um agente a um aplicativo que já está em execução, use este comando:

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

Se o plug-in JVMTI ainda não foi carregado, anexar um agente carrega o plug-in e a biblioteca do agente.

Um agente só pode ser anexado a um aplicativo em execução marcado como depurável (parte do manifesto do aplicativo, com o atributo android:debuggable definido como true no nó do aplicativo). Tanto a classe ActivityManager quanto o ART realizam verificações antes de permitir que um agente seja anexado. A classe ActivityManager verifica as informações atuais do aplicativo (derivadas dos dados da classe PackageManager ) quanto ao status depurável e o tempo de execução verifica seu status atual, que foi definido quando o aplicativo foi iniciado.

Locais de agentes

O tempo de execução precisa carregar agentes no processo atual, para que o agente possa vincular-se diretamente e se comunicar com ele. O próprio ART é agnóstico em relação ao local específico de onde o agente vem. A string é usada para uma chamada dlopen . As permissões do sistema de arquivos e as políticas do SELinux restringem o carregamento real.

Para entregar agentes que podem ser executados por um aplicativo depurável, faça o seguinte:

  • Incorpore o agente no diretório da biblioteca do APK do aplicativo.
  • Use run-as para copiar o agente no diretório de dados do aplicativo.

API

O método a seguir foi adicionado 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 {

Outras APIs do Android

O comando attach-agent é visível publicamente. Este comando anexa um agente JVMTI a um processo em execução:

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;\''

Os comandos am start -P e am start-profiler/stop-profiler são semelhantes ao comando attach-agent.

JVMTI

Esse recurso expõe a API JVMTI aos agentes (código nativo). Os recursos importantes incluem:

  • Redefinindo uma classe.
  • Rastreamento de alocação de objetos e coleta de lixo.
  • Iterando sobre todos os objetos em um heap, seguindo a árvore de referência de objetos.
  • Inspecionando pilhas de chamadas Java.
  • Suspendendo (e retomando) todos os tópicos.

Diferentes recursos podem estar disponíveis em diferentes versões do Android.

Compatibilidade

Esse recurso precisa de suporte de tempo de execução principal que está disponível apenas no Android 8.0 e superior. Os fabricantes de dispositivos não precisam fazer alterações para implementar esse recurso. Faz parte da AOSP.

Validação

O CTS testa o seguinte no Android 8 e superior:

  • Testes que os agentes anexam a aplicativos depuráveis ​​e falham ao anexar a aplicativos não depuráveis.
  • Testa todas as APIs JVMTI implementadas
  • Testa se a interface binária para agentes é estável

Testes adicionais foram adicionados ao Android 9 e superior e estão incluídos nos testes CTS para esses lançamentos.