PEView – 실행 파일 구조, PE Header 분석

실행 파일 구조, PE Header 분석

과거 리버스 엔지니어링은 프로그래머의 전유물처럼 여겨졌는데, 지금은 바이러스와 핵툴과 같은 악성 프로그램들의 끊임없는 등장으로, 보안의 핵심/종착지와 같은 중요한 분야가 되었다. 여기서는 일반인과 보안 담당자에게 필요한 분석 기술중 가장 기본이 되는 PE Header라는 구조체에서 이해하여 파일에서 필요한 정보들을 얻고, 리버스 엔지니어링의 재미를 보여주고자 한다. J

1. 프로그램 분석의 기초

PE 파일 포맷

먼저 PE HEADER 이해를 돕기 위해 PE 파일 포맷이 무엇인지 이해할 필요가 있다.

PE 파일 포맷은 Windows 운영체제에서 정의한 파일 포맷으로 Portable Executable의 약자이다.

PE 파일 포맷의 구조만 가지고도 책한 권을 쓸 수 있는 분량이기에 여기서는 필요한 정보만 다르며, 더 깊이 있게 공부해보고 싶으신 분은 MSDN과 관련 책들을 참고하기를 미리 알리는 바이다.

우리가 흔히 윈도우에서 접하는 확장자중 PE 파일 포맷으로 작성된 파일은 EXE, SCR, DLL, OCX, SYS, OBJ가 있으며, 직접 실행 가능한 EXE를 제외한 나머지 파일 종류중 OBJ를 제외하고는 간접적(서비스, 디버깅, 레지스트리등)으로 실행이 가능한 파일들이다.

다음 그림은 오래전 MSDN에 공개되었던 PE 파일의 일반적은 구조다.

[그림] : PE Header 구조 출처 : MSDN

다른곳에서 제공하는 그림과 약간 모양이 다를수 있지만, 필수 Header들은 동일하다. 위 왼쪽의 그림은 파일상태의 그림으로 필수로 있어야 하는 부분이고, 각 구조체를 구분하는 방법은 각 끝부분은 Null Padding을 통해 구분할 수 있도록 되어있다.

그럼 HEX 에디터로 내용을 더욱 자세히 살펴보자.

그리고 [그림] PE Header 구조의 오른쪽 그림의 메모리에 로딩되었을 때 위치가 변경되는 것은 파일에서는 offset으로 메모리는VA(Virtual Address)로 표현하는데, Section 크기와 위치를 PE Header에 로드될 메모리 위치를 지정하게 되는데, 최소 기본 단위에 맞춰 메모리에서 위치가 변경되게 된다.

[그림] PE Header 구조의 많은 구조체를 크게 DOS Header 그리고, NT Header(위 MSDN 그림상의 PE Header이나 구분을 위해 앞으로 NT Header로 표기), Sections Table을 합쳐서 보통 PE Header라고 부르며 그 위 Section들을 PE Body라고 한다.

그리고 여기서는 PE 구조체를 사람이 구분하기 쉽게 하기 위해, PEView와 PEBrowse를 통해 그림 및 설명을 추가할 것이니, 독자 여러분도 이번 기회에 한번 다루어 보는것도 좋겠다.

이렇게 PE 파일 포맷의 전체적인 구조를 간략히 살펴보았다, 이제부터 여기서 다루어야할 PE Header 그리고 중요한 몇몇 DataDirectory(IAT, EAT등등)에 대해 보다 자세히 알아보자.

DOS Header

DOS Header를 실제 파일에서 어떻게 작성되는지 이해를 위해 위 그림을 다시 참고 하자.

[그림] HxD를 이용하여 확인한 DOS Header의 HEX값

위 그림의 내용 중 네모 박스 안에 내용들이 DOS Header이다. 그 안에는 DOS Stub가 40h부터 포함되어 있는데, 이는 DOS모드에서 실행시, 안내창 같은 역할을 해주며, 없어도 상관이 없는 부분이다. DOS Stub에서는 DOS환경에서 실행시 동작할 내용을 저 공간에 16Bit로 정의한다. 그리고 DOS Header에서는 밑줄 그은 2개의 멤버가 중요한데, MZ코드(ASCII)는 맴버 e_magic의 값으로써 DOS Signature로 모든 PE 파일의 시작하는 코드이다. d0h부터 16Byte가 NULL Padding인 이유가 e_lfanew값와 관계가 있다. 그리고 구조체의 끝은 000000E0는 DOS Header의 멤버 e_lfanew으로, NT Header의 Offset값 즉 시작위치를 표시한다. 그리고 PE코드(ASCII)는 바로 오늘 관심있게 봐야 할 PE Signature다. PE Header 구조체로 Windows에서 실행에 필요한 정보를 저곳에 담고 있다.

DOS Header를 넘어가기 앞서 DOS Header의 구조체는 아래 그림과 같다.

[내용] IMAGE_DOS_HEADER의 구조체 출처: Microsoft SDK WinNT.h

이 정도까지 DOS Header에 대해서는 알아보고, 크게 중요한 내용은 아니기 때문에 여기서는 더 다루지 않겠다. 그럼 다음인 NT Header로 가보자

NT Header

이제부터 본격적으로 PE Header, 즉 IMAGE_NT_HEADERS에 대해 알아보도록 하자.

그럼 먼저 NT Header의 구조체를 확인해 보자.

[내용] IMAGE_NT_HEADER의 구조체 출처: Microsoft SDK WinNT.h

 

NT Header에는 1개의 멤버와 2개의 헤더가 존재하며, 각 멤버/헤더에 대해 계속 확인해 보자.

첫번째 멤버인 1. Signature는 DOS Header의 Signature와 같이, PE(ASCII)코드로 NT Header시작을 알리는 것이다, 그럼 계속 File Header의 멤버의 구조체도 확인해 보도록 하자.

[내용] _IMAGE_FILE_HEADER의 구조체 출처: Microsoft SDK WinNT.h

 

1. Machine은 본 파일이 동작 가능한 머신의 종류를 코드에 담고 있으며, 코드의 내용별 의미는 WinNT.h에 정의되어 있으므로, 아래 내용을 참고하기 바란다.

[내용] IMAGE_FILE_MACHINE의 정의 출처: Microsoft SDK WinNT.h

 

2. NumberOfSection의 현재 PE 파일이 가지고 있는 Section 개수를 의미한다.

3. TimeDateStamp는 파일을 빌드한 시간을 나타내는 값이 된다.

4. SizeOfOptionalHeader는 이 다음에 설명드릴 IMAGE_OPTIONAL_HEADER32 구조체의 크기를 나타내는 값이며, 마지막으로 5. Charcteristics 멤버는 PE 파일 속성에 대한 정보를 가지고 있으며 WinNT.h에 해당 설명이 자세히 나와 있다.

[내용] IMAGE_FILE의 정의 출처: Microsoft SDK WinNT.h

 

이해를 돕기 위해 REGEDIT의 실제 코드를 확인해 보자

[그림] PEBrowse를 통해 확인한 File Header 구조체

REGEDIT.EXE의 Characteristics의값인 102h는 0x0100, 0x0002를 표현한 값으로 위 그림과 같이 32bit machine에 실행파일이라는 정보를 얻을 수 있다. 앞에 설명한 Machine의 값인 14ch는 Intel 386 호환 모델이라는 것을 나타낸다.

이렇게 FileHeader를 지나, 이제부터 중요한데, IMAGE_OPTIONAL_HEADER32의 구조체를 살펴 보도록 하자.

[내용] IMAGE_OPTIONAL_HEADER32의 구조체 출처: Microsoft SDK WinNT.h

 

1. Magic는 IMAGE_OPTIONAL_HEADER32(32Bit), IMAGE_OPTIONAL_HEADER64(64Bit)인지를 구분하는 값으로, 32Bit인 경우 10bh, 64Bit인 경우 20bh의 값을 가지게 된다. 2. SizeOfCode는 .text Section의 파일 크기를 나타내는데, 이후 나오는 .text Section의 SizeOfRawData와 같은 값을 가진다.

3. AddressOfEntryPoint는 많이 접하게 되는 값으로, 프로그램 시작점(Entry Point)를 위치하며 상대주소(Relative Virtual Address) 값을 나타낸다. 메모리에서는 로딩이 완료후 ImageBase + AddressOfEntryPoint값을 EIP 레지스터에 대입해 프로그램을 시작하게 된다.

4. BaseOfCode, 5, BaseOfData는 Code와 Data의 시작 주소를 가진다.

6. ImageBase는 메모리 내에 파일이 로딩이 되는 시작 주소를 가진다.

7. SectionAlignment, 8. FileAlignment는 메모리와 파일에서 세션의 최소 단위를 나타내는 값으로 해당 세션 크기는 반드시 SectionAlignment, FileAlignment의 배수로 되어야 하므로 남는 바이트는 NULL로 채워지게 된다.

9. SizeOfImage는 메모리에 로딩될 전체 크기이고, 10. SizeOfHeader는 파일에서 PE Header의 전체 크기를 나타낸다.

11. Subsystem는 본 프로그램의 구동하는 기반 환경을 나타낸 값으로 WinNT.h에 정의되어있다.

[내용] Subsystem의 정의 출처 : Microsoft SDK WinNT.h

 

12. NumberOfRvaAndSizes는 DataDirectory 배열의 개수를 표시한다. WinNT.h에 10h(16)으로 정의되어 있지만, 실제로는 PE Header의 값을 참조한다.

13. DataDirectory에 조금 길기 때문에 아래 설명 하겠다.

그럼 여기서 실제 REGEDIT의 Optional Header값을 가지고 확인해보자

[그림] PEBrowse의 Optional Header 정보를 확인한 화면

REGEDIT의 Magic값은 10bh로 IMAGE_OPTIONAL_HEADER32(32bit)임을 나타내고 있다.

SizeOfCode의 크기는 1b600h(112128)이며, Code의 시작 위치는 RVA(상대주소)로 1000+1000000(ImageBase) = 1001000h 이며, 세션과 파일의 기본 단위는 1000h(4096)/200h(512)가 된다.

REGEDIT의 전체 크기는 67d78h(425336)이고, Header의 전체 크기는 400h(1024)로 구성되어 있고, Subsystem은 2h로써 Windows GUI 기반 응용프로그램임을 나타낸다.

DataDirectory 배열의 개수는 10h(16)로 되어 있다.

이제 13. DataDirectory의 IMAGE_DATA_DIRECTORY 구조체를 살펴보자.

[내용] IMAGE_DATA_DIRECTORY 구조체 출처 : Microsoft SDK WinNT.h

 

아래 16개의
Directory Entry중 중요한 항목은 아래 굵게 표시했다. 본 4가지 항목은 PE Header에서 필수로 이해가 필요한 핵심부분으로 IAT(Import Address Table), EAT(Export Address Table)과 큰 연관이 있다. IAT, EAT에 대해서는 아래 Section Header을 설명한 이후 다루도록 하겠다. 이외 몇가지 더 있지만 이는 따로 공부해보기 바란다. 미리 간략히 애기하자면, PE 파일이 어떤 라이브러리를 제공하고/필요한지를 정의한 테이블의 위치와 크기가 DataDirectory에 위치한다.

[내용] PEBrowse로 확인한 DataDirectory의 구조체

 

Section Header

이렇게 IMAGE_OPTIONAL_HEADER32로 NT Header을 지나, PE Header의 마지막인 Section Header의 구조체를 확인하자.

[내용] IMAGE_SECTION_HEADER 구조체 출처 : Microsoft SDK WinNT.h

 

설명을 드리자면,

1. VirtualSize는 메모리에서 해당 세션이 차지하는 크기이고, 2. VirtualAddress는 메모리에서 해당 Section이 시작하는 주소값을 확인할수 있다.

3. SizeOfRawData는 파일에서 세션이 차지하는 크기이며,

4. PointerToRawData는 파일에서의 세션이 시작하는 위치 값이다.

5. Characteristics는 Section의 특징이 나타내는데 WinNT.h에서 해당 값의 세부 멤버를 확인할 수 있다.

[내용] Characteristics의 정의 출처 : Microsoft SDK WinNT.h

 

예를 들어 REGEDIT의 Characteristics값인 6000020h이라면, 20h(코드영역)으로 40000000h(읽기), 20000000h(쓰기)가 가능하다는 의미이다.

아래는 REGEDIT를 Ollydbg로 Section Header의 값을 확인한 결과이다. 보는데 크게 무리가 없을 것은 생각된다.

[내용] Ollydbg로 확인한 Section Header의 구조체

 

이제 앞서 애기하였던 중요한 IAT, EAT에 대해 확인해 보자

IAT(Import Address Table), EAT(Export Address Table)

IAT는 PE Header 이해에 있어 제일 중요한 부분이라고 할 수 있다, 그래서 이 부분은 필수로 이해하여야 한다.

IAT는 프로그램이 필요로 하는 라이브러리의 함수들의 기술한 테이블이다.

Windows 운영체제에서 PE 파일내에 사용되는 함수들을 파일에 포함하지 않고, 여러 프로세스가 공유하도록 설계되었다. 이로써 메모리 낭비를 막을 수 있고, 파일의 크기도 줄일 수 있는데, 쉽게 셜명 하자면,

CreateFile을 하기 위해, 해당 함수를 파일내에 포함하는 것이 아닌, 별도 라이브러리(DLL)화된 파일의 해당 함수 위치를 기억해 놓았다가 필요 인자값들과 함께 해당 함수를 호출하게 된다.

그리하여 DLL(Dynamic Linked Library)라는 개념이 나오게 되었으며, 프로그램을 실행할 떄 IAT에기술된 함수의 위치를 확인하는데, DLL의 함수 위치를 고정하지 않은 이유는 Windows 운영체제 마다 위치가 다를수 있고, DLL이 메모리에 로딩된 위치가 변경될수 있기 때문에, 프로그램 실행시, PE 파일에서 필요로 하는 DLL의 함수들의 주소값들을 조사하여 갱신하고, 프로그램 종료시 주소값을 저장하지 않고, 해제되게 된다.

예로, REGEDIT의 GetStartupInfoA를 호출하는 과정을 보자면, IAT의 특정 주소에 GetStartupInfoA라는 함수의 주소값을 지정되어, 프로그램은 단지 IAT의 주소값을 호출하면 프로그램이 실행시 실행중인 Windows의 해당 함수 위치를 찾아 IAT를 갱신하게 된다.

OLLYDBG를 위해 실제 CALL 명령문을 확인해 보았다. 프로그램 내에서는 단지 특정 IAT의 주소값을 가리키는 것으로 실행되는 것을 확인할 수 있다.

[그림] Ollydbg로 확인한 GetStartupInfoA를 호출하는 주소

EAT(Export Address Table)은 반대로 자신이 라이브러리가 되어, 다른 프로그램들에게 자신의 함수를 제공하게 된다.

그럼 IAT의 사용되는 구조체 IMAGE_IMPORT_DESCRIPTOR와 IMAGE_IMPORT_BY_NAME를 확인해 보자.

[내용] IMAGE_IMPORT_DESCRIPTOR 구조체 출처 : Microsoft SDK WinNT.h

 

IMAGE_IMPORT_DESCRIPTOR 구조체는 다른 이름으로도 불리는데, IMPORT Directory Table이라고는 이름으로도 불리니, 용어에 혼동이 없기를 바란다.

1. Name는 라이브러리(DLL)의 이름값이 들어 있는 주소를 확인 할 수 있습니다.

2. OriginalFirstThunk의 값을 통해 아래 IMAGE_IMPORT_BY_NAME 구조체를 가르켜, 함수 이름 문자열을 확인하고, 각 값들을 얻어오게 되는데, IMAGE_IMPORT_BY_NAME의 구조체 정보는 아래와 같다.

[내용] IMAGE_IMPORT_BY_NAME 구조체 출처 : Microsoft SDK WinNT.h

 

3. FirstThunk는 라이브러리의 주소 값이 들어있는 주소를 가리키게 되며 NULL을 만날 때까지 해당 라이브러리 안의 함수 주소 값을 가져오게 된다

다음 그림을 통해 이해를 조금 쉽게 했으면 한다.

OriginalFirstThunk를 통해 함수 이름을 확인하고, FirstThunk를 통해
해당 함수를 주소를 확인하다는것이 핵심이 있다.

[그림] PEview로 확인한 kernel32.dll의 IAT 정보

여기서 EAT에 대해서는 자세히 언급하지는 않지만, 기본적으로 IAT와 크게 다르지 않으므로 IAT를 이해 했다면, EAT를 이해하는건 크게 어렵지 않을 것이다.

그럼 EAT의 구조체를 확인해 보자.

[내용] IMAGE_EXPORT_DIRECTORY 구조체 출처 : Microsoft SDK WinNT.h

 

먼저 1. Name을 통해 해당 DLL의 이름을 얻는다, 그리고 2. NumberOfFunctions을 통해 제공하는 함수의 개수를 확인하고, 3. NumberOfNames를 통해 이름있는 함수의 개수를 확인한다.

그후, 4. AddressOfFunctions를 통해 함수의 주소 위치 값을 RVA(상대주소)로 확인하고, 해당 주소의 이름은 5. AddressOfNames를 통해 확인하게 된다. 마지막 6. AddressOfNameOrdinals은 제공함수들의 번호로 마지막 번호가 NumberOfNames와 같다.

그럼 예제를 통해 확인해 보자

AddressOfNames를 통해 함수 이름을 확인하고, AddressOfFunctions를 통해
해당 함수를 주소를 확인하다는것이 핵심이 있다.

[그림] PEview로 확인한 kernel32.dll의 EAT 정보

이제 PE Header를 통해 프로그램의 전체적인 정보를 확인할 수 있게 되었다. 이로써 프로그램 분석을 위한 기본적인 준비가 완료 된 것이다. 여기서 확인한 내용들은 차후 파일 분석이 큰 도움이 될 것이다. 이제 실제 프로그램을 통해, 지금 배운 내용을 사용해 보도록 하자. J

2. 프로그램 분석의 준비 및 실전 분석

분석 준비

프로그램 분석에 있어 먼저 분석에 필요 프로그램을 준비할 필요가 있다

설명하자면, 프로그램 코드 이해를 위해 만든 컴파일러에 대해 알아야 하고, PE Header 구조를 파악하고, 디버거를 통해 파일 내용을 분석하여야 할 것 이다.

그리고 추가로, 시스템 환경 변화를 감시하기 위해 포랜식 도구들에 대해서도 확인하여야 한다

그럼 다음 내용에 기입된 툴들을 준비해 보자

1. 컴파일러 확인 – PEiD

http://www.peid.info/

2. PE Header 구조 확인 – PEview, PEBrowse

http://www.magma.ca/~wjr/

http://www.smidgeonsoft.com/

3. 디버거 – IDA, Ollydbg

http://www.datarescue.com/

http://www.ollydbg.de/

4. 시스템 레지스티리, 파일의 변화 확인 – ProcMon

http://technet.microsoft.com/en-us/sysinternals/bb896645

[내용] 실전 분석에 필요한 도구들

이외에도 여러 도구들이 있다. 여기서 언급한 툴 외에도 많은 도구들이 사용되지만, 여기서는 일반적으로 사용되는 툴로 예제 분석에 필요한 도구들만 언급하였으니, 그외 툴들에 대해서는 본인들이 찾아보기를 권장한다.그리고, 대다수 툴들이 설치가 필요 없을 툴들이며, 설치 역시 어렵지 않다.

위 툴들을 준비하였다면, 이제 본격적으로 분석을 진행하도록 하자

실전 분석

분석전 미리 애기하자면, 실제 프로그램 분석에 있어서는 PE Header만으로는 부족하다,

리버스 엔지니어링 기술을 사전에 이해하여야 실전 프로그램 분석을 원활히 진행할 수 있다.

하지만 여기서는 해당 부분에 대해서 자세히 다루지 않을 예정이니, 이점을 이해해주기를 바란다.

여기서 분석할 프로그램은 ntsec.exe로, NT 보안 설정용으로 만든 간단한 프로그램이다.

따라서 초기 분석용도로 사용하기에 적합하다.

이 프로그램은 4가지 보안 설정 기능을 제공인데, 다음과 같다.

TCP SYN Protect

Root Share Disable

Login Banner Enable

Last Login User Diable

이 프로그램의 실행 구조를 우리가 배운 PE Header를 이용하여 역분석을 진행해보자.

앞서 다른 PE Header 값들에 대해서도 확인하여야 하지만, 그렇게 진행하기에는 지면을 많이 차지하므로, 개인의 몫으로 남기고, 여기서는 바로 해당 프로그램 분석을 위해 ntsec.exe가 사용하는 API를 확인하기 위해, PEiD 확인후, PEBrowse로 해당 파일을 열어, IAT를 확인해 보도록 하자.

[그림] PEiD로 확인한 ntsec의 PE Header 구조

PEiD를 사용하는 이유는 프로그램에 사용된 언어를 사전에 확인하여, 언어별 코드의 차이점을 사전에 인지하고자 함에 있다. 그외의 유용한 정보들도 많이 얻을수 있으므로, 파일분석시에 적용 활용하도록 하자.

그럼 이제 IAT를 확인해 보자.

[내용] PEBrowse로 확인한 ntsec의 IAT 구조체

 

많은 API가 사용되는 것을 확인할 수 있다.

이중 KERNEL32.DLL은 프로그램 실행에 기본적으로 필요한 함수들이 많다,

이를 전부 분석하기란 매우 큰 작업이 될 것이다. 이를 위해 분석할 API를 정해야 하는데,

여기서는 ADVAPI32.DLL, SHELL32.DLL을 먼저 확인 하도록 하겠다.

ADVAPI32.DLL

(+0x0000) 0x00027396 (356, RegDeleteValueA)

(+0x0004) 0x00027366 (347, RegCloseKey)

(+0x0008) 0x00027374 (390, RegSetValueExA)

(+0x000C) 0x00027386 (370, RegOpenKeyExA)

SHELL32.DLL

(+0x014C) 0x000273B6 (114, ShellExecuteA)

위 API들을 MSDN에서 확인 하면 해당 API를 이해하는데 큰 도움이 된다.

[내용] RegDeleteValueA RegSetValueExA ShellExecuteA API 함수 출처 : MSDN

 

물론 이름만으로도 용도를 확인이 가늠할 정도이다.

RegDeleteValueA 는 registry의 값을 지우는 것이고, RegSetValueExA은 registry의 값을 설정하는 API 함수 이다. 그리고 ShellExecuteA는 CLI에서 처럼 특정 파일을 실행할 수 있는 API이다.

따라서 ntsec.exe은 레지스트리의 값을 바꾸고, 특정 명령을 실행하는 기능이 들어있다고 추측할 수 있다. 이렇게 추측으로 분석을 완료 할 수도 있지만, 확실히 어떤 값을 쓰고, 실행하는지 확인할 필요가 있다. 그리고 이렇게 확인한 정보는 디버깅시 등대와 같은 역할을 해줄 것이다.

이제 본격적으로 파일을 분석을 해보자, IDA, Ollydbg등을 통해 정적 혹은 동적 분석을 진행하고 Procmon등을 통한 실행상태를 확인하면서 분석을 진행하면 된다.

여기서는 많은 API중 RegSetValueExA, ShellExecuteA에 브레이크포인트를 걸어놓고, Ollydbg로 프로그램을 구동해 보도록 하자.

[그림] Ollydbg로 RegSetvalueExA, ShellExecuteA에 브레이크포인트 설정

위 그림과 같이 설정후 프로그램을 실행하면 아래와 같은 내용에서 브레이크포인트가 걸리며, 실행내용을 확인할 수 있다.

[내용] Ollydbg로 확인한 RegSetvalueExA, ShellExecuteA의 진행 내용

 

이제 실제 실행하는 코드들을 확인하여, 프로그램이 어느 레지스트리를 쓰는지 어떤 실행 명령을 사용하는지 위 내용과 같이 파악하였다. 앞서 설명한 ntsec의 동작 내용과 크게 다르지 않고, 위 내용에 대해서는 쉽게 이해할 수 있을 거라 생각되어, 추가로 설명하지는 않겠다.

여기에 각 API별 정확한 분석을 하고자 한다면, 앞서 확인한 MSDN을 통해 확인한 API 함수에 기재된 멤버들과, 위 내용에 나타난 각 값들을 비교하면 이해하는데 큰 도움이 될 것 이다.

그럼 이제 IDA를 통해 다른 코드들에 대해서도 확인해 보도록 하자, IDA를 통한 분석은 Ollydbg 이후 꼭 진행이 필요한 것은 아니다.

여기서는 소개를 위해 이렇게 진행하는 것이고 실제는 IDA 분석만 하여도 되고, Ollydbg로만 분석하여도 충분하다는 점을 알려드린다.

그럼 IDA를 통해 ntsec.exe를 열어서, 우리가 분석하지 않은 부분을 확인해 보자

[그림] IDA로 확인한 RegDeleteValueA의 흐름도

위 내용은 RegDeleteValueA를 IDA로 확인한 내용인데, 그림과 같이 IDA의 큰 장점은 전체적인 프로그램의 내용을 흐름도 처럼 확인이 가능하다는 것이다. 이를 통해 프로그램의 처리 흐름을 쉽게 이해할 수 있을 것이다.

이제 마지막으로 ProcMon등을 통해 시스템의 변화를 감시하여 기록하면, 실제적인 환경 변화에대해 분석을 할 수 있다.

[그림] Process Monitor를 통해 확인한 Registry 모니터링 값

위 그림과 같이 ntsec.exe 프로그램이 접근하고, 변경한 Registry 내용을 모니터링 하므로써, 실제 디버깅 한 내용대로 작동됨을 검증할 수 있고, 코드상 확인하지 못한 변화되는 내용을 확인할 수 있게 된다.

이외에도 여러 도구를 통해 다각도로 해당 프로그램을 분석할 수 있지만, 여기서는 이만 줄이고

그 부분들은 각자의 몫으로 남기도록 하겠다.

마치며

앞으로 역분석에 있어 바이러스 분석은 가상화 머신 에서 네트워크를 차단하고 분석을 하기를 권한다. IDA, Ollydbg에서 분석을 진행하는 것도, 프로그램이 실행이 되므로 현재 운영중인 운영체제에 영향주기 때문에 바이러스를 분석을 한다고 실제 머신 에서 분석을 한다면, 아주 위험한 상황이 연출될 수 있다.

그리고 앞으로 어셈블리, 패킹, 후킹과 같은 언어와 기술들의 이해하고 여러 프로그램 경험하여 숙달하여야 할 것이다.

이리 저리 내용이 길어졌지만, 리버스 엔지니어링에서는 분석의 흐름을 이해하는 게 매우 중요하다. 그래서 PE Header를 먼저 분석하여, 분석의 흐름을 잡을 수 있는 큰 단서를 발견할 수 있다는 것은, 모래밭에서 바늘을 찾은 것과 같이 중요하다.

예전 읽었던 책 중에 인상 깊은 구문이 있었는데, “고전을 배워라.”였다. 요즘 나온 기술들은 기존 기술들을 흡수하면서 파생되어, 원리를 이해하는 게 더욱 힘들게 되어있다. 하지만 기초가 되는 기술들은 탄탄히 배워놓는다면, 그에 파생된 응용기술들을 쉽게 이해하고, 자신의 원하는 대로 응용 있을 것이다. 여기서 리버스 엔지니어링을 시작하고자 하시는 분이 있다면, 기본기를 잘 다지기 바란다. 그리고, 포기하지 말고, 많이 경험해 보길 권하며, 글을 여기서 마치겠다.

Facebook Comments

Leave A Reply

이메일은 공개되지 않습니다. 필수 입력창은 * 로 표시되어 있습니다.