자료는 블랙펄시큐리티 블로그의 내용을 참고해서 메모했다. https://bpsecblog.wordpress.com/2016/03/07/about_got_plt_1/
-
PLT (Procedure Linkage Table) : 외부 프로시저를 연결해주는 테이블이다. PLT를 통해 다른 라이브러리에 있는 프로시저를 호출해 사용할 수 있다.
-
GOT (Global Offset Table) : PLT가 참조하는 테이블이다. 프로시저들의 주소가 들어있다.
기본적으로 함수를 호출하면(PLT를 호출) GOT로 점프하는데 GOT에는 함수의 실제 주소가 쓰여있다.첫 번째 호출이라면 GOT는 함수의 주소를 가지고 있지 않고, '어떤 과정'을 거쳐 주소를 알아낸다. 두 번째 호출 부터는 첫 번째 호출 때 '어떤 과정'으로 알아낸 주소에 바로 점프한다.
여기서 우리가 봐야할 것은 '어떤 과정'이다. 이 과정을 통해 GOT가 주소를 알아낸다. 이 '어떤과정'은 무엇일까?
먼저, 링킹(Linking)에 대해 알아보자.
- 링킹은 라이브러리 등과 같은 소스코드에 필요한 오브젝트 파일들을 연결시키는 작업을 링킹이라고 한다.
링크를 하는 방법에도 Static 방식과 Dynamic 방식이 있다.
-
Static Link 방식은 파일 생성시 라이브러리 내용을 포함한 실행파일을 만든다.
gcc -o test test.c -static
- gcc 옵션 중 static 옵션을 적용해서 컴파일을 하면 Static Link 방식으로 컴파일이 된다.
-
Dynamic Link 방식은 라이브러리를 하나의 메모리 공간에 매핑하고 여러 프로그램에서 공유하는 공유 라이브러리를 사용한다.
gcc -o test test.c
- 아무런 옵션도 주지 않는다면, 자동으로 Dynamic Link 방식으로 컴파일 한다.
여기서!!!
Dynamic Link 방식으로 컴파일을 했을 때 PLT와 GOT를 사용하게 된다.
Static Link 방식으로 컴파일을 하면 라이브러리가 실행파일 내부에 있기 때문에 함수의 주소를 알아내는 과정이 필요가 없지만, Dynamic Link 방식으로 컴파일을 하면 라이브러리가 프로그램 외부 메모리에 위치해 있기 때문에 함수의 주소를 알아오는 과정이 필요한 것이다.
원리
Dynamic Link 방식으로 프로그램이 만들어지면 함수를 호출할 때 PLT를 참조하게 된다. PLT에서는 GOT로 점프를 하게 되는데, GOT에 라이브러리에 존재하는 실제 함수의 주소가 적혀있어 함수 호출이 가능하다.
이 때, 첫 번째 호출이라면 GOT에 실제함수의 주소가 쓰여있지 않다. 그래서 첫 호출을 할 때는 Linker가 dl_resolve라는 함수를 사용해 필요한 함수의 주소를 알아오고, GOT에 그 주소를 써준 후 해당 함수를 호출한다.
그리고 두 번째 호출이라면 GOT에 실제 함수의 주소가 쓰여있어 바로 호출하면 된다!
'메모용' 카테고리의 다른 글
ASLR 정리 (0) | 2021.08.24 |
---|---|
메모리 보호 기법 [ NX-Bit(MS : DEP) ] (0) | 2020.12.18 |
Format String Bug - simplefsb (Y.CTF) (0) | 2020.12.12 |