ฉันต้องการค้นหารายการไลบรารีแบบไดนามิกที่โหลดแบบไบนารีเมื่อทำงาน (ด้วยเส้นทางแบบเต็ม) ฉันใช้ CentOS 6.0 ทำอย่างไร
ฉันต้องการค้นหารายการไลบรารีแบบไดนามิกที่โหลดแบบไบนารีเมื่อทำงาน (ด้วยเส้นทางแบบเต็ม) ฉันใช้ CentOS 6.0 ทำอย่างไร
คำตอบ:
คุณสามารถทำได้ด้วยldd
คำสั่ง:
NAME
ldd - print shared library dependencies
SYNOPSIS
ldd [OPTION]... FILE...
DESCRIPTION
ldd prints the shared libraries required by each program or shared
library specified on the command line.
....
ตัวอย่าง:
$ ldd /bin/ls
linux-vdso.so.1 => (0x00007fff87ffe000)
libselinux.so.1 => /lib/x86_64-linux-gnu/libselinux.so.1 (0x00007ff0510c1000)
librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007ff050eb9000)
libacl.so.1 => /lib/x86_64-linux-gnu/libacl.so.1 (0x00007ff050cb0000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007ff0508f0000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007ff0506ec000)
/lib64/ld-linux-x86-64.so.2 (0x00007ff0512f7000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007ff0504ce000)
libattr.so.1 => /lib/x86_64-linux-gnu/libattr.so.1 (0x00007ff0502c9000)
otool -L <path-to-binary>
readelf -d $executable | grep 'NEEDED'
สามารถใช้งานได้หากคุณไม่สามารถเรียกใช้ไฟล์ปฏิบัติการได้เช่นถ้าคอมไพล์ข้ามหรือถ้าคุณไม่เชื่อถือ:
ในกรณีปกติ ldd เรียกใช้ dynamic linker มาตรฐาน (ดู ld.so (8)) ด้วยตัวแปรสภาพแวดล้อม LD_TRACE_LOADED_OBJECTS ที่ตั้งค่าเป็น 1 ซึ่งทำให้ linker แสดงการขึ้นต่อกันของไลบรารี อย่างไรก็ตามโปรดทราบว่าในบางสถานการณ์ ldd บางรุ่นอาจพยายามรับข้อมูลการพึ่งพาโดยการเรียกใช้งานโปรแกรมโดยตรง ดังนั้นคุณไม่ควรใช้ ldd ในการปฏิบัติการที่ไม่น่าเชื่อถือเนื่องจากอาจส่งผลให้มีการใช้รหัสโดยอำเภอใจ
ตัวอย่าง:
readelf -d /bin/ls | grep 'NEEDED'
ตัวอย่าง ouptut:
0x0000000000000001 (NEEDED) Shared library: [libselinux.so.1]
0x0000000000000001 (NEEDED) Shared library: [libacl.so.1]
0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
โปรดทราบว่าไลบรารีสามารถขึ้นอยู่กับไลบรารีอื่นดังนั้นตอนนี้คุณต้องค้นหาการอ้างอิง
วิธีการที่ไร้เดียงสาที่มักใช้งานได้คือ:
$ locate libselinux.so.1
/lib/i386-linux-gnu/libselinux.so.1
/lib/x86_64-linux-gnu/libselinux.so.1
/mnt/debootstrap/lib/x86_64-linux-gnu/libselinux.so.1
แต่วิธีที่แม่นยำกว่านั้นคือการเข้าใจldd
เส้นทางการค้นหา / แคช ฉันคิดว่าldconfig
เป็นวิธีที่จะไป
เลือกหนึ่งรายการแล้วทำซ้ำ:
readelf -d /lib/x86_64-linux-gnu/libselinux.so.1 | grep 'NEEDED'
ตัวอย่างผลลัพธ์:
0x0000000000000001 (NEEDED) Shared library: [libpcre.so.3]
0x0000000000000001 (NEEDED) Shared library: [libdl.so.2]
0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
0x0000000000000001 (NEEDED) Shared library: [ld-linux-x86-64.so.2]
และอื่น ๆ
ดูสิ่งนี้ด้วย:
/proc/<pid>/maps
สำหรับกระบวนการทำงาน
พูดถึงโดย Basileสิ่งนี้มีประโยชน์ในการค้นหาไลบรารีทั้งหมดที่ใช้งานอยู่ในปัจจุบันโดยการเรียกใช้โปรแกรมปฏิบัติการ เช่น:
sudo awk '/\.so/{print $6}' /proc/1/maps | sort -u
แสดงการพึ่งพาแบบไดนามิกที่โหลดในปัจจุบันทั้งหมดของinit
(PID 1
):
/lib/x86_64-linux-gnu/ld-2.23.so
/lib/x86_64-linux-gnu/libapparmor.so.1.4.0
/lib/x86_64-linux-gnu/libaudit.so.1.0.0
/lib/x86_64-linux-gnu/libblkid.so.1.1.0
/lib/x86_64-linux-gnu/libc-2.23.so
/lib/x86_64-linux-gnu/libcap.so.2.24
/lib/x86_64-linux-gnu/libdl-2.23.so
/lib/x86_64-linux-gnu/libkmod.so.2.3.0
/lib/x86_64-linux-gnu/libmount.so.1.1.0
/lib/x86_64-linux-gnu/libpam.so.0.83.1
/lib/x86_64-linux-gnu/libpcre.so.3.13.2
/lib/x86_64-linux-gnu/libpthread-2.23.so
/lib/x86_64-linux-gnu/librt-2.23.so
/lib/x86_64-linux-gnu/libseccomp.so.2.2.3
/lib/x86_64-linux-gnu/libselinux.so.1
/lib/x86_64-linux-gnu/libuuid.so.1.3.0
วิธีนี้ยังแสดงไลบรารีที่เปิดด้วยdlopen
ทดสอบด้วยการตั้งค่าขั้นต่ำนี้ซึ่งถูกแฮ็กด้วยกับsleep(1000)
Ubuntu 18.04
ดูเพิ่มเติม: วิธีดูวัตถุที่แชร์ที่โหลดไว้ใน Linux ในปัจจุบันได้อย่างไร? | ผู้ใช้ขั้นสูง
ldd และ lsof แสดงห้องสมุดโหลดทั้งโดยตรงหรือที่ช่วงเวลาที่กำหนด พวกเขาไม่บัญชีสำหรับห้องสมุดโหลดผ่านdlopen
(หรือทิ้งdlclose
) คุณสามารถรับภาพที่ดีขึ้นของการใช้strace
เช่น
strace -e trace=open myprogram
(เนื่องจากการdlopen
โทรในท้ายที่สุดopen
- แน่นอนว่าคุณอาจมีระบบที่ใช้ชื่อต่างกันสำหรับการเปิด 64- บิต ... )
ตัวอย่าง:
strace -e trace=open date
แสดงให้ฉันเห็นนี้:
open("/etc/ld.so.cache", O_RDONLY) = 3
open("/lib/x86_64-linux-gnu/librt.so.1", O_RDONLY) = 3
open("/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY) = 3
open("/lib/x86_64-linux-gnu/libpthread.so.0", O_RDONLY) = 3
open("/usr/lib/locale/locale-archive", O_RDONLY) = 3
open("/etc/localtime", O_RDONLY) = 3
Wed Apr 12 04:56:32 EDT 2017
จากที่หนึ่งสามารถ grep ชื่อ ".so" เพียงแค่ดูวัตถุที่ใช้ร่วมกัน
strace -e trace=open,openat myprogram
/proc/<pid>/maps
นอกจากนี้ยังแสดงdlopen
libs btw: unix.stackexchange.com/questions/120015/… ltrace -S
เอาท์พุทจะเย็นลงเนื่องจากมันแสดงทั้ง syscalls และการเรียกใช้ไลบรารี่เช่นdlopen
: unix.stackexchange.com/questions/226524/ …
lsofยังสามารถแสดงให้คุณเห็นว่าไลบรารีใดที่ถูกใช้สำหรับกระบวนการเฉพาะอย่างใดอย่างหนึ่ง
กล่าวคือ
$ pidof nginx
6920 6919
$ lsof -p 6919|grep mem
nginx 6919 root mem REG 0,64 65960 43 /lib64/libnss_files-2.12.so
nginx 6919 root mem REG 0,64 19536 36 /lib64/libdl-2.12.so
nginx 6919 root mem REG 0,64 10312 1875 /lib64/libfreebl3.so
nginx 6919 root mem REG 0,64 1923352 38 /lib64/libc-2.12.so
nginx 6919 root mem REG 0,64 88600 1034 /lib64/libz.so.1.2.3
nginx 6919 root mem REG 0,64 1967392 1927 /usr/lib64/libcrypto.so.1.0.1e
nginx 6919 root mem REG 0,64 183080 1898 /lib64/libpcre.so.0.0.1
nginx 6919 root mem REG 0,64 40400 1217 /lib64/libcrypt-2.12.so
nginx 6919 root mem REG 0,64 142688 77 /lib64/libpthread-2.12.so
nginx 6919 root mem REG 0,64 154664 31 /lib64/ld-2.12.so
สำหรับกระบวนการของ pid 1234 คุณสามารถอ่านไฟล์/proc/1234/maps
(ต้นฉบับ) หลอก (อ่านproc (5) ... ) หรือใช้pmap (1)
ซึ่งจะให้พื้นที่ที่อยู่เสมือนของกระบวนการนั้นดังนั้นไฟล์ (รวมถึงไลบรารีที่แชร์แม้กระทั่งdlopen (3) -ed หนึ่ง) ซึ่งเป็นหน่วยความจำที่แมป
(แน่นอนใช้ps aux
หรือpgrep (1)เพื่อค้นหากระบวนการทำงานบางโปรแกรมที่กำหนด)
สร้างสคริปต์ขนาดเล็ก ( useslib
) และใส่ในเส้นทาง (หรือระบุเส้นทางแบบเต็มในคำสั่งด้านล่าง)
#! /bin/bash
ldd $1 | grep -q $2
exit $?
ใช้ในfind
คำสั่งตัวอย่างเช่น:
find /usr/bin/ -executable -type f -exec useslib {} libgtk-x11-2.0 \; -print
(libgtk-x11-2.0 น่าจะเป็น gtk2 lib)
pmap
มันคือการใช้ที่เป็นไปได้
ตัวอย่างเช่นเริ่มกระบวนการ: $ watch date
รับ pid: $ ps -ef | grep watch
แสดงแผนที่หน่วยความจำ: $ pmap <pid>
แสดงด้วยเส้นทางแบบเต็ม: $ pmap <pid> -p
$ pmap 72770
72770: watch date
00005613a32c9000 20K r-x-- watch
00005613a34cd000 4K r---- watch
00005613a34ce000 4K rw--- watch
00005613a4f6a000 264K rw--- [ anon ]
00007f2f3a7d5000 204616K r---- locale-archive
00007f2f46fa7000 1748K r-x-- libc-2.27.so
00007f2f4715c000 2048K ----- libc-2.27.so
00007f2f4735c000 16K r---- libc-2.27.so
00007f2f47360000 8K rw--- libc-2.27.so
00007f2f47362000 16K rw--- [ anon ]
00007f2f47366000 12K r-x-- libdl-2.27.so
00007f2f47369000 2044K ----- libdl-2.27.so
00007f2f47568000 4K r---- libdl-2.27.so
00007f2f47569000 4K rw--- libdl-2.27.so
00007f2f4756a000 160K r-x-- libtinfo.so.6.1
00007f2f47592000 2048K ----- libtinfo.so.6.1
00007f2f47792000 16K r---- libtinfo.so.6.1
00007f2f47796000 4K rw--- libtinfo.so.6.1
00007f2f47797000 232K r-x-- libncursesw.so.6.1
00007f2f477d1000 2048K ----- libncursesw.so.6.1
00007f2f479d1000 4K r---- libncursesw.so.6.1
00007f2f479d2000 4K rw--- libncursesw.so.6.1
00007f2f479d3000 148K r-x-- ld-2.27.so
00007f2f47bdb000 20K rw--- [ anon ]
00007f2f47bf1000 28K r--s- gconv-modules.cache
00007f2f47bf8000 4K r---- ld-2.27.so
00007f2f47bf9000 4K rw--- ld-2.27.so
00007f2f47bfa000 4K rw--- [ anon ]
00007ffd39404000 136K rw--- [ stack ]
00007ffd3959b000 12K r---- [ anon ]
00007ffd3959e000 8K r-x-- [ anon ]
ffffffffff600000 4K r-x-- [ anon ]
total 215692K
$ pmap 72770 -p
72770: watch date
00005613a32c9000 20K r-x-- /usr/bin/watch
00005613a34cd000 4K r---- /usr/bin/watch
00005613a34ce000 4K rw--- /usr/bin/watch
00005613a4f6a000 264K rw--- [ anon ]
00007f2f3a7d5000 204616K r---- /usr/lib/locale/locale-archive
00007f2f46fa7000 1748K r-x-- /usr/lib64/libc-2.27.so
00007f2f4715c000 2048K ----- /usr/lib64/libc-2.27.so
00007f2f4735c000 16K r---- /usr/lib64/libc-2.27.so
00007f2f47360000 8K rw--- /usr/lib64/libc-2.27.so
00007f2f47362000 16K rw--- [ anon ]
00007f2f47366000 12K r-x-- /usr/lib64/libdl-2.27.so
00007f2f47369000 2044K ----- /usr/lib64/libdl-2.27.so
00007f2f47568000 4K r---- /usr/lib64/libdl-2.27.so
00007f2f47569000 4K rw--- /usr/lib64/libdl-2.27.so
00007f2f4756a000 160K r-x-- /usr/lib64/libtinfo.so.6.1
00007f2f47592000 2048K ----- /usr/lib64/libtinfo.so.6.1
00007f2f47792000 16K r---- /usr/lib64/libtinfo.so.6.1
00007f2f47796000 4K rw--- /usr/lib64/libtinfo.so.6.1
00007f2f47797000 232K r-x-- /usr/lib64/libncursesw.so.6.1
00007f2f477d1000 2048K ----- /usr/lib64/libncursesw.so.6.1
00007f2f479d1000 4K r---- /usr/lib64/libncursesw.so.6.1
00007f2f479d2000 4K rw--- /usr/lib64/libncursesw.so.6.1
00007f2f479d3000 148K r-x-- /usr/lib64/ld-2.27.so
00007f2f47bdb000 20K rw--- [ anon ]
00007f2f47bf1000 28K r--s- /usr/lib64/gconv/gconv-modules.cache
00007f2f47bf8000 4K r---- /usr/lib64/ld-2.27.so
00007f2f47bf9000 4K rw--- /usr/lib64/ld-2.27.so
00007f2f47bfa000 4K rw--- [ anon ]
00007ffd39404000 136K rw--- [ stack ]
00007ffd3959b000 12K r---- [ anon ]
00007ffd3959e000 8K r-x-- [ anon ]
ffffffffff600000 4K r-x-- [ anon ]
total 215692K
lld
ใน darwin, มันปรากฏขึ้น, และฉันไม่สามารถหามันผ่าน homebrew