-
[pwnable] PLT와 GOTEVI$ION/SYSTEM HACKING 2019. 7. 19. 23:07
소스코드를 컴파일하면 오브젝트 파일이 생성되고, 이를 라이브러리와 연결시키는 링킹(Linking) 작업을 통해 최종적으로 실행 파일이 생성된다. 링킹 방식에는 Static Linking과 Dynamic Linking, 2가지 방식이 존재한다.
Static Linking 방식은 실행파일 내에 필요한 라이브러리 내용을 모두 포함하여 파일을 생성한다. 실행파일 내에 모든 코드가 포함되기 때문에 라이브러리를 따로 연동하고 관리할 필요가 없다. 하지만 파일의 용량이 크고, 같은 라이브러리를 사용하더라도 해당 라이브러리를 사용하는 파일들은 라이브러리 내용을 모두 메모리에 매핑시켜야한다는 단점이 있다.
반면 Dynamic Linking 방식은 공유 라이브러리를 사용하기 때문에 Static Linking 방식과 달리 파일의 용량이 훨씬 작고 파일 실행 시에도 적은 메모리 공간을 차지한다. 또한 라이브러리를 공유하기 때문에 업데이트도 유연하게 할 수 있다. 그러나 Dynamic Linking 방식으로 생성된 파일은 라이브러리에 의존해야 하기 때문에 라이브러리가 없으면 실행이 불가능하다.
Static Linking 방식은 프로그램 내에 라이브러리가 포함되어 있기 때문에 라이브러리 함수의 주소를 따로 알아내야 할 필요가 없다. 하지만 Dynamic Linking 방식을 사용하면, 라이브러리가 프로그램 외부에 있기 때문에, 라이브러리 함수를 사용하기 위해선 해당 함수의 주소를 알아야 한다. 즉, 라이브러리 함수의 주소를 알아내기 위해서 사용하는 것이 PLT와 GOT이다.
PLT와 GOT의 정의는 아래와 같다.
1. PLT (Procedure Linkage Table)
: 외부 프로시저를 연결해주는 테이블로, PLT를 통해 다른 라이브러리에 있는 프로시저를 호출하여 사용할 수 있다.
외부 라이브러리를 연결해주는 함수라고 이해하면 된다.
2. GOT (Global Offset Table)
: PLT가 참조하는 테이블로, 프로시저들의 주소가 들어있다. 외부 프로시저를 호출할 때 PLT는 GOT를 참조하여 프로시저를 호출한다.
정리하면,
Dynamic Linking 방식으로 생성된 파일은 라이브러리 함수를 호출할 때 PLT를 참조하고, 이 PLT를 통해 GOT으로 점프한다. 그 다음 GOT에 있는 실제 라이브러리 함수의 주소를 통해 함수를 호출한다.
그런데 사용하고자 하는 함수가 첫 호출인지 아닌지에 따라 함수 호출 과정이 달라진다.
printf( ) 함수를 예로 들어 설명해보겠다.
1) printf 함수가 처음 호출되었을 때
printf 함수 호출 → PLT 이동 → ① GOT 참조 → ② GOT에 printf 함수의 주소가 없으므로 다시 PLT로 이동 → ③ _dl_runtime_resolve 함수 호출 → ④ printf 함수 실제 주소를 GOT에 저장한 후 해당 함수 주소로 점프
2) printf 함수 호출이 처음이 아닐 때
① printf 함수 호출 → ② PLT로 이동 → ③ GOT로 이동 → ④ printf 함수 주소로 점프
[참고 자료]
https://bpsecblog.wordpress.com/2016/03/07/about_got_plt_1/
'EVI$ION > SYSTEM HACKING' 카테고리의 다른 글
[시스템해킹 #5] RET SLED, FEBP (0) 2019.06.24 [시스템해킹 #4] NOP Sledding, strcpy와 gets, 링크, RTL (0) 2019.05.13 [시스템해킹 #3] 메모리 보호 기법, 쉘코드, 환경변수 (0) 2019.05.06 [시스템해킹 #2] 어셈블리어, 함수 프롤로그/에필로그, gdb, setUID (0) 2019.05.05 [시스템해킹 #1] 함수의 호출/복귀 원리, 메모리 구조, 스택 프레임, 함수 프롤로그/에필로그, 지역변수/전역변수 할당, 어셈블리어 기 (0) 2019.05.05