songining

dreamhack을 톡해 κ³΅λΆ€ν•œ λ‚΄μš©μ„ μ •λ¦¬ν•œ ν¬μŠ€νŠΈμž…λ‹ˆλ‹€.

 

ν”Όμ—°μ‚°μž μ’…λ₯˜ 

- μƒμˆ˜

- λ ˆμ§€μŠ€ν„°

- λ©”λͺ¨λ¦¬ (BYTE(1), WORD(2), DWORD(4), QWORD(8))

 

λ°μ΄ν„°μ˜ 이동 

- MOV a, b => b에 μžˆλŠ” 값을 a에 λŒ€μž… 

- LEA a,b => b의 μ£Όμ†Œκ°’μ„ a에 λŒ€μž… 

 

EX) 

mov eax, dword ptr ss:[ebp-4]  의 κ²½μš°μ—λŠ” [ebp-4]κ°€ ν•˜λ‚˜μ˜ μ£Όμ†Œλ‘œ ν•΄λ‹Ή μ£Όμ†Œμ˜ 값을 eax에 λŒ€μž…ν•œλ‹€. 

lea eax, dword ptr ss:[ebp-4] 의 κ²½μš°μ—λŠ” mov eax, ebp 후에 sub eax,4 λ₯Ό ν•˜λŠ” 것과 κ°™λ‹€. 

 

+) [ ] κΈ°ν˜ΈλŠ” μ£Όμ†Œμ˜ 참쑰값을 μ˜λ―Έν•˜λ©° [ ] μ•ˆμ—μ„œ μ£Όμ†Œμ˜ 사칙 연산이 이루어진닀.  

 

μ‚°μˆ μ—°μ‚°  

- add a,b => a= a+b

- sub a,b => a = a-b

- inc a,b => a = a+1

- dec a,b => a = a-1 

 

논리연산 

- and a,b => a와 b λͺ¨λ‘ λΉ„νŠΈκ°€ 1이면 1 

- or a,b => λ‘˜μ€‘μ— ν•˜λ‚˜λΌλ„ 1이면  1 

- xor a,b => λ‘˜μ΄ 달라야 1 

- not a,b => λΉ„νŠΈ λ°˜μ „ 

 

비ꡐ

- cmp a,b  => 두 ν”Όμ—°μ‚°μžλ₯Ό λΉΌμ„œ λŒ€μ†Œ 비ꡐ (κ²°κ³ΌλŠ” a에 μ €μž₯λ˜μ§€ μ•ŠμœΌλ©° μ„€μ •λœ ν”Œλž˜κ·Έλ₯Ό 보고 κ²°κ³Ό νŒλ‹¨)

- test a,b => 두 ν”Όμ—°μ‚°μž AND μ—°μ‚° ( λ§ˆμ°¬κ°€μ§€λ‘œ κ²°κ³ΌλŠ” a에 μ €μž₯λ˜μ§€ μ•ŠμœΌλ©° μ„€μ •λœ ν”Œλž˜κ·Έλ₯Ό 보고 κ²°κ³Ό νŒλ‹¨) 

 

λΆ„κΈ°

- jmp => ν•΄λ‹Ή μ£Όμ†Œλ‘œ 점프 -> μ „μœΌλ‘œ λŒμ•„κ°ˆ 수 μ—†μŒ μ•„μ˜ˆ 이동. 

- je => jump if equal (직전에 cmp λ“±μœΌλ‘œ λΉ„κ΅ν•œ 두 ν”Όμ—°μ‚°μžμ˜ 값이 κ°™μœΌλ©΄ 점프!)

- jg => 직전에 λΉ„κ΅ν•œ 두 ν”Όμ—°μ‚°μž 쀑 μ „μžκ°€ 더 크면 점프 

 

μŠ€νƒ 

- push val => val을 μŠ€νƒ μ΅œμƒλ‹¨μ— μŒ“μŒ (rspλ₯Ό 8만큼 뺌 = μœ„μ— μŒ“μŒ)

- pop reg => μŠ€νƒ μ΅œμƒλ‹¨μ˜ 값을 κΊΌλ‚΄μ„œ reg에 λŒ€μž… (rsp 8 더함 = μ•„λž˜λ‘œ 내렀감)

 

ν”„λ‘œμ‹œμ €

- νŠΉμ • κΈ°λŠ₯을 μˆ˜ν–‰ν•˜λŠ” μ½”λ“œ 쑰각 

- call : ν”„λ‘œμ‹œμ €λ₯Ό λΆ€λ₯΄λŠ” ν–‰μœ„ 

- return : ν”„λ‘œμ‹œμ €μ—μ„œ λŒμ•„μ˜€λŠ” 것 

( call λ‹€μŒμ˜ λͺ…λ Ήμ–΄ μ£Όμ†Œλ₯Ό μŠ€νƒμ— μ €μž₯ν•˜κ³  ripλŠ” ν•΄λ‹Ή μ£Όμ†Œλ₯Ό κ°€λ¦¬ν‚€κ²Œ ν•΄μ„œ μ›λž˜μ˜ μ‹€ν–‰νλ¦„μœΌλ‘œ λŒμ•„μ˜¨λ‹€. )

( ripλŠ” ν”„λ‘œκ·Έλž¨ μΉ΄μš΄ν„°! )

 

- call addr : ν”„λ‘œμ‹œμ € 호좜 (push return_address / jmp addr )

- leave  : μŠ€νƒ ν”„λ ˆμž„ 정리 (mov esp,ebp / pop ebp )

- ret addr ( pop rip )

 

μ‹œμŠ€ν…œ 콜(System call)μ΄λž€ ?

-> μœ μ €λͺ¨λ“œμ—μ„œ 컀널λͺ¨λ“œμ˜ μ‹œμŠ€ν…œ μ†Œν”„νŠΈμ›¨μ–΄μ—κ²Œ μ–΄λ– ν•œ λ™μž‘μ„ μš”μ²­ν•  λ•Œ μ‚¬μš© ( syscall ) 

ex) cat flag ( 파일 읽기 )

μš”μ²­: rax

인자 μˆœμ„œ: rdi → rsi → rdx → rcx → r8 → r9 → stack

 

[Dream Hack Assembly 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

 

x86 μ–΄μ…ˆλΈ”λ¦¬μ˜ 경우 λ¦¬ν‹€μ—”λ””μ•ˆ λ°©μ‹μœΌλ‘œ λ©”λͺ¨λ¦¬ μ €μž₯ν•˜λŠ”λ“―..!(---> μ£Όμ†Œ 증가방ν–₯)

 

[풀이]

1. BYTE PTR 의 경우 1λ°”μ΄νŠΈλ₯Ό 지정함. dl λ ˆμ§€μŠ€ν„° λ˜ν•œ λ§ˆμ°¬κ°€μ§€λ‘œ ν•˜μœ„ 1λ°”μ΄νŠΈλ₯Ό μ €μž₯ν•˜λŠ” λ ˆμ§€μŠ€ν„° 

rsi+rcx = 0x400000 + 0 의 μ£Όμ†Œ 참쑰값은 0x67 0x55 0x5c 0x53 0x5f 0x5d 0x55 0x10 μ΄λ―€λ‘œ

dl = 0x67μž„ 

2. dl = 0x67 XOR 0x30 = 0x57 

3. 0x400000 자리의 ν•˜μœ„ 1λ°”μ΄νŠΈλ₯Ό dlκ°’μœΌλ‘œ λ„£μ–΄μ€Œ (0x57)

4. rcx =1 둜 증가 

5. rcx와 0x19 비ꡐ 

6. rcxκ°€ 더 크지 μ•ŠμœΌλ―€λ‘œ 1둜 점프

μ•„μŠ€ν‚€μ½”λ“œ 0x57= 'W'

=====================================================================

1.  0x400000+1 의 μ£Όμ†Œ μ°Έμ‘°κ°’ 1λ°”μ΄νŠΈ 0x55λ₯Ό dl에 λŒ€μž…

2. dl = 0x55 XOR 0x30 = 0x65 

.. 

이걸 jg λ₯Ό ν†΅κ³Όν• λ•ŒκΉŒμ§€ λ°˜λ³΅ν•œλ‹€!!

μ •λ‹΅ : Welcome to assembly world!

 

[Dream Hack Assembly Quiz -2 ]

λ‹€μŒ μ–΄μ…ˆλΈ”λ¦¬ μ½”λ“œλ₯Ό μ‹€ν–‰ν–ˆμ„ λ•Œ 좜λ ₯λ˜λŠ” 결과둜 μ˜¬λ°”λ₯Έ 것은?

[Code]
main:
    push rbp // μŠ€νƒμ— rbp λ„£μŒ 
    mov rbp, rsp // rbp에 rsp λŒ€μž… (μŠ€νƒ ν”„λ ˆμž„ 생성) 
    mov esi, 0xf // esi = 0xf(15) 
    mov rdi, 0x400500 // rdi = 0x40050 
    call 0x400497 <write_n> // ν•¨μˆ˜ 호좜 
    mov eax, 0x0 // 리턴값 0 
    pop rbp // μ—ν•„λ‘œκ·Έ
    ret // μ—ν•„λ‘œκ·Έ 
    
write_n:
    push rbp // μŠ€νƒμ— rbp λ„£μŒ 
    mov rbp, rsp // ν•¨μˆ˜ μŠ€νƒ ν”„λ ˆμž„ 생성 
    mov QWORD PTR [rbp-0x8],rdi // QWOD PTR [rbp-0x8] = 0x40050 
    mov DWORD PTR [rbp-0xc],esi // DWORD PTR [rbp-0xc] = 0xf
    xor rdx, rdx // rdx = 0
    mov edx, DWORD PTR [rbp-0xc] // edx = 0xf
    mov rsi,QWORD PTR [rbp-0x8] // rsi = 0x40050 
    mov rdi, 0x1 // rdi = 1
    mov rax, 0x1 // rax = 1
    syscall // syscall 호좜 (rax = 1μ΄λ―€λ‘œ write(1,0x40050,15) 호좜) 
    pop rbp // ν•¨μˆ˜ μ—ν•„λ‘œκ·Έ
    ret // ν•¨μˆ˜ μ—ν•„λ‘œκ·Έ -> 즉 이전 μŠ€νƒ ν”„λ ˆμž„μœΌλ‘œμ˜ 볡귀(ν•¨μˆ˜ 끝) 
    
==================================    
[Memory]
0x400500 | 0x3037207964343372
0x400508 | 0x003f367562336420

μœ„μ™€ 같이 주석을 달아 해석을 ν•΄λ³΄μ•˜λ‹€. 

writeν•¨μˆ˜μ˜ 각 μΈμžλŠ” (좜λ ₯ 슀트림, 좜λ ₯ 버퍼, 좜λ ₯ 길이)λ₯Ό λ‚˜νƒ€λƒ„ 

즉 1은 stdout이고 15길이의 0x400500 λ©”λͺ¨λ¦¬ μ£Όμ†Œμ— λ“€μ–΄μžˆλŠ” 0x3037207964343372λ₯Ό μ•„μŠ€ν‚€μ½”λ“œλ₯Ό μ΄μš©ν•΄ 문자둜 λ³€ν™˜ν•˜λ‹ˆ 정닡이 λ‚˜μ™”λ‹€.!! 

μ •λ‹΅ :  r34dy 70 d3bu6?