본문 바로가기
리버싱(Reversing)/리버싱 개념

리버싱 핵심원리 13장(PE File Format)

by LIZ0904 2020. 10. 5.
반응형

1. PE File Format

PE(Portable Executable) 파일 또는 PE32 : Windows 운영체제에서 사용되는 32bit형태의 실행 파일 형식

(64비트형태의 PE파일은 PE+ 또는 PE32+ 라고 불림)

 

PE 파일 종류에는 아래 표에 명시되어 있다. obj 파일을 제외한 모든 파일은 실행가능하다.

종류

주요 확장자

종류

주요 확장자

실행계열

exe, scr

드라이버 계열

sys, vxd

라이브러리 계열

dll, ocx, cpl, drv

오브젝트 파일 계열

obj

 

 

 

 

2. 기본 구조

 

DOS header부터 Section header까지는 PE헤더, 그 밑의 Section들은 PE 바디라고 한다. 파일에서는 Offest으로, 메모리에서는 절대주소(Virtual Address)로 위치를 표현한다. 파일이 메모리에 로딩되면 모양이 달리지며, 내용은 보통 코드, 데이터, 리소스 섹션에 나뉘에서 저장된다.

 

섹션헤더에는 각 섹션에 대한 파일/메모리에서의 크기, 위치, 속성 등이 정의되어 있으며, PE 헤더의 끝부분과 각 섹션의 끝에는 NULL padding 영역이 있다. 최소 기본 단위 개념을 사용하기 때문에, 파일/메모리에서 섹션의 시작위치는 최소 기본 단위의 배수에 해당해야 하는 위치여야 하고 나머지 공간은 NULL로 채워버림으로써 NULL padding 영역이 생긴다.

 

 

 

 

3. VA(절대주소)와 RVA(상대주소)

VA(Virtual Address)는 프로세스 가상 메모리의 절대주소를 말하며, RVA(Relative Virtual Address)는 어느 기준 위치(ImageBase)에서부터의 상대주소를 말한다. 즉, 어느 기준 위치(ImageBase)에서부터 상대주소(RVA)를 더하면 절대주소(VA)가 나오게 되는 것이다.

 

 

 

 

 

4. PE 헤더

PE헤더는 많은 구조체로 이루어져 있다.

 

(1) DOS Header

PE File Format은 DOS 파일에 대한 하위 호환성을 고려해 만들어졌는데, 그 결과로 크기는 40의 IMAGE_DOS_HEARDER 구조체가 생겨났다.

이 구조체에서는 e_magic과 e_lfanew 멤버를 유심히 봐야 한다. e_magic은 DOS signature로, 4D5A(아스키 값으로 MZ)으로 나타난다. e_lfanew는 NT header의 Offest을 표시하는데, 파일에 따라 가변적인 값을 가진다. 즉, 모드 PE파일은 시작 부분에 'MZ'가 존재하고, e_lfanew 값이 가리키는 위치에 NT Header 구조체(IMAGE_NT_HEARDERS)가 존재한다는 의미다. 

 

 

(2) DOS Stub

DOS Header 아래에는, 코드와 데이터의 혼합으로 이루어져 있는 DOS Stub이 존재한다. 이는 크기가 일정하지 않고, 옵션으로 설정되며(개발도구에서 지원해줘야 함), 없어도 파일 실행에는 딱히 문제가 없다. 

 

 

(3) NT Header - IMAGE_NT_HEADERS

IMAGE_NT_HEADERS 구조체는 Signature(값 : 5045000h, PE00), File Header, Optional Header 구조체 멤버가 있다. 총 크기는 F8로 상당히 큰 구조체이다.

 

 

(4) NT Header - File Header

IMAGE_NT_HEADERS 구조체의 구조체 멤버인 File Header는 IMAGE_FILE_HEADER 구조체이다. 파일의 개략적인 속성을 나타내며, 아래 표에 명시된 4가지 멤버들이 정확히 세팅되어 있지 않으면 파일은 정상적으로 실행되지 않는다.

멤버

역할

내용

Machine

CPU 별로 고유한 값

32비트 Inter x86 호환 칩은 14C의값을 가짐.

NumberOfSections

PE 파일은 코드, 데이터, 리소스 등의 섹션에 나뉘어서 저장되는데, 여기서 그 세션의 개수를 의미함.

반드시 0보다 커야하며, 정의된 섹션 개수와 실제 섹션이 다르면 에러가 발생함.

SizeOfOptionalHeader

IMAGE_NT_HEADERS 구조체의 마지막 멤버는 IMAGE_OPTIONAL_HEADER32 구조체인데, 이 구조체의 크기를 나타냄.

PE+32 형태의 파일인 경우 IMAGE_OPTIONAL_HEADER64 구조체를 사용하는데, 32와 64 구조체의 크기가 달라 SizeOfOptionalHeader 멤버에 크기를 명시하는 것임.

Characteristics

파일의 속성을 나타내는 값으로, 실행가능한지/DLL파일인지 등의 정보들이 bitOR 형식으로 조합되어 있음

PE파일 중에 object 파일/recource DLL 같은 파일일 경우, not executable인 경우가 있을 수 있음.

 

 

(5) NT Header - Optional Header

PE 헤더 구조체 중 가장 크기가 큰, IMAGE_OPTIONAL_HEADER32 구조체이다. 아래 표에 명시된 9가지 멤버들이 정확히 세팅되어 있지 않으면 파일은 정상적으로 실행되지 않는다.

멤버

역할

내용

Magic

IMAGE_OPTIONAL_HEADER32면 10B, IMAGE_OPTIONAL_HEADER64면 20B 값을 가짐

AddressOfEntryPoint

EP(Entry Point)의 RVA(상대주소) 값을 갖고 있음.

프로그램에서 최초로 실행되는 코드의 시작주소이기 때문에 매우 중요함.

ImageBase

PE 파일이 로딩되는 시작주소를 나타냄.

일반적으로 개발도구들이 만들어내는 exe파일의 ImageBase 값은 00400000, DLL 파일의 ImageBase값은 10000000임.

FileAlignment, SectionAlignment

FileAlignment - 파일 섹션의 최소 단위
SectionAlignment - 메모리 섹션의 최소단위

파일/메모리의 섹션크기는 FileAlignment, SectionAlignment의 배수가 되어야 함.

SizeOflmage

PE 파일이 메모리에 로딩되었을 때 가상 메모리에서 PE Image가 차지하는 크기

일반적으로 파일크기와 메모리에 로딩된 크기는 다르기 때문에 존재함.

SizeOfHeader

PE 헤더의 전체 크기

FileAlignment의 배수여야 하며, 파일 시작에서 SizeOfHeader Offset만큼 떨어진 위치에 첫번째 섹션이 위치함.

Subsystem

시스템 드라이버 파일(.sys)인지 일반 실행파일(.exe, .dll)인지 구분할 수 있는 값

NumberOfRvaAndSizes

DataDirectory 배열의 개수

DataDirctory 배열의 개수는 16으로 명시되어 있지만, PE로더는 NumberOfRvaAndSizes를 보고 배열의 크기를 인식함.

DataDirectory

IMAGE_DATA_DIRECTORY 구조체의 배열로, 배열의 각 항목마다 정의된 값을 가짐

 

 

(6) 섹션 헤더

각 섹션의 속성(property)을 정의한 것이 섹션헤더이다. 프로그램의 안정성을 위해서 만들어진 것으로 저자는 유추하고 있다. 

 

 

 

 

 

5. RVA to RAW

PE 파일이 메모리에 로딩되었을 때, 각 섹션에서 메모리의 주소(RVA)와 파일 옵셋을 매핑하는 것을 일반적으로 RVA to RAW 라고 부른다. Offset에 RVA를 더하면 된다.

반응형

댓글