프로그램이 어떤 파일에 액세스하는지 보여주는 도구인가요?

프로그램이 어떤 파일에 액세스하는지 보여주는 도구인가요?

저는 AppArmor Complaint Mode와 같은 복잡한 도구를 사용하지 않을 것이며, 특정 프로그램에서 어떤 파일에 액세스하는지 알려주는 간단한 도구를 원합니다.

답변1

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

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
[...]

strace이는 시스템 호출을 다시 시작 하지 않고도 kprobe를 사용하기 때문에 매우 효율적입니다 .

strace(아마도 추적 프로세스의 하위 프로세스) 를 사용하여 이 작업을 수행할 수도 있지만 -f이를 수행하는 방법에는 다음과 같이 시스템 호출을 다시 시작하는 것이 포함됩니다.애플리케이션 속도가 약간 느려집니다.

# 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].

답변3

응용 프로그램이 열리는 파일을 모니터링하기 위해 제가 가장 좋아하는 도구는 강력한 모니터링 프레임워크입니다 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

다음 프로세스에 대한 시스템 호출 수준에서 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)); }'

sysdig, strace및 외에도 프로세스에서 호출/수신된 신호/동적 라이브러리/시스템 호출을 기록/가로채는 가 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 모드의 바이너리에만 나타날 수도 있습니다.

관련 답변도 참조하세요진실은 왜 그렇게 거짓인가?

배포판이 바이너리/파일과 함께 제공되는 경우 배포판의 소스 저장소나 실제 유틸리티의 공식 저장소에서 소스 코드를 얻을 수도 있습니다.

최후의 수단으로 항상 다음과 같은 도구를 사용할 수 있습니다.데이터 베이스또는₩₩실시간으로 바이너리 디버깅.

관련 정보