what is different between .got & .got.plt

실행 파일 구조에는 .got 와 .got.plt 가 존재한다. 이 둘의 차이점은 뭘까?
우리가 흔히 말하는 got overwrite에서 got는 .got.plt 을 의미한다. plt함수에서 실제 libc상의 함수
.got 영역은 전역변수들의 주소를 저장한다.
전역변수들이 .data 영역에 존재하는데 왜 .got ? 라고 말할 수도 있다.
하지만, 다른 라이브러리에 있는 전역 변수를 사용한다면, 로더가 재배치를 하여야 해당 전역변수의 실제 위치를 알 수 있다. 이럴때 사용되는게 .got 영역이다.
C
22 .got 00000008 0000000000601ff8 0000000000601ff8 00001ff8 2**3
CONTENTS, ALLOC, LOAD, DATA
23 .got.plt 00000080 0000000000602000 0000000000602000 00002000 2**3
CONTENTS, ALLOC, LOAD, DATA
24 .data 00000010 0000000000602080 0000000000602080 00002080 2**3
CONTENTS, ALLOC, LOAD, DATA
25 .bss 00000030 00000000006020a0 00000000006020a0 00002090 2**5
ALLOC
C
(pwn) amemoyoi ~$ objdump -R Notepad
Notepad: file format elf64-x86-64
DYNAMIC RELOCATION RECORDS
OFFSET TYPE VALUE
0000000000601ff8 R_X86_64_GLOB_DAT __gmon_start__
00000000006020a0 R_X86_64_COPY stdout@GLIBC_2.2.5
00000000006020b0 R_X86_64_COPY stdin@GLIBC_2.2.5
00000000006020c0 R_X86_64_COPY stderr@GLIBC_2.2.5
0000000000602018 R_X86_64_JUMP_SLOT remove@GLIBC_2.2.5
0000000000602020 R_X86_64_JUMP_SLOT puts@GLIBC_2.2.5
0000000000602028 R_X86_64_JUMP_SLOT fclose@GLIBC_2.2.5
0000000000602030 R_X86_64_JUMP_SLOT system@GLIBC_2.2.5
0000000000602038 R_X86_64_JUMP_SLOT strchr@GLIBC_2.2.5
0000000000602040 R_X86_64_JUMP_SLOT read@GLIBC_2.2.5
0000000000602048 R_X86_64_JUMP_SLOT __libc_start_main@GLIBC_2.2.5
0000000000602050 R_X86_64_JUMP_SLOT ftell@GLIBC_2.2.5
0000000000602058 R_X86_64_JUMP_SLOT fseek@GLIBC_2.2.5
0000000000602060 R_X86_64_JUMP_SLOT setvbuf@GLIBC_2.2.5
0000000000602068 R_X86_64_JUMP_SLOT fopen@GLIBC_2.2.5
0000000000602070 R_X86_64_JUMP_SLOT sprintf@GLIBC_2.2.5
0000000000602078 R_X86_64_JUMP_SLOT strstr@GLIBC_2.2.5objdump -h 명령어로 섹션을 살펴보고
objdump -R 명령어로 재배치 되야할 항목들에 대해 살펴보면, 여러가지가 나온다. 그중 타입이
R_X86_64_JUMP_SLOT 인 얘들이 보인다. 얘내들은 딱봐도 .got.plt 인것을 알 수 있을 것이다.
0000000000601ff8 R_X86_64_GLOB_DAT __gmon_start__
그리고 섹션상으로 얘가 .got 영역인것을 알 수 있다.
C
00000000006020a0 R_X86_64_COPY stdout@GLIBC_2.2.5
00000000006020b0 R_X86_64_COPY stdin@GLIBC_2.2.5
00000000006020c0 R_X86_64_COPY stderr@GLIBC_2.2.5R_X86_64_COPY 타입인 얘내들은 전역변수의 값이 외부에 정의되어 있고 그 값을 로더가 복사해 오는 얘들이다. 주소 bss 섹션을 쓴다.
좀 더 깊숙하게 따지자면, .got 은 never resolved lazily 하다. 그에 반해
.got.plt 은 resolved lazily 하다. 그리고 RELRO와 같은 보안 기법으로 보호되는 공간은 .got.plt 뿐이다.