[Dreamhack] System Hacking Stage 2 - x86 Assembly 1

2022. 8. 27. 17:42·Hacking/System

x64 어셈블리 언어

어셈블리 언어 : 컴퓨터의 기계어와 치환되는 언어

동사에 해당하는 명령어(Operation Code, Opcode)와 목적어에 해당하는 피연산자(Operand)로 구성된다.

명령 코드
데이터 이동(Data Transfer)
mov, lea
산술 연산(Arithmetic)
inc, dec, add, sub
논리 연산(Logical)
and, or, xor, not
비교(Comparison)
cmp, test
분기(Branch)
jmp, je, jg
스택(Stack)
push, pop
프로시져(Procedure)
call, ret, leave
시스템 콜(System call)
syscall

 

피연산자

상수(Immediate Value), 레지스터(Register), 메모리(Memory)가 올 수 있다.

메모리 피연산자 크기 지정자 타입에는 BYTE, WORD, DWORD, QWORD가 올 수 있으며, 각각 1바이트, 2바이트, 4바이트, 8바이트의 크기를 지정한다.

ex) QWORD PTR [0x8048000] : 0x8048000의 데이터를 8바이트만큼 참조

ex) WORD PTR [rax] : rax가 가르키는 주소에서 데이터를 2바이트 만큼 참조

 

데이터 이동

어떤 값을 레지스터나 메모리에 옮기도록 지시

 

mov dst, src : src에 들어있는 값을 dst에 대입
mov rdi, rsi
rsi의 값을 rdi에 대입
mov QWORD PTR[rdi], rsi
rsi의 값을 rdi가 가리키는 주소에 대입
mov QWORD PTR[rdi+8*rcx], rsi
rsi의 값을 rdi+8*rcx가 가리키는 주소에 대입
lea dst, src : src의 유효 주소(Effective Address, EA)를 dst에 저장
lea rsi, [rbx+8*rcx]
rbx+8*rcx 를 rsi에 대입

 

예제) 레지스터, 메모리 및 코드가 다음과 같을 때, 아래에서 적절한 값을 채우시오.

[Register]
rbx = 0x401A40
=================================
[Memory]
0x401a40 | 0x0000000012345678
0x401a48 | 0x0000000000C0FFEE
0x401a50 | 0x00000000DEADBEEF
0x401a58 | 0x00000000CAFEBABE
0x401a60 | 0x0000000087654321
=================================
[Code]
1: mov rax, [rbx+8]
2: lea rax, [rbx+8]

Q1. Code를 1까지 실행했을 때, rax에 저장된 값은 0xC0FFEE 이다.
// rbx(0x401A40)+8 = 0x401a48, 0x401a48의 값을 rax에 대입해야 한다. 답은 0x0000000000C0FFEE

Q2. Code를 2까지 실행했을 때, rax에 들어있는 값은 0x401A48 이다.
// rbx(0x401A40)+8 = 0x401a48, 이 값을 rax에 대입한다. 답은 0x401a48
 

산술연산

덧셈, 뺄셈, 곱셈, 나눗셈 연산을 지시

 

add dst, src : dst에 src의 값을 더함
add eax, 3
eax += 3
add ax, WORD PTR[rdi]
ax += *(WORD *)rdi
sub dst, src: dst에서 src의 값을 뺌
sub eax, 3
eax -= 3
sub ax, WORD PTR[rdi]
ax -= *(WORD *)rdi
inc op: op의 값을 1 증가시킴
inc eax
eax += 1
dec op: op의 값을 1 감소 시킴
dec eax
eax -= 1

 

예제) 레지스터, 메모리 및 코드가 다음과 같을 때, 아래에서 적절한 값을 채우시오.

[Register]
rax = 0x31337
rbx = 0x555555554000
rcx = 0x2
=================================
[Memory]
0x555555554000| 0x0000000000000000
0x555555554008| 0x0000000000000001
0x555555554010| 0x0000000000000003
0x555555554018| 0x0000000000000005
0x555555554020| 0x000000000003133A
==================================
[Code]
1: add rax, [rbx+rcx*8]
2: add rcx, 2
3: sub rax, [rbx+rcx*8]
4: inc rax

Q1. Code를 1까지 실행했을 때, rax에 저장된 값은 0x3133A 이다.
rax의 값은 rbx+0x10(0x555555554010) 에 저장된 0x3 만큼 증가한다. 0x31337 + 0x3 = 0x3133A

Q2. Code를 3까지 실행했을 때, rax에 저장된 값은 0 이다.
rax의 값은 rbx+0x20에 저장된 0x3133A 만큼 감소한다. 0x3133A - 0x3133A = 0

Q3. Code를 4까지 실행했을 때, rax에 저장된 값은 1 이다.
rax의 값은 1 증가한다. 0 + 1 = 1
 

논리연산

and, or, xor, neg 등의 비트 연산을 지시함

 

and dst, src: dst와 src의 비트가 모두 1이면 1, 아니면 0
[Register]
eax = 0xffff0000
ebx = 0xcafebabe
[Code]
and eax, ebx
[Result]
eax = 0xcafe0000
or dst, src: dst와 src의 비트 중 하나라도 1이면 1, 아니면 0
[Register]
eax = 0xffff0000
ebx = 0xcafebabe
[Code]
and eax, ebx
[Result]
eax = 0xcafe0000

 

예제) 레지스터, 메모리 및 코드가 다음과 같을 때, 아래에서 적절한 값을 채우시오.

[Register]
rax = 0xffffffff00000000
rbx = 0x00000000ffffffff
rcx = 0x123456789abcdef0
==================================
[Code]
1: and rax, rcx
2: and rbx, rcx
3: or rax, rbx

Q1. Code를 1까지 실행했을 때, rax에 저장된 값은 0x1234567800000000 이다.
//0xffffffff00000000 = 1111 1111 1111 1111 1111 1111 1111 1111 0000 0000 0000 0000 0000 0000 0000 0000
//0x123456789abcdef0 = 0001 0010 0011 0100 0101 0110 0111 1000 1001 1010 1011 1100 1101 1110 1111 0000

Q2. Code를 2까지 실행했을 때, rbx에 저장된 값은 0x000000009abcdef0 이다.
//0x00000000ffffffff = 0000 0000 0000 0000 0000 0000 0000 0000 1111 1111 1111 1111 1111 1111 1111 1111
//0x123456789abcdef0 = 0001 0010 0011 0100 0101 0110 0111 1000 1001 1010 1011 1100 1101 1110 1111 0000

Q3. Code를 3까지 실행했을 때, rax에 저장된 값은 0x123456789abcdef0 이다.
//0x1234567800000000 = 0001 0010 0011 0100 0101 0110 0111 1000 0000 0000 0000 0000 0000 0000 0000 0000
//0x000000009abcdef0 = 0000 0000 0000 0000 0000 0000 0000 0000 1001 1010 1011 1100 1101 1110 1111 0000

 

xor dst, src: dst와 src의 비트가 서로 다르면 1, 같으면 0
[Register]
eax = 0xffffffff
ebx = 0xcafebabe
[Code]
xor eax, ebx
[Result]
eax = 0x35014541
not op: op의 비트 전부 반전
[Register]
eax = 0xffffffff
[Code]
not eax
[Result]
eax = 0x00000000
 

예제) 레지스터, 메모리 및 코드가 다음과 같을 때, 아래에서 적절한 값을 채우시오.

[Register]
rax = 0x35014541
rbx = 0xdeadbeef
==================================
[Code]
1: xor rax, rbx
2: xor rax, rbx
3: not eax

Q1. Code를 1까지 실행했을 때, rax에 저장되는 값은 0xebacfbae 이다.
//0x35014541 = 0011 0101 0000 0001 0100 0101 0100 0001
//0xdeadbeef = 1101 1110 1010 1101 1011 1110 1110 1111
//0xebacfbae = 1110 1011 1010 1100 1111 1010 1010 1110

Q2. Code를 2까지 실행했을 때, rax에 저장되는 값은 0x35014541 이다.
//xor연산을 동일한 값으로 두 번 실행할 경우, 원래 값으로 돌아간다.

Q3. Code를 3까지 실행했을 때, rax에 저장되는 값은 0xcafebabe 이다.
//0x35014541 = 0011 0101 0000 0001 0100 0101 0100 0001
//0xcafebabe = 1100 1010 1111 1110 1011 1010 1011 1110

 

 

비교

두 피연산자의 값을 비교하고, 플래그를 설정

 

cmp op1, op2: op1과 op2를 비교
[Code]
1: mov rax, 0xA
2: mov rbx, 0xA
3: cmp rax, rbx ; ZF=1
test op1, op2​: op1과 op2를 비교
[Code]
1: xor rax, rax
2: test rax, rax ; ZF=1

 

분기

rip를 이동시켜 실행 흐름을 바꿉니다.

 

jmp addr: addr로 rip를 이동시킵니다.​
[Code]
1: xor rax, rax
2: jmp 1 ; jump to 1
je addr: 직전에 비교한 두 피연산자가 같으면 점프 (jump if equal)
[Code]
1: mov rax, 0xcafebabe
2: mov rbx, 0xcafebabe
3: cmp rax, rbx ; rax == rbx
4: je 1 ; jump to 1
jg addr: 직전에 비교한 두 연산자 중 전자가 더 크면 점프 (jump if greater)
[Code]
1: mov rax, 0x31337
2: mov rbx, 0x13337
3: cmp rax, rbx ; rax > rbx
4: jg 1  ; jump to 1
 
 

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

​

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

[rsi+rcx]의 값을 1바이트만큼 가져와서 dl에 대입하면 된다.

0x400000 + 0 = 0x400000, [0x400000] = 0x67

dl = 0x67

2: xor dl, 0x30

0x67 = 0110 0111

0x30 = 0011 0000

0x57 = 0101 0111 = dl

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

dl값을 [rsi+rcx]에 대입하면 된다.

0x400000 + 0 = 0x400000

[0x400000] = 0x57

4: inc rcx

rcx +=1

rcx = 0x1

5: cmp rcx, 0x19

rcx(0x01)과 0x19를 비교한 뒤 플래그를 설정한다.

0x01<0x19이므로 SF(Sign Flag)를 설정한다.

6: jg end

직전에 비교한 두 연산자 중 전자가 더 크면 점프하는데, 이 경우에는 후자가 더 크기 때문에 점프하지 않는다.

7: jmp 1

1로 돌아간다.

​

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

1번 했을 때의 메모리이다.

rcx>0x19가 될 때까지 반복되므로 위에서 1번 한 것을 포함해 총 20번 실행된다.

​

최종적으로 저장된 메모리를 살펴보면

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

이렇게 된다.

'Hacking/System' 카테고리의 다른 글
  • [Dreamhack] System Hacking Stage 3 - Tool: gdb
  • [Dreamhack] System Hacking Stage 2 - x86 Assembly 2
  • [Dreamhack] System Hacking Stage 2 - Linux Memory Layout
  • [Dreamhack] System Hacking Stage 2 - Computer Architecture
단축키실행해보세요
단축키실행해보세요
공대생
  • 단축키실행해보세요
    Ctrl + Shift + ESC
    단축키실행해보세요
  • 전체
    오늘
    어제
    • 분류 전체보기 (168)
      • 외부 활동 (4)
      • BOJ (36)
        • Python (24)
        • C++ (12)
        • Java (0)
      • Hacking (91)
        • Crypto (4)
        • Forensics (2)
        • Mobile Hacking (5)
        • Reversing (21)
        • System (21)
        • Web Hacking (38)
      • Cloud (13)
        • Serverless (1)
        • AWS (7)
      • ML (3)
      • Data Structure (16)
      • Git (0)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    loctus
    자료구조
    Reflected
    cloud
    Reversing
    XML
    XPath
    SAA
    bWAPP
    basicrce3
    datastructure
    Dreamhack
    부하테스트
    htmlinjection
    백준
    AI
    AWS
    pwnable
    Systemhacking
    backjoon
    beebox
    S3
    python
    EC2
    유석종교수님
    System
    acc
    SISS
    CodeEngn
    c
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
단축키실행해보세요
[Dreamhack] System Hacking Stage 2 - x86 Assembly 1
상단으로

티스토리툴바