Post

GOT( Global Offset Table ) Layout과 link\_map structure

ELF 파일의 Section header를 조사하여 got 의 위치를 얻을 수 있다. 위 파일의 got 크기는 0x20이므로 32byte임을 알 수 있다.

Partial-RELRO(default) 바이너리는 .got.plt를 사용한다. 이 경우 . got는 4byte에 0만 들어있다. Full-RELRO 옵션으로 컴파일된 바이너리는 .got를 사용한다. 이 경우 .got.plt가 아예 없다. 따로 옵션을 주지 않으면 partial-RELRO로 컴파일되므로, .got.plt( 0x0804a000 )가 got라고 생각하면 된다. * 구식 OS는 .got.plt 없이 그냥 .got가 .got.plt를 포함하고 있는 경우도 있다.

got[0], 첫번째 entry는 이 module(실행 파일)의 dynamic section 주소다.

1
2
3
4
5
6
7
struct link\_map
{
ElfW(Addr) l\_addr;        /\* Base address shared object is loaded \*/
char \*l\_name;             /\* Absolute file path object was found in.\*/
ElfW(Dyn) \*l\_ld;          /\* Dynamic section of the shared object.  \*/
struct link\_map \*l\_next, \*l\_prev;      /\* Chain of loaded objects.\*/
};

got[2], 세번째 entry는 _dl_runtime_resolve 주소다.

got 네번째 entry 부터는 PLT에서 참조하는 global offset table 정보가 들어있다.

resolve 되기 전에는 PLT를 가리키고 있으며, 한번 호출되어 _dl_runtime_resolve에 의해 resolve되면 함수마다 각 library에 위치한 실제 함수 코드의 위치를 가리키게 된다. libraryname 뒤에 @plt가 붙은 함수들이 아직 resolve 되지 않은 함수들이며, PLT( 0x0804… )를 가리키고 있다. resolve 되면 Memory mapping segment ( 0xb7e… ) 를 가리키게 된다. 아직 resolve 되지 않은 함수들이 가리키는 위치에는 push 0x? 명령어가 있는데, _dl_runtime_resolve에서 이를 받아 해당 함수를 resolve 하게 된다.

참고

2016/11/01 - [System/LINUX & UNIX] - PLT, GOT

This post is licensed under CC BY 4.0 by the author.