티스토리 뷰

PE(Portable Executeable)이란?

Windows 운영 체제에서 사용되는 실행 파일, DLL(Dynamic Link Library), Object 코드, SYS 드라이버와 같은 파일을 위한 포맷이다.



우리가 흔히 접하는 exe 파일은 다음과 같이 PE File Format의 형태로 구성되어 있고, 크게 보면

구조체 형태로 크기가 정해져 있는 실행 파일의 정보를 담고 있는 "PE Header"와,

프로그램이 실행되었을 때 메모리로 옮겨져야할 코드들과 데이터들을 담고 있는 섹션인 "PE Body"로 이루어져 있다.



PE Header

먼저, PE 파일의 다양한 속성과 필수 정보를 담고 있는 PE Header부터 살펴본다. 

앞에서 언급 했듯이, PE Header는 구조체 형태로 이루어져 있어 그 크기가 정해져 있으며, 크게

IMAGE_DOS_HEADER, IMAGE_NT_HEADERS, IMAGE_SECTION_HEADER 이 세 가지로 구성되어 있다.

(IMAGE_NT_HEADERS 에서는 또다른 구조체로 IMAGE_OPTION_HEADERS 가 포함되어 있다.)


> 전체 PE Header 사진


IMAGE_DOS_HEADER | DOS Stub code

도스 헤더는 말 그대로 Windows DOS 시스템을 위한 헤더이다. 

이 PE Headers는 Windows NT 3.1버전 일 때 처음 도입되었는데, 이 당시에는 아직까지 수많은 프로그램이 DOS 애플리케이션이였고, 다른 NT 이전 버전 윈도우 운영체제들은 전부다 DOS 시스템을 기반으로 실행되어야 했기 때문에 도스 헤더를 버리지 않고, NT 헤더를 도스 헤더 다음에 붙여서 사용했던 것으로 보인다.

또 다른 의미로는 이러한 PE Header의 특징으로 인해 Windows x86 버전과 DOS 버전 두 곳에서 모두 실행될 수 있는 애플리케이션을 제작할 수 도 있다.


다음은 IMAGE_DOS_HEADER의 총 64바이트로 구성된 구조체이다.

typedef struct _IMAGE_DOS_HEADER {
	WORD e_magic; // "ZM" (little endian) -> "MZ (0x4D5A)
	WORD e_cblp;
	WORD e_cp;
	WORD e_crlc;
	WORD e_cparhdr;
	WORD e_minalloc;
	WORD e_maxalloc;
	WORD e_ss;
	WORD e_sp;
	WORD e_csum;
	WORD e_ip;
	WORD e_cs;
	WORD e_lfarlc;
	WORD e_ovno;
	WORD e_res[4];
	WORD e_oemid;
	WORD e_oeminfo;
	WORD e_res2[10];
	LONG e_lfanew;
} IMAGE_DOS_HEADER,*PIMAGE_DOS_HEADER;
// winnt.h

다양한 옵션들이 존재하지만, 본 포스트에서는 NT 헤더 학습을 주 목적으로 하므로, 간단히 두 개만 확인할 것이다.

맨 위의 e_magic과 맨 아래의 e_lfanew 를 살펴도로록 하자.

1. e_magic

PE 파일의 시작을 알리는 데이터(Signiture)이다. 2바이트로 구성되어 있으며, PE 파일을 헥스 에디터로 열어보면 "MZ" 라는 데이터를 확인할 수 있다.

이 값을 변경하게 되면 Windows 에서는 이 파일을 PE 파일로 간주하지 않는다.


2. e_lfanew (0 ~ offset : 60 bytes)

PE 파일 안의 IMAGE_NT_HEADER의 절대 위치(offset)을 가리키는 데이터로, 4바이트가 little endian 으로 저장되어 있다. 

글 서두에 각각의 헤더 데이터는 구조체로 선언되어 있어, 그 크기가 변하지 않는다고 하였다. 하지만 여기에 예외가 존재하는데, 바로 DOS 헤더와 NT 헤더 사이에 존재하는 DOS시스템에서 실행될 수 있는 코드가 존재하기 때문이다.

앞에서 PE 파일 포맷은 DOS 시스템과 32, 64비트 시스템도 지원한다고 하였다. 이러한 점을 위해 Microsoft는 PE헤더의 DOS헤더, NT헤더 사이에 해당 시스템에서 실행 가능한 16비트 명령어를 넣을 수 있는 공간을 만들어 두었고, 이러한 코드를 "Dos Stub" 이라고 한다.

이 명령어의 최대 크기를 제한하지 않기 위해 이 e_lfanew 구조체에 윈하는 NT헤더가 존재하는 파일에서의 위치를 입력함으로써, Dos Stub 코드를 길이 제한 없이 입력할 수 있다.


실제로 대부분의 exe를 헥스 에디터로 뜯어보면 64바이트 이후에 "This program ...." 과 같은 문자열을 찾아볼 수 있는데, 

16비트 시스템에서는 해당 문자열을 출력하고, 프로그램을 종료하는 코드이다.

e_lfanew 에 있는 값을 little endian 으로 읽어서, 파일의 해당 offset 으로 가면 NT Header가 존재하며, (Absolute offset)

NT Header의 signiture인 "PE" (0x5045) 로 확인할 수 있다.



참고:

https://ko.wikipedia.org/wiki/PE_%ED%8F%AC%EB%A7%B7

http://www.reversecore.com/18

https://www.trustwave.com/Resources/SpiderLabs-Blog/Basic-Packers--Easy-As-Pie/

https://upload.wikimedia.org/wikipedia/commons/7/70/Portable_Executable_32_bit_Structure_in_SVG.svg

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG
more
«   2024/05   »
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 29 30 31
글 보관함