System Hacking
STAGE 2 - Background: Computer Science (3/3)
x86 Assembly (1), (2) 퀴즈 풀이
Quiz 1.
end로 점프하면 프로그램이 종료된다고 가정하자. 프로그램이 종료됐을 때, 0x400000 부터 0x400019까지의 데이터를 대응되는 아스키 문자로 변환하면 어느 문자열이 나오는가?
[Register]
rcx = 0
rdx = 0
rsi = 0x400000
=======================
[Memory]
0x400000 | 0x67 0x55 0x5c 0x53 0x5f 0x5d 0x55 0x10
0x400008 | 0x44 0x5f 0x10 0x51 0x43 0x43 0x55 0x5d
0x400010 | 0x52 0x5c 0x49 0x10 0x47 0x5f 0x42 0x5c
0x400018 | 0x54 0x11 0x00 0x00 0x00 0x00 0x00 0x00
=======================
[code]
1: mov dl, BYTE PTR[rsi+rcx]
2: xor dl, 0x30
3: mov BYTE PTR[rsi+rcx], dl
4: inc rcx
5: cmp rcx, 0x19
6: jg end
7: jmp 1
답: Welcome to assembly world!
풀이:
mov dl, BYTE PTR[rsi+rcx]
dl에 BYTE PTR[rsi+rcx]가 가리키는 값을 대입해라 라는 뜻이다.
rsi+rcx는 0x400000+0=0x400000이다.
0x400000의 메모리에서 BYTE, 즉 1바이트의 값을 옮겨라 라는 뜻이 되므로
dl에는 0x67이 들어간다.
xor dl, 0x30
dl과 0x30의 값을 xor 연산을 해라 라는 뜻이다.
검색을 통해 0x67과 0x30의 xor 연산 값을 알아보니 0x57이 나왔다.
그럼 dl에는 0x57이 저장된다.
mov BYTE PTR[rsi+rcx], dl
BYTE PTR[rsi+rcx]에 dl의 값을 대입해라 라는 뜻이다.
0x400000의 메모리 첫 번째 0x67 부분에 dl 값인 0x57이 저장된다.
inc rcx
산술 연산 명령어인 inc는 rcx의 값을 +1 시키는 연산자이다.
따라서 rcx이 값은 0에서 1이 된다.
cmp rcx, 0x19
비교 명령어 cmp는 rcx와 0x19의 값을 빼서 두 피연산자의 크기를 비교하는 연산자이다.
rcx의 십진수로 1이고, 0x19는 십진수로 32이므로 같지 않다.
jg end
분기 명령어 jg는 직전에 비교한 두 연산자 중 전자가 더 크면 end로 점프하라는 뜻이다.
이 문제에서는 end로 점프하면 프로그램이 종료된다고 한다.
rcx < 0x19 이므로 그냥 넘어간다.
jmp 1
1로 rip을 이동시킨다. 즉, 1부터 코드를 다시 실행한다.
위 과정을 end로 점프할 때까지 반복하면 메모리의 결과는
[Memory]
0x400000 | 0x57 0x65 0x6c 0x63 0x6f 0x6d 0x65 0x20
0x400008 | 0x74 0x6f 0x20 0x61 0x73 0x73 0x65 0x6d
0x400010 | 0x62 0x6c 0x79 0x20 0x77 0x6f 0x72 0x6c
0x400018 | 0x64 0x21 0x00 0x00 0x00 0x00 0x00 0x00
위와 같이 된다.
따라서 이 16진수를 아스키코드로 변환하면 "Welcome to assembly world!" 라는 문장이 나온다.
Quiz 2.
다음 어셈블리 코드를 실행했을 때 출력되는 결과로 올바른 것은?
[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
A 4r3 y0u r34dy 70 d3bu6?
B are you ready to debug?
C r34dy 70 d3bu6? ✔️
D ready to debug?
풀이:
[Code]
main:
push rbp // rbp를 스택 최상단에 쌓음
mov rbp, rsp // rsp의 값을 rbp에 대입, rsp = rbp
mov esi, 0xf // 0xf = 15의 값을 esi에 대입, esi = 15
mov rdi, 0x400500 // 0x400500의 값을 rdi에 대입, rdi = 0x400500
call 0x400497 <write_n> // write_n 함수 실행
// write_n 함수
write_n:
push rbp // 스택 최상단에 rbp를 쌓는다
mov rbp, rsp // rbp = rsp
mov QWORD PTR [rbp-0x8],rdi // QWORD PTR [rbp-0x8] = rdi = 0x400500
mov DWORD PTR [rbp-0xc],esi // DWORD PTR [rbp-0xc] = esi = 0xf = 15
xor rdx, rdx // rdx = 0x0
mov edx, DWORD PTR [rbp-0xc] // edx = DWORD PTR [rbp-0xc] = 0xf = 15
mov rsi,QWORD PTR [rbp-0x8] // rsi = QWORD PTR [rbp-0x8] = 0x400500
mov rdi, 0x1 // rdi = 0x1
mov rax, 0x1 // rax = 0x1
syscall // 커널에게 시스템 콜 요청
pop rbp // 스택 최상단의 값을 rbp에 넣음
ret // 호출자의 실행 흐름으로 돌아간다
// main 함수
mov eax, 0x0 // 0x0의 값을 eax에 대입, eax = 0x0
pop rbp // 스택 최상단의 값을 꺼내서 rbp에 대입
ret // 호출자의 실행 흐름으로 돌아간다
0x400500 | 0x30 37 20 79 64 34 33 72
0 7 SP y d 4 3 r = r34dy 70
0x400508 | 0x00 3f 36 75 62 33 64 20
0 ? 6 u b 3 d SP = d3bu6?
따라서 메모리 값을 두 자리씩 끊어서 아스키코드 값으로 변환해 주면 "r34dy 70 d3bu6?"라는 문자열이 나온다.
'동아리 활동' 카테고리의 다른 글
[Python] 동아리 스터디 문제 & 코드 모음 (0) | 2023.05.18 |
---|---|
System Hacking : x86 어셈블리 (2) (0) | 2023.05.01 |
System Hacking : x86 어셈블리 (1) (0) | 2023.05.01 |
System Hacking : 컴퓨터 아키텍처 Quiz 풀이 (0) | 2023.04.29 |
System Hacking : 컴퓨터 아키텍처 (0) | 2023.04.28 |