1. 리버싱 기초

악성코드 분석

2018. 8. 19. 17:43

반응형

1. 리버싱 기초

리버싱(Reversing)은 한국어로 역공학이라고도 부른다.

01 어셈블리

- C/C++코드와 어셈블리 코드의 차이
- 한 가지 동작까지 세세하게 지정

C/C++코드 예
1
2
3
4
5
6
7
8
9
void 물마심()
{
    BOOL bOpen = 냉장고문오픈 ();
    if (bOpen)
    {
        물을꺼냄();
        마심();
    }
}
cs

어셈블리 코드 예

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
_asm{
    냉장고앞으로간다
    냉장고문을잡는다
    냉장고문을연다
   오픈성공:
    냉장고안을본다
    손을든다
    냉장고안에넣는다
    물병을잡는다
    물병을꺼낸다
    뚜껑을연다
    물을컵에따른다
    컵을손에든다
    컵에든것을마신다
}
cs


02 어셈블리의 명령 포맷

- 주로 IA-32를 사용
- 기본형태 : 명령어(옵코드, opcode) + 인자(오퍼랜드, operand 1~2)

03 레지스터 - 레지스터의 종류

- CPU가 사용하는 변수

레지스터

역할

EAX

(Accumulator)

각종 연산에 쓰임

가장 많이 쓰이는 변수

주로 리턴 값을 저장

EDX (data)

각종 연산에 쓰이는 변수

ECX (Count)

for 문에서 i 역할

ECX 미리 값을 정해놓고 0

때까지 진행

변수로 사용해도 무방

EBX

목적이 없는 레지스터

공간이 필요할 덤으로 사용

ESI, EDI

(source Index, destination Index)

문자열이나 각종 반복데이터를 처리 또는 메모리를 옮기는데 사용

ESP

스택 포인터

EBP

베이스 포인터

EIP

인스트럭션 포인터



03 레지스터 - 레지스트리 단위

32bit

16bit

상위 8bit

하위 8bit

EAX

AX

AH

AL

EDX

DX

DH

DL

ECX

CX

CH

CL

EBX

BX

BH

BL



03 레지스터 - 사용 예

- Plus (c 코드) vs. PlusAsm (Asm 코드)
- 두 함수가 같은 값을 반환

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <windwows.h>
#include <stdio.h>
int Plus(int a, int b)
{
    return a + b;
}
 
__declspec (naked) PlusAsm(int a, intb)
{
    __asm
    {
        mov ebx, dword ptr 55:[esp+8// b를 ebx에 저장
        mov edx, dword ptr 55:[esp+4// a를 edx에 저장
        add edx, ebx // a + b
        mov eax, edx // 결과값을 eax에 저장
        retn
    }
}
 
void main(int argc, char *argv[])
{
    int valude Plus(34);
    printf("value: %d\n ", value);
    int value2 = PlusAsm(34);
    printf("value2: %d\n", value2);
 
    return;
}
cs



04 외울 필요가 없는 어셈블리 명령어

- PUSH, POP (PUSHAD, POPAD)
- MOV : source를 가져옴
- LEA : source의 주소를 가져옴
- ADD
- SUB
- INT : 인터럽트 명령 (CPU가 잠깐 정지)
- CALL
- INC, DEC (i++, i--)
- AND, OR, XOR
- NOP
- CMP, JMP


05 리버스 엔지니어링에 필요한 스택

- 함수 프롤로그

- 스택 구조


06 함수의 호출 & 리턴 주소

- 메인 함수에서 HelloFunction 함수 호출
- LIFO 방식으로 스택을 삽입'

1
2
3
4
5
6
main()
{
    DWORD dwRet = HelloFunction(0x370x480x39);
    if (dwRet)
    // .........
}
cs

함수 호출 시 스택 구성

ebp+0x16

116h

39h

ebp+0x12

112h


ebp+0x8

108h

37h

ebp+0x4

104

RET주소 (ebp, esp가 여길 가르킴)

ebp

100h

ebp

 

 

 

 

 

 

 

 

 


반응형