
Journaliser les fichiers accédés par tout processus Linux
Whatfiles est un utilitaire Linux qui journalise les fichiers qu'un autre programme lit/écrit/crée/supprime sur votre système. Il trace également tous les nouveaux processus et threads créés par le processus ciblé, et enregistre si chaque opération a réussi.
Je suis depuis longtemps frustré par l'absence d'un utilitaire simple permettant de voir quels fichiers un processus touche depuis main() jusqu'à sa sortie. Que vous ne fassiez pas confiance à un éditeur de logiciels ou que vous vous inquiétiez des malwares, il est important de pouvoir savoir ce qu'un programme ou un installeur fait à votre système. lsof n'observe qu'un instant donné et strace est volumineux et quelque peu compliqué.
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
Chaque ligne indique ce qui a été fait au fichier, le fichier lui-même, quel appel système l'a fait, quel processus et quel thread, et ce que le noyau a renvoyé. Les chemins sont toujours absolus : les chemins relatifs sont résolus par rapport au répertoire de travail du processus, ou par rapport au répertoire passé à un appel système *at(). result est la valeur de retour de l'appel système, ce qui permet de distinguer les accès réussis des accès échoués.
Outre l'ouverture, la création et la suppression, whatfiles signale rename, link, symlink, mkdir, rmdir, truncate, chmod, chown et exec d'un programme. SYSCALLS.md couvre ce qui n'est pas encore signalé et pourquoi chaque ajout vaudrait la peine d'être fait.
utilisation de base, lance ls et écrit la sortie dans un fichier journal dans le répertoire courant :
$ whatfiles ls -lah ~/Documents
spécifier l'emplacement du fichier de sortie avec -o :
$ whatfiles -o MyLogFile cd ..
inclure la sortie de débogage, écrire sur stdout plutôt que dans le fichier journal :
$ whatfiles -d -s apt install zoom
s'attacher à un processus en cours d'exécution (nécessite les privilèges root) :
$ sudo whatfiles -p 1234
tuer le programme tracé si whatfiles lui-même est tué, au lieu de le laisser continuer sans être tracé :
$ whatfiles -k ./installer.sh
Appuyez sur Ctrl-C à tout moment : whatfiles se détache de tout ce qu'il trace, laisse ces processus en cours d'exécution et termine l'écriture du journal.
Des binaires prêts à l'emploi sont disponibles sur la page releases ! Quelqu'un l'a aussi aimablement ajouté au dépôt Arch, et letompouce a également mis en place un pipeline GitLab.
gcc et make) :$ cd whatfiles
$ make
$ sudo make install
Prend en charge les architectures x86, x86_64, ARM32 et ARM64. make install respecte PREFIX et DESTDIR.
Linux 3.4 ou plus récent est requis. Sur Linux 5.3 et plus récent, whatfiles interroge directement le noyau à chaque arrêt d'appel système, ce qui permet de décoder correctement les appels système 32 bits sur une machine 64 bits ; sur les noyaux plus anciens, il se rabat sur la lecture des registres.
Compilez en croisé avec le NDK, puis poussez le binaire sur l'appareil :
$ 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 sélectionne arm64, la valeur par défaut, ou arm32, x86_64 ou x86. ANDROID_API définit le
niveau d'API minimum et vaut 21 par défaut.
Quelques choses diffèrent sur un appareil :
/data/local/tmp. /sdcard est monté sans permission d'exécution.adb shell n'est pas accessible en écriture, donc passez -o avec un chemin sous
/data/local/tmp, ou -s pour écrire sur stdout.adb root sur une build userdebug. Sur un émulateur Android 14, cela a fonctionné avec SELinux en mode enforcing ;
la politique d'un appareil de production peut toutefois encore refuser.make test-android NDK=~/Android/Sdk/ndk/<version> compile whatfiles et les programmes de test pour
l'appareil connecté, y exécute les vérifications et supprime ce qu'il a poussé.make test compile les programmes dans tests/ et les exécute sous whatfiles pour vérifier son comportement, y compris la livraison des signaux, la couverture des threads et des processus enfants, et la gestion des interruptions.
N'est-ce pas simplement une réimplémentation de strace -fe trace=creat,open,openat,unlink,unlinkat ./program ?
Oui. Bien qu'il vise à être plus simple et plus convivial.
Existe-t-il des versions Mac et Windows ?
Non. Tracer les appels système sur Mac nécessite task_for_pid(), qui nécessite la signature de code, que je n'arrive pas à faire fonctionner, et de toute façon je n'ai aucun intérêt à payer Apple 100 $/an pour écrire des logiciels libres. dtruss sur Mac peut être utilisé pour suivre un seul processus et ses enfants, bien que l'option -t semble n'accepter qu'un seul appel système à filtrer. fs_usage fait quelque chose de similaire, mais je ne suis pas sûr qu'il suive les processus/threads enfants. Process Monitor pour Windows est plutôt excellent.
Les programmes qui délèguent à une copie d'eux-mêmes. Les navigateurs en particulier : si une instance est déjà
en cours d'exécution, celle que vous lancez transmet votre requête à cette instance et se termine, donc whatfiles n'a plus rien à
tracer et s'arrête, tandis que la fenêtre que vous avez demandée provient de la copie non tracée. Tracez plutôt une instance
séparée, avec quelque chose comme whatfiles firefox --no-remote --profile ~/ff-trace-profile
et un répertoire de profil qui n'existe pas encore, ou quittez d'abord la copie en cours d'exécution.
Pas une frontière de sécurité. Un programme qui ne veut pas être surveillé peut détecter qu'il est tracé, et io_uring effectue des opérations sur les fichiers sans les appels système que whatfiles surveille. Considérez le journal comme une description de ce qu'un programme a fait, et non comme la preuve de tout ce qu'il aurait pu faire.
Vitesse. Chaque appel système arrête le processus tracé deux fois, donc les programmes à forte utilisation d'appels système s'exécutent plusieurs fois plus lentement que d'habitude. C'est le même coût que strace paie lorsqu'il suit tous les appels système.
L'attachement nécessite des privilèges. -p nécessite généralement root, ou un /proc/sys/kernel/yama/ptrace_scope assoupli. Un attachement refusé laisse la cible fonctionner normalement.
Si whatfiles est tué directement avec SIGKILL, le programme qu'il traçait continue de s'exécuter, sans être tracé, sauf s'il a été lancé avec -k.
Merci de votre intérêt, et veuillez également découvrir Cloaker, Nestur et Flying Carpet !