[11] 어셈블리 argc, argv 이해하기

2017. 10. 30. 20:15SystemHacking/Assembly




1. main함수의 인자


포인터 배열 : 주소를 원소로 하는 배열

배열 포인터 : 배열을 가리키는 포인터


[ 사용법 ] 

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

{

printf("%s \n", argv[1] );            // argv[1] 은 주소이다 !

return 0;                                // 실행파일의 첫번째 인자의 주소 !

}                                                  // argv[0] 은 실행파일의 이름임

=>실행결과 #./a.out hello

     hello



*argv[] : 포인터 배열 ( 인자들이 주소 )


ebp+8  :   argc  : 인자의 개수, 즉 *argv[]배열의 인자 개수

ebp+12 : argv[] : 실행파일의 이름이 들어있다

ebp+16 : argv[1] : 실행파일의 첫번째 인자의 주소값(포인터)이 들어있다

ebp+20 : argv[2] : 실행파일의 두번째 인자의 주소값(포인터)이 들어있다



char *argv[] -> 0xbffffba4


포인터배열 *argv[] 는 '포인터'를 인자로 가지는 배열의 첫번째 주소를 값으로 가지고 있다

인자로 들어가 있는 '포인터' 들은 실행파일의 인자들의 주소이다



extern printf


section .data

prompt_int:     db      '%d', 10, 00

prompt_hex:     db      '0x%08x',10,00

prompt_str:     db      '%s',10,00


section .text

global main

main:

push    ebp

mov     ebp,    esp


mov     eax,    [ebp+12] ; [ebp+12] : argv[0]의 주소

push    eax ; argv[0]의 주소 push

push    prompt_hex

call    printf

add     esp,    8


mov     eax,    [ebp+12] ; [ebp+12] : argv[0]의 주소

push    dword [eax] ; argv[0]의 값 push

push    prompt_str

call    printf ; 실행파일의 이름이 출력된다

add     esp,    8


mov     eax,    [ebp+12] ; eax = [ebp+12] : argv[0]의 주소

lea     eax,    [eax+4] ; eax+4 = [ebp+16] : argv[1]의 주소

push    eax ; argv[1]의 주소 push

push    prompt_hex

call    printf

add     esp,    8


mov     eax,    [ebp+12] ; eax = [ebp+12] : argv[0]의 주소

lea     eax,    [eax+4] ; eax+4 + [ebp+16] : argv[1]의 주소

push    dword [eax] ; argv[1]의 값 push 

push    prompt_str

call    printf ; 실행파일의 첫번째 인자가 출력된다

add     esp,    8


leave

ret




[root@EH /root]# ./argv hello

0xbffffba4

./argv

0xbffffba8

hello

0xbfffffba4  

 0xbfffffba8  0xbfffffbac 
 0xbffffc9f 0x00000000 ( 배열의끝을알리는역할 )