본문 바로가기

정보보안/리버싱

reverse_assembly 기본명령어 IDIV

22_어셈블리(IDIV)

 - 분석 환경 : WindowsXP(32bit)
 - 분석 도구 : OllyDbg, VS2008


1. IDIV

 - 형식 : IDIV [Operand 1] [Operand 2]
 - 내용 : [Operand 1]과 [Operand 2]를 나누기하여 EAX에 값을 저장한다.
 - 예제 : IDIV EAX, EBX
 - 해석 : EAX = EAX / EBX

 1) VS 2008을 이용하여 'idiv.exe' 파일을 제작한다.

 - 파일 -> 새로 만들기 -> 프로젝트 -> 빈 프로젝트 -> 위치(04_테스트) & 이름(idiv.) -> 확인
 - '소스 파일' 우클릭 -> 추가 -> 새 항목 -> 'C++ 파일(.cpp)' 선택 -> 이름(idiv.) -> 추가

#include <stdio.h>

int main()
{
int num1 = 6;
int num2 = 2;
int num3;

num3 = num1 / num2;
return 0;
}

 - 파일 -> 모두 저장 -> 닫기


 2) 'cl' 명령어를 이용한 최적화 컴파일 실시





3. 올리디버거를 이용한 'idiv.exe' 분석


 - 메모리 주소, 레지스터 저장 값, 스택 내용, 메모리 덤프 내용 확인

 

1) Main함수 찾기(F8)

 

Main함수를 call하기 직전의 모습이다. Main함수의 주소는 401000임을 확인할 수 있다.

 2) Main함수 진입(F7) – 함수 프롤로그, 함수본체, 함수 에필로그 확인

<  함수 프롤로그  >

00401000  /$  55            PUSH EBP
00401001  |.  8BEC          MOV EBP,ESP

______________________________________________________________________________

 

< 함수 본체 >

 

00401003  |.  83EC 0C       SUB ESP,0C

-      SUB를 통해 다음과 같이  ESP값을 4byte * 3 만큼 위로 올려 int형 지역변수 num1, num2, num3를 위한 공간을 스택에 할당시켰다.

00401006  |.  C745 F4 06000>MOV DWORD PTR SS:[EBP-C],6

0040100D  |.  C745 F8 02000>MOV DWORD PTR SS:[EBP-8],2

 

-      num1의 공간 EBP-C, num2의 공간 EBP-8 에 각각 6과 2를 대입하여 값을 지정해주었다.

코드 상의  int num1 = 6; int num2 = 2;  의 과정이라 볼 수 있다 .

00401014  |.  8B45 F4       MOV EAX,DWORD PTR SS:[EBP-C]

-      다음과 같이 6을 EAX에 복사한다.

00401017  |.  99            CDQ

 

 //참고

     CDQ :   IDIV가 진행하기 이전에 나타나는 부호 비트 확장 코드

                    EAX의 부호비트를 EDX 레지스터까지 확장한다. ( DWORD --> QWORD )

              

                  - >  나눗셈을 진행하고 부호비트를 넣어줄 공간을 확보하는데 기존 공간의 2배를 할당한다.

                  -  CDQ는 eax에 저장될 데이터를 edx까지 확장하겠다는 뜻인데 EAX는 그대로 유지되고 EDX는 EAX에 확장당한 꼴이라서 값이 00000000으로 초기화된다 

 

EAX의 값은 변하지 않았는데 EDX가 0으로 초기화된것을 확인할 수 있음

CBW     BYTE     -> WORD

CWD     WORD   -> DWORD

CDQ     DWORD -> QWORD 8byte 

 

00401018  |.  F77D F8       IDIV DWORD PTR SS:[EBP-8]

 

-      그 후, num1 / num2의 값을 수행하기 위해 EAX / [EBP-8]를 곱한 값인 3을 다시 EAX에 저장한다.

EAX에는 num1 / num2의 값이 들어있게 된다.

 

num1/num2 값 저장

 0040101B  |.  8945 FC       MOV DWORD PTR SS:[EBP-4],EAX

-      다음은 num3에 num1 / num2 의 값을 초기화해주는 과정이다.

직전에 저장해뒀던 EAX의 값을 num3 에 해당하는 스택 EBP-4에 복사하여 값을 지정해주어 num3 = num1 / num2; 를 수행하였다. 따라서 3이 들어가있는 모습을 확인할 수 있다.

 

이후, XOR을 통해 EAX를 0으로 초기화 시켜준 후, 함수에필로그가 수행되며 main함수는 종료된다.

0040101E  |.  33C0          XOR EAX,EAX

_____________________________________________________________________________________________

 

<  함수에필로그  >

 

00401020  |.  8BE5          MOV ESP,EBP

00401022  |.  5D            POP EBP

____________________________________          main함수 소멸 

00401023  \.  C3            RETN  ---> main함수 다음주소로 리턴