[Code]
main:
push rbp
mov rbp, rsp
mov esi, 0xf
mov rdi, 0x400500
call 0x400497 <write_n>
mov eax, 0x0
pop rbp
ret
write_n:
push rbp
mov rbp, rsp
mov QWORD PTR [rbp-0x8],rdi
mov DWORD PTR [rbp-0xc],esi
xor rdx, rdx
mov edx, DWORD PTR [rbp-0xc]
mov rsi,QWORD PTR [rbp-0x8]
mov rdi, 0x1
mov rax, 0x1
syscall
pop rbp
ret
==================================
[Memory]
0x400500 | 0x3037207964343372
0x400508 | 0x003f367562336420
main함수부터 시작
push rbp, mov rbp, rsp: 기존 스택프레임 저장 (main함수를 실행하는 함수)
mov esi, 0xf: esi = 0xf
mov rdi, 0x400500: rdi = 0x400500
call 0x400497 <write_n>: write n 함수 호출
write n 함수 실행
push rbp, mov rbp, rsp: 기존 스택프레임 저장(main 함수)
mov QWORD PTR [rbp-0x8], rdi: 0x400500을 rbp-0x8이 가리키는 곳에 8바이트만큼 대입
mov DWORD PTR [rbp-0xc], esi: 0xf를 rbp-0xc가 가리키는 곳에 4바이트만큼 대입
xor rdx,rdx: rdx=0
mov edx, DWORD PTR [rbp-0xc]: rbp-0xc가 가리키는 데이터를 edx에 대입 (edx는 rdx의 하위 32비트이므로 rdx=edx=0xf)
mov rsi, QWORD PTR [rbp-0x8]: rbp-0x8이 가리키는 데이터를 rsi에 대입 (rsi=0x400500)
mov rdi, 0x1: rdi = 0x1
mov rax, 0x1: rax = 0x1
syscall: 시스템 콜 호출
rax=0x1 → write
rdi=0x1 → stdout
rsi=0x400500 → 문자열 위치가 0x400500
rdx=0xf → 문자열 길이가 0xf
pop rbp: 원래의 스택프레임(main 함수)으로 복귀
ret: 원래의 흐름으로 복귀
main 함수로 복귀
mov eax, 0x0: eax=0x0
pop rbp: 원래의 스택프레임(main 함수를 실행하는 함수)으로 복귀
ret: 원래의 흐름으로 복귀
따라서 출력되는 결과는
72 33 34 64 79 20 37 30 20 64 33 62 75 36 3f 00
아스키코드로 변환하면
r34dy 70 d3bu6?
원래의 순서가 아닌 역순인 이유
: x86-64 아키텍처 에서는 리틀 엔디안 방식이므로 높은 주소에서 낮은 주소로 바이트를 배열한다.
- 엔디안 : 단어를 형성하는 2진 바이트에서 저장하는 바이트의 순서를 나타내는 방법.
- 리틀 엔디안은 최하위 비트(LSB)부터 부호화되어 저장된다.