
whatfiles v2.0
任意のLinuxプロセスがアクセスするファイルをログに記録する
whatfiles
Whatfiles は、別のプログラムがシステム上でどのファイルを読み取り/書き込み/作成/削除するかを記録する Linux ユーティリティです。対象プロセスによって作成された新しいプロセスやスレッドもすべてトレースし、各操作が成功したかどうかを記録します。
理由:
main() から終了までの間にプロセスがどのファイルに触れるかを確認するためのシンプルなユーティリティが存在しないことに、長い間不満を感じていました。ソフトウェアベンダーを信用していない場合でも、マルウェアが心配な場合でも、プログラムやインストーラーがシステムに対して何を行うかを知ることができるのは重要です。lsof はある瞬間しか観察できず、strace は大規模でやや複雑です。
出力例:
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
各行は、ファイルに対して何が行われたか、そのファイル自体、どのシステムコールがそれを行ったか、どのプロセスとスレッドか、そしてカーネルが何を返したかを示します。パスは常に絶対パスです。相対パスはプロセスの作業ディレクトリ、または *at() システムコールに渡されたディレクトリに対して解決されます。result はシステムコールの戻り値なので、失敗したアクセスと成功したアクセスを区別できます。
開く、作成、削除のほかに、whatfiles はプログラムの rename、link、symlink、mkdir、rmdir、truncate、chmod、chown、exec を報告します。SYSCALLS.md では、まだ報告されていないものと、それぞれの追加がなぜ価値があるかを説明しています。
使用方法:
-
基本的な使用法。
lsを起動し、出力をカレントディレクトリのログファイルに書き込みます:$ whatfiles ls -lah ~/Documents -
-oで出力ファイルの場所を指定します:$ whatfiles -o MyLogFile cd .. -
デバッグ出力を含め、ログファイルではなく標準出力に出力します:
$ whatfiles -d -s apt install zoom -
現在実行中のプロセスにアタッチします (root 権限が必要):
$ sudo whatfiles -p 1234 -
whatfiles 自体が強制終了された場合、トレース対象のプログラムをトレースされないまま継続させるのではなく、終了させます:
$ whatfiles -k ./installer.sh
いつでも Ctrl-C を押してください。whatfiles はトレースしているすべてからデタッチし、それらのプロセスは実行したままにして、ログの書き込みを完了します。
配布
すぐに使えるバイナリは releases ページにあります! どなたかが親切にも Arch リポジトリに追加してくれ、letompouce が GitLab パイプラインもセットアップしてくれました。
コンパイル (gcc と make が必要):
$ cd whatfiles
$ make
$ sudo make install
x86、x86_64、ARM32、ARM64 アーキテクチャをサポートします。make install は PREFIX と DESTDIR を尊重します。
Linux 3.4 以降が必要です。Linux 5.3 以降では、whatfiles は各システムコール停止についてカーネルに直接問い合わせます。これにより、64 ビットマシン上の 32 ビットシステムコールが正しくデコードされます。古いカーネルではレジスタの読み取りにフォールバックします。
Android
NDK でクロスコンパイルし、バイナリをデバイスにプッシュします:
$ 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 はデフォルトの arm64、または arm32、x86_64、x86 を選択します。ANDROID_API は
最小 API レベルを設定し、デフォルトは 21 です。
デバイス上ではいくつかの点が異なります:
- バイナリを
/data/local/tmpに置いてください。/sdcardは実行権限なしでマウントされています。 adb shellの作業ディレクトリは書き込み可能ではないため、/data/local/tmp以下のパスを 指定して-oを渡すか、標準出力に書き込む-sを渡してください。- whatfiles の下でコマンドを実行するのは通常のシェルユーザーとして動作し、そのユーザーが起動した
プロセスへのアタッチも同様です。それ以外 (例えばアプリ) へのアタッチには root が必要なので、
userdebug ビルドでは
adb rootを使います。Android 14 エミュレータでは SELinux が enforcing の 状態で動作しましたが、製品版デバイスのポリシーは依然として拒否する可能性があります。 make test-android NDK=~/Android/Sdk/ndk/<version>は、接続されたデバイス用に whatfiles と テストプログラムをビルドし、そこでチェックを実行し、プッシュしたものを削除します。- arm64 ビルドからトレースされた 32 ビットアプリは、64 ビットのものと見なされるのではなく、 32 ビットのシステムコール番号と引数レジスタで読み取られます。このパスは実機では検証されていません。 ここでのテストに使用したエミュレータには 32 ビット ABI がありません。
make test は tests/ 内のプログラムをビルドし、whatfiles の下で実行してその動作を確認します。これにはシグナル配送、スレッドと子プロセスのカバレッジ、割り込み処理が含まれます。
いつか聞かれるかもしれない質問:
-
これは単に
strace -fe trace=creat,open,openat,unlink,unlinkat ./programの再実装ではないですか?はい。ただし、よりシンプルでユーザーフレンドリーであることを目指しています。
-
Mac 版と Windows 版はありますか?
いいえ。Mac でシステムコールをトレースするには
task_for_pid()が必要で、それにはコード署名が必要ですが、うまく動作させることができません。そもそも、無料ソフトウェアを書くために Apple に年間 100 ドルを支払う気はありません。Mac のdtrussは単一のプロセスとその子を追跡するのに使えますが、-tフラグはフィルタリングする単一のシステムコールしか受け付けないようです。fs_usageも同様のことをしますが、子プロセス/スレッドを追跡するかはわかりません。Windows の Process Monitor はかなり素晴らしいです。
制限事項:
-
自分自身のコピーに処理を引き渡すプログラム。 特にブラウザ: インスタンスがすでに 実行中の場合、起動したインスタンスはリクエストをそれに渡して終了するため、whatfiles は トレースするものが何も残らず停止しますが、要求したウィンドウはトレースされていないコピーから 来ます。代わりに別のインスタンスをトレースしてください。例えば
whatfiles firefox --no-remote --profile ~/ff-trace-profileのように、まだ存在しない プロファイルディレクトリを指定するか、先に実行中のコピーを終了してください。 -
セキュリティ境界ではありません。 監視されたくないプログラムは、自分がトレースされていることを 知ることができ、
io_uringは whatfiles が監視するシステムコールを使わずにファイル操作を行います。 ログはプログラムが行ったことの記述として扱い、行い得たすべての証拠として扱わないでください。 -
速度。 すべてのシステムコールはトレース対象プロセスを 2 回停止させるため、システムコールの多い プログラムは通常より数倍遅く実行されます。これは
straceがすべてのシステムコールを追跡するときに 支払うのと同じコストです。 -
アタッチには権限が必要です。
-pは通常 root、または緩和された/proc/sys/kernel/yama/ptrace_scopeを必要とします。アタッチが拒否されても、対象は通常どおり 実行され続けます。 -
whatfiles 自体が
SIGKILLで強制終了された場合、トレースしていたプログラムは-k付きで 起動されていなければ、トレースされないまま実行し続けます。
予定されている機能:
- 現在はありません。リクエストや PR を歓迎します。
興味を持っていただきありがとうございます。ぜひ Cloaker、Nestur、Flying Carpet もチェックしてみてください!