먼저 명령어는 연산자(Operator)라고도 불리며, 명령어에 따라 오퍼랜드 개수가 다르다.
(ex) MOV EAX, val1
명령어 연산자 1, 연산자 2
명령어의 분류
1) 데이터의 이동 : MOV, LEA
2) 논리, 연산 : ADD, SUB, DEC, INC
3) 흐름 제어 : cmp, jmp
4) 프러시저 : call, ret
5) 스택 조작 : push, pop
6) 인터럽트 : int
1) 데이터 이동
1.MOV
- 형식 : MOV dest, src
- 기능 : src위치에 있는 데이터를 복사하여 dest위치에 저장
- 원칙 1) 메모리와 레지스터 사이의 데이터 이동.
2) 레지스터와 레지스터, 값을 레지스터나 메모리에 대입할 때 사용.
3) src와 dest의 크기가 같아야 함.
**movs 또한 mov와 같은 기능을 하지만 movs는 String 데이터를 복사한다는 점에 차이를 둠.
2.LEA
- 형식 : LEA dest, src //Load Effective Address
- 기능 : src 오퍼랜드에서 지정된 주소를 dest로 로드
- 원칙 1) src의 오퍼랜드는 메모리에 위치해야 함.
2) mov와 비교하여 메모리 주소 표현 및 레지스터에 대한 직접적인 연산이 가능.
2) 연산
1.ADD
- 형식 : ADD dest, src
- 기능 : dest에 src의 값을 더해서 그 결과를 dest에 저장.
- 원칙 1) 메모리끼리 덧셈 불가
2) 연산 결과에 따라 ZF(Zero), OF(Overflow), CF(Code)가 세트가 될 수 있다.
2.SUB
- 형식 : SUB dest, src
- 기능 : dest에서 src를 뺀 다음 결과를 opr1에 저장.
- 원칙 1) 메모리끼리 뺄셈 불가
2) 연산 결과에 따라 ZF, OF, CF가 세트가 될 수 있다.
3.INC
- 형식 : INC dest
- 기능 : dest(피연산자)에 1을 증가시키고 결과값을 다시 저장.
- 원칙 1) 레지스터와 메모리만 사용 가능
2) ZF, OF가 세트가 될 수 있다.
4.DEC
- 형식 : DEC dest
- 기능 : dest(피연산자)에 1을 감소시키고 결과값을 다시 저장.
- 원칙 1) 레지스터와 메모리만 사용 가능
2) ZF, OF가 세트가 될 수 있다.
3) 흐름 제어
1.JMP
- 형식 : JMP proc
- 기능 : 프로그램의 흐름 바꾸기, proc주소로 가서 그곳의 명령어 실행
- 원칙 1) 주로 if/else문이나 loop문에서 사용됨
2) 명령어들은 16비트, 32비트 또는 세그먼트 : 오프셋 포인터를 가진다.
3) 종류로는 상대, 조건부, 절대, 간접 레지스터 점프가 있다.
2.CMP
- 형식 : CMP dest, src
- 기능 : dest피연산자에서 src연산자를 묵시적으로 빼서 값을 비교한다.
- 원칙 1) 뺀 값이 0일 경우 ZF가 1로 세트 되고, 다를 경우 0으로 세트 됨.
2) 처음 상태일 때는 NZ(Not Zero)로 ZF가 0이지만, 계산 값이 0일 경우 ZF가 1로 세트 되면서 NZ가 ZR로 변경됨.
3) 혼자 사용 X, 언제나 조건 점프 혹은 조건 이동 명령어와 함께 사용됨
**조건 점프 명령어 꼭 확인.
3.CALL
- 형식 : CALL target
- 기능 : 함수 호출 시 사용, 스택 상에 CS를 다음에 오는 명령의 오프셋 주소를 PUSH 하고 주어진 주소로 제어를 옮긴다. (EIP를 변경시킴)
**JMP와 다른 점 : CALL명령어는 되돌아올 return 주소를 스택에 저장함.
4.RET
- 형식 : RET
- 기능 : 호출된 함수에서 호출한 함수로 복귀
- 원칙 : ESP에 있는 값을 꺼내서(pop) EIP 레지스터에 할당한다.
4) 스택 조작
1.PUSH
- 형식 : PUSH dest
- 기능 : 스택이라는 공간에 메모리 저장
- 원칙 : ESP레지스터도 워드 크기(4바이트)만큼 증가한다.
**워드 크기? CPU가 한 번에 처리할 수 있는 데이터 크기이다.
32비트 컴퓨터의 경우 CPU가 메모리로 보낼 수 있는 데이터가 32비트(=4바이트)
2.POP
- 형식 : POP dest
- 기능 : 스택 맨 윗부분(top)에서 하나의 워드를 꺼내고 바로 그 전의 데이터를 가리킴
- 원칙 : ESP레지스터도 워드 크기(4바이트)만큼 감소한다.
5) 인터럽트
1.INT
- 형식 : INT //interrupt:일시중지
- 기능 : 소프트웨어 인터럽트를 발생시켜 운영체제의 서브루틴을 호출
- 원칙 : 상수만 사용 가능하다.
2.NOP
- 형식 : NOP
- 기능 : 아무 일도 하지 않는 명령어, 리버싱 작업에서 목적에 따라 유용하게 사용
- 원칙 : ESP레지스터도 워드 크기(4바이트)만큼 증가한다.
3.LOOP
- 형식 : LOOP reg
- 기능 : 반복하고자 하는 내용을 그룹화하고, LOOP명령어를 통해 반복 내용을 묶음
- 원칙 : CX 레지스터를 사용, CX레지스터 값만큼 반복
6) 논리
1.AND
- 형식 : ADD dest, src
- 기능 : dest와 src 피연산자의 각 비트가 AND 연산됨
- 원칙 : 각 비트가 모두 1일 때만 결과도 1이 됨
2.OR
- 형식 : OR dest, src
- 기능 : dest와 src 피연산자의 각 비트가 OR 연산됨
- 원칙 : 하나의 비트라도 1이면 결과 값이 1이 됨. CF, OF, ZF플래그가 세트가 될 수 있음
3.XOR
- 형식 : XOR dest, src
- 기능 : dest와 src 피연산자의 각 비트가 XOR 연산됨
- 원칙 1) 각 비트가 서로 다른 값일 때만 결과가 1, 같은 값이라면 결과는 0.
2) OF, CF가 0으로 세트가 되고 결과에 따라서 ZF가 1로 세트 될 수 있음.
**레지스터를 0으로 초기화하는 방법
- MOV AX, 0 //일반적인 AX에 0 값을 넣는 명령어
- SUB AX, AX //AX-AX인 자신끼리 뺄셈 계산을 하는 방식
- XOR AX, AX //서로 같은 값을 가질 경우 0이 되는 방식
'보안 공부 > Reversing' 카테고리의 다른 글
[리버싱] CMP와 TEST 명령어 차이 (0) | 2019.11.01 |
---|---|
[리버싱] MOV와 LEA의 차이 (5) | 2019.09.17 |
[리버싱] 어셈블리어란/어셈블리어종류 (0) | 2019.09.17 |
[리버싱] 레지스터란, 레지스터 종류 (0) | 2019.09.15 |
[리버싱] 리버싱이란, 디버그란 (0) | 2019.09.15 |
댓글