[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
[Code]
main:
push rbp
mov rbp, rsp
새로운 스택프레임 생성을 위해서 rsp 를 rpb 로 옮김
mov esi, 0xf
esi == 0xf (대입)
mov rdi, 0x400500
rdi == 0x400500 (대입)
call 0x400497 <write_n> // write_n 함수 호출
mov eax, 0x0
pop rbp
ret
일단 write_n 으로 이동한다
write_n:
push rbp
mov rbp, rsp
새로운 스택프레임 생성을 위해서 rsp 를 rpb 로 옮김
mov QWORD PTR [rbp-0x8],rdi
'rbp-0x8' 의 주소에 8byte 만큼 참조하여 rdi 대입
[rbp-0x8] == rdi == 0x400500
mov DWORD PTR [rbp-0xc],esi
'rbp-0xc' 의 주소에 4byte 만큼 참조하여 esi 대입
[rbp-0xc] == esi == 0xf
xor rdx, rdx // rdx 를 xor 연산
mov edx, DWORD PTR [rbp-0xc]
edx 에 'rbp-0xc' 의 주소에 있는 값을 4byte 만큼 참조하여 대입
edx == 0xf
mov rsi,QWORD PTR [rbp-0x8]
rsi == 'rbp-0x8'의 주소에 있는 값(8byte만큼 참조) == 0x400500
mov rdi, 0x1
rdi == 0x1
mov rax, 0x1
rax == 0x1
syscall
rax == 0x1 이기 때문에 write syscall 이 호출된다.
rdi == 0x1, rsi == 0x400500, edx == 0xf 이므로
커널이 write(0x1(stdout: 표준출력), 0x400500(출력할 데이터의 주소값), 0xf(문자열 길이)) 를 수행!
write 의 첫번째 arg0 은 ‘unsigned int fd’
즉,
0x400500 | 0x3037207964343372
-> 0x400500 | 0x30 0x37 0x20 0x79 0x64 0x34 0x33 0x72
-> (reverse)| 0x72 0x33 0x34 0x64 0x79 0x20 0x37 0x30
0x400508 | 0x003f367562336420
-> 0x400508 | 0x00 0x3f 0x36 0x75 0x62 0x33 0x64 0x20
-> (reverse)| 0x20 0x64 0x33 0x62 0x75 0x36 0x3f 0x00
이다. ASCII 코드로 변환하면, 다음과 같다