본문으로 바로가기

[D+5] 리버싱 소개 (5)

category 해킹&보안/리버싱 2017. 3. 27. 21:50
336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.

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