농소
asm 지역변수 배열, main 함수의 인자 int argc, char *argv[ ] 본문
asm 지역변수 배열활용
이번에 asm에서 배열을 지역변수로 나타내려면 어떻게 표현해야 하는지 알아보자
스택이 쌓일 수록 메모리주소값은 작아지는데 배열도 마찬가지로
첫주소가 다음주소보다 높다는 생각을 할 수도 있다.
하지만 배열같은경우 c에서 처럼 낮은 주소부터 높은 주소로 표현된다.
즉, 배열의 시작주소는 지정된 크기중 가장 낮은 주소에 위치한다.
우선 이전에 했던 입력한 문자열을 반대로 출력하는 코드를 지역변수로 변환해서 asm으로 작성해보겠다.
C 언어
int main()
{
char buffer[1024] = {0,};
int len =0;
printf("input: ");
gets( buffer );
while(buffer[len] !=0) {
len++
}
len--;
while( len >= 0) {
printf("%c", buffer[len]);
len--;
}
printf("\n");
return 0;
}
ASM
extern printf
extern gets
segment .data
msg db 'input: ', 00
output db '%c', 10, 00
newline db 10, 00
segment .text
global main
main:
push ebp
mov ebp, esp // prologue
sub esp, 1028 // 지역변수 크기 할당
mov ecx, 256
xor eax, eax
lea edi, [ebp-1024]
rep stosd // 배열에 전부 0으로 초기화
mov dword [ebp-1028], 0
push msg
call printf
add esp, 4
lea eax, [ebp-1024]
push eax
call gets
add esp, 4
while1: // 문자열의 길이 확인
mov eax, dword [ebp-1028]
cmp byte [ebp - 1024 + eax * 1], 0 // 1바이트씩 읽어서 비교
je .end
inc dword [ebp-1028]
jmp while1
.end:
dec dword [ebp-1028]
while2:
mov eax, dword [ebp-1028]
cmp eax, 0
jl .end
movzx ebx, byte [ebp - 1024 + eax * 1]
push ebx
push output
call printf // 1바이트씩 읽어서 출력
add esp, 8
dec dword [ebp-1028]
jmp while2
.end:
push newline
call printf
add esp, 4
xor eax, eax // return 0
leave
ret
main 함수의 인자
c 표준 main 인자
int main( );
int main( int argc, char *argv[ ] );
표준이 아닌 void main(void)도 많이 사용하긴 하는데
이 경우 컴파일러가 알아서 해석해서 return 처리를 해준다.
우선 c에서 이 인자들이 어떻게 동작하는지 알아보자.
int main( int argc, char *argv[] )
{
printf("argc: %d\n", argc); // 인자의 개수, 최소는 arg1, null 이다
printf("argv: 0x%08x\n", argv); // 주소
printf("*argv: 0x%08x\n", *argv); // 주소의 메모리 호출 거기에도 주소가 들어있음.
printf("*argv[]: %c\n", **argv); // 메모리의 첫번째 문자
printf("*argv[]: %s\n", argv[0]); // 첫번째 인자의 메모리. 문자열을 출력한다
printf("%s\n", argv[1]); // 두번째 인자의 문자열을 호출
return 0;
}
인자 하나만 넣고 실행 했을때와 두개를 넣었을 때 실행한 결과를 보면
인자가 abc가 추가됨에 따라 arg count가 1증가하였고 argv[1] 이 null에서 abc로 출력되었다.
자 이제 asm에서 메인 함수 인자들이 어떻게 표현되는지 알아본다
argc, *argv[ ]는 스택 메모리 영역중에 메인보다 상위부분 ebp + 8, ebp +12에 위치해 있다.
extern printf
segment .data
prompt_hex db 'address: 0x%08x', 10, 00
prompt_chr db 'memory: %c', 10, 00
prompt_int db 'argc: %d', 10, 00
prompt_str db 'memory: %s', 10, 00
segment .text
global main
main:
push ebp
mov ebp, esp // prologue
push dword [ebp+8]
push prompt_int
call printf // argc
add esp, 8
lea eax, [ebp+12]
push eax
push prompt_hex
call printf // esp address
add esp, 8
mov eax, [ebp+12]
push eax
push prompt_hex
call printf // *argv[] address
add esp, 8
mov eax, [ebp+12]
mov ebx, [eax]
push ebx
push prompt_hex
call printf // argv[] address
add esp, 8
mov eax, [ebp+12]
mov ebx, [eax]
mov ecx, [ebx]
push ecx
push prompt_chr
call printf // argv memory 첫 문자 출력
add esp, 8
mov eax, [ebp+12]
mov ebx, [eax]
push ebx
push prompt_str // argv[] address 문자열출력
call printf
add esp, 8
mov eax, [ebp+12]
mov ebx, [eax+4] // 두번째 인자 위치로 이동
push ebx
push prompt_str
call printf // 두번째 인자 문자열 출력
add esp, 8
leave // epilogue
ret
위와 동일하게 인자 하나만 넣고 실행 했을때와 두개를 넣었을 때 실행한 결과를 보면
인자가 abc가 추가됨에 따라 arg count가 1증가하였고 argv[1] 이 null에서 abc로 출력되었다.
[실습]
- 두번째 인자값을 출력
- %s로 출력하지말고 반복문을 이용하여 %c로 출력하시오
extern printf
segment .data
prompt_chr db 'memory: %c', 10, 00
prompt_int db 'argc: %d', 10, 00
prompt_str db 'memory: %s', 10, 00
segment .text
global main
main:
push ebp
mov ebp, esp // prologue
sub esp, 4 // len 지역변수 메모리 확보
mov dword [ebp-4], 0
push dword [ebp+8]
push prompt_int
call printf // argc 출력
add esp, 8
mov eax, [ebp+12]
mov ebx, [eax]
push ebx
push prompt_str // 첫번째 인자 문자열 출력
call printf
add esp, 8
mov eax, [ebp+12]
mov ebx, [eax+4]
push ebx
push prompt_str // 두번째인자 문자열 출력
call printf
add esp, 8
while:
mov eax, dword [ebp-4]
cmp eax, 0 // null이 나올때 까지 반복문 진행
je .end
mov ebx, [ebp+12]
mov ecx, [ebx+4]
mov edx, [ecx + eax * 1] // 1바이트씩 읽어들임
push edx
push prompt_chr // 1바이트씩 문자 출력
call printf
add esp, 8
inc dword [ebp-4]
jmp while
.end:
leave // epilogue
ret
'Security > System Hacking' 카테고리의 다른 글
디버거 GDB 사용법 (0) | 2018.01.26 |
---|---|
시스템 프로그래밍, 시스템 콜 (0) | 2018.01.25 |
프로세스 메모리 구조, 스택 레지스터, 함수 (0) | 2018.01.23 |
nasm 반복문 연습2 (0) | 2018.01.20 |
nasm 반복문 연습 (0) | 2018.01.19 |