2 pontos por GN⁺ 2024-09-15 | 1 comentários | Compartilhar no WhatsApp

FlowTracker: rastreamento do fluxo de dados em programas Java

FlowTracker é um agente Java que rastreia como um programa lê, manipula e grava dados. Com isso, ele permite inspecionar I/O de arquivos e rede e conectar entradas e saídas para mostrar de onde veio uma saída. Assim, é possível entender o que a saída de um programa Java significa.

Demonstração

Spring PetClinic é uma aplicação de demonstração do framework Spring. Para mostrar os recursos do FlowTracker, observa-se como o PetClinic processa requisições HTTP e gera páginas HTML a partir de templates e do banco de dados. É possível executar a demonstração no navegador ou assistir ao vídeo.

  • Processamento HTTP: o FlowTracker mostra qual código gerou qual saída. Por exemplo, ao clicar em "HTTP/1.1" ou em um cabeçalho HTTP, é possível ver que essa parte foi gerada por classes do pacote org.apache.coyote.
  • Templates Thymeleaf: mostra como a entrada lida pelo programa (template HTML) se conecta à saída. Ao clicar no nome de uma tag HTML, é possível ver que essa parte veio do arquivo layout.html.
  • Banco de dados: mostra que as informações na tabela da página HTML vieram do banco de dados. Por exemplo, ao clicar em George na tabela, é possível ver que esse valor veio do banco de dados.

Essa demonstração usa um banco de dados em memória, o que permite rastrear até os scripts SQL. Ao usar um banco de dados MySQL, também é possível rastrear até a conexão com o banco.

Como usar

Atualmente, o FlowTracker está na fase de prova de conceito e pode não funcionar bem com todos os programas. Ele também adiciona muito overhead, tornando a execução do programa mais lenta. Para usar, baixe o arquivo jar do agente FlowTracker e adicione-o à linha de comando do Java.

Como funciona internamente

Explicação simples

O FlowTracker injeta código em arquivos de classe (bytecode) para rastrear dados na memória e sua origem. Ele rastreia principalmente dados textuais e binários (String, arrays de char e de byte).

  • Substitui chamadas de métodos do JDK por chamadas de métodos do FlowTracker.
  • Injeta código em pontos importantes do JDK para rastrear entradas e saídas.
  • Faz análise de fluxo de dados e instrumentação mais profunda para rastrear valores de variáveis locais e da pilha dentro dos métodos.
  • Adiciona código antes e depois de chamadas de métodos, bem como no início e no fim dos métodos, para rastrear argumentos e valores de retorno.

Modelo de dados: Tracker

Principais classes e conceitos do modelo de dados do FlowTracker:

  • Tracker: mantém informações sobre o conteúdo do objeto rastreado e sua origem.
    • content: o conteúdo que passou pelos dados. Ex.: todos os bytes que passaram por um InputStream ou OutputStream.
    • source: conecta intervalos do conteúdo a intervalos de origem em outros trackers.
  • TrackerRepository: mantém um mapa global que associa objetos interessantes aos seus trackers.
  • TrackerPoint: aponta para uma posição em um tracker que representa um único valor primitivo.

Instrumentação básica

Para manter os trackers atualizados, insere chamadas aos métodos de hook do FlowTracker em chamadas de métodos específicos do JDK. Por exemplo, uma chamada a System.arraycopy é substituída por uma chamada a com.coekie.flowtracker.hook.SystemHook.arraycopy.

Valores primitivos, análise de fluxo de dados

Rastrear valores primitivos é um desafio maior. Por exemplo, para rastrear um valor byte, o tracker é armazenado em variáveis locais dentro do método.

Chamadas de métodos

Modela como valores primitivos fluem para outros métodos como argumentos de chamadas e valores de retorno. Usa Invocation para armazenar os PointTracker dos argumentos e do valor de retorno.

Uso do próprio código como origem

Rastreia valores que vêm do próprio código, como constantes primitivas e constantes String. Cria um tracker para cada classe e o referencia quando uma constante é usada.

Literais String

Copia novamente os literais String e conecta o conteúdo da String ao ClassOriginTracker. Por exemplo, String s = "abc"; é reescrito como String s = StringHook.constantString("abc", 1234, 81);.

Abordagem alternativa para valores não rastreados

Nem todos os valores do programa são rastreados. Quando um valor não rastreado chega a um ponto que deveria ser rastreado, ele é tratado de forma semelhante a uma constante.

Resumo do GN⁺

  • O FlowTracker rastreia o fluxo de dados em programas Java para ajudar a entender a saída do programa.
  • Com a demonstração do Spring PetClinic, é possível verificar visualmente o processamento de requisições HTTP, o uso de templates e a integração com o banco de dados.
  • Atualmente está em fase de prova de conceito, pode não funcionar bem com todos os programas e tem alto overhead de desempenho.
  • Rastreia a origem de valores primitivos e objetos por meio de análise de fluxo de dados e rastreamento de chamadas de métodos.
  • Ferramentas com recursos semelhantes incluem Dynatrace e New Relic.

1 comentários

 
GN⁺ 2024-09-15
Comentários do Hacker News
  • Apresenta uma ferramenta chamada FlowStorm para Clojure

    • Faz um fork do compilador oficial de Clojure para inserir bytecode adicional
    • Como a maioria dos valores é imutável, é possível manter ponteiros e tirar snapshots
    • Fornece um link para uma demo de depuração de app web: demo do FlowStorm
  • Elogia como as ferramentas do ecossistema Java/JVM são excelentes

    • Ficou impressionado em um nível parecido com o jitwatch
    • O FlowTracker lembra análise de taint
    • Palavra-chave relacionada: "dynamic taint tracking/analysis"
    • Links de projetos relacionados:
  • Ficou impressionado com a demo que rastreia elementos HTML até instruções SQL

    • Uma ferramenta assim pode se tornar a primeira linha de defesa para resolver bugs
  • Lembra o ambiente Smalltalk

    • É possível rastrear e interagir com todos os objetos e mensagens
  • Enfatiza que o vídeo de demonstração é muito útil

    • Deve ser útil ao explorar uma base de código desconhecida
  • Compartilha a experiência de ter experimentado um conceito semelhante a source maps de HTML

    • Ferramentas de desenvolvimento web se beneficiariam muito desse tipo de propriedade full-stack
    • Integrar isso a frameworks existentes é um grande desafio
    • Link de projeto relacionado: HTML Source Maps
  • Menciona que é semelhante à demo do Eve-lang

  • Lembra de um artigo semelhante sobre uma ferramenta para encontrar SQL injection dinamicamente

  • Compartilha que já teve a visão de rastrear dados na internet

    • Este é um passo na direção de rastrear a origem de uma imagem ou o caminho de uma string
  • Agradece pela tentativa de usar essa ferramenta no VSCode e em um projeto

    • No momento está pausado, mas pretende tentar de novo