본문 바로가기
System_Security

07. 메인 함수

by Jnamelight 2017. 8. 1.

메모리의 구조에대해서 공부해 보았다.


그럼 우리가 C언어를 이용할때 사용되는 main 함수역시 함수인대 어떤식으로 인자들이 처리되는지 공부해보자.



일단 main 함수의 기본적인 정의는


int main( int argc, char *argv[]){


}


물론 우리는 간편하게


int main(){


}



이런식으로 생략형을 쓰긴 하지만 원래는 위의 표현이 정확한 표현이다.


여기서 두가지 인자에 대해서 알아보자.


argc : 메인함수의 인자 카운트 즉, 인자의 갯수를 넘겨준다.


*argv[] : 인자의 갯수만큼의 주소값을 넘겨준다.



어떤식으로 사용되는지 정확히 알기위해서는 간단한 실습예제를 통해서 알아보자.


// 과제 추가내용

printf 역시 메모리 정리를 해주어야한다.
메모리 누수를 없에야됨




1. 메인 함수의 인자값 처리

  int main();	// 생략가능
  int main( int argc, char *argv[] );	// 이것이 원형
  // 입력된 아규먼트, 입력된 아큐머트 주소


C

int main( int argc, char *argv[]){
	printf("%d",argc);
	return 0;	// xor	eax,	eax
}

// 위와같이 원형으로 해주어야 쓸수가 있다.


extern  printf

segment         .data
print_int       db      '%d',10,00
print_hex       db      '0x%08x',10,00

segment         .text
global          main

main:
        push    ebp
        mov     ebp,    esp

        push    dword [ebp+8]
        push    print_int
        call    printf
        add     esp,    8

        xor     eax,    eax

        leave
        ret




[root@ITBank /jmk]# ./main aaa aaa
3



-----------------------------------------------------------------


extern  printf

segment         .data
print_int       db      '%d',10,00
print_hex       db      '0x%08x',10,00
print_str       db      '%s',10,00

segment         .text
global          main

main:
        push    ebp
        mov     ebp,    esp

        push    dword [ebp+8]
        push    print_int
        call    printf
        add     esp,    8

        lea     eax,    [ebp+12]	// 아규먼트 주소를 가지고있는 주소
        push    eax			// 스택상 ebp +12
        push    print_hex
        call    printf
        add     esp,    8


        push    dword [ebp +12]		// 아규먼트 배열의 시작 주소값
        push    print_hex		// 아규먼트의 (인자 마지막)+1 널이들어감.
        call    printf			// 따라서 배열의 크기는 +4 바이트 크다.
        add     esp,    8

        mov     eax,    [ebp+12]
        push    dword [eax]		// 출력할 문자열의 주소값
        push    print_str
        call    printf
        add     esp,    8

        xor     eax,    eax

        leave
        ret

위의 코드는 main 함수의 인자값을 알수있는 함수이다.

이전 시간에 배웠던 메모리의 구조를 정확히 알고 있다면

인자값을 스택의 어떤 부분에 넘기는지 알고 있을 것이다. 복습할겸 다시한번 정리해보자면

 ebp 는 스택상 숫자가 높은쪽에 자리잡고, esp 는 낮은 쪽에 보통 자리를 잡는다.

esp 는 스택을 사용할때마다 이동하기 떄문에 기준점이 되는 ebp 를 통해서 변수, 인자 등을 넘기게 되는대

스택구조상 함수안의 변수는 ebp 보다 작은 값에 존재하게 된다. 그럼 인자값은?


ebp 보다 큰값에 존재하게 되는대

ebp+4 는 saved pointer 로써 리턴해서 돌아갈 곳의 주소를 저장하는 공간임으로 이것을 제외한

ebp+8 부터가 4바이트의 인자값으로 넘길수가 있다.


자 그럼 main 함수 역시 인자의 값을 알아보기 위해서 각각의 ebp+8 , ebp+12 를 출력하는 코드이다.
각각은 argc, argv 의 값을 가지고 있다.


간단한 예제로 실행시 넘겨주는 인자값을 출력해주는 어셈블 코드를 작성해보자.

// 과제 추가내용

printf 역시 메모리 정리를 해주어야한다.
메모리 누수를 없에야됨




1. 메인 함수의 인자값 처리

  int main();	// 생략가능
  int main( int argc, char *argv[] );	// 이것이 원형
  // 입력된 아규먼트, 입력된 아큐머트 주소


C

int main( int argc, char *argv[]){
	printf("%d",argc);
	return 0;	// xor	eax,	eax
}

// 위와같이 원형으로 해주어야 쓸수가 있다.


extern  printf

segment         .data
print_int       db      '%d',10,00
print_hex       db      '0x%08x',10,00

segment         .text
global          main

main:
        push    ebp
        mov     ebp,    esp

        push    dword [ebp+8]
        push    print_int
        call    printf
        add     esp,    8

        xor     eax,    eax

        leave
        ret




[root@ITBank /jmk]# ./main aaa aaa
3



-----------------------------------------------------------------


extern  printf

segment         .data
print_int       db      '%d',10,00
print_hex       db      '0x%08x',10,00
print_str       db      '%s',10,00

segment         .text
global          main

main:
        push    ebp
        mov     ebp,    esp

        push    dword [ebp+8]
        push    print_int
        call    printf
        add     esp,    8

        lea     eax,    [ebp+12]	// 아규먼트 주소를 가지고있는 주소
        push    eax			// 스택상 ebp +12
        push    print_hex
        call    printf
        add     esp,    8


        push    dword [ebp +12]		// 아규먼트 배열의 시작 주소값
        push    print_hex		// 아규먼트의 (인자 마지막)+1 널이들어감.
        call    printf			// 따라서 배열의 크기는 +4 바이트 크다.
        add     esp,    8

        mov     eax,    [ebp+12]
        push    dword [eax]		// 출력할 문자열의 주소값
        push    print_str
        call    printf
        add     esp,    8

        xor     eax,    eax

        leave
        ret

위와같은 코드를 작성하면 각각의 인자값을 출력을 해주게 된다.

!! 여기서 실행하는 코드의 이름 역시 인자로 넘기기 때문에 다음 배열부터가 넘겨주는 파라매터가 된다.





'System_Security' 카테고리의 다른 글

09. 디버거  (0) 2017.08.03
08. 시스템 콜  (0) 2017.08.01
06. 프로세스 메모리 구조  (0) 2017.07.26
05. 분기문,반복문  (0) 2017.07.24
04. 비트연산자 & 형변환  (0) 2017.07.20

댓글