プログラムがアクセスするファイルを表示するツールはありますか?


12

AppArmorの不平モードのような複雑なツールを使うつもりはありません。特定のプログラムがどのファイルにアクセスしているのかを知るための簡単なツールが必要です。


7
どのオペレーティングシステムで
ジェフシャラー

読み取り、書き込み、追加、のみ取得-また、どのようにあなたがアクセスファイルにプログラムを期待し説明するのに便利かもしれませんfstat()か、lstat()などの情報、
Sergiy Kolodyazhnyy

SuseとUbuntuの両方
Boll19

私が知る必要がある方法は問題ありません、それはfstat()またはlstat()がプログラミングしているのですか?
Boll19、18年

Sergiy Kolodyazhnyyのコメント:つまり、プログラムがファイルの長さ、変更日、アクセス許可、またはその他のプロパティをチェックするが、ファイルのデータにアクセスしない場合、「ファイルにアクセスする」かどうかをカウントしますか?
telcoM 2018

回答:


12

Chris Downによるとstrace -p既に実行中のプロセスを調べて、straceを終了するかプロセス自体が終了するまでに現在開いているファイルを確認できます。

あなたのために開いたファイルを参照したい場合は全期間のプロセスのを開始してから、右、使用strace実行可能ファイル名を持ちます。追加-fすると、フォークされたサブプロセスも報告されます。例

# strace -e open -f /bin/id
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
open("/lib64/libselinux.so.1", O_RDONLY|O_CLOEXEC) = 3
open("/lib64/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
open("/lib64/libpcre.so.1", O_RDONLY|O_CLOEXEC) = 3
open("/lib64/libdl.so.2", O_RDONLY|O_CLOEXEC) = 3
open("/lib64/libpthread.so.0", O_RDONLY|O_CLOEXEC) = 3
open("/usr/lib/locale/locale-archive", O_RDONLY|O_CLOEXEC) = 3
open("/proc/thread-self/attr/current", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("/proc/self/task/1581/attr/current", O_RDONLY|O_CLOEXEC) = 3
open("/usr/share/locale/locale.alias", O_RDONLY|O_CLOEXEC) = 3
open("/usr/share/locale/en_US.UTF-8/LC_MESSAGES/coreutils.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/share/locale/en_US.utf8/LC_MESSAGES/coreutils.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/share/locale/en_US/LC_MESSAGES/coreutils.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/share/locale/en.UTF-8/LC_MESSAGES/coreutils.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/share/locale/en.utf8/LC_MESSAGES/coreutils.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/share/locale/en/LC_MESSAGES/coreutils.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/etc/nsswitch.conf", O_RDONLY|O_CLOEXEC) = 3
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
open("/lib64/libnss_files.so.2", O_RDONLY|O_CLOEXEC) = 3
open("/etc/passwd", O_RDONLY|O_CLOEXEC) = 3
open("/etc/group", O_RDONLY|O_CLOEXEC)  = 3
open("/etc/group", O_RDONLY|O_CLOEXEC)  = 3
uid=0(root) gid=0(root) groups=0(root) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
+++ exited with 0 +++
#

lsofプロセスが現在開いているファイルを確認するために使用する

# lsof -p $(pidof NetworkManager)
COMMAND   PID USER   FD      TYPE             DEVICE  SIZE/OFF     NODE NAME
NetworkMa 722 root  cwd       DIR              253,0       224       64 /
NetworkMa 722 root  rtd       DIR              253,0       224       64 /
NetworkMa 722 root  txt       REG              253,0   2618520   288243 /usr/sbin/NetworkManager
NetworkMa 722 root  mem       REG              253,0     27776    34560 /usr/lib64/libnss_dns-2.17.so
[...]
#

SystemTapを使用している場合は、開かれているファイルについてホスト全体を監視できます。

[root@localhost tmp]# cat mon
#!/usr/bin/env stap
probe syscall.open { printf ("pid %d program %s opened %s\n", pid(), execname(), filename) }
# ./mon
pid 14813 program touch opened "/etc/ld.so.cache"
pid 14813 program touch opened "/lib64/libc.so.6"
pid 14813 program touch opened 0x7f7a8c6ec8d0
pid 14813 program touch opened "foo2"
[...]
#

2
open関連するシステムコールはこれだけではありません。たとえば、UNIXソケットを介してプロセス間でファイル記述子を渡すことが可能でありopenat、ファイルを開くこともできるシステムコールがあります。
カスペルド

---- SIGUSR1 {si_signo = SIGUSR1、si_codeに= SI_TKILL、si_pid = 6026、si_uidを設定= 1002} ----いただきましたこと
Boll19

kaspers、strace出力コマンドで「openat」を検索するだけでよいですか?
Boll19

ファイルを開こうとすると(ただし、ファイルが存在しない場合があります)、「strace」出力にも表示されますか?
-Boll19

Boll19、存在しないために開くことができないファイルstraceは、内で喜んで報告されます、例のENOENT行を参照してください。
スティーブ

5

opensnoop内部でeBPFを使用するBCCから使用できます。

# ./opensnoop -p 1576
PID    COMM      FD ERR PATH
1576   snmpd     11   0 /proc/sys/net/ipv6/conf/lo/forwarding
1576   snmpd     11   0 /proc/sys/net/ipv6/neigh/lo/base_reachable_time_ms
1576   snmpd      9   0 /proc/diskstats
1576   snmpd      9   0 /proc/stat
1576   snmpd      9   0 /proc/vmstat
[...]

これは、syscallを再起動する必要がなく、kprobeを使用するため、非常にパフォーマンスが高くなりますstrace

これをstrace-fトレースされたプロセスの子を追跡するために)使用することもできますが、ptraceの一部としてsyscallsを再起動することを含むその動作方法は、アプリケーションを多少遅くします。

# strace -e open -p 15735
open("/usr/lib/locale/locale-archive", O_RDONLY|O_CLOEXEC) = 3
open("/usr/lib/gconv/gconv-modules.cache", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/lib/gconv/gconv-modules", O_RDONLY|O_CLOEXEC) = 3
open("/usr/lib/python2.7/site-packages", O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC) = 4
open("/usr/lib/locale/locale-archive", O_RDONLY|O_CLOEXEC) = 3
open("/etc/localtime", O_RDONLY|O_CLOEXEC) = 8
[...]

必要に応じてstrace [executable]、またはを使用して、この方法でアプリケーションを起動することもできますstrace -f [executable]


5

アプリケーションが開くファイルを監視するための私のお気に入りのツールは、強力な監視フレームワークsysdigです。

次の名前のプログラムによって開かれたすべての開いているファイルを監視する場合exe_file

sudo sysdig -p "proc.name=exe_file %12user.name %6proc.pid %12proc.name %3fd.num %fd.typechar %fd.name" evt.type=open

サーバーで開かれているすべてのファイルを監視する:

sudo sysdig -p "%12user.name %6proc.pid %12proc.name %3fd.num %fd.typechar %fd.name" evt.type=open

ホームディレクトリの書き込みイベントのみが含まれるトレースファイルを作成します(後でで検査できますsysdig -r writetrace.scap.gz)。

sudo sysdig -p "%user.name %proc.name %fd.name" "evt.type=write and fd.name contains /home/" -z -w writetrace.scap.gz

という名前のプロセスが行うsyscallレベルのすべてを見ると、次のようになりますexe_file

sudo sysdig proc.name=exe_file

Sysdigにはたくさんのノミがあります。

あなたはまた、持っているdtrace多くのLinuxでは使用されないが、それでも* BSDオペレーティングシステムで多く使用されています。

# Files opened by process,
dtrace -n 'syscall::open*:entry { printf("%s %s",execname,copyinstr(arg0)); }'

sysdigstraceおよびdtraceに加えて、ltraceプロセスによって呼び出される/受信されるシグナル/動的ライブラリ/システムコールを記録/インターセプトするを取得しました。

ltraceは、指定されたコマンドを単に終了するまで実行するプログラムです。実行されたプロセスによって呼び出される動的ライブラリ呼び出しと、そのプロセスによって受信される信号をインターセプトして記録します。また、プログラムによって実行されるシステムコールをインターセプトして印刷することもできます。

$ltrace exe_file
_libc_start_main(0x400624, 1, 0x7ffcb7b6d7c8, 0x400710 <unfinished ...>  
time(0)                                                                              = 1508018406  
srand(0x59e288e6, 0x7ffcb7b6d7c8, 0x7ffcb7b6d7d8, 0)                                 = 0  
sprintf("mkdir -p -- '/opt/sms/AU/mo'", "mkdir -p -- '%s'", "/opt/sms/AU/mo")        = 28  
system("mkdir -p -- '/opt/sms/AU/mo'" <no return ...>  
--- SIGCHLD (Child exited) ---  
<... system resumed> )                                                               = 0  
rand(2, 0x7ffcb7b6d480, 0, 0x7f9d6d4622b0)                                           = 0x2d8ddbe1  
sprintf("/opt/sms/AU/mo/tmp.XXXXXX", "%s/tmp.XXXXXX", "/opt/sms/AU/mo")      = 29  
mkstemp(0x7ffcb7b6d5c0, 0x40080b, 0x40081a, 0x7ffffff1)                              = 3  
sprintf("/opt/sms/AU/mo/tmp.XXXXXX", "%s/tmp.XXXXXX", "/opt/sms/AU/mo")      = 29  
mkstemp(0x7ffcb7b6d5c0, 0x40080b, 0x40081a, 0x7ffffff1)                              = 4  
+++ exited (status 0) +++  

プログラムが小さい場合は、でobjdump -d exe_file逆アセンブルするか、で逆アセンブル/逆コンパイルしてHopper、処理するすべてのファイルを確認することもできます。

詳細については、「Linuxバイナリの機能を理解する」を参照してください。

最初のアプローチとして、私も次のようにします。

strings exe_file

これは低コストのアプローチであり、運が良ければ、いくつかのファイル名がASCIIモードで幸運なバイナリファイルに存在する可能性があります。

関連する回答もご覧ください。なぜ真と偽がそれほど大きいのですか?

ディストリビューションに付属するバイナリ/ファイルの場合、ディストリビューションのソースリポジトリ、または実際のユーティリティの公式リポジトリからソースを取得することもできます。

最後のリソースとして、gdbrrなどのツールを使用して、リアルタイムでバイナリをデバッグできます。


aaa43bb66:〜#sudo proc.name = exe_file sysdig -p "%12user.name%6proc.pid%12proc.name%3fd.num%fd.typechar%fd.name" evt.type = openドライバエラーをロードできませんデバイス/ dev / sysdig0を開きます。ルート認証情報があり、sysdig-probeモジュールがロードされていることを確認してください。
Boll19、2018年

/ * <pre> aaa43bb66:〜#sudo proc.name = exe_file sysdig -p "%12user.name%6proc.pid%12proc.name%3fd.num%fd.typechar%fd.name" evt.type = open Unableデバイス/ dev / sysdig0を開くときにドライバエラーをロードします。ルート認証情報があり、sysdig-probeモジュールがロードされていることを確認してください。<code> * /
Boll19

@ Boll19そこにエラーが発生し、修正しました。そのメッセージはsysdigバグについてのようです(ARMを使用していますか?)。新しい質問を投稿してください。
ルイFリベイロ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.