`` main``의 상위 frame은 `` __libc_start_main``이다.


__libc_start_main

`` __libc_start_main``은 `` init, fini, stack_end`` 등을 인자로 받는데, 

첫 번째 인자로 `` main``의 함수 포인터를 받는다.

```c

int __cdecl _libc_start_main(int (__cdecl *main)(int, char **, char **), int argc, char **ubp_av, 

void (*init)(void), void (*fini)(void), void (*rtld_fini)(void), void *stack_end)


.text:0000000000000A5D       lea     rdi, main       ; main

.text:0000000000000A64       call    __libc_start_main

```


`` __libc_start_main``의 상위 frame은 `` _start``다.


start ( = Entry point )

OEP(Original Entry Point) = Image Base + Address of Entry Point(RVA)


바이너리에서 코드의 시작 지점은 `` Image Base + Base of Code``지만, 
실제로 프로그램이 맨 처음 실행하게 되는 Instruction은 Entry Point다.
그리고 OEP에는 `` start``가 있다.

* Base of Code와 OEP(Address of Entry Point)는 전혀 관련이 없다. Base of Code는 단순히 코드 섹션이 거기서 부터 시작한다는 것을 의미한다.
* Base of Code에는 컴파일러가 포함한 스타트업 루틴 등 stub code가 위치하게 되는데, 단순히 위치 상으로 Address of Entry Point 이전에 있는 코드라고 해서 스타트업 루틴으로 간주해서는 안된다.
* 스타트업 루틴 등이 위치한 경우 디버거로 봐도 EIP에 들어가는걸 볼 수 없다. 그런 루틴이 끝나야 디버거에 로드되기 때문.


`` _start  →  __libc_start_main →  main`` 순으로 호출하고,

`` main``에서 `` ret``시 `` __libc_start_main``의 끝부분 (+255)로 가게 된다.

여기서 `` call`` instruction을 수행하면서 어딘가로 가게되는데  `` dl``계열 함수들이나 exit함수를 통해 자원반납이나 종료선행작업을 하는 듯 보인다.



`` __libc_start_main``에서 `` ret``시 `` _start+33``으로 가게 되는데, 여기서 `` hlt`` instruction을 실행하게 된다.

`` hlt``를 실행하면 CPU는 외부 인터럽트가 들어올 때 까지 대기한다.


Windows

Windows도 크게 다르지 않다.

`` start → [jmp : tmainCRTStartup ... call : main] → main`` 순으로 호출한다.


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

[Linux] Memory Layout, Segment + Kernel  (0) 2016.11.21
[compile process] Shared Library  (0) 2016.11.21
[setuid] ruid, euid  (0) 2016.11.15
[shell] pipe  (0) 2016.11.03
PLT, GOT  (0) 2016.11.01