[4주차] PE 구조 분석 & notepad.exe PE 헤더 분석, 가상 메모리 구조 분석

PE파일이란?

리눅스 실행파일이 ELF인 것처럼 윈도우에서 사용하는 실행파일

PE파일의 종류

EXE, DLL, OBJ 등 윈도우OS에서 돌아가는 실행파일들이 있다. 

 

PE파일의 구조

PE 파일은 위 그림처럼 구조체 형식으로 저장되어 있다. 크게는 PE header와 body가 존재한다. 

메모장을 PEview로 열면 구조화되어 있는 걸 알 수 있다. 


1. PE header

1. DOS Header

IMAGE_DOS_HEADER 구조체

1. e_magic: DOS signature이다. PE 파일이라는 걸 나타낸다. MZ로 총 2바이트. 

위 메모장에서도 data가 5A4D로 고정됨을 알 수 있다. 

2. e_lfanew: NT header가 시작되는 위치 offset. 

 

2. DOS stub(옵션) 

DOS환경에서 실행되는 코드+데이터가 적혀있다. 

위를 DOS환경에서 실행하면 "This program cannot be run in DOS mode"를 출력하고 종료한다. 

* DOS: 디스크 운영 체제의 일종.. 

 

3. NT Header 

IMAGE_NT_HEADERS 구조체 

파일 실행에 필요한 정보 저장(중요) 

1. signature:

data를 읽으면(참고로 리틀엔디안) 00004550인데 이것은 PE를 뜻한다. 

2. file header: 파일의 간략 정보를 나타낸다. 

IMAGE_FILE_HEADER 구조체를 갖는다. 

주요 멤버명  의미  notepad.exe 
Machine  실행되는 아키텍처  8664는 AMD64를 나타낸다. 
NumberOfSections  파일에 존재하는 섹션 개수  7개이다. 
SizeOfOptionalHeader  Optional Header의 크기  0x00F0만큼 차지 
Characteristics  속성  bit OR계산을 해보면 
0x0002 EXECUTABLE_IMAGE
0x0020 LARGE_ADDRESS_AWARE 
를 갖는 걸 알 수 있다. 
TimeDateStamp  파일의 생성 일시  value를 보면 2007/06/20에 생성된 걸 알 수 있다. 

 

3. optional header: 파일 실행에 필요한 정보들 저장 

위 파일 헤더에 적혀있던 것처럼 0x00F0만큼 갖는다. 

주요 멤버명  의미  notepad.exe 
Magic  32비트 or 64비트  020B는 64를 의미 
AddressOfEntryPoint  로더가 실행을 시작할 주소 
처음으로 실행될 코드 주소 
19a0부터 .text 
ImageBase  메모리 상의 시작 주소  140000000
SectionAlignment, FileAlignment 섹션의 최소단위  0128
SizeOfImage   Image 전체 크기  5A000 
SizeOfHeader  PE header의 전체 크기  0x1000 
Subsystem  동작환경 정의  0002 -> windows GUI 
NumberOfRvaAndSize  datadirectory배열의 개수  0x10 
DataDirectory  IMAGE_DATA_DIRECTORY 구조체의 배열 

디렉토리별 각각의 정보 작성 
 

 

 

 

4. Section Header 

아래서 설명할 Section에 대한 header이다. 메모리에 로드될 때 참조된다. 

섹션의 자세한 .text, .rdata, .data등은 후술..하고 주요 멤버만 짚고 넘어간다. 

1. VirtualSize: 메모리에서 섹션 크기 

2. VirtualAddress: 메모리에서 섹션의 시작주소(RVA라고 한다) 

3. SizeOfRawData: 파일에서 섹션의 크기 

4. PointerToRawData: 파일에서 섹션의 Offset(길이) 

5. Characteristics: 섹션의 속성(위에서 본 멤버와 같은 원리) 

 

? 디버깅 도중 다른 메모리 영역에 문자열 생성하고 파일로 저장하면 제대로 실행되지 않는 이유

- 해당 주소를 가리켜도 그 주소부터 시작하는 옾셋을 가리키는 멤버가 없으므로 오류 발생 


2. PE body

body는 여러 개의 섹션으로 구성되어 있다. 

code 영역  .text  실행 코드를 담고 있는 섹션 
data 영역  .data  읽고 쓰기가 가능한 데이터 섹션
초기화된 전역변수와 정적 변수 등 위치 
.rdata  읽기만 가능한 데이터 섹션 
상수형 변수, 문자열 상수 등 위치 
.bss  초기화되지 않은 전역변수 위치 
import API  .idata  import할 DLL, API 정보 섹션 
IAT 존재 
.didat  Delay-loading import DLL 정보 섹션 
export API  .edata  export할 DLL 정보 섹션 
Resource  .rsrc  리소스 관련 데이터 정보 섹션 
relocation  .reloc  재배치 정보 섹션 
TLS  .tls 스레드 지역 저장소 
Debugging  .debug$p  미리 컴파일된 헤더가 있을 시 

 

 

notepad.exe에는 위와 같은 섹션이 존재한다. 중요한 code, data 영역 헤더를 살펴보자 

위는 .text의 섹션 헤더이다. 

characteristics를 보면 실행, 읽기 권한이 있다. 

왼쪽이 .data이고, 오른쪽이 .rdata이다. 속성 차이를 보면 왼쪽은 읽기, 쓰기 권한이 있지만 오른쪽은 읽기 권한만 존재한다. 

rdata에는 문자열 상수 등이 위치한다. 

 

 

가상 메모리 구조 분석 

위 그림과 같이 메모리에 PE파일이 로드된다. 

왼쪽 파일에서는 offset의 개념을 쓰지만 오른쪽 메모리에서는 RVA(relative virtual address)을 개념을 차용한다. 

RVA는 시작 주소에 대한 상대적 VA를 말한다. 이 RVA를 이용한 VA 식은 다음과 같다. 

VA = ImageBase + RVA 

 

image_file_header 뒷부분 IMAGE_OPTIONAL_HEADER 구조체에 메모리 로드 관련 멤버들이 존재한다. 아까 위에서 설명했던 optional header에서는 주요 멤버만 설명하고 넘어갔는데 좀 더 자세히 설명해보자면.. 

주요 멤버명  의미 
Magic  실행되는 아키텍처 
SizeOfCode .text의 크기 
AddressOfEntryPoint  로더가 실행을 시작할 주소 
처음으로 실행될 코드 주소 
ImageBase  메모리 상의 시작 주소 
SectionAlignment, FileAlignment 섹션의 최소단위 
SizeOfImage   Image 전체 크기 -> 위 alignment의 배수 
SizeOfHeader  PE header의 전체 크기 -> 위 alignment의 배수 
Subsystem  동작환경 정의 
NumberOfRvaAndSize  datadirectory배열의 개수 
stack, heap 사이즈 관련 멤버  프로세스마다 가지는 자신만의 스택, 힙 
그것들을 생성하기 위한 크기, 속성를 지정해주는 멤버 
DataDirectory  IMAGE_DATA_DIRECTORY 구조체의 배열 

디렉토리별 각각의 정보 작성 

datadirectory를 보면 다음과 같다. 

각 섹션별 RVA와 size가 정의되어 있다. 

'SWING > reversing' 카테고리의 다른 글

[5주차] Crackme#4  (0) 2024.05.13
[5주차] Crackme#5  (0) 2024.05.13
[3주차] 디버깅 실습 문서화  (0) 2024.04.02
[3주차] swing_register_asssignment.exe 분석  (0) 2024.04.02
[2주차] 함수 호출 분석  (0) 2024.03.25