Plt와 Got
개념
PLT
Procdedure Linkage Table의 약자로 프로시져들을 연결해 주는 테이블을 말합니다. 프로그램을 어떻게 구현 했느냐에 따라 달라지기도 합니다.
실제 호출 코드를 담고 있으며 이 내용을 참조해 _dl_runtime_resolve가 수행되고, 실제 시스템 라이브러리 호출이 이루어 집니다.
GOT
Global Offset Table의 약자로 함수들의 주소를 담고 있는 테이블입니다. 라이브러리 함수를 호출할때 PLT가 GOT를 참조하게 됩니다.
첫 호출시엔 코드의 영역의 벡터 주소가 들어가 있고, 두번째 호출부터 그 함수의 실제 주소가 들어가져 있다.
설명
위 C 코드를 보면 매우 간단하게 printf와 puts를 사용하고 있습니다. 그저 단순 출력 소스코드 입니다.
해당 파일을 컴파일 하고, gdb를 통해 확인해 보도록 하겠습니다.
printf와 puts의 call하는 부분을 확인 할 수 있습니다.
그런데 그냥 printf, puts가 아니라 printf@plt, puts@plt라고 적혀있습니다.
일단 printf와 puts에 들어간 문자들이 저장된 곳이 각각 0x8048510, 0x8048510 입니다. 같은 이유는 같은 문자를 담고 있기 때문이죠.
여튼 이게 중요한게 아니고...
왜 Plt가 붙어있는지가 중요합니다. 일단 printf@plt의 위치에 브레이크 포인트를 걸고 call하는 곳으로 들어가 보겠습니다.
printf@plt의 위치로 이동했습니다.
마지막 어셈블리어의 jmp 0x8048300으로 이동해 보겠습니다.
계속 따라 들어가다 보면 _dl_runtime_resolve로 이동하는 것을 알 수 있습니다.
그리고 중간에 _dl_fixup으로 이동하는 것도 알 수 있습니다.
_dl_fixup으로 들어가 보면 _dl_lookup_symbol_x에 들어가는 것이 보입니다.
그리고 쭉 실행해보면 다시 _dl_fixup으로 이동합니다. 중간에 다른 곳으로 호출되는 부분이 나타나지만 해당 부분으로 들어가지 않습니다.
_dl_fixup에서 나오면 __printf로 이동하게 됩니다.
마찬가지로 __x86.get_pc_thunk.bx에 들어간 후 다시 나오게 됩니다. 또한 _IO_vfprintf_internal에 들어간 후 다시 돌아옵니다.
__printf에서 ret 를 통해 빠져나오면서 main으로 돌아옵니다. 그리고 printf에 넣었던 인자인 Plt and Got가 출력됩니다.
마찬가지로 puts@plt또한 printf@plt와 똑같이 수행합니다.
일단 여기까지의 과정을 정리하면 아래와 같습니다.
그렇다면 printf를 계속해서 사용한다면 위와 같은 과정을 계속해서 하게 될까요?
소스코드를 조금 바꿔서 분석해 보도록 하겠습니다.
위와 같이 모두 printf만 사용하여 출력하도록 해보았습니다. 이제 gdb로 분석해 보겠습니다.
첫 번째 printf는 앞서 설명한 것 처럼 여러군데들어 갔다가 main으로 돌아오게 됩니다.
두 번째 printf는 어떻게 될까요?
마찬가지로 printf@plt로 이동했습니다. jmp를 통해서 0x804a00c로 이동하고 있습니다. 해당 위치에 있는 값을 확인해보면 아래와 같습니다.
해당 주소로 점프를 하고 있는데 한번 이동해 보도록 하겠습니다.
해당 위치로 이동한 결과 __printf로 이동하게 되었습니다.
그리고 ret를 통해서 다시 main으로 돌아오게 됩니다.
정리하면 아래와 같습니다.
중간의 _dl_runtime_resolve와 _dl_looup_symbole_x를 거치지 않았습니다.
printf@plt의 실행 주소를 확인해보면 아래와 같습니다.
정리
결국에는 plt에서 got로 이동하기 위한 과정들이였습니다. 간략이 정리하자면 아래와 같습니다.
1. PLT에서 GOT로 이동한다.
2. 처음 실행되는 함수는 _dl_rumtime_resolve와 _dl_lookup_symbol_x에 들어간다. 그러면서 GOT에 함수의 주소를 저장한다.
3. 두 번째 실행되는 함수는 바로 GOT로 넘어간다.
'High Level Technique > System Hacking' 카테고리의 다른 글
Format String Bug (FSB) (0) | 2016.04.25 |
---|---|
Return To Library (RTL) (2) | 2016.04.20 |
Fake EBP (0) | 2016.04.19 |
main의 SFP는 왜 0이 되는가? (1) | 2016.04.19 |
Save Frame Pointer Overwrite (SFO) (0) | 2016.04.15 |