본문 바로가기
Study/Reversing

어셈블리 명령어

by Melpin 2015. 5. 15.

어셈블리 명령어

INC : 피연산자에 1을 더한다

결과에 따라 ZF, OF가 세트될 수 있다.

 

DEC : 피연산자에 1을 뺀다

결과에 따라 ZF, OF, CF가 세트될 수 있다.

 

ADD : Destination 에 Source 값을 더해서 Destination에 저장하는 명령이다

ex) ADD destination , source

결과에 따라 ZF, OF, CF가 세트될 수 있다.

 

SUB : Destination 에 Source의 값을 빼서 Destination에 저장하는 명령이다.

ex) SUB destination, source

결과에 따라 ZF, OF, CF가 세트될 수 있다.

 

MUL : 부호 없는 al, ax eax의 값을 피연사자와 곱한다.

피연산자가 8비트이면 al과 곱해서 ax에 저장되고 16비트이면 ax와 곱하고 dx:ax에 저장된다.

결과에 따라 OF, ZF가 세트될 수 있다.

 

IMUL : 부호 있는 al, ax, eax의 값을 피연산자와 곱한다.

ex) IMUL r/m

단일 피연산자일 경우 피연산자를 al, ax eax에 곱한다.

ex) IMUL destination, value

value를 al, ax, eax와 곱해서 destination에 저장한다.

ec) IMUL destination, value, value

value끼리 곱해서 destination에 저장한다.

연산결과가 destination 레지스터의 크기보다 크다면 OF, CF가 세트된다.

 

DIV : 8, 16, 32비트 부호없는 정수의 나눗셈을 수행한다.

결과에 따라 CF, OF, ZF가 세트될 수 있다.

 

MOV : Source에서 Destination으로 데이터를 복사한다.

ex) MOV Destination, Source

ESI혹은 SI레지스터에 의해 지정된 메모리 주소의 내용을 EDI, DI레지스터에 의해 지정되는 메모리 주소로 복사한다.

이때 피연산자 타입은 레지스터와 메모리 모두 해당된다.

MOV EAX, [EBP]

로 중괄호 표현이 있는경우 EBP가 가리키는 주소에서 값을 가져와 EAX에 대입한다.

MOV EAX, [EBP + 10]

이면 EBP의 주소에서 10만큼 더한 주소지의 값을 가져와 EAX에 대입한다.

 

MOVS : Source에서 Destination으로 데이터를 복사한다.

ex) MOV Destination, Source

 

ESI혹은 SI레지스터에 의해 지정된 메모리 주소의 내용을 EDI, DI레지스터에 의해 지정되는 메모리 주소로 복사한다.

이때 피연산자 타입은 레지스터만 가능하다.

작은데이터 단위를 크게 확장한다.

MOVSB : BYTE단위로 복사한다.

MOVSW : WORD단위로 복사한다.

MOVSD : DWORD단위로 복사한다.

방향플래그(DF)가 1로 세트되어 있으면 ESI와 EDI는 복사시에 감소하게된다.

DF가 0으로 세트되어있으면 ESI와 EDI는 복사시에 증가하게 된다.

 

MOVSX : BYTE나 WORD크기의 피연산자를 WORD나 DWORD크기로 확장하고 부호는 그대로 유지한다.

MOVZX : BYTE나 WORD크기의 피연산자를 WORD나 DWORD크기로 확장하고 남은 비트는 0으로 채운다.

 

INT : 소프트웨어 인터럽트를 발생시켜 운영체제의 서브루틴을 호출한다.

※서브루틴 >> 어떤 특정한 기능을 하는 부 프로그램(함수)

 

AND : Destination 과 Source 피연산자의 각 비트가 AND연산 된다.

ex) Destination : 10011100

Source : 11001010

>> 10001000

OF, CF가 0으로 세트되고 결과에따라서 ZF가 1로 세트될 수 있다.

 

OR : Destination 과 Source 피연산자의 각 비트가 OR연산 된다.

ex) Destination : 10011100

Soruce : 11001010

>> 11011110

OF, CF가 0으로 세트되고 결과에 따라서 ZF가 1로 세트될 수 있다.

 

XOR : Destination 과 Source 피연산자의 각 비트가 XOR연산 된다.

ex) Destination : 10011100

Source : 11001010

>> 01010110

OF, CF가 0으로 세트되고 결과에 따라 ZF가 1로 세트될 수 있다.

피연산자가 같다면 결과는 항상 0이다.

레지스터를 0으로 초기화 시킬때 MOV명령어를 사용하기보다는 XOR reg, reg으로 많이 사용한다.

 

TEST : 두 피연산자를 AND연산을 수행하여 플래그 레지스터에 여향을 주지만 결과 값은 저장하지 않는다

OF, CF는 항상 0으로 세트되고 TEST연산 결과값이 0이면 ZF가 1 아니면 0으로 세트된다.

 

STC : CF를 1로 세트한다

CLC : CF를 0으로 세트한다.

 

STD : DF를 1로 세트한다.

CLD : DF를 0으로 세트한다.

 

STI : IF를 1으로 세트한다.

CLI : IF를 0으로 세트한다.

 

SHL : Destination 피연산자를 Source피연산자의 크기만큼 왼쪽으로 쉬프트연산한다.

쉬프트된 최상위 비트는 CF로 복사되고 최하위비트는 0으로 채워진다

ex) SHL Destination, Source

Destination = 10010000

Source = 1

>> Destination = 00100000, CF = 1

SHR : Destination 피연산자를 Source피연산자의 크기만큼 오른쪽으로 쉬프트연산한다.

쉬프트된 최하위 비트는 CF로 복사되고 최상위비트는 0으로 채워진다

ex) SHL Destination, Source

Destination = 10010001

Source = 1

>> Destination = 01001000, CF = 1

 

PUSH :스택에 값을 넣는다

ESP의 값이 4만큼 줄어들고 이 위치에 새로운 값이 채워진다.

PUSHAD : EAX, EBX, ECX, EDX, ESI, EDI, ESP, EBP 레지스터의 값을 스택에 PUSH한다.

레지스터의 값들을 보관할 때 사용한다.

PUSHFD : 플래그 레지스터를 스택에 PUSH한다.

플래그 레지스터값을 보관할 때 사용한다.

 

POP : ESP 레지스터가 가리키고 있는 위치의 스택 공간에서 4byte만큼을 Destination 피연산자에 복사하고 ESP레지스터의 값에 4를 더한다.

POPAD : 스택에 존재하는 값을 EAX, EBX, ECX, EDX, ESI, EDI, ESP, EBP레지스터로 POP한다.

PUSHAD 로 스택에 보관해 놓은 레지스터 정보를 다시 이용하려고 할 때 사용한다.

POPFD : 스택에 존재하는 값을 플래그 레지스터로 POP한다.

PUSHFD 로 스택에 보관해 놓은 플래그 레지스터 정보를 다시 이용하려고 할 때 사용한다.

 

XCHG : 두 피연산자의 내용이 서로 교환된다.

IMM값은 피연산자가 될 수 없다.

 

NEG : 피연산자의 2의 보수를 계산하여 결과를 피연산자에 저장한다.

 

PTR : 피연산자의 크기를 재설정한다.

ex) MOV eax DWORD PRT value

value의 크기를 DWORD크기로 재설정하여 eax 레지스터에 복사하라는 뜻이다.

 

OFFSET : 세그먼트의 시작으로부터 변수가 위치한 거리까지의 상대적 거리를 리터한다.

ex) MOV esi, OFFSET value

value가 존재하는 위치를 세그먼트 시작 지점부터의 상대적 거리를 구해서 esi 레지스터에 복사하라는 의미이다.

 

LEA : Source 피연산자의 유효 주소를 계산하여 Destination 피연산자에 복사한다.

ex) LEA Destination, Source

Destination에는 레지스터만 올 수 있다.

LEA EAX, [EBP + 10]

EBP주소의 값에 10을 더한뒤 EAX에 대입한다. >> MOV에서의 주소연산과 다름

 

REP : ECX 레지스터를 카운터로 사용해서 문자열 관련 명령을 ECX > 0동안 반복한다.

 

JMP : 피연산자의 위치로 실행 흐름이 변경된다.

short jmp는 -127~127바이트 범위 안에서 사용된다.

near jmp는 세그먼트 내부에서 사용된다.

far jmp는 현재 세그먼트를 벗어날 때 사용한다.

jmp명령어는 돌아올 리턴 어드레스를 저장하지 않는다.

 

CALL : jmp명령어와 같이 실행흐름이 변경되지만 CALL명령어는 리턴 어드레스를 스택에 저장한다.

 

CMP : 두 피연산자를 비교하는 작업을 한다.

두 피연산자의 값이 같다면 결과는 0이되고 ZF 가 1로 세트된다.

다르다면 0으로 세트된다.

 

NOP : 아무일도 하지 않는 명령어이다.

이미 있는 명령어를 삭제할 때 사용.

 

비교구문 cmp와 test

cmp명령어는 주어지는 두 값을 뺄셈을 해서 처리하고, test명령어는 주어지는 두 값을 더해서 처리한다.

cmp eax, ebx 이면 두 값을 빼서 0이면 참이되는 형태이다.

test eax, ebx 이면 두 값을하는대 이때 발생하는 플래그들만 저장을 한다.

CMP는 ZF, OF, SF, CF에 영향을 미친다.

TEST는 SF, ZF, PF에 영향을 미친다.

ZF = 1로 세팅되어 있다면 두 값이 같다는 의미이다.

OF, SF, CF를 이용해서 어느쪽이 더 큰지를 알 수 있다.

 

조건 점프 명령

 

 명령어

명령어의 의미 

 명령어가 수행되기 위한 플래그

 레지스터와 볌용 레지스터의 상태 

JA

Jump if (unsigned) above

 CF = 0 and ZF = 0

JAE

Jump if (unsigned) above or equal

 CF = 0

JB

Jump if (unsigned) below

 CF = 1

JBE

Jump if (unsigned) below or equal

 CF = 1 or ZF = 1

JC

Jump if carry flag set

 CF = 1

JCXZ

Jump if CX is 0

 CX = 0

JE

Jump if equal

 ZF = 1

JECX

Jump if ECX is 0

 ECX = 0

JG

Jump if (signed) greater

 ZF = 0 and SF = 0

JGE

Jump if (signed) greater or equal

 SF = OF

JL

Jump if (signed) less

 SF != OF

JLE

Jump if (signed) less or equal

 ZF = 1 and OF != OF

JNA

Jump if (unsigned) not above

 CF = 1 or ZF = 1

JNAE

Jump if (unsigned) not above or equal

 CF = 1

JNB

Jump if (unsigned) below

 CF = 0

JNBE

Jump if (unsigned) below or equal

 CF = 0 and ZF = 0

JNC

Jump if carry flag not set

 CF = 0

JNE

Jump if not equal

 ZF = 0

JNG

Jump if (signed) not greater

 ZF = 1 or SF != OF

JNGE 

Jump if (signed) not greater or equal

 SF != OF

JNL

Jump if (signed) not less

 SF = OF

JNLE

Jump if (signed) not less or equal

 ZF = 0 and SF = OF

JNO

Jump if overflow flag not set

 OF = 0

JNP

Jump if  parity flag not set

 PF = 0

JNS

Jump if sign flag not set

 SF = 0

JNZ

Jump if not zero

 ZF = 0

JO

Jump if overflow flag is set

 OF = 1

JP

Jump if parity flag is set

 PF = 1

JPE

Jump if parity is equal

 PF = 1

JPO 

Jump if parity is odd

 PF = 0

JS

Jump if sign flag is set

 SF = 1

JZ

Jump if zero

 ZF = 1

 

 전역변수

전역변수의 경우 DATA 섹션에 저장되고, 프로그램을 초기화 하는 과정에서 세팅되거나 실행중에 변경이 될 수도 있다.

ex)

.data : 0088A1A1 'This Program is powerful', 0

data섹션에 문자열이 들어 있다면

.text : 006A2A22 mov eax, 88A1A1h

.text : 006A2A27 retn

 

분기문의 사용

C언어 에서 if문은 어셈블리어에서 조건 점프문으로 대체할 수 있다.

 

반복문의 사용

반복문의 경우에는 같은 내용이 반복처리되다가 반복문을 종료하는 비교문을 만나서 점프하여 반복문을 벗어나도록 구현되어있다.

cmp, jnz이용하여 ecx에 들어있는 값만큼 반복할 수 있다.

 

함수의 사용

함수의 시작부분과 끝나는 부분을 확인할 수 있는 구분자가 있어서 확인이 그리 어렵지 않다.

시작부분에서는 push명령어를 통해 현재 레지스터값들을 스택에 넣어두고 함수를 진행하고

끝나는 부분은 호출이 끝나서 리턴되기 ret명령어가 쓰여있다.

'Study > Reversing' 카테고리의 다른 글

키젠문제 풀이  (0) 2015.05.18
Unpack, Back To User mode  (0) 2015.05.18
CPU레지스터와 데이터타입  (0) 2015.05.15
abexcm1.exe풀이  (0) 2015.05.14
올리디버거 다운로드 및 설정  (1) 2015.05.13

댓글