1. 리버싱 소개
2) 레지스터
▣ 레지스터 종류
(1) EFLAGS
- 전체가 하나의 값으로 취급되는게 아닌 비트별로 의미가 존재
- 32 bit 저장공간이 32개의 서로 다른 flag로 사용됨 (0 : clear / 1 : set)
1. ZF (Zero Flag)
- 조건문에서 많이 쓰임.
- 연산결과가 0이나오면 flag값이 set. (1)
- 연산결과가 1이 나오면 flag값이 clear. (0)
2. SF (Sign Flag)
- 음수일 때 set, 양수일 때 clear (MSB 생각하면 됨)
3. AF ~ OF : 연산에 사용됨. 연산범위를 넘어섰을 때 set.
① CF (Carry Flag) : 부호없는 연산으로 판단 (unsigned)
② OF (Overflow Flag) : 부호있는 연산으로 판단 (signed)
signed -128 ~ 127
unsigned 0 ~ 255
* 0-1 = -1 -> CF : set, OF : clear
* 128 + 1 -> CF : clear, OF : set
③ AF (Adjust Flag) = half flag
3) 어셈블리 언어
▣ 데이터 형식
데이터 타입 |
사용 용도 |
BYTE |
부호 없는 1byte |
WORD |
부호 없는 2byte |
DWORD |
부호 없는 4byte |
▣ 어셈블리 언어
- 어셈블리 표현법 : IA32 (Intel Architecture)->a=1 , AT&T->1=a
- 모든 opcode는 자신이 가지는 operand의 개수와 종류가 모두 정해져있음. (fixed)
표시 기호 | 설명 |
mem | 메모리 |
label | 지정된 레이블 |
imm | 즉시 값 (상수) |
reg | 범용 레지스터 |
- label : 메모리상의 주소에 이름(꼬리표)를 붙여줌. 가상의 개념. 코드의 주소를 직접 쓰기에는 불편해서.
4) 연산자
▣ INC (Increase)
- operand를 1만큼 증가. (operand는 딱 1개)
INC reg ex) INC EAX |
INC mem ex) INC [EBP-0x04] |
#include <stdio.h> int main() { int a = 0; printf("%d\n", a); _asm { inc a inc a } printf("%d\n", a); return 0; }
- _asm{} : 인라인 어셈. 상위레벨인 c언어 상에서 하위레벨인 어셈블리어를 쓸 수 있게 해줌. (대소문자 구분x)
- 실행 결과
▣ DEC (Decrease)
- operand를 1만큼 감소
DEC reg ex) INC EAX |
DEC mem ex) INC [EBP-0x04] |
#include <stdio.h> int main() { int a = 2; printf("%d\n", a); _asm { dec a dec a } printf("%d\n", a); return 0; }
▣ ADD, SUB
- operand가 2개 필요.
- ADD/SUB op1, op2 (op1 +- op2 값을 op1에 저장)
- 크기지정해줘야함. 안하면 나머지 한쪽에 맞춰짐.
- operand 2개의 크기가 서로 맞지 않으면 컴파일 에러가 남.
ex) add [ebp-4], eax -> [ebp-4] : 4바이트로 맞춰짐.
ex) add [ebp-4], ax -> [ebp-4] : 2바이트로 맞춰짐.
ADD reg, reg ex) ADD EAX, EBX |
ADD reg, mem ex) ADD EAX, [EBP-0x04] |
ADD mem, reg ex) ADD [EBP-0x04], EAX |
ADD mem, imm ex) ADD [EBP-0x04], 0x05 |
ADD reg, imm ex) ADD EAX, 0x05 |
#include <stdio.h> int main() { int a = 0; printf("%d\n", a); _asm { add a, 0x05 sub a, 0x03 } printf("%d\n", a); return 0; }
▣ MOV
- operand가 2개 필요
- MOV op1, op2 (op2의 값을 op1에 대입)
MOV reg, reg ex) MOV EAX, EBX |
MOV reg, mem ex) MOV EAX, [EBP-0x04] |
MOV mem, reg ex) MOV [EBP-0x04], EAX |
MOV mem, imm ex) MOV [EBP-0x04], 0x05 |
MOV reg, imm ex) MOV EAX, 0x05 |
- 왜 MOV mem, mem 은 없음?
☞ operand를 2개를 가지는 모든 opcode에서 불가능!!
☞ mov a, b (x) : 레지스터에 b 값 넣어두고 다시 그 값을 a에 넣고 해야함.. 귀찮..
- 사람과 컴파일러가 짠 어셈블리어는 티가나게 다름.
☞ 컴파일러는 연산을 무조건 레지스터로 옮긴후에 해야한다는 원칙이 존재하기 때문.
i2sec 대구지점 23기 수료생.
'해킹&보안 > 리버싱' 카테고리의 다른 글
[D+6] 리버싱 소개 (6) (0) | 2017.03.28 |
---|---|
[D+5] 리버싱 소개 (5) (0) | 2017.03.27 |
[D+4] 리버싱 소개 (4) (0) | 2017.03.26 |
[D+3] 리버싱 소개 (3) (0) | 2017.03.23 |
[D+1] 리버싱 소개 (1) (0) | 2017.03.21 |