
whatfiles v2.0
Registre quais arquivos são acessados por qualquer processo Linux
whatfiles
Whatfiles é um utilitário Linux que registra quais arquivos outro programa lê/escreve/cria/exclui no seu sistema. Ele também rastreia quaisquer novos processos e threads criados pelo processo alvo, e registra se cada operação foi bem-sucedida.
Justificativa:
Há muito tempo me frustrava a falta de um utilitário simples para ver quais arquivos um processo acessa desde main() até a saída. Seja por desconfiança de um fornecedor de software ou por preocupação com malware, é importante saber o que um programa ou instalador faz no seu sistema. O lsof observa apenas um momento no tempo e o strace é grande e um tanto complicado.
Exemplo de saída:
mode: exec, file: /usr/bin/cp, syscall: execve(), PID: 17004, process: sh, result: 0
mode: read, file: /tmp/demo/copy.txt, syscall: openat(), PID: 17004, process: /usr/bin/cp, result: -1 (No such file or directory)
mode: read, file: /etc/hostname, syscall: openat(), PID: 17004, process: /usr/bin/cp, result: 3
mode: write+create, file: /tmp/demo/copy.txt, syscall: openat(), PID: 17004, process: /usr/bin/cp, result: 4
mode: chmod, file: /tmp/demo/copy.txt, syscall: fchmodat(), PID: 17005, process: /usr/bin/chmod, result: 0
mode: rename, file: /tmp/demo/copy.txt, to: /tmp/demo/renamed.txt, syscall: renameat2(), PID: 17006, process: /usr/bin/mv, result: 0
mode: read, file: /tmp/demo/missing.txt, syscall: openat(), PID: 17007, process: /usr/bin/cat, result: -1 (No such file or directory)
mode: delete, file: /tmp/demo/renamed.txt, syscall: unlinkat(), PID: 17008, process: /usr/bin/rm, result: 0
Cada linha informa o que foi feito com o arquivo, o próprio arquivo, qual syscall o fez, qual processo e thread, e o que o kernel retornou. Os caminhos são sempre absolutos: caminhos relativos são resolvidos em relação ao diretório de trabalho do processo, ou em relação ao diretório passado para uma syscall *at(). result é o valor de retorno da syscall, então acessos com falha e bem-sucedidos podem ser diferenciados.
Além de abrir, criar e excluir, o whatfiles reporta rename, link, symlink, mkdir, rmdir, truncate, chmod, chown e exec de um programa. SYSCALLS.md cobre o que ainda não é reportado e por que cada adição valeria a pena.
Uso:
-
uso básico, inicia
lse grava a saída em um arquivo de log no diretório atual:$ whatfiles ls -lah ~/Documents -
especifique o local do arquivo de saída com
-o:$ whatfiles -o MyLogFile cd .. -
inclua saída de depuração, imprima em stdout em vez de arquivo de log:
$ whatfiles -d -s apt install zoom -
anexe a um processo em execução no momento (requer privilégios de root):
$ sudo whatfiles -p 1234 -
encerre o programa rastreado se o próprio whatfiles for encerrado, em vez de deixá-lo continuar sem rastreamento:
$ whatfiles -k ./installer.sh
Pressione Ctrl-C a qualquer momento: o whatfiles se desanexa de tudo o que está rastreando, deixa esses processos em execução e termina de gravar o log.
Distribuição
Binários prontos para uso estão na página de releases! Alguém também gentilmente o adicionou ao repositório Arch, e letompouce também configurou um pipeline no GitLab.
Compilação (requer gcc e make):
$ cd whatfiles
$ make
$ sudo make install
Suporta arquiteturas x86, x86_64, ARM32 e ARM64. make install respeita PREFIX e DESTDIR.
É necessário Linux 3.4 ou mais recente. No Linux 5.3 e mais recente, o whatfiles pergunta diretamente ao kernel sobre cada parada de syscall, o que faz com que syscalls de 32 bits em uma máquina de 64 bits sejam decodificadas corretamente; em kernels mais antigos, ele recorre à leitura de registradores.
Android
Compile de forma cruzada com o NDK e depois envie o binário para o dispositivo:
$ make android NDK=~/Android/Sdk/ndk/<version>
$ adb push bin/whatfiles-android /data/local/tmp/whatfiles
$ adb shell chmod 755 /data/local/tmp/whatfiles
$ adb shell /data/local/tmp/whatfiles -o /data/local/tmp/ls.log ls /sdcard
ANDROID_ABI seleciona arm64, o padrão, ou arm32, x86_64 ou x86. ANDROID_API define o
nível mínimo de API e tem como padrão 21.
Algumas coisas são diferentes em um dispositivo:
- Coloque o binário em
/data/local/tmp./sdcardé montado sem permissão de execução. - O diretório de trabalho no
adb shellnão é gravável, então passe-ocom um caminho sob/data/local/tmp, ou-spara gravar em stdout. - Executar um comando sob o whatfiles funciona como o usuário comum do shell, e anexar a um
processo iniciado por esse usuário também. Anexar a qualquer outra coisa, um app por exemplo, precisa de root, então
adb rootem uma build userdebug. Em um emulador Android 14 isso funcionou com o SELinux em modo enforcing; a política de um dispositivo de produção ainda pode recusar. make test-android NDK=~/Android/Sdk/ndk/<version>compila o whatfiles e os programas de teste para o dispositivo conectado, executa as verificações lá e remove o que foi enviado.- Um app de 32 bits rastreado a partir de uma build arm64 é lido com os números de syscall de 32 bits e registradores de argumentos, em vez de ser tomado como um de 64 bits. Esse caminho não foi exercitado em hardware real: o emulador usado para testes aqui não tem ABI de 32 bits.
make test compila os programas em tests/ e os executa sob o whatfiles para verificar seu comportamento, incluindo entrega de sinais, cobertura de threads e processos filhos, e tratamento de interrupções.
Perguntas que poderiam ser feitas em algum momento:
-
Isso não é apenas uma reimplementação de
strace -fe trace=creat,open,openat,unlink,unlinkat ./program?Sim. Embora tenha como objetivo ser mais simples e mais amigável ao usuário.
-
Existem versões para Mac e Windows?
Não. Rastrear syscalls no Mac requer
task_for_pid(), que requer assinatura de código, o que não consigo fazer funcionar, e de qualquer forma não tenho interesse em pagar US$ 100/ano à Apple para escrever software livre. Odtrussno Mac pode ser usado para acompanhar um único processo e seus filhos, embora a flag-tpareça aceitar apenas uma única syscall para filtrar. Ofs_usagefaz algo semelhante, embora eu não tenha certeza se ele acompanha processos/threads filhos. O Process Monitor para Windows é muito bom.
Limitações:
-
Programas que passam o controle para uma cópia de si mesmos. Navegadores especialmente: se uma instância já estiver em execução, a que você inicia passa sua solicitação para ela e sai, então o whatfiles não tem mais nada para rastrear e para, enquanto a janela que você pediu vem da cópia não rastreada. Rastreie uma instância separada em vez disso, com algo como
whatfiles firefox --no-remote --profile ~/ff-trace-profilee um diretório de perfil que ainda não exista, ou feche a cópia em execução primeiro. -
Não é uma fronteira de segurança. Um programa que não quer ser observado pode perceber que está sendo rastreado, e o
io_uringrealiza operações de arquivo sem as syscalls que o whatfiles observa. Trate o log como uma descrição do que um programa fez, não como prova de tudo o que ele poderia ter feito. -
Velocidade. Cada syscall interrompe o processo rastreado duas vezes, então programas com muitas syscalls rodam várias vezes mais devagar que o normal. Esse é o mesmo custo que o
stracepaga ao acompanhar todas as syscalls. -
Anexar precisa de privilégios.
-pgeralmente requer root, ou um/proc/sys/kernel/yama/ptrace_scoperelaxado. Uma anexação recusada deixa o alvo em execução normalmente. -
Se o whatfiles for encerrado abruptamente com
SIGKILL, o programa que ele estava rastreando continua em execução, sem rastreamento, a menos que tenha sido iniciado com-k.
Recursos planejados:
- Nenhum no momento, aberto a solicitações e PRs.
Obrigado pelo seu interesse, e por favor confira também Cloaker, Nestur e Flying Carpet!