티스토리 뷰

출처 : https://bbolmin.tistory.com/33

https://g-idler.tistory.com/57

https://gdtbgl93.tistory.com/149

https://bpsecblog.wordpress.com/2016/03/07/about_got_plt_1/



먼저 프로시저가 뭔지 알아보자.


프로시저란?

프로시저란 매개변수는 존재하지만 반환값이 없는 함수이다.
특정 로직만 처리 후 종료한다.


PLT와 GOT에 대해 알기전에 동적 링크와 정적 링크에 대해서도 알아야 한다.

정적링크와 동적 링크

우리가 코드를 작성한 후 컴파일을 하는 과정에서 링킹이라는 단계가 필요하다.

링킹이란 단계는 printf()함수와 같이 헤더에 포함되어 있는 함수들을 불러와 오브젝트 파일과 연결한다. 여기서 오브젝트 파일은 우리의 코드를 어셈블리어로 바꿔놓은 파일이다.

헤더의 함수들과 오브젝트 파일을 합치는 방법에 따라 정적링크 와 동적링크로 나뉜다.

정적링크는 헤더에 포함된 함수들의 구현코드를 긁어와 내 코드에 같이 붙히는 방식이다.
이 방법을 사용하면 코드의 길이가 커지고 컴파일 시간도 길어진다.

동적링크는 헤더에 포함된 함수들의 주소를 하나의 메모리 공간에 매핑하고 여러 프로그램에서 공유하는 방법이다.
이 방법을 사용하면 파일의 크기도 작고 메모리도 적게 차지한다. 하지만 매핑할 메모리 공간이 없으면 실행할 수 없다.

동적링크를 사용할 때 바로 PLT와 GOT를 쓴다.

PLT와 GOT

PLT(Procedure Linkage Table) : 외부 프로시저를 연결해주는 테이블. PLT를 통해 다른 라이브러에 있는 프로시저를 호출할 수 있다.


GOT(Global Offset Table) : PLT가 참조하는 테이블. 프로시저들의 주소가 담겨있다.


동적링크를 사용할 때 쓰는 메모리 공간이 바로 PLT와 GOT 이다.



printf()함수를 처음으로 호출한다고 해보자.

첫 호출 시에는 링커가 dl_resolve라는 함수를 사용해 printf()의 주소를 알아오고,

GOT에 그 주소를 써준 후 해당 함수를 호출한다.


예제로 알아보자.


main+16에서 puts를 처음으로 불러왔다. 원래는 printf()인데 왜 puts인지는 모르겠다.


puts의 어셈블리를 보면



PLT를 사용하는게 보인다.

그럼 처음 jmp문으로 가보자.



PLT에서 GOT로 점프했다.


그런데 잘 보니 GOT가 가리키는 주소가 PLT+6의 주소이다. 그럼 



[printf 함수 호출] -> [PLT로 이동] -> [GOT 호출] -> [다시 PLT로 이동]


이런 과정이다.


PLT+6에서 0x18을 push하고 0x8048410으로 점프한다.

주소로 가보니



어떤 값을 push하고 또 어디로 이동한다.


이 jmp로 이동하는 곳이 _dl_runtime_resolve 함수의 주소이다.

이 함수가 printf()의 주소를 가져와 GOT에 저장한다.





'포너블 > 포너블 공부' 카테고리의 다른 글

ROP에 대해  (0) 2021.01.02
pwntools 이용하기  (0) 2020.12.01
execve() 함수  (0) 2020.09.08
Return To Libc 기법  (0) 2018.07.31
레이스 컨디션 해킹  (0) 2018.06.27
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/12   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
글 보관함