1. 리버싱 소개
4) 연산자
▣ AND
- operand가 2개 필요
- 비트논리 연산
- 첫번째 operand에 값을 저장. ( &= )
AND reg, reg ex) AND EAX, EBX |
AND reg, mem ex) AND EAX, [EBP-0x04] |
AND mem, reg ex) AND [EBP-0x04], EAX |
AND mem, imm ex) AND [EBP-0x04], 0x05 |
AND reg, imm ex) AND EAX, 0x05 |
#include <stdio.h> int main() { int a = 10; printf("%d\n", a); _asm { and a, 0x06 } printf("%d\n", a); return 0; }
- 특정한 비트 자리를 0으로 만들어주기 위해 사용.
ex) rand() 함수의 제일 마지막에
and eax, 7FFF
4바이트 eax를 1바이트의 양수로 걸러줌. (rand() 범위 : 0 ~ 32767)
▣ OR
- operand 2개 필요
- 비트논리 연산
- 첫번째 operand에 값을 저장. ( |= )
- 특정한 비트 자리를 1로 만들어주기 위해 사용
OR reg, reg ex) OR EAX, EBX |
OR reg, mem ex) OR EAX, [EBP-0x04] |
OR mem, reg ex) OR [EBP-0x04], EAX |
OR mem, imm ex) OR [EBP-0x04], 0x05 |
OR reg, imm ex) OR EAX, 0x05 |
#include <stdio.h> int main() { int a = 10; printf("%d\n", a); _asm { or a, 0x06 } printf("%d\n", a); return 0; }
▣ XOR
- operand 2개 필요
- 비트논리 연산
- 첫번째 operand에 값을 저장. ( ^= )
- A ^ A = 0 으로 가장 많이 쓰임.
ex) return 0; == xor eax, eax
XOR reg, reg ex) XOR EAX, EBX |
XOR reg, mem ex) XOR EAX, [EBP-0x04] |
XOR mem, reg ex) XOR [EBP-0x04], EAX |
XOR mem, imm ex) XOR [EBP-0x04], 0x05 |
XOR reg, imm ex) XOR EAX, 0x05 |
#include <stdio.h> int main() { int a = 10; printf("%d\n", a); _asm { xor a, 0x06 } printf("%d\n", a); return 0; }
▣ SHL & SHR
- Shift 연산
- operand 2개 필요
- 비트논리 연산
- SHL op1, op2 : op1의 비트를 op2만큼 왼쪽(또는 오른쪽)으로 민다.
☞ SHL (왼쪽으로 밀 때) : 범위안이라면 × 2
☞ SHR (오른쪽으로 밀 때) : 범위안이라면 ÷ 2
- op2는 반드시 8bit 상수여야 함.
- 첫번째 operand에 값을 저장. ( <<= )
SHL reg, imm8 ex) SHL EAX, 0x01 |
SHL mem, imm8 ex) SHL [EBP-0x04], 0x02 |
#include <stdio.h> int main() { int a = 10; printf("%d\n", a); _asm { shl a, 0x01 shl a, 0x02 } printf("%d\n", a); return 0; }
▣ PUSH & POP
- 스택프레임과 관련.
- push : 스택에 operand를 추가 (push op1)
- pop : 스택 최상단의 값을 해당 operand에 저장 (pop op1)
- operand들은 변수형태임 (메모리, 레지스터)
PUSH |
PUSH reg16/reg32 ex) PUSH EAX |
PUSH mem16/mem32 ex) PUSH [EBP-0x04] |
PUSH imm16/imm32 ex) XOR 0x05 |
POP |
POP reg16/reg32 ex) POP EAX |
POP mem16/mem32 ex) POP [EBP-0x04] |
#include <stdio.h> int main() { int a = 1; _asm { push a push 0x10 push eax pop eax pop a pop ebx } printf("%d\n", a); return 0; }
☞ push a : a의 주소가 아닌 a에 있는 값을 넣는것.
☞ push eax : eax에 있는 값을 넣음.
- PUSH & POP을 사용해서 ESP 값을 바꿨다면 반드시 원래 값으로 돌려놔야함!! (모든 함수는 끝날때 EBP == ESP가 되어야함)
i2sec 대구지점 23기 수료생.
'해킹&보안 > 리버싱' 카테고리의 다른 글
[D+6] 리버싱 소개 (6) (0) | 2017.03.28 |
---|---|
[D+5] 리버싱 소개 (5) (0) | 2017.03.27 |
[D+4] 리버싱 소개 (4) (0) | 2017.03.26 |
[D+2] 리버싱 소개 (2) (0) | 2017.03.22 |
[D+1] 리버싱 소개 (1) (0) | 2017.03.21 |