1. 리버싱 소개
1) 연산자
▣ MOVS
- ESI가 가리키고 있는 곳의 값을 EDI가 가리키는 곳에 지정한 크기만큼 저장.
- 문자열 복사
MOVS dest, src |
#include <stdio.h> int main() { char *str1 = "Hello I2SEC!!"; char str2[20]; int len = strlen(str1); _asm { mov esi, dword ptr [str1] lea edi, dword ptr [str2] mov ecx, len rep movs byte ptr [edi], byte ptr [esi] mov byte ptr [edi], 0x00 } printf("%s\n", str2); return 0; }
- 실행 결과
- 설명
☞ mov와 lea의 차이
: mov는 현재 내가 쓰는 op의 값이 필요할 때고 lea는 주소가 필요할 때 씀.
☞ 11줄 : str1은 문자열 상수가 존재하는 주소값이 저장되어 있음. 그러므로 mov를 사용.
☞ 12줄 : str2는 c언어에서는 주소를 뜻하지만 어셈블리어에서는 변수(메모리)로 취급.
▶ [ ] : 참조가 아니라 메모리임을 뜻하는 것.
ex) [ a ] == a (a의 값 X)
2) 제어문
: 저장하지 않고 연산만 수행하는 Opcode 필요
▣ TEST
- AND 연산만 수행 (저장은 X)
- ex) test eax, eax -> 0인지 아닌지를 체크할 때 많이 쓰임(ZF 세팅/클리어)
TEST reg, reg ex) TEST EAX, EBX |
TEST reg, mem ex) TEST EAX, [EBP-0x04] |
TEST mem, reg ex) TEST [EBP-0x04], EAX |
TEST mem, imm ex) TEST [EBP-0x04], 0x05 |
TEST reg, imm ex) TEST EAX, 0x05 |
#include <stdio.h> int main() { int a = 3; _asm { TEST a, 0x02 } printf("%d\n", a); return 0; }
▣ CMP (Compare)
- usage : CMP op1, op2
CMP reg, reg ex) CMP EAX, EBX |
CMP reg, mem ex) CMP EAX, [EBP-0x04] |
CMP mem, reg ex) CMP [EBP-0x04], EAX |
CMP mem, imm ex) CMP [EBP-0x04], 0x05 |
CMP reg, imm ex) CMP EAX, 0x05 |
CMP 연산 결과 |
ZF |
CF |
op1 < op2 |
0 |
1 |
op1 > op2 |
0 |
0 |
op1 == op2 |
1 |
0 |
- 정상적인 연산에서 ZF, CF 둘 다 1이 되는 일은 없음.
▣ JMP (Jump)
- EIP(다음에 실행할 명령어의 주소)를 바꿈.
- Like. C언어의 GoTo문과 같음.
- usage : JMP op1 (EIP에 op1값을 넣음/조건없이)
JMP label(=imm) ex) JMP L3 |
JMP reg16 ex) JMP AX |
JMP mem16 ex) JMP [0xFFFF] |
JMP mem32 ex) JMP [0xFFFFFFFF] |
#include <stdio.h> int main() { int a = 3; _asm { JMP L1 MOV a, 0x0A L1: MOV a, 0x01 } printf("%d\n", a); return 0; }
- 설명
☞ 9줄 : 레이블 L1으로 뛰어넘음.
☞ LABLE : 코드 상 특정위치를 나타내는 이름. 가상의 값.
☞ 레이블명은 레이블명 다음줄의 명령어 주소를 담고있음.
▣ 조건 점프 명령
- 특정 조건에 만족할 때만 JUMP! (=EIP 바뀜)
- FLAG의 상태에 따라!
- 조건 점프명령은 c언어와 반대로 생각하면 쉬움!
조건 점프 명령 |
산술, 논리 연산 |
JA |
CMP A > B |
JB |
CMP A < B |
JE |
CMP A == B |
JNE |
CMP A != B |
JZ |
TEST EAX, EAX (EAX == 0) |
JNZ |
TEST EAX, EAX (EAX == 0) |
- FLAG의 중요성
MOV a, 10 MOV a, 10
CMP a, 1 CMP a, 1
JA MOV a, -10
JA
=> JUMP함 => JUMP 함 (MOV는 연산이 아니고 flag로 판단하기 때문에 jump함)
명령어 |
명령어 의미 |
부등호 |
플래그 조건 |
JA |
Jump if (unsigned) above |
> |
CF = 0 && ZF = 0 |
JAE |
Jump if (unsigned) above or equal |
>= |
CF = 0 || ZF = 1 |
JB |
Jump if (unsigned) below |
< |
CF = 1 |
JBE |
Jump if (unsigned) below or equal |
<= |
CF = 1 || ZF = 1 |
JC |
Jump if carry flag set |
CF = 1 |
|
JCXZ |
Jump if CX is 0 |
CX = 0 |
|
JE |
Jump if equal |
== |
ZF = 1 |
JECXZ |
Jump if ECX is 0 |
ECX = 0 |
|
JG(<->JL) |
Jump if (signed) greater |
> |
ZF = 0 && SF == OF |
JZ | Jump if zero | == | ZF = 1 |
- JG <-> JL
CMP -1, 1
JA (O) : unsigned 기준 (-1이 존재하지 않음)
JG (X) : signed 기준
=> FF - 01 = FE(11 10)
=> CF : 0, ZF : 0, SF : 1, OF : 0
i2sec 대구지점 23기 수료생.
'해킹&보안 > 리버싱' 카테고리의 다른 글
[D+7] 함수호출규약 (0) | 2017.03.30 |
---|---|
[D+6] 리버싱 소개 (6) (0) | 2017.03.28 |
[D+4] 리버싱 소개 (4) (0) | 2017.03.26 |
[D+3] 리버싱 소개 (3) (0) | 2017.03.23 |
[D+2] 리버싱 소개 (2) (0) | 2017.03.22 |