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 주소다.


got[1], 두번째 entry는 link_map의 시작 node 주소다.

```c
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


'OS > LINUX & UNIX' 카테고리의 다른 글

[excp] 읽기 권한 없는 파일 복사하기  (0) 2016.12.21
.s 파일 수정  (0) 2016.12.10
[Linux] Memory Layout, Segment + Kernel  (0) 2016.11.21
[compile process] Shared Library  (0) 2016.11.21
main startup routine bt  (0) 2016.11.15