PE File Format이란?
Windows 실행 파일의 구성 방식
개발자가 코드를 작성하면 개발도구(VisualStudio)의 컴파일러가 PE File Format에 맞게 실행 파일로 만들어줌
- 컴파일 과정: 전처리기 -> 컴파일러 -> 어셈블러 -> 링커
PE File 구조
- PE Header: DOS Header, Dos stub, NT Header, Section Header로 구성
- PE Body: 섹션들로 구성
PE File Header
작은 구조체들이 모여서 만들어진 데이터 덩어리
- DOS Header: DOS와 호환성을 위해서 만들어짐. 파일의 처음에 위치하고 0x40 크기를 가짐
- DOS Stub: PE 파일이 MS-DOS에서 실행될 경우, 화면에 출력될 메시지와 코드가 기록되어 있음. 옵션이기 때문에 실행에 영향 없음.
- NT Header: 파일 실행에 필요한 전반적인 정보를 가지고 있음. 0xF8 크기를 가짐
- Section Header: 각 섹션의 속성 정보를 가지고 있음
1. DOS Header
IMAGE_DOS_HEADER 구조체에 값을 채워서 만듦
- DOS Signature(2byte): "MZ(0x4D5A)"라는 시작 값을 가짐
- NT Header Offset(4byte): NT 헤더의 시작 지점에 대한 정보를 가지고 있음
2. DOS Stub
16bit 명령코드와 데이터의 혼합으로 이루어져 있음
3. NT Header
파일 실행에 필요한 전반적인 정보를 가지고 있음
- PE Signature(4byte): 0x50450000 값을 가짐
- File Header: "IMAGE_FILE_HEADER" 구조체에 값을 채워서 만듦
- Optional Header: "IMAGE_OPTIONAL_HEADER32" 구조체에 값을 채워서 만듦
이렇게 3개의 멤버로 구성되어있는데, 2, 3번 멤버 각각은 하나의 작은 구조체임
3-1. PE Signature
PE 로더는 이 값을 보고, 올바른 PE 파일인지 확인함
3-2. File Header
파일의 물리 정보를 가지고 있음
- Machine(2byte): 파일이 실행될 UPU 타입 정보를 가지고 있음
- Number of Sections(2byte): 섹션 개수의 정보를 가지고 있음
- Size of Optional Header(2byte): Optional Header의 크기 값을 가지고 있음
- Characteristics(2byte): 파일의 속성 정보를 가지고 있음. EXE와 DLL 구분
3-3. Optional Header
파일의 논리 정보를 가지고 있음
- Magic(2byte): Optional Header 구조체 뒤에 32가 붙을 경우 0x010B, 64가 붙을 경우 0x020B
- Address of EntryPoint(4byte): 파일의 코드 시작 지점에 대한 RVA 값을 가지고 있음
- Image Base(4byte): 파일이 메모리에 올라갈 때, 기준이 되는 주소 값
- EXE: 0x00400000
- DLL: 0x10000000
- Section Alignment & File Alignment(4byte)
- File Alignment는 파일에서 섹션의 최소 단위
- Section Alignment는 메모리에서 섹션의 최소 단위
- Major O/S Version(2byte)
- Size of Image(4byte): 메모리에 올라간 파일 데이터의 크기 값
- Size of Headers(4byte): DOS Header, NT Header, Section Header를 합친 총 크기 값
- subsystem(2byte)
- Number of Data Directories(4byte): Data Directory의 개수
- Data Directories(-): Number of Data Directories 필드의 개수만큼 활성화. 일반적으로 0x10개의 정보를 가짐
4. Section Header
PE 파일이 가지는 섹션 수만큼 존재
- Section Name(8byte): 섹션의 이름 정보
- VirtualSize(4byte): 메모리에서 섹션이 차지하는 크기
- RVA(4byte): 메모리에서 섹션의 시작 주소
- SizeOfRawData(4byte): 파일에서 섹션이 차지하는 크기
- OffsetToRawData(4byte): 파일에서 섹션의 시작 주소
- Characteristics(4byte): 섹션의 속성 정보
▶ 위치 표현
- OffSet: 파일에서의 위치
- VA: 메모리에서의 위치
- RVA: 메모리에서의 파일의 시작 주소를 기준으로 상대 위치
∴ VA = Image Base + RVA
PE File Body
Section 유형
- Code
- .text: 프로그램 실행 코드를 담고 있는 섹션
- Data
- .data: 읽고 쓰기가 가능한 데이터 섹션, 초기화된 전역 변수와 정적 변수 등
- .rdata: 읽기 전용 데이터 섹션, 상수형 변수, 문자열 등
- .bss: 초기화되지 않은 전역 변수
- Import API
- .idata: Import할 DLL과 API에 대한 정보를 담고 있는 섹션
- .didat: Delay-loading importDLL 정보
- Export API
- .edata: Export할 API 정보를 담고 있는 섹션(주로 DLL에서 사용)
- Resource
- .rsrc: 리소스 관련 데이터를 담고 있는 섹션(예) 아이콘, 커서 등
- 재배치 정보
- .reloc: 기본 재배치 정보를 담고 있는 섹션(주로 DLL에서 사용)
- TLS
- .tls: 스레드 지역 저장소
- Debugging
- .debug$p: 미리 컴파일된 헤더 사용 시에만 존재
Notepad.exe PE 분석