[System Hacking][DreamHack][Stage2] Quiz: x86 Assembly2

marceline·2024년 3월 26일
0

[System Hacking]

목록 보기
15/17

Q1. 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

먼저 code 1을 실행하기위해서 dl 레지스터에 대해 알아봤다.

위 사진에 의해서 dl == 0x00 이다

1: mov dl, BYTE PTR[rsi+rcx]

==> dl + BYTE PTR[0x400000 + 0]
==> dl + [0x4]
==> 0x0 + 0x67
==> 0x67

[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 2 를 실행한 결과는 다음과 같다.

2: xor dl, 0x30

==> 0x67 XOR 0x30
==> 0x57
dl = 0x57

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 3

3: mov BYTE PTR[rsi+rcx], dl

==> BYTE PTR[0x4] = 0x57


0x400000 | 0x57 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 0x70

code 4

4: inc rcx

rcx = 1

code 5

5: cmp rcx, 0x19

==> 0x1 CMP 0x19
ZF == 0

code 6
jg: Jump If A greater than B

6: jg end
==> if (0x10 > 0x19) true: end
==> if (0x10 > 0x19) false : code 7

code 7 에 도착하면 code 1 로 점프하여 처음부터 다시 해당 과정을 반복한다.

아래에는 해당 과정들을 회차별로 수행한 결과이다.

1st

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]
// dl 에 [rsi+rcx] 대입
// dl 에 [0x400000] 대입
// dl = 0x67
2: xor dl, 0x30
// xor 0x67 0x30
// dl = 0x57
3: mov BYTE PTR[rsi+rcx], dl
// 0x400000 | 0x57
4: inc rcx
// rcx = 1
5: cmp rcx, 0x19
// 0x01, 0x19 비교 
// 0x01 != 0x19 이므로 ZF = 0
6: jg end
// 0x10 > 0x19 일시 end 로 jump 
// 그러나 False 이므로 Code 7 로 이동
7: jmp 1
// Code 1 로 점프

2nd

rcx = 1
rdx = 0
rsi = 0x400000
=======================
[Memory]
0x400000 | 0x57 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]
// dl 에 [0x400001] 대입
// dl = 0x55
2: xor dl, 0x30
// 0x55와 0x30 xor 연산
// dl = 0x65
3: mov BYTE PTR[rsi+rcx], dl
// 0x400001 | 0x65
4: inc rcx
// rcx = 2
5: cmp rcx, 0x19
// 0x2, 0x19 비교, 다르므로 ZF = 0
6: jg end
// 0x2 < 0x19 이므로 프로그램 종료 안함
// Code 7 로 이동
7: jmp 1
// Code 1로 이동

3rd

rcx = 0x2
rdx = 0
rsi = 0x400000
=======================
[Memory]
0x400000 | 0x57 0x65 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]
// dl 에 [rsi+rcx] 대입
// dl 에 [0x400002] 대입
// dl=0x5c
2: xor dl, 0x30
// 0x5c 와 0x30 xor 연산
// dl = 0x6c
3: mov BYTE PTR[rsi+rcx], dl
// 0x400002 | 0x6c
4: inc rcx
// rcx = 0x3
5: cmp rcx, 0x19
6: jg end
7: jmp 1

.
.
.

rcx = 0x19 일때까지 Code 1~ 7 반복 실행

rcx = 0x19
rdx = 0
rsi = 0x400000
=======================
[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 0x11 0x00 0x00 0x00 0x00 0x00 0x00
=======================
[code]
1: mov dl, BYTE PTR[rsi+rcx]
// dl = [rsi+rcx]
// dl = [0x400019]
// dl = 0x11
2: xor dl, 0x30
// 0x11, 0x30의 xor 연산
// dl = 0x21
3: mov BYTE PTR[rsi+rcx], dl
// 0x400019 | 0x21
4: inc rcx
// rcx = 0x1a
5: cmp rcx, 0x19
// 0x1a > 0x19 이다
6: jg end
// 앞서 실행한 비교문에서 전자가 더 크기 때문에 프로그램 종료 !

result

rcx = 0x1a
rdx = 0
rsi = 0x400000
=======================
[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
=======================

0x400000 ~ 0x400019 까지의 데이터를 ASCII 로 변경하면

이용한 사이트

xor 연산
16진수 ASCII 텍스트 변환기

0개의 댓글