Day-02 어셈블리어

i2sec/Reverse Engineering 2014. 4. 28. 19:56

1.데이터 형식

메모리에 접근 했을때 얼만큼 읽어들일지 결정

데이터 타입

사용 용도 

 BYTE

부호 없는 1 byte  

 WORD

부호 없는 2 byte 

DWORD 

부호 없는 4 byte 


2. 어셈블리언어 명령어

플랫폼에 따라서 다르다(IA32 : intel 기반, AT&T : linux 기반)

ADD      [EBP-0x04],0x01

     └> 명령어(OPCODE)   └>피연산자(OPERAND)

1.명령어(OPCODE)

사용할 명령어가 들어가는 부분


2.피연산자(OPERAND)

operand의 갯수는 opcode에 따라 정해져 있다.(','로 구분)

<[EBP-0x04]>

메인 함수도 함수이기 때문에 호출 시 스텍프레임 생성

32bit 레지스터 이기때문에 자료형에 상관없이 4씩 변화

<0x01> : 상수

10진수로 표현가능하나 어셈블리어로 열면 16진수로 표시되어 있기 때문에 혼동이 될수도 있다.


<operand 표시법>

표시 기법 

설명

mem 

메모리 

label 

지정된 레이블 

imm

즉시 값, 상수 

reg 

범용 레지스터 

*레이블은 소스코드 중간에 이름을 지정하는것으로 뛰어넘을때나 반복할때 사용된다.

-뛰어넘기

int main(void)

{

int a = 0;

goto L1;

a = 5;

L1:

printf("%d\n", a);

return 0;

}

이렇게 되면 a=5;는 뛰어넘고 바로 printf로 가게 되어 0이 출력된다.


-반복하기

int main(void)

{

int a = 0;

L1:

a = 5;

printf("%d\n", a);

goto L1;

return 0;

}

이렇게되면 a=5; 와 printf가 계속 반복해서 실행되어 5가 무한번 출력된다.


3.INC

opernad의 값을 1증가시켜주는 명령어(operand 1개)

"++"연산자와 동일

결과 : a = 2

<사용가능한 operand>

INC reg (ex>INC EAX) 

INC mem(ex>INC [EBP-0x04]) 


*인라인 어셈

-상위레벨 언어에서 어셈블리어를 사용할 수 있게 해준다.

-문법상 오류가 발생해도 오류를 잘 표시 안된다

-한줄에는 한 명령어만!

-opcode 대/소문자 구분하지 않는다

-변수 a 대신에 [EBP-0x04]로 표현가능하다(피연산자 부분 참조)

-"_asm"영역 안에서는 기존 c언어의 함수를 사용할수없다(printf등)


4.DEC

operand의 값을 1감소시켜주는 명령어(operand 1개)

"--"연산자와 동일

결과 : a = 0

<사용가능한 operand>

DEC reg (ex>DEC EAX) 

DEC mem(ex>DEC [EBP-0x04]) 


5.ADD

첫번째 operand의 값과 두번째 operand의 값을 더해서 첫번째 operand에 저장(operand 2개)

"+="과 동일

결과 : a = 20, b= 10 (동일한 결과지만 형태가 다른것을 보기위해서 저렇게 표현함)

<사용가능한 operand>

ADD reg, reg(ex>ADD EAX,EBX) 

ADD mem,reg(ex>ADD [EBP-0x04], EAX) 

ADD reg, mem(ex>ADD EBX, [EBP-0x04])

ADD reg, imm(ex>ADD EAX, 0x04) 

ADD mem, imm(ex>ADD [EBP-0x04], 0x01) 

 


6.SUB

첫번째 operand의 값과 두번째 operand의 값을 빼서 첫번째 operand에 저장(operand 2개)

"-="과 동일

결과 : a = -15, b = -2

*주석처리한결과가 다른 이유(주의!!!)

[EBP-0x08]은 b의 주소값이다. 그런데 b는 현재 0으로 초기화되있다. 

이 경우 0에서 -2를 하는 것이아니라 메모리공간의 끝인 256에서 -2가 되기때문에 254가 출력된다.


*그렇다면 a는 왜 그렇게 되지 않을까?

a는 현재 5라고 초기화되어 있고 바로 앞에서 이미 계산이 되고 있기 때문에 이어서 계산이 진행된다.


<사용가능한 operand>

SUB reg, reg(ex>SUB EAX,EBX) 

SUB mem,reg(ex>SUB [EBP-0x04], EAX) 

SUB reg, mem(ex>SUB EBX, [EBP-0x04])

SUB reg, imm(ex>SUB EAX, 0x04) 

SUB mem, imm(ex>SUB [EBP-0x04], 0x01) 

 


7.MOV

첫번째 operand에 두번째 operand의 값을 복사(대입) 한다(operand 2개)

변수 초기화와 동일

결과 : a = 16

<사용가능한 operand>

MOV reg, reg(ex>MOV EAX,EBX) 

MOV mem,reg(ex>MOV [EBP-0x04], EAX) 

MOV reg, mem(ex>MOV EBX, [EBP-0x04])

MOV reg, imm(ex>MOV EAX, 0x04) 

MOV mem, imm(ex>MOV [EBP-0x04], 0x01) 

 


*operand가  mem,mem 은 실행되지 않는다

<해결법> : mem의 값을 reg에 저장 후 사용


레지스터는 저장공간이기 때문에 어떠한 레지스터를 사용하던 상관없다.


<예제 1>

a=16;   b=5;    b++;  c=a+b; d=a-b; 를 어셈블리어로 표현하라.

결과 : a=16, b=6 c=22, d=10


<예제 2>

a=3;      b=5;      c=10;       b++;        c--;       a=b+c;      b=a-c; 를 어셈블리어로 표현하라.

결과 : a=15, b=6, c=9

'i2sec > Reverse Engineering' 카테고리의 다른 글

DAY 1 - 어셈블리언어  (0) 2014.04.25