글
어셈블리 기본 명령어
어셈블리 ( 기본 명령어 이해 )
1. 어셈블리어 형식
- 형식 : OPCODE 오퍼랜드1 , 오퍼랜드2
- intel 문법 : OPCODE [ Destination ] [ Source ]
- AT&T 문법 [ Source ] [ Destination ]
2. 어셈블리 자료형 이름
BYTE 1byte char
WORD 2byte short
DWORD 4byte int
QWORD 8byte double
3. 복사 / 이동 / 대입 명령어
1) MOV
- 형식 : MOV [ Destination ] [ Source ]
- 내용 : [ Source ] 를 [ Destination ]으로 대입 / 이동 한다. 이때 , [ Source ] 값은 병경되지 않는다.
- 예제 : MOV ECX , EAX
2) MOVZX
- 형식 : MOVZX [ Destination ] [ Source ]
- 내용 : [ Source ] 를 [ Destination ]으로 대입 / 이동 한다. 만약 대입한 이후에 빈공간이 있으면 0 bit 로 채움
- 예제 : MOV ECX , AX
3) MOVSX
- 형식 : MOVSX [ Destination ] [ Source ]
- 내용 : [ Source ] 를 [ Destination ]으로 대입 / 이동 한다. 만약 대입한 이후에 빈공간이 있으면 부호비트로 채움
- 예제 : MOV ECX , AX
4) MOVS
- 형식 : MOVS
- 내용 : ESI가 가르키는 주소에 있는 값을 EDI가 가르키는 주소에 대입한다
5) LEA
- 형식 : LEA [ Destination ] [ Source ]
- [ Source ] 의 주소 값을 [ Destination ] 으로 대입한다
- 예제 : LEA EAX ,DWORD PTR SS:[EBP- 4]
4. 더하기 / 빼기 명령어
1) ADD
- 형식 : ADD [ Operand 1 ] [ Operand 2 ]
- 내용 : [ Operand 1 ] 과 [ Operand 2 ] 를 더해서 [ Operand 1 ] 에 저장한다
- 예제 : ADD EAX , 5
- 해석 : EAX = EAX + 5
2) SUB
- 형식 : SUB [ Operand 1 ] [ Operand 2 ]
- 내용 : [ Operand 1 ] 과 [ Operand 2 ] 를 빼서 [ Operand 1 ] 에 저장한다
- 예제 : SUB EAX , 5
- 해석 : EAX = EAX - 5
5. 곱하기 / 나누기 명령어
1) MUL
- 형식 : MUL [ Operand 1 ] [ Operand 2 ]
- 내용 : [ Operand 1 ] 과 [ Operand 2 ] 를 곱해서 EAX에 값을 저장한다.
- 예제 : MUL EAX , EBX
- 해석 : EAX = EAX * EBX
2) IMUL
- 부호가 있는경우
- 형식 : IMUL [ Operand 1 ] [ Operand 2 ]
- 내용 : [ Operand 1 ] 과 [ Operand 2 ] 를 곱해서 EAX에 값을 저장한다.
- 예제 : MUL EAX , EBX
- 해석 : EAX = EAX * EBX
3) DIV
- 형식 : DIV [ Operand 1 ] [ Operand 2 ]
- 내용 : [ Operand 1 ] 과 [ Operand 2 ] 를 나누기 하여 EAX에 값을 저장한다.
- 예제 : MUL EAX , EBX
- 해석 : EAX = EAX / EBX
4) IDIV
- 부호가 있는경우
- 형식 : IDIV [ Operand 1 ] [ Operand 2 ]
- 내용 : [ Operand 1 ] 과 [ Operand 2 ] 를 나누기 하여 EAX에 값을 저장한다.
- 예제 : MUL EAX , EBX
- 해석 : EAX = EAX / EBX
[ 참고 ] CVW , CWD , CDQ
- IDIV가 진행하기 이전에 나타나는 부호 비트 확장 코드
- 나눗셈을 진행하고 부호비트를 넣어줄 공간을 확보하는데 기존 공간의 2배를 할당한다.
CBW BYTE -> WORD
CWD WORD -> DWORD
CBQ DWORD -> QWORD
6. 증가 / 감소 명령어
1) INC
- 형식 : INC [ Operand ]
- 내용 : [ Operand ] 값에서 '1' 을 증가한다.
- 예제 : INC EBX
- 해석 : EBX 값에서 '1'을 증가시킨다.
2) DEC
- 형식 : DEC [ Operand ]
- 내용 : [ Operand ] 값에서 '1' 을 감소한다.
- 예제 : DEC EBX
- 해석 : EBX 값에서 '1'을 감소시킨다.
7. 비교 관련 명령어
1) CMP
- 형식 : CMP [ Operand 1 ] [ Operand 2 ]
- 내용 : [ Operand 1 ] 에서 [ Operand 2 ] 를 빼서 결과 값이 '0'인지 확인한다.
- 예제 : CMP EAX , 1
- 해석 : EAX 값에서 '1'을 뺀 경유 , 결과 값이 '0' 이라면 두 오퍼랜드 값은 동일하다.
2) TEST
- 형식 TEST [ Operand 1 ] [ Operand 2 ]
- 내용 : [ Operand 1 ] 과 [ Operand 2 ]를 AND 연산을 실시한다.
- 예제 : TEST EAX , EAX
- 해석 : 두 오퍼랜드가 '0' 인지 아닌지를 판단할 수 있다.
- 즉 , 두 오퍼랜드가 '0' 이면 AND 연산 결과 값이 '0'으로 나온다. 그래서 함수의 리턴값이 '0'인지 아닌지를 판단할
때 주로 사용 한다.
3) 상태 플래그
- CMP , TEST 비교 이후에 분기 명령어가 있으면 상태 플래그를 확인하여 분기를 실시한다.
ZF Zero Flag 연산 결과가 '0' 이면 참 , ZF = 1 설정
SF Sign Flag 연산 결과가 음수이면 참 , SF = 1 설정
CF Carry Flag 부호 없는 숫자의 연산 결과 비트 범위를 넘으면 참 , CF = 1 설정
OF OVerflow Flag 부호 있는 숫자의 연산 결과가 비트 범위를 넘으면 참 , OF = 1 설정
8. 분기 관련 명령어
- CMP , TEST 결과에 따라서 ZF가 '1' 또는 '0'으로 설정되며 , ZF 플래그 값에 따라서 분기되는 내용이 다르다
- CMP 결과 값이 '0'이면 두 값은 동일한 값(참) 이며 , ZF = 1 로 설정 된다
- 만약 , CMP 결과 값이 '0'이 아니면 두 값은 다른 값(거짓)이며 , ZF = 0 으로 유지된다
- TEST 결과 값이 '0'이면 ZF = 1 로 설정된다.
- 만약 , TEST 결과 값이 '0'이 아니면 , ZF = 0 으로 유지된다.
1) JMP
- 형식 : JMP [ Code Address ]
- 내용 : 무조건 해당 주소로 점프한다
- 예제 : JMP 401140
- 해석 : 무조건 401140 번지로 점프한다
2) JZ ( JE 동일 )
- 형식 : JZ [ Code Address ]
- 내용 : 비교 결과 값이 '0' 이면 (ZF =1 설정된 경우 ) , 해당 주소로 점프한다.
- 예제 : JZ 401140
- 해석 : ZF = 1 인 경우 , 401140 으로 점프한다.
- 조건 : Operand 1 == Operand 2
3) JNZ ( JNE 동일 )
- 형식 : JZ [ Code Address ]
- 내용 : 비교 결과 값이 '0' 이면 (ZF = 0 설정된 경우 ) , 해당 주소로 점프한다.
- 예제 : JZ 401140
- 해석 : ZF = 0 인 경우 , 401140 으로 점프한다.
- 조건 : Operand 1 != Operand 2
4) JLE ( JBE 비슷함 )
- 형식 JLE [ Code Address ]
- 내용 : 비교 결과 값이 '0'이거나 (ZF =1) , 작을 경우 해당 주소로 점프한다.
- 예제 : JLE 401140
- 해석 : ZF =1 이거나 , 결과 값이 작은 경우 401140으로 점프한다.
- 조건 : Operand 1 <= Operand 2
5) JGE ( JAE 비슷함 )
- 형식 JGE [ Code Address ]
- 내용 : 비교 결과 값이 '0'이거나 (ZF =1) , 작을 경우 해당 주소로 점프한다.
- 예제 : JGE 401140
- 해석 : ZF =1 이거나 , 결과 값이 작은 경우 401140으로 점프한다.
- 조건 : Operand 1 <= Operand 2
6) JL ( JB 비슷함 )
- 형식 JL [ Code Address ]
- 내용 : Operand 1 이 Operand 2 보다 작은 경우 해당 주소로 점프한다
- 예제 : JL 401140
- 해석 : Operand 1 이 Operand 2 보다 작은 경우 401140으로 점프한다
- 조건 : Operand 1 < Operand 2
7) JG ( JG 비슷함 )
- 형식 JG [ Code Address ]
- 내용 : Operand 1 이 Operand 2 보다 큰 경우 해당 주소로 점프한다
- 예제 : JG 401140
- 해석 : Operand 1 이 Operand 2 보다 큰 경우 401140으로 점프한다
- 조건 : Operand 1 > Operand 2
9. 스택 관련 명령어
1) PUSH
- 형식 : PUSH [ Operand ]
- 내용 : Operand 값을 스택에 4byte 공간을 확보하고 저장한다.
- 예제 : PUSH ECX
- 해석 : 스택에 4byte 공간을 확보하고 'ECX' 값을 저장한다.
- 용도 : 스택에 지역 변수 값을 저장 , 함수 인자 값 저장
- 특징 : 'CALL' 명령어를 이용하여 함수를 호출하기 이전에 'PUSH' 명령어를 확인할 수 있다.
- 참고 : 'PUSHAD' 명령어는 EAX ~ EDI 레지스트 값을 스택에 저장 (백업)할 때 사용한다.
2) CALL
- 형식 CALL [ 함수 주소 ]
- 내용 : [ 함수 주소 ] 로 이동하여 함수를 실행한다.
- 예제 : CALL 401000
- 해석 : '401000' 주소에 있는 함수를 실행한다.
- 함수가 호출되어 실행되기 이전에 다음과 같은 동작을 실시한다.
'PUSH EIP' 를 실시하여 EIP 값(다음 명령어 / 리턴 주소)을 스택에 저장한다.
그리고 해당 함수가 처리 완료되면 스택에 저장된 EIP 값을 확인하여 다음 명령어로 이동한다.
'JMP [ 함수 주소 ] '를 실시하여 해당 함수로 점프하여 함수 내의 명령을 실행한다.
3) POP
- 형식 : POP [ Operand ]
- 내용 : PUSH를 통해서 저장된 값 / 확보된 공간을 제거한다
- 예제 : POP ECX
- 해석 : 스택에 저장된 ECX를 재거한다
- 참고 : 'POPAD' 명령어는 스택에 저장된 EAX ~ EDI 레지스터를 제거(복원)할때 사용한다.
4) RET
- 형식 : RET
- 내용 : CALL 명령어를 통해서 호출된 함수를 종료하고 다음 명령어로 이동한다.
- RET이 실행되면 다음과 같은 동작을 실시한다.
'POP EIP'를 실시하여 함수 호출때 스택에 PUSH한 EIP 값을 제거한다.
'JMP EIP'를 실시하여 EIP 값의 주소로 점프하여 다음 명령어를 실행한다.
5) NOP
- 형식 : NOP
- 내용 : 아무 명령도 수행하지 않는 명령어이다.
- 용도 : 명령어와 명령어 사이에 빈공간(1byte)을 채워주는 용도로 사용하며 , 16진수 값으로는 '0x90' 이다.
'리버싱' 카테고리의 다른 글
어셈블리 ( 구조체 ) (0) | 2019.11.15 |
---|---|
어셈블리 ( 스택 프레임) (0) | 2019.11.14 |
어셈블리(레지스터 이해) (0) | 2019.11.13 |
화면 잠금 프로그램 'Lock Workstation' 제작 (0) | 2019.11.13 |
PE 파일 분석 IAT & Pre Binding (0) | 2019.11.11 |