어셈블리 코드 실행시 출력되는 결과를 고르는 문제이다.
A | 4r3 y0u r34dy 70 d3bu6? |
B | are you ready to debug? |
C | ready to debug? |
D | r34dy 70 d3bu6? |
[code]를 보면
mov rdi, 0x400500
rdi 레지스터에 0x400500의 주소를 대입하라
call 0x400497 <write_n>
0x400497주소의 <write_n> 함수를 호출한다
<write_n>의 함수를 살펴보면
mov QWORD PTR[rbp-0x8], rdi
rdi 레지스터의 주소(0x400500)를 [rbp-0x8]에 대입한다
mov DWORD PTR[rbp-0xc], esi
데이터 조작 및 복사시 소스 데이터 주소가 저장되는 esi 레지스터의 주소(0xf)를 [rbp-0xC]에 대입한다
xor rdx, rdx
xor 연산으로 rdx를 0으로 만든다
mov edx, DWORD PTR [rbp-0xc]
edx 레지스터에 [rbp-0xc] 주소를 대입한다
mov rsi, QWORD PTR [rbp-0x8]
rsi 레지스터에 [rbp-0x8] 주소를 대입한다
mov rdi, 0x1
rdi 레지스터에 1을 대입한다
mov rax,0x1
rax 레지스터에 1을 대입한다
syscall
시스템 콜을 통해 출력하는듯하다
그 외의 어셈블리어는 프로그램을 종료되도록 하는 코드이다.
mov QWORD PTR[rbp-0x8], rdi
mov DWORD PTR[rbp-0xc], esi
코드를 표로 보면 아래와 같다.
rbx | |
rbp-0x8 | 0x400500 |
rbp-0xc | 0xf |
[rbp-0x8] 위치에 0x400508이 [rbp-0xc] 위치에 0xf가 있는 것이다.
또한, x86 아키텍처인 리틀엔디안 방식으로 저장되기에 아래의 표와 같다.
0x400500 | 0x72 | 0x33 | 0x34 | 0x64 | 0x79 | 0x20 | 0x37 | 0x30 |
0x400508 | 0x20 | 0x64 | 0x33 | 0x62 | 0x75 | 0x36 | 0x3f | 0x00 |
syscall 동작 방식을 찾아보면 rax, rdi, rsi, rdx, r10,r8,r9 순으로 인자를 받는 것을 알 수 있다.
xor 연산 후 edx 레지스터에 0xf를, rsi에 0x400500을 대입하고 rax,rdi에 1을 대입해 syscall을 불러 인자로 쓰이고 있다.
syscall 인자는 rax가 1이므로 write를 rdi에 1을 넣어 파일 디스크립터 1인 표준출력, 출력할 주소인 rsi(0x400500)을, 출력 사이즈인 rdx(0xf, 10진수 15)를 가지고 있다.
그렇기에 리틀엔디안 방식으로 0x400500부터 0x400508의 0x72~x3f까지를 출력하게 된다.
그 문자열을 아스키 코드로 바꾸면 정답은 이와 같다.
( D ) r34dy 70 d3bu6?
'리버싱' 카테고리의 다른 글
dreamhack Quiz:x86 Assembly 1 (0) | 2022.08.24 |
---|