현재 Unix 계열의 운영체제에서 거의 표준으로 정착된 ELF 포맷을 사용하는 시스템에서 공유 라이브러리를 처리하는 방법에 대해 설명한다.

 

ELF 파일은 section이나 segment로 표현되는 파일로써 실행 파일이나 라이브러리 모두에 공통적으로 적용이 되는 포맷이다. 실행 파일과 라이브러리는 파일이 포함하는 section이나 segment의 종류가 다를 뿐이다.

ELF 공유 라이브러리는 메모리의 어떤 주소에도 로딩이 될 수 있도록 만들어지는데 프로그램 코드는 반드시 PIC(Position Independent Code)로 만들어져야 한다. PIC 코드는 코드 내에서의 심볼의 참조가 특정 레지스터(베이스 포인터 : 386에서는 EBX)에 상대적이도록 만들어지는 코드이다. GNU 컴파일러의 경우 pic 옵션을 이용해 컴파일하면 이러한 코드가 나오게 된다.

공유 라이브러리는 이와 함께 심볼을 재배치하기 위해 GOT(Global Offset Table)를 사용한다. 이 테이블은 프로그램에서 참조하는 라이브러리 내의 모든 정적(static) 심볼들에 대한 포인터를 담고 있다. 이 테이블은 동적 링커인 ld.so에 의해 재배치되어 실제 주소가 채워지게 된다. 일반적으로 이 테이블의 크기는 그리 크지 않은데 350K 크기의 코드에 대해서는 약 180개 정도의 GOT 엔트리가 존재하게 된다. 

 

다음 그림은 프로그램에서 함수를 호출했을 때, 어떤 절차를 따라 실제 라이브러리의 함수가 호출되는 지를 그림으로 표현한 것이다.

프로그램에서 call을 하면 먼저 PLT(Procedure Linkage Table)를 거쳐 실제 참고하고자 하는 심볼을 담고 있는 GOT를 통해 실제 라이브러리의 해당 함수로 제어가 이동하게 된다.

 

ELF 동적 라이브러리는 동적 링커가 필요로 하는 모든 정보를 담고 있어야 하는데 그 내용은 .hash, .dynsym, dynstr, .plt, .got, .dynamic 섹션들이다. 각각에 대해서 간략하게 설명하면 다음과 같다:

.dynsym

동적 심볼 테이블로서 파일이 import/export하는 모든 심볼을 담고 있다.

 

.dynstr

.dynsym에 의해 참조되는 것으로서 심볼의 실제 이름을 담고 있다.

 

.hash

동적 링커가 심볼 lookup을 빨리 할 수 있도록 만들어 놓은 해시 테이블이다.

 

.dynamic

동적 링커가 필요로 하는 모든 정보를 담고 있는 것으로써 .header를 통해 바로 찾을 수 있다.

동적 링커는 이 섹션을 통해 동적 링킹을 위한 다른 섹션들의 정보를 얻을 수 있댜.

이 테이블의 엔트리들은 태그와 포인터의 쌍으로 표현되며 재배치 작업을 위해 다음과 같은 정보들을 담고 있다.

  • NEEDED : 필요한 라이브러리의 STRTAB의 인덱스를 담고 있음
  • SONAME : 이 공유 라이브러리의 이름으로 역시 인덱스를 담고 있음
  • SYMTAB, STRTAB, HASH, SYMENT, STRSZ : 심볼 테이블 포인터, 연관된 스트링과 해시 테이블, 심볼 테이블 엔트리의 크기, 스트링 테이블의 크기
  • PLTGOT : GOT나 PLT를 가리키는 포인터
  • REL, RELSZ, and RELENT : 재배치 포인터, 개수, 재배치 엔트리의 크기
  • RELA, RELASZ, and RELAENT : 앞의 것과 동일하지만 addends를 포함하는 것
  • JMPREL, PLTRELSZ, and PLTREL : PLT에 의해 참조되는 데이터를 위한 재배치 정보
  • INIT, FINI : 라이브러리의 초기화 루틴과 종료 루틴의 포인터

아래 그림은 이들 섹션들의 위치와 어떻게 연관이 되는 지를 나타낸 것이다.

그림에서 위의 섹션들은 모두 read-only 영역이고 아래 부분은 모두 쓰기 가능한 데이터 영역이다.

'Linker & Loader' 카테고리의 다른 글

참고자료  (0) 2009.11.08
정적 라이브러리의 구조 - ar, ranlib  (0) 2009.11.05
SHARED LIBRARY CALL REDIRECTION VIA ELF PLT INFECTION  (0) 2009.11.04
링크(Linkers) 와 로더(Loaders)  (0) 2009.11.04

WRITTEN BY
RootFriend
개인적으로... 나쁜 기억력에 도움되라고 만들게되었습니다.

,