[dreamhack] 라이브러리 (Static Link, Dynamic Link)
1. 라이브러리?
- 함수, 변수 등을 공유해서 사용할 수 있도록 자주 사용하는 함수들의 정의를 묶어 하나의 라이브러리로 만들어 제공
- libc라는 C의 표준 라이브러리는 어디에나 탑재되는 편
2. 링크?
- 컴파일의 마지막 단계
- 프로그램에서 라이브러리의 함수를 사용하는 경우, 함수와 실제 라이브러리의 함수를 연결해줌!
- 심볼과 관련된 정보를 찾아서 실행 파일에 링크(연결)해 줌!
- 리눅스의 경우 다음과 같은 표준 라이브러리들이 gcc 빌드시에 항상 들어가게 됨.
- 이 표준 라이브러리들은 컴파일될때 모두 탐색됨!!
$ ld --verbose | grep SEARCH_DIR | tr -s ' ;' '\n'
SEARCH_DIR("=/usr/local/lib/x86_64-linux-gnu")
SEARCH_DIR("=/lib/x86_64-linux-gnu")
SEARCH_DIR("=/usr/lib/x86_64-linux-gnu")
SEARCH_DIR("=/usr/lib/x86_64-linux-gnu64")
SEARCH_DIR("=/usr/local/lib64")
SEARCH_DIR("=/lib64")
SEARCH_DIR("=/usr/lib64")
SEARCH_DIR("=/usr/local/lib")
SEARCH_DIR("=/lib")
SEARCH_DIR("=/usr/lib")
SEARCH_DIR("=/usr/x86_64-linux-gnu/lib64")
SEARCH_DIR("=/usr/x86_64-linux-gnu/lib")
3. Static link VS Dynamic link?
- 라이브러리는 크게 정적/동적 라이브러리로 구분되며, 각각의 링크는 정적/동적 링크라고 함
- 동적 링크 : 동적 라이브러리가 프로세스의 메모리에 맵핑되고 호출될 때 함수의 주소를 찾아 실행!
- 정적 링크 : 바이너리 자체에 라이브러리의 모든 함수가 포함됨!
- 정적 링크를 디버깅하는 경우, 정적 라이브러리의 함수 주소를 직접 참조
- 반면, 동적 링크의 경우에는 PLT를 참조하고 있음. 왜냐? 찾아야하므로!
4. PLT & GOT
- PLT : Procedure Linkage Table
- GOT : Global Offset Table
- 둘 모두 동적 라이브러리의 심볼 주소를 찾을 때 사용되는 테이블!
- 동적 링크의 경우, 함수가 호출되면 라이브러리에서 심볼을 찾고 찾은 주소로 실행 flow를 이동시킴!
- 이 과정을 runtime resolve라고 하는데, 이 코드는 PLT에 포함되어있다!!!
- 최초로 함수가 불리우면 PLT를 확인해서 안에 쓰인 GOT로 점프시키고자 함
- 그런데 이 때 GOT에는 실제 해당 함수의 주소가 쓰여있지 않음
- 이 때 동작하는 것이 runtime resolve. 이걸 통해서 실제 함수의 주소를 알아내고 GOT에 기록함
- 그러나 해당 함수가 여러번 호출되면 이 '찾는 행위(탐색)'가 반복적으로 발생함
- 이를 방지하기 위해, 한번 찾은 함수들의 주소를 보관하는 곳이 GOT
- 여기서 한번 실행된 함수의 주소가 GOT에 저장됨을 이용해서 GOT를 덮어씌워 공격을 수행한다면? GOT overwrite공격 가능