Simple Science

Ciência de ponta explicada de forma simples

# Informática# Linguagens de programação

Melhorando os Testes de Software com Fuzzing de Caixa Cinza

Uma nova abordagem para testes de software usando fuzzing de caixa cinza e descida do gradiente.

― 7 min ler


Avanço no FuzzingAvanço no FuzzingGray-Boxdescobrir bugs de forma eficaz.Testes de software de outro nível pra
Índice

Fuzzing é uma maneira de testar software fornecendo entradas aleatórias ou inesperadas. Isso ajuda a encontrar bugs que podem causar travamentos ou outros problemas. Este artigo fala sobre um novo método chamado gray-box fuzzing, que busca melhorar esse processo de teste combinando-o com gradient descent, uma técnica matemática usada para achar o mínimo ou máximo de uma função. Esse método olha especificamente para como valores numéricos são convertidos em valores verdadeiros ou falsos no software.

O que é Gray-Box Fuzzing?

Gray-box fuzzing é um tipo de teste que tem conhecimento sobre o funcionamento interno do software enquanto ainda usa entradas aleatórias. Isso é diferente do black-box testing, onde o testador não sabe nada sobre como o software opera. Ao entender algumas partes do software, gray-box fuzzing pode gerar entradas que têm mais chances de levar a resultados interessantes.

Por que usar Gradient Descent?

Gradient descent é útil porque ajuda a identificar as entradas certas que podem mudar o resultado de certas instruções dentro do software. Fazendo isso, o processo de gray-box fuzzing pode direcionar áreas específicas que são mais propensas a ter bugs.

Instruções Booleanas e Cobertura

Instruções booleanas são comandos em um programa que avaliam condições e produzem resultados verdadeiros ou falsos. Um exemplo é a comparação entre dois números. Maximizar a cobertura dessas instruções booleanas pode levar a melhores resultados de teste, já que isso garante que vários caminhos e condições na lógica do programa sejam explorados.

A Ferramenta de Fuzzing

O novo método de gray-box fuzzing é implementado em uma ferramenta de software. Esta ferramenta é projetada para interagir com executáveis de 64 bits, pegando programas escritos em C e convertendo-os em binários testáveis. A ferramenta é composta por vários componentes que trabalham juntos para gerar entradas, rodar o programa sendo testado e analisar os resultados.

Geração de Entradas

O loop de fuzzing funciona gerando entradas baseadas em dados anteriores. Isso pode incluir entradas aleatórias ou mais focadas com base em características conhecidas do software. Para uma geração de entrada eficaz, a ferramenta deve entender quais entradas são mais sensíveis a mudanças no programa.

Bits Sensíveis

Alguns bits na entrada têm um impacto maior nos resultados do que outros. Ao identificar esses bits sensíveis, a ferramenta de fuzzing pode focar seus esforços em gerar entradas mais úteis, em vez de perder tempo com mudanças que podem não afetar o resultado.

Usando Dados Históricos

A ferramenta acompanha quais entradas foram bem-sucedidas em alcançar certas condições. Esses dados históricos são úteis para gerar novas entradas que podem empurrar o programa para novos estados, potencialmente descobrindo mais bugs.

Loop de Fuzzing

O loop de fuzzing é o núcleo do processo de teste. Em cada iteração, a ferramenta gera uma entrada, roda o programa com essa entrada e coleta dados sobre como o programa se comporta.

Execução da Entrada

Quando o programa executa com a entrada gerada, ele pode produzir vários resultados: pode terminar normalmente, travar, exceder limites de tempo ou violar certos limites operacionais. Cada possível resultado é registrado, permitindo que a ferramenta aprenda com suas interações com o programa.

Comunicação Entre Componentes da Ferramenta

A ferramenta usa tanto memória compartilhada quanto comunicação por rede para gerenciar a geração e execução de entradas. A memória compartilhada permite uma transferência rápida de dados entre processos, enquanto a comunicação por rede fornece uma maneira flexível de configurar ambientes de teste.

Monitorando a Execução

Para entender como as entradas geradas se saem, a ferramenta insere código de monitoramento no programa. Esse código coleta dados-chave sobre como o software executa cada instrução booleana.

Coletando Dados

O código de monitoramento registra várias informações, como o resultado de cada instrução booleana, os valores que levaram a esses resultados e se certas condições foram atendidas antes das avaliações. Esses dados são cruciais para entender o comportamento do programa sob diferentes entradas.

Construindo uma Árvore de Execução

Enquanto o loop de fuzzing roda, a ferramenta constrói uma árvore de execução. Cada nó dessa árvore representa um ponto no programa onde uma instrução booleana foi executada. O caminho por essa árvore mostra como o software chegou a esse ponto, e a árvore ajuda a visualizar quais partes do programa foram cobertas.

Atualizando a Árvore

Após cada iteração do loop de fuzzing, a árvore de execução é atualizada com novos dados do código de monitoramento. Isso inclui marcar nós como "visitados" quando são executados e registrar se levaram a resultados bem-sucedidos ou não.

Usando Funções de Ramificação

Funções de ramificação são usadas para descrever as condições sob as quais certos resultados são alcançados. A ferramenta visa encontrar entradas que mudem os resultados dessas funções com sucesso.

Encontrando Entradas

Usando dados históricos, a ferramenta pode amostrar valores de entrada estrategicamente para aumentar a probabilidade de produzir os resultados desejados. O gradient descent ajuda a refinar essas entradas enquanto busca aquelas que levam a diferentes resultados de avaliação.

Análise de Sensibilidade

A análise de sensibilidade é feita para identificar quais bits de entrada afetam os resultados de forma significativa.

Identificando Bits Sensíveis

Testando várias combinações de bits de entrada, a ferramenta determina quais mudanças levam a diferentes resultados de instruções booleanas. Essas informações ajudam a focar esforços de testes futuros nesses bits sensíveis.

Análise de Bitshare

A análise de bitshare ajuda a reutilizar bits sensíveis de entradas anteriores para criar novas. Ao combinar elementos bem-sucedidos de testes anteriores, a ferramenta pode gerar novas entradas que provavelmente produzirão resultados diferentes.

Análise de Minimização

A análise de minimização busca encontrar a entrada mais curta ou simples que ainda produz um efeito significativo no comportamento do software. Essa análise é crucial para eficiência, já que entradas complexas podem ser mais difíceis de gerenciar e analisar.

Gerando Entradas Seed

Antes que o gradient descent possa ser aplicado, a ferramenta precisa de entradas seed. Essas entradas seed são geradas com base em testes anteriores bem-sucedidos e têm a intenção de guiar rapidamente o processo de teste para encontrar novas entradas eficazes.

Conclusão

Gray-box fuzzing combinado com gradient descent e cobertura de expressões booleanas fornece um método poderoso para melhorar o teste de software. Ao focar no comportamento do programa e nos bits de entrada sensíveis, essa abordagem pode descobrir bugs de forma mais eficaz do que métodos tradicionais. A integração de dados históricos, monitoramento e análise cria uma ferramenta robusta para garantir a qualidade e confiabilidade do software.

Trabalho Futuro

Desenvolvimentos futuros no gray-box fuzzing podem envolver o aprimoramento das técnicas de geração de entradas, melhoria da eficiência do código de monitoramento e expansão do uso de machine learning para analisar o comportamento do programa e guiar os esforços de teste. Ao continuar a refinar esses métodos, o objetivo de alcançar testes de software mais abrangentes pode ser realizado.

Fonte original

Título: Gray-Box Fuzzing via Gradient Descent and Boolean Expression Coverage (Technical Report)

Resumo: We present a novel gray-box fuzzing algorithm monitoring executions of instructions converting numerical values to Boolean ones. An important class of such instructions evaluate predicates, e.g., *cmp in LLVM. That alone allows us to infer the input dependency (c.f. the taint analysis) during the fuzzing on-the-fly with reasonable accuracy, which in turn enables an effective use of the gradient descent on these instructions (to invert the result of their evaluation). Although the fuzzing attempts to maximize the coverage of the instructions, there is an interesting correlation with the standard branch coverage, which we are able to achieve indirectly. The evaluation on Test-Comp 2023 benchmarks shows that our approach, despite being a pure gray-box fuzzing, is able to compete with the leading tools in the competition, which combine fuzzing with other powerful techniques like model checking, symbolic execution, or abstract interpretation.

Autores: Martin Jonáš, Jan Strejček, Marek Trtík, Lukáš Urban

Última atualização: 2024-01-23 00:00:00

Idioma: English

Fonte URL: https://arxiv.org/abs/2401.12643

Fonte PDF: https://arxiv.org/pdf/2401.12643

Licença: https://creativecommons.org/publicdomain/zero/1.0/

Alterações: Este resumo foi elaborado com a assistência da AI e pode conter imprecisões. Para obter informações exactas, consulte os documentos originais ligados aqui.

Obrigado ao arxiv pela utilização da sua interoperabilidade de acesso aberto.

Artigos semelhantes