[7] PLT / GOT / objdump활용법

2017. 6. 14. 13:56SystemHacking/System




[1] PLT ( Procedure Linkage Table )

PLT는 일종의 실제 호출 코드를 담고있는 테이블로써 _dl_resolve함수를 통해서 실제 시스템 라이브러리 호출이 이루어진다



[2] GOT ( Global Offset Table )

GOT는 PLT가 참조하는 테이블로써 프로시져들의 주소를 가지고 있다

PLT가 외부 프로시져를 호출할 때 GOT를 참조해서 해당 주소로 점프한다



ex) 어떤 프로그램에서 printf()함수를 호출한 상황

[1] printf()함수를 처음 호출 했을 때 과정

1> printf()함수 호출

2> PLT로 이동

3> dl_resolve()함수 실행

4> GOT에 printf()함수의 주소를 저장

5> printf()함수의 실제 주소로 점프한다


[2] 다시한번 printf()함수를 호출 했을 때

1> printf()함수를 호출

2> PLT로 이동

3> GOT를 참조한다

4> printf()함수의 실제 주소로 점프



>> 왜 이렇게 PLT와 GOT를 가지고 함수를 사용하는 것일까?

우리가 프로그램을 만들기 위해 코드를 짯다고 생각해봅시다. 하지만 해당 코드들로는 아무것도 할 수 없습니다

printf() 함수나 system()함수 등등 해당 함수들을 구현시킬 수 있는 코드들이 필요하겠죠?

이러한 코드들을 컴파일 해놓은 오브젝트 파일들이 모여있는 곳이 바로 라이브러리(GOT) 입니다

따라서 우리는 라이브러리와 프로그램을 " 링킹 "(연결) 시켜서 프로그램을 실행시켜야합니다

여기서, 링킹 방식에는 두가지가 있습니다. 

라이브러리를 프로그램에 포함시키는 Static방식과 각각을 개별적으로 사용하는 Dynamic방식입니다



[3] Linking방식


1> Static Link

라이브러리 내용을 포함한 실행파일을 생성하여서 라이브러리와의 연동과정이 필요없습니다

실행파일 안에 함수에 대한 정보가 다 들어있음

#gcc -o testtest.c -static 

" -static " 옵션을 주고 컴파일 시키면 static방식으로 링킹이 됩니다


2> Dynamic Link

라이브러리를 하나의 메모리 공간에 매핑하고 여러 프로그램에서 공유하여 사용합니다

해당 방식으로 연결하였을 때 PLT와 GOT를 사용하게 됩니다

라이브러리가 프로그램 외부에 있기 때문에 함수의 주소를 알아오는 과정이 필요하게된다

함수의 주소를 알아내기 위해서 우리는  " objdump " 명령어를 사용합니다


[4] objdump


$objdump -t ./format4 | head -10

[ 그림1 ]


Protostar Format4번 문제에서 사용한 명령어들을 예로 들어서 설명해드리겠습니다

" format4 " 실행파일내에서 사용한 함수들의 주소들을 보여주고 있습니다

그림1에 보이는 hello 함수와 vuln 함수는 사용자가 선언한 함수들입니다 ( 시스템의 내장함수가 아니다 )


$objdump -TR ./format4

[ 그림2 ]


DYNAMIC RELOCATION RECOREDS 의 내용들이 보입니다

" format4 "실행파일에서 사용한 exit()함수의 GOT내에서의 주소를 보여주고 있습니다

exit()함수는 시스템 내장 함수여서 GOT라이브러리에서 가져와서 사용한다

따라서 -TR옵션을 활용해 GOT내에서의 exit()함수의 주소를 알아내었다


[ 그림3 ]


" -d " 옵션은 참고로 적어놓았습니다. 대상파일의 기계어코드를 확인 할 수 있습니다 ( d == disassemble )