일반적으로 프로그램이 시작하면 맨 처음 main함수가 실행 된다고 알고 있는데.. 메인함수를 실행 시키기 위한 환경을 만들어 주는 과정이 있다.

 

이 과정에서 먼저 실행되는 함수가 있는데 _start()함수다.

메인함수도 이 _start()함수가 실행된 후에 실행되므로 main보다 먼저 실행이 된다.

 

우선 코드를 컴파일해서 확인해보자.

 

test1.c

#include<stdio.h>
#include<stdlib.h>
_start()
{
   exit(my_main());
}
int my_main()
{
   printf("Hello");
   return 0;
}

gcc  -nostartfiles  test1.c 

 

main함수 없이 코드를 작성했고 위와 같이 컴파일 한 후 실행시켜 봤다.

이처럼 메인함수 없이도 내 임의의 main을 실행 시킬 수 있다.

 

이제 gdb로 이 _start()함수를 확인해보자.

 

코드를 짠대로 _start()함수에서 my_main()을 콜한다.

 

만약 실제 main()함수를 실행할 때는 어떻게 동작하는지 이번엔 main()함수가 있는 코드를 작성해서 컴파일해봤다.

#include <stdio.h>

int main()
{
        printf("Hello");
        return 0;
}

 

먼저 이 코드를 컴파일을 해주고 gdb로 열었다.

_start()함수의 주소를 찾았다. 이제 여기서 main()을 call하는 부분을 확인해야한다.

 

해당 주소에 bp를 걸고 레지스터들을 확인해야 한다.

 

레지스터를 보면 64비트에선 rdi, rsi가 함수의 첫번째와 두번째 인자로 들어가는데 여기서 rdi와 rsi는 각각 main()함수 시작주소와 해당 함수의 첫번 째 인자를 넣는 것이다.

즉 call할때 첫번째 인자에는 실행시킬 함수를 주고, 두번째 인자에는 해당 함수에 들어갈 인자 값을 넣는 것이다.

 

이번에는 다시 main()함수가 없는 test1.c의 my_main()을 하는 부분에 bp를 걸고 다시 확인해보자.

이번에는 my_main()함수를 직접 호출하기 때문에 rdi에는 어떤 0을 가리키는 값이 들어갔고 rsi에는 또 1이 들어갔다.

정확히 확인해보기 위해 이번에는 my_main()함수에 인자를 추가해야겠다.

 

#include<stdio.h>
#include<stdlib.h>
_start()
{
   exit(my_main(31));
}
int my_main(int i)
{
   printf("Hello");
   return 0;
}

 

이번에도 똑같이 컴파일한 후 gdb로 확인해봤다.

이번에는 rdi에 my_main()의 첫번째 인자엔 십진수로 33인 0x1f가 들어가 있다.

이제 대충 _start()함수의 원리를 아주 조금 안 것 같다.

다음엔 직접 libc의 소스를 보면서 파악을 해봐야 겠다.

===========================================================================

start In Kernel

- start_kernel 함수

 

ref.http://egloos.zum.com/studyfoss/v/5283161

ref.https://stackoverflow.com/questions/5764298/how-to-compile-c-source-code-without-a-main-function

ref.https://tistory.0wn.kr/368

'HACKING > System hacking' 카테고리의 다른 글

리버스 쉘(nc via mkfifo)  (0) 2018.07.28
python의 pickle 모듈 취약점  (0) 2018.07.28
nc -e 옵션 사용이 안될때  (0) 2018.07.19
gdb-peda 기능들  (0) 2018.07.08
Shell Escaping tips  (0) 2018.06.23

+ Recent posts