Capítulo 9 — Programação II
Mapa da aula
Aula 09 publicada. Mapa, exemplo, EX025.
flowchart TD
N0["9.1 De scripts a programas"]
N1["9.3 Logging"]
N2["9.4 Testes"]
N3["9.5 Disciplina de somente leitura"]
N4["9.6 Dependências"]
N5["9.7 Revisão de código"]
N6["Controle de versão"]
N7["Síntese"]
N0 --> N1 --> N2 --> N3 --> N4 --> N5 --> N6 --> N7
N7 --> EX["Exemplo resolvido"]
EX --> Q["Exercício EX025"]
Desenho lógico
flowchart LR
N0["9.1 De scripts a programas"]
N1["9.3 Logging"]
N2["9.4 Testes"]
N3["9.5 Disciplina de somente leitura"]
N4["9.6 Dependências"]
N5["9.7 Revisão de código"]
N6["Controle de versão"]
N7["Síntese"]
N0 --> N1 --> N2 --> N3 --> N4 --> N5 --> N6 --> N7 --> Q["EX025"]
[9.1 De scripts a programas]
|
v
[9.3 Logging]
|
v
[9.4 Testes]
|
v
[9.5 Disciplina de somente leitura]
|
v
[9.6 Dependências]
|
v
[9.7 Revisão de código]
|
v
[Controle de versão]
|
v
[Síntese]
|
v
[Exemplo resolvido] --> [Exercício EX025]
Objetivos de aprendizagem
Você vai (1) estruturar programas maiores com funções e módulos; (2) tratar erros sem perder dados; (3) registrar em log o que um programa fez; (4) escrever testes.
9.1 De scripts a programas
O script de verificação de Priya cresce até virar uma ferramenta que processa muitos arquivos de evidência. Ela o divide em funções: read_chunks, hash_file, compare, report. Cada função faz uma única tarefa e pode ser testada isoladamente. read_chunks entrega bytes sem saber nada sobre hashes, e hash_file a usa sem saber de onde vêm os bytes. compare recebe dois resumos e devolve um veredito. report formata os resultados. Quando Hugo mais tarde pede suporte a SHA-512, só hash_file muda, e os testes das outras três funções mostram que nada mais quebrou.
9.2 Tratamento de erros
Arquivos ilegíveis não devem derrubar a execução em silêncio. Cada erro é capturado, registrado em log com o nome do arquivo e o motivo, e a execução continua. O resumo final conta sucessos e falhas. Capturar todas as exceções possíveis esconde bugs, por isso Priya captura apenas as esperadas, como erros de permissão, arquivos ausentes e falhas de leitura, e deixa que qualquer outra coisa interrompa a execução de forma ruidosa. A linha de resumo diz, por exemplo, '412 verified, 3 failed (see log)'. Uma execução com falhas termina com código de saída diferente de zero, de modo que nenhuma automação que chame a ferramenta possa confundir uma execução parcial com uma completa.
9.3 Logging
Toda execução grava um log: hora de início, versão da ferramenta, entradas, saídas, erros. Os logs sustentam a documentação que o SP 800-86 exige e permitem que um revisor reproduza a execução. Cada linha do log traz um carimbo de tempo em UTC, uma severidade e uma mensagem. As primeiras linhas registram a versão da ferramenta, a versão do Python, o algoritmo de hash e a linha de comando completa, para que um revisor possa reconstruir a invocação exata. Os logs são gravados na pasta de saída e nunca são sobrescritos: cada execução recebe um arquivo novo, nomeado com sua hora de início.
9.4 Testes
Os testes unitários verificam cada função com entradas conhecidas; um teste de integração executa a ferramenta inteira sobre um pequeno conjunto sintético de evidências com respostas conhecidas. O conjunto sintético de evidências contém cinco arquivos com resumos conhecidos, uma cópia deliberadamente corrompida e um arquivo ilegível. O teste de integração afirma quatro coincidências, uma divergência e um erro registrado, e confere a linha de resumo palavra por palavra. Se alguém mudar o formato da saída, o teste falha, o que força uma decisão deliberada sobre se os relatórios e as ferramentas posteriores também precisam ser atualizados.
9.5 Disciplina de somente leitura
A ferramenta abre as evidências em modo somente leitura e grava as saídas numa pasta separada. Um teste verifica que os horários de modificação das entradas não mudam. Abrir um arquivo em modo somente leitura impede gravações por meio daquele handle, mas alguns sistemas atualizam os horários de acesso na leitura. O teste registra os metadados de cada entrada antes e depois da execução e falha se algo tiver mudado. Nas estações de trabalho do laboratório, as evidências também ficam num ponto de montagem somente leitura, de modo que um bug na ferramenta não consegue alcançar os originais, mesmo que o código tente.
9.6 Dependências
Usar apenas a biblioteca padrão mantém a ferramenta fácil de validar e de reproduzir; cada pacote extra precisa ele próprio ser rastreado e testado. Cada pacote de terceiros traz suas próprias versões, defeitos e ciclo de atualização, e cada um precisa ser validado junto com a ferramenta. O verificador de Priya não precisa de nada além de hashlib, os, argparse e logging, todos da biblioteca padrão. Se um recurso posterior precisar de um pacote, ela fixa sua versão exata e registra seu hash num arquivo de requisitos, para que o mesmo código possa ser instalado de novo mais tarde.
9.7 Revisão de código
Hugo revisa o pull request dela e pede uma mudança: imprimir o nome do algoritmo de hash ao lado de cada resumo. O pedido parece pequeno, mas importa para a evidência. Um resumo sem o nome do algoritmo pode ser mal interpretado anos depois, sobretudo quando valores MD5 e SHA-256 aparecem lado a lado em relatórios antigos. Hugo também verifica se os testes mudaram junto com a saída e se a mensagem do commit explica o porquê. Os comentários da revisão ficam guardados com o pull request como parte do histórico de validação da ferramenta.
Controle de versão
Cada mudança na ferramenta é registrada num commit com uma mensagem que descreve o porquê. As versões lançadas recebem tags, e os relatórios citam a tag. Se um bug for encontrado mais tarde, o laboratório pode identificar exatamente quais casos usaram a versão afetada e decidir se os resultados precisam de revisão, o que é uma forma prática de garantia da qualidade.
Exemplo resolvido
Numa pasta de 200 arquivos sintéticos, um está bloqueado por permissões. A primeira versão parou após 120 arquivos, sem resumo. A versão revisada registra "permission denied: case7/notes.txt", processa os 79 restantes e relata 199 com hash calculado e 1 com falha.
Caso sintético. A pasta e os arquivos são inventados.
Erros e limites
Os testes mostram que a ferramenta funciona nos casos testados; formatos não testados continuam sendo um risco.
Exercícios
- EX025 — Correção da parada. Como a ferramenta revisada tratou o arquivo bloqueado? Rubrica: 3 = registrou o motivo, continuou, resumo 199/1; 2 = parcial; 1 = pulou em silêncio; 0 = nada.
- EX026 — Teste de somente leitura. Como um teste pode confirmar que as entradas não foram modificadas? Rubrica: 3 = comparar hashes/mtimes antes e depois; 2 = parcial; 1 = confiar; 0 = nada.
- EX027 — Rótulo do algoritmo. Por que imprimir o nome do algoritmo ao lado de cada resumo? Rubrica: 3 = resumo sem sentido sem o algoritmo; evita confusão; 2 = parcial; 1 = estilo; 0 = nada.
Síntese
Código estruturado, registrado em log, testado e de somente leitura é o que torna confiáveis as ferramentas forenses.
Continue estudando — capítulo 09 de 50
← Capítulo 08 (rascunho) · Índice de capítulos do curso · Capítulo 10 (rascunho) →