PE File Format 0x03
0x01. NT Header
Windows에서 제공하는 WinNT.h의 _IMAGE_NT_HEADERS 구조체입니다.
"PE.."(50 45 00 00) 값을 가지는 signature
IMAGE_FILE_HEADER 구조체인 FileHeader
IMAGE_OPTIONAL_HEADER32 구조체인 OptionalHeader
위 세가지로 구성되어 있습니다.
IMAGE_NT_HEADERS 구조체의 크기는 0xF8 입니다.
Signature /* PE signature입니다.
ASCII 값으로 "PE.."(50 45 00 00) 입니다.
Portable Excutable을 의미합니다. */
0x02. FileHeader
Windows에서 제공하는 WinNT.h의 _IMAGE_FILE_HEADER 구조체입니다.
파일의 개략적인 속성을 나타냅니다.
중요한 부분은 Machine, NumberOfSections, SizeOfOptionalHeader, Characteristics 입니다.
Machine /* CPU별로 고유한 값이며 32-bit Intel x86 호환 chip은 0x14C의 값을 가집니다.
Windows에서 제공하는 WinNT.h의 machine number 값들입니다. */
NumberOfSections /* Section은 일반적으로 용도별로 코드 영역, 데이터 영역, 리소스 영역으로 나뉩니다.
Section의 개수는 일정하지 않으며 NumberOfSections가 section의 개수를 나타냅니다.
이 값은 반드시 0보다 커야합니다.
정의된 값보다 실제 section의 수가 적은 경우 오류가 발생합니다.
정의된 값보다 실제 section의 수가 많은 경우 정의된 수 만큼만 인식합니다. */
SizeOfOptionalHeader /* NT header의 마지막에 있는 OptionalHeader의 크기를 나타냅니다.
Windows의 PE loader는 해당 값을 보고 OptionalHeader의 크기를 인식합니다.
OptionalHeader는 _IMAGE_OPTIONAL_HEADER32 구조체로 크기가 정해져 있습니다.
하지만 PE32+ 형태의 파일인 경우에는 _IMAGE_OPTIONAL_HEADER64 구조체를 사용합니다.
두 구조체의 크기가 서로 다르기 때문에 SizeOfOptionalHeader에 크기를 저장하는 것 입니다. */
Characteristics /* 파일의 속성을 나타냅니다.
Windows에서 제공하는 WinNT.h의 characteristics 값들입니다. */
각 값들이 bit-OR 형식으로 조합됩니다.
실행이 가능한지, DLL인지 등의 값을 저장합니다.
0x03. OptionalHeader
이름과는 달리 중요한 정보를 많이 가지고 있습니다.
Windows에서 제공하는 WinNT.h의 _IMAGE_OPTIONAL_HEADER 구조체입니다.
정말 많습니다.
아왜
하나하나 보려니 눈돌아갈것 같습니다.
중요한 부분만 하나씩 살펴보도록 하겠습니다.
Magic /* OptionalHeader의 signature입니다.
_IMAGE_OPTIONAL_HEADER32 구조체인 경우 0x10B가 저장되어 있으며
_IMAGE_OPTIONAL_HEADER64 구조체인 경우 0x20B가 저정되어 있습니다. */
AddressOfEntryPoint /* EP(Entry Point)의 RVA(Relative Virtual Address) 값을 가지고 있습니다.
프로그램에서 최초로 실행되는 code의 시작 주소입니다. */
ImageBase /* PE 파일이 memory에 mapping되는 시작 주소입니다.
프로세스를 생성해 파일이 memory에 mapping되면
초기 EIP는 ImageBase + AddressOfEntryPoint가 됩니다. */
SectionAlignment /* Memory에서 section 크기의 최소 단위를 나타냅니다.
Memory에서 section의 크기는 반드시 SectionAlignment의 배수가 되어야 합니다. */
FileAlignment /* File에서 section 크기의 최소 단위를 나타냅니다.
File에서 section의 크기는 반드시 FileAlignment의 배수가 되어야 합니다. */
SizeOfImage /* PE 파일이 memory에 mapping 되었을 때 PE image가 차지하는 크기를 나타냅니다.
일반적으로 disk 상의 파일 크기와 memory에 mapping된 크기는 다릅니다. */
SizeOfHeader /* PE header의 전체 크기를 나타냅니다.
이 값 역시 FileAlignment의 배수가 되어야 합니다.
파일 시작 지점에서 SizeOfHeader offset 만큼 떨어진 위치에 첫 번째 section이 있습니다. */
Subsystem /* 파일이 system driver file(*.sys)인지 일반 실행 파일인지 나타냅니다.
값이 1 이면 Driver file (*.sys)을 의미하고
값이 2 이면 GUI file(Graphic User Interface file)을 의미하고
값이 3 이면 CUI file(Console User Interface file)을 의미합니다. */
NumberOfRvaAndSizes /* Optional Header의 마지막에 있는 DataDirectory 배열의 수를 나타냅니다.
DataDirectory 배열의 수는 WinNT.h에 명시되어 있지만
Windows의 PE loader는 해당 값을 보고 배열의 크기를 인식합니다.
꼭 16이 아니어도 된다는 뜻입니다. */
DataDirectory /* _IMAGE_DATA_DIRECTORY 구조체의 배열입니다.
각 항목별로 정의된 값을 가지고 있습니다.
Windows에서 제공하는 WinNT.h의 _IMAGE_DATA_DIRECTORY 구조체입니다. */
DataDirectory 배열의 각 항목별 정의입니다.
'Reversing > PE File Format' 카테고리의 다른 글
PE File Format 0x06 (0) | 2012.11.11 |
---|---|
PE File Format 0x05 (0) | 2012.11.07 |
PE File Format 0x04 (0) | 2012.10.31 |
PE File Format 0x02 (0) | 2012.10.29 |
PE File Format 0x01 (1) | 2012.10.28 |