Self-Improvement
리버싱 기초 4 (어셈블러 명령어) 본문
*부울 연산자
- AND
설명 | 목적지와 소스 데이터를 부울 AND 연산 후 목적지에 저장 |
예시 | 명령어 : AND EAX, ECX |
연산 전 : EAX(FFFFFFF0), ECX(11100033) | |
연산 후 : EAX(11100033), ECX(11100033) |
- OR
설명 | 목적지와 소스 데이터를 부울 OR 연산 후 목적지에 저장 |
예시 | 명령어 : OR EAX, ECX |
연산 전 : EAX(FFFFFFF0), ECX(11100033) | |
연산 후 : EAX(FFFFFFF3), ECX(11100033) |
- XOR
설명 | 목적지와 소스 데이터를 배타적 OR 연산(다르면 1, 같으면 0)후 목적지에 저장 |
예시 | 명령어 : XOR EAX, ECX |
연산 전 : EAX(FFFFFFF0), ECX(FFF000FF) | |
연산 후 : EAX(000FFF0F), ECX(FFF000FF) |
*분기 명령어
- CMP : 비교
설명 | 인자 1과 인자 2가 같으면 CF는 0, ZF는 1로 설정, CF가 0인 상태에서 인자 1과 인자 2가 다르면 CF는 그대로 0이다. |
예시 | 명령어 : CMP EAX, ECX |
연산 전 : EAX(00000001), ECX(00000001), C(1), Z(0) | |
연산 후 : EAX(00000001), ECX(00000001), C(0), Z(1) |
- JMP : 점프
설명 | 목적지 주소로 이동한다. 복귀 주소를 백업하지 않는다. |
예시 | 명령어 : JMP 00401018 |
- JE : 같은 경우 점프
설명 | ZF가 1일 경우 점프한다. 보통 CMP 명령어 뒤에 온다. |
예시 | 명령어 : JE 00401018 |
- JNE : 다를 경우 점프
설명 | ZF가 0일 경우 점프한다. 보통 CMP 명령어 뒤에 온다. |
예시 | 명령어 : JNE 00401018 |
- JZ : 0일 경우 점프
설명 | ZF가 1이거나 앞의 연산 결과가 0이면 점프한다. 보통 DEC나 CMP 명령어 뒤에 온다. |
예시 | 명령어 : JZ 00401018 |
- JNZ : 0이 아닐때 점프
설명 | ZF가 0이거나 앞의 연산 결과가 0이 아니면 점프한다. 보통 DEC나 CMP 명령어 뒤에 온다. |
예시 | 명령어 : JNZ 00401018 |
- JA : 앞의 값이 크면 점프
설명 | CMP 인수 1, 인수 2 명령어 뒤에 와서 인수 1이 인수 2보다 크면 목적지로 점프한다. |
예시 | 명령어 : CMP EAX, ECX JA 00401018 |
- JB : 뒤의 값이 크면 점프
설명 | CMP 인수 1, 인수 2 명령어 뒤에 와서 인수 2가 인수 1보다 크면 목적지로 점프한다. |
예시 | 명령어 : CMP EAX, ECX JB 00401018 |
* 시프트 연산자
- SHL : 왼쪽으로 비트 이동
설명 | 목적지에 있는 데이터를 비트 수만큼 왼쪽으로 이동. 곱셈과 관련이 있다. SAL도 같은 명령어다. |
예시 | 명령어 : SHL EAX, 2 |
연산 전 : EAX(00000FFF) | |
연산 후 : EAX(00003FFC) |
왼쪽을 이동하는 명령어다. 16진수를 이진수로 바꾼 다음 지정한 비트 수만큼 왼쪽으로 이동하고 오른쪽 공간은 0으로 채운다. 즉 곱셈 연산에 사용된다.
- SHR : 오른쪽으로 비트 이동
설명 | 목적지에 있는 데이터를 비트 수만큼 오른쪽으로 이동. 나눗셈과 관련이 있다. SAR도 같은 명령어다. |
예시 | 명령어 : SHR EAX, 2 |
연산 전 : EAX(00000FFF) | |
연산 후 : EAX(000003FF) |
- PUSH
설명 | 데이터를 스택에 저장. ESP를 4바이트 만큼 감소시킴. 함수에 인수 전달하거나 데이터를 백업하고 지역변수를 위한 공간을 할당할 때 사용한다. |
예시 | 명령어 : PUSH 0 |
- POP
설명 | 데이터를 스택에서 데이터를 꺼내서 목적지에 저장. ESP를 4바이트만큼 증가시킨다. |
예시 | 명령어 : POP 0 |
- PUSHAD : 레지스터 백업
설명 | EAX -> ECX -> EDX -> EBX -> ESP -> ESI -> EDI 레지스터 순서대로 스택에 PUSH 한다. 레지스터 백업 용도로 사용된다. ESP 레지스터는 32비트 만큼 감소한다. |
예시 | 명령어 : PUSHAD |
- POPAD : 레지스터 복구
설명 | 스택에 존재하는 값을 EAX, EBX, ECX, EDX, ESI, EDI, ESP, EBP 레지스터로 POP 한다. ESP 레지스터는 32비트 만큼 증가한다. |
예시 | 명령어 : POPAD |
* 기타 연산자
- CALL : 서브루틴 호출
설명 | 복귀 주소(EIP 레지스터 값)를 스택에 백업한 후에 목적지 주소에 있는 서브루틴으로 이동한다. |
예시 | 명령어 : CALL 00403050 |
- RETN : 복귀
설명 | 백업된 복귀 주소로 이동한다. POP EIP와 같은 의미이다. 즉 현재 스택 맨 위에 있는 주소를 EIP에 저장한다. EIP는 다음에 실행될 주소가 저장된 레지스터이므로 복귀 주소가 된다. RETN 명령어 뒤에 오는 바이트 수는 스택을 사용하고 나서 반환해야 하는 바이트 수를 의미한다. |
예시 | 명령어 : RETN 4 |
- TEST : 테스트
설명 | 인수 1과 인수 2의 내용을 AND 연산하여 결과가 0이면 ZF를 1로 설정한다. 보통 NULL 체크할 때 사용 |
예시 | 명령어 : TEST EAX, ECX |
연산 전 : EAX(0000FFFF), ECX(FFFF0000), ZF(0) | |
연산 후 : EAX(0000FFFF), ECX(FFFF0000), ZF(1) |
- POP 없이 스택에서 데이터 읽기
예시 : MOV EAX, DWORD PTR SS:[ESP+4]
= ESP 레지스터 주소에서 4바이트 떨어진 위치에 있는 스택의 값을 EAX에 4바이트 복사
※ SS : Stack Segment
- 메모리에서 데이터 읽기
예시 : MOV EAX, DWORD PTR DS:[00402000]
= ESP 레지스터 주소에서 4바이트 떨어진 위치에 있는 스택의 값을 EAX에 4바이트 주소
※ DS : Data Segment
'리버싱 기초' 카테고리의 다른 글
함수 호출 규약 (0) | 2018.11.03 |
---|---|
MOV vs LEA (0) | 2018.10.28 |
리버싱 기초 3 (어셈블러 명령어) (0) | 2018.10.23 |
리버싱 기초 2 (어셈블리어) (0) | 2018.10.20 |
리버싱 기초 1 (메모리, 레지스터) (0) | 2018.10.20 |