본문 바로가기

미분류

170316 어셈블리 언어

1. 어셈블리 명령어

연산기능

산술 연산 

ADD(+) , SUB(-) , MUL(*) , DIV(/), CMP(비교) 

논리 연산 

NOT(!), AND(&), OR(|), XOR(^), SHIFT(>>, <<) 

자료전달 기능  

MOV, PUSH, POP 

제어기능 

JMP,  CALL, RET, INT



2. 명령어 형식

  1. opcode (0-주소 형식)
  2. - 스택 이용

    - 예) ADD

  3. opcode operand (1-주소 형식)
  4. - 누산기 이용

    - ADD eax

  5. opcode operand1 operand2
  6. - 2주소 형식

    - opcode로 operand1과 operand2를 연산한 결과가 operand1에 저장된다.



3. 어셈블리 코드 분석해보기


<+0>:        push   ebp
<+1>:        mov    ebp,esp
<+6>:        sub    esp,0x20
<+9>:        mov    DWORD PTR [esp+0x1c],0x1
<+17>:        mov    DWORD PTR [esp+0x18],0x1
<+25>:        mov    DWORD PTR [esp+0x10],0x0
<+33>:        mov    eax,0x8048520
<+38>:        mov    edx,DWORD PTR [esp+0x1c]
<+42>:        mov    DWORD PTR [esp+0x4],edx
<+46>:        mov    DWORD PTR [esp],eax
<+49>:        call   0x80482f4 <printf@plt>
<+54>:        mov    eax,0x8048520
<+59>:        mov    edx,DWORD PTR [esp+0x18]
<+63>:        mov    DWORD PTR [esp+0x4],edx
<+67>:        mov    DWORD PTR [esp],eax
<+70>:        call   0x80482f4 <printf@plt>
<+75>:        mov    DWORD PTR [esp+0x14],0x0
<+83>:        jmp    0x8048452 <main+142>
<+85>:        mov    eax,DWORD PTR [esp+0x18]
<+89>:        mov    edx,DWORD PTR [esp+0x1c]
<+93>:        lea    eax,[edx+eax*1]
<+96>:        mov    DWORD PTR [esp+0x10],eax
<+100>:        mov    eax,0x8048520
<+105>:        mov    edx,DWORD PTR [esp+0x10]
<+109>:        mov    DWORD PTR [esp+0x4],edx
<+113>:        mov    DWORD PTR [esp],eax
<+116>:        call   0x80482f4 <printf@plt>
<+121>:        mov    eax,DWORD PTR [esp+0x18]
<+125>:        mov    DWORD PTR [esp+0x1c],eax
<+129>:        mov    eax,DWORD PTR [esp+0x10]
<+133>:        mov    DWORD PTR [esp+0x18],eax
<+137>:        add    DWORD PTR [esp+0x14],0x1
<+142>:        cmp    DWORD PTR [esp+0x14],0x9
<+147>:        jle    0x8048419 <main+85>
<+149>:        mov    eax,0x0
<+154>:        leave 
<+155>:        ret    

   

   push ebp

   mov ebp, esp  // 함수의 시작 프롤로그 부분


   sub     esp, 0x20  

   mov    DWORD PTR [esp+0x1c], 0x1
   mov    DWORD PTR [esp+0x18], 0x1
   mov    DWORD PTR [esp+0x10], 0x0 //변수 세개의 값을 넣고 


   
mov    eax,0x8048520 
   mov    edx,DWORD PTR [esp+0x1c]
   mov    DWORD PTR [esp+0x4],edx
   mov    DWORD PTR [esp],eax
   call     0x80482f4 <printf@plt> //  esp+0x1c부분 printf 함


  mov    eax,0x8048520

  mov    edx,DWORD PTR [esp+0x18]
  mov    DWORD PTR [esp+0x4],edx
  mov    DWORD PTR [esp],eax
  call     0x80482f4 <printf@plt> // 여기는 esp+0x18 부분 printf


  mov    DWORD PTR [esp+0x14],0x0 

  jmp    0x8048452 <main+142> // esp+0x14에 0을 넣고 main+142 부분으로 점프


  cmp    DWORD PTR [esp+0x14],0x9

  jle      0x8048419 <main+85> // cmp 의 A 부분이 B보다 작거나 같으면 jmp.

                                                 esp+0x14 = 0 이므로 점프


  mov    eax,DWORD PTR [esp+0x18]

  mov    edx,DWORD PTR [esp+0x1c]
  lea    eax,[edx+eax*1]  

  mov    DWORD PTR [esp+0x10],eax // [esp+0x10] = [esp+0x18] + [esp+0x1c] * 1


  mov    eax,0x8048520
  mov    edx,DWORD PTR [esp+0x10]
  mov    DWORD PTR [esp+0x4],edx
  mov    DWORD PTR [esp],eax
  call   0x80482f4 <printf@plt> // esp+0x10 을 printf


  mov    eax,DWORD PTR [esp+0x18]

  mov    DWORD PTR [esp+0x1c],eax // esp+0x1c = esp+0x18
  mov    eax,DWORD PTR [esp+0x10]
  mov    DWORD PTR [esp+0x18],eax // esp+0x18 = esp+0x10
  add    DWORD PTR [esp+0x14],0x1 //  [esp+0x14] + 1 (반복문의 증가값)


   cmp    DWORD PTR [esp+0x14],0x9 

   jle    0x8048419 <main+85> // 반복



위의 어셈블리 코드를 리버싱해서 만든 C 코드>



결과>