강좌 & 팁
글 수 2,412
2011.02.26 20:05:23 (*.138.143.120)
64579
ldd - 공유 라이브러리 의존관계
공유 라이브러리를 사용할수 있게 되었는데 실행시 해당 라이브러리가 실행 라이브러리가
없다며 실행이 안된다면 매우 난감하게 된다.
root@boggle70-desktop:tmp# ./slink
./slink: error while loading shared libraries: libfoo.so.0: cannot open shared object file: No such file or directory
이런 식으로 불평 불만을 이야기 하게 되는데 뭐가 필요한지 알아 보는 방법을 알아 보자.
먼저 objdump 를 이용해 보자.
root@boggle70-desktop:tmp# objdump -p slink
slink: file format elf32-i386
Program Header:
PHDR off 0x00000034 vaddr 0x08048034 paddr 0x08048034 align 2**2
filesz 0x00000100 memsz 0x00000100 flags r-x
INTERP off 0x00000134 vaddr 0x08048134 paddr 0x08048134 align 2**0
filesz 0x00000013 memsz 0x00000013 flags r--
LOAD off 0x00000000 vaddr 0x08048000 paddr 0x08048000 align 2**12
filesz 0x000005e0 memsz 0x000005e0 flags r-x
LOAD off 0x00000f04 vaddr 0x08049f04 paddr 0x08049f04 align 2**12
filesz 0x00000114 memsz 0x0000011c flags rw-
DYNAMIC off 0x00000f18 vaddr 0x08049f18 paddr 0x08049f18 align 2**2
filesz 0x000000d8 memsz 0x000000d8 flags rw-
NOTE off 0x00000148 vaddr 0x08048148 paddr 0x08048148 align 2**2
filesz 0x00000044 memsz 0x00000044 flags r--
STACK off 0x00000000 vaddr 0x00000000 paddr 0x00000000 align 2**2
filesz 0x00000000 memsz 0x00000000 flags rw-
RELRO off 0x00000f04 vaddr 0x08049f04 paddr 0x08049f04 align 2**0
filesz 0x000000fc memsz 0x000000fc flags r--
Dynamic Section:
NEEDED libfoo.so.0
NEEDED libc.so.6
INIT 0x080483c0
FINI 0x080485ac
HASH 0x0804818c
GNU_HASH 0x080481d0
STRTAB 0x080482cc
SYMTAB 0x0804820c
STRSZ 0x00000094
SYMENT 0x00000010
DEBUG 0x00000000
PLTGOT 0x08049ff4
PLTRELSZ 0x00000020
PLTREL 0x00000011
JMPREL 0x080483a0
REL 0x08048398
RELSZ 0x00000008
RELENT 0x00000008
VERNEED 0x08048378
VERNEEDNUM 0x00000001
VERSYM 0x08048360
Version References:
required from libc.so.6:
0x0d696910 0x00 02 GLIBC_2.0
NEEDED 를 보면 무엇무엇을 참조하는지 확인이 된다.
또 다른 방법으로는 readelf 를 이용하는 것이다.
root@boggle70-desktop:tmp# readelf -d slink
Dynamic section at offset 0xf18 contains 22 entries:
Tag Type Name/Value
0x00000001 (NEEDED) Shared library: [libfoo.so.0]
0x00000001 (NEEDED) Shared library: [libc.so.6]
0x0000000c (INIT) 0x80483c0
0x0000000d (FINI) 0x80485ac
0x00000004 (HASH) 0x804818c
0x6ffffef5 (GNU_HASH) 0x80481d0
0x00000005 (STRTAB) 0x80482cc
0x00000006 (SYMTAB) 0x804820c
0x0000000a (STRSZ) 148 (bytes)
0x0000000b (SYMENT) 16 (bytes)
0x00000015 (DEBUG) 0x0
0x00000003 (PLTGOT) 0x8049ff4
0x00000002 (PLTRELSZ) 32 (bytes)
0x00000014 (PLTREL) REL
0x00000017 (JMPREL) 0x80483a0
0x00000011 (REL) 0x8048398
0x00000012 (RELSZ) 8 (bytes)
0x00000013 (RELENT) 8 (bytes)
0x6ffffffe (VERNEED) 0x8048378
0x6fffffff (VERNEEDNUM) 1
0x6ffffff0 (VERSYM) 0x8048360
0x00000000 (NULL) 0x0
역시 NEEDED에 필요한 공유 라이브러리 목록을 확인할수 있다.
이번에는 ldd 를 한번 이용해 보자.
root@boggle70-desktop:tmp# ldd slink
linux-gate.so.1 => (0x008ed000)
libfoo.so.0 => not found
libc.so.6 => /lib/tls/i686/cmov/libc.so.6 (0x00110000)
/lib/ld-linux.so.2 (0x00ca8000)
제일 쿨하게 나오는것 같다.
실행이 안되는 것은 libfoo.so.0 을 찾지 못해서이다.
이렇게 ldd 같은 경우 현재의 LD_LIBRARY_PATH 에 따라서 이쁘게 표시해준다.
거기다가 의존성 관계도 잘 표시해 준다.
ldd 파일은 어디 있을까?
root@boggle70-desktop:tmp# whereis ldd
ldd: /usr/bin/ldd /usr/share/man/man1/ldd.1.gz
궁금하신 분들은 vi 로 열어보시면 그것은 바로 쉘스크립트입니다.
궁금하신 분들은 분석해 보시는 것도...(후유증은 책임 못집니다)
혹시 보실 분들은 LD_TRACE_LOADED_OBJECTS 환경 변수에 주목하세요.
이 환경 변수가 1 로 세팅되면 프로그램 실행시 ELF 인터프리터가 필요한 공유 라이브러리를 찾아
메모리에 로딩해서 그 정보를 표시한 후 실제 프로그램이 실행되기 전에 종료하게 됩니다.
따라서 ldd 를 이용하는 것과 동일한 결과를 얻을수 있습니다.
root@boggle70-desktop:tmp# LD_TRACE_LOADED_OBJECTS=1 ./slink
linux-gate.so.1 => (0x00a99000)
libfoo.so.0 => /lib/libfoo.so.0 (0x005c9000)
libc.so.6 => /lib/tls/i686/cmov/libc.so.6 (0x00b70000)
/lib/ld-linux.so.2 (0x00531000)
이렇게 공유라이브러리의 의존관계는 실행파일이나 공유 라이브러리에서 필요로 하는
공유 라이브러리의 SONAME 이 ELF 정보내의 동적 섹션에 있는 NEEDED에 기록된 정보로 관리되고 있음을 의미한다.
개별 파일내의 NEEDED는 objdump 나 readelf 를 사용할수 있지만 의존관계를 이루고 있는 공유 라이브러리를
출력하려면 ldd 명령을 이용해야 합니다. ldd명령은 내부적으로 LD_TRACE_LOADED_OBJECTS 환경 변수를 사용합니다
참고 자료 : Binary Hacks - O'REILLY