동적 링킹

IT 위키
(정적 링킹에서 넘어옴)
Dynamic Linking
외부 라이브러리를 실행 파일에 포함시키지 않고, 실행 시점에 공유 라이브러리를 찾아 연결하는 방식
  • 리눅스의 .so, 윈도우의 .dll이 공유 라이브러리다.
  • 실행 파일이 작아지고 여러 프로그램이 같은 라이브러리를 공유한다. 라이브러리를 고쳐도 프로그램을 다시 컴파일할 필요가 없다.
  • 대신 실행할 때 라이브러리가 없거나 버전이 다르면 실행되지 않는다.

정적 링킹과의 비교

[편집 | 원본 편집]
구분 정적 링킹 동적 링킹
연결 시점 컴파일(링크) 시점 실행 시점
실행 파일 크기 크다 작다
메모리 프로세스마다 사본을 가진다 여러 프로세스가 공유한다
라이브러리 갱신 다시 링크해야 한다 라이브러리만 교체하면 된다
실행 속도 호출이 직접적이라 약간 빠르다 첫 호출에 주소 해석 비용이 있다

PLT와 GOT

[편집 | 원본 편집]
  • 컴파일 시점에는 외부 함수가 메모리 어디에 올라올지 알 수 없다. 그래서 표 두 개를 두고 실행 시점에 주소를 채운다.
이름 역할
PLT Procedure Linkage Table 외부 함수를 호출할 때 거쳐 가는 표. 코드 영역에 있다
GOT Global Offset Table 외부 함수의 실제 주소가 저장되는 표. 데이터 영역에 있다
  • 호출 흐름은 프로그램 → PLT → GOT → 실제 함수 순이다.
  • 처음 호출할 때는 GOT에 주소가 없으므로 동적 링커가 함수를 찾아 GOT에 기록한다. 두 번째 호출부터는 GOT를 통해 바로 간다. 이를 지연 바인딩(lazy binding)이라 한다.
  • GOT는 쓰기 가능한 영역이므로 버퍼 오버플로우 등으로 값을 바꾸면 실행 흐름을 공격자가 원하는 함수로 돌릴 수 있다. 이를 GOT Overwrite라 한다.
  • 대응으로 RELRO(Relocation Read-Only)를 적용한다. Full RELRO는 지연 바인딩을 끄고 시작할 때 모든 주소를 채운 뒤 GOT를 읽기 전용으로 바꾼다.

같이 보기

[편집 | 원본 편집]