본문 바로가기
정상을향해/Program Analysis

PE File Format (3)

by 사이테일 2013. 11. 10.

출처 : http://www.reversecore.com

 

 

NT Header

 

다음은 NT header 구조체 IMAGE_NT_HEADERS 이다.

 

typedef struct _IMAGE_NT_HEADERS {

    DWORD Signature;                          // PE Signature : 50450000 ("PE"00)

    IMAGE_FILE_HEADER FileHeader;

    IMAGE_OPTIONAL_HEADER32 OptionalHeader;

} IMAGE_NT_HEADERS32, *PIMAGE_NT_HEADERS32;

 

* 출처 : Microsoft Visual C++ 에서 제공하는 winnt.h

(위 구조체는 32 bit 용이며, 64 bit 용은 세번째 멤버가 IMAGE_OPTIONAL_HEADER64로 되어있다.)

 

IMAGE_NT_HEADER 구조체는 3개의 멤버로 구성된다.

첫 번째 멤버는 Signature 로서 50450000h ("PE"00) 값을 가진다. (변경 불가!)

그리고 FileHeader OptionalHeader 구조체 멤버가 있다.

 

notepad.exe IMAGE_NT_HEADERS 의 내용을 hex editor로 살펴보자.

 

 

IMAGE_NT_HEADERS 구조체의 크기는 F8h로 상당히 큰 편이다.

FileHeader OptionalHeader 구조체를 하나하나 살펴보자.

 

 

 

IMAGE_NT_HEADERS : IMAGE_FILE_HEADER

 

IMAGE_FILE_HEADER 구조체는 파일의 개략적인 속성을 나타낸다.

 

typedef struct _IMAGE_FILE_HEADER {

    WORD    Machine;

    WORD    NumberOfSections;

    DWORD   TimeDateStamp;

    DWORD   PointerToSymbolTable;

    DWORD   NumberOfSymbols;

    WORD    SizeOfOptionalHeader;

    WORD    Characteristics;

} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;

 

* 출처 : Microsoft Visual C++ 에서 제공하는 winnt.h

 

IMAGE_FILE_HEADER 구조체에서는 다음 4가지 멤버들이 중요하다.

(이 값들이 정확히 세팅되어 있지 않으면 파일은 정상적으로 실행되지 않는다.)

 

 

#1. Machine

Machine 넘버는 CPU 별로 고유한 값이며 32bit Intel 호환 칩은 14Ch 의 값을 가진다.

아래는 winnt.h 파일에 정의된 Machine 넘버의 값들이다. (일반적인 14Ch 의 값을 기억하면 된다.)

 

#define IMAGE_FILE_MACHINE_UNKNOWN           0

#define IMAGE_FILE_MACHINE_I386              0x014c  // Intel 386.

#define IMAGE_FILE_MACHINE_R3000             0x0162  // MIPS little-endian, 0x160 big-endian

#define IMAGE_FILE_MACHINE_R4000             0x0166  // MIPS little-endian

#define IMAGE_FILE_MACHINE_R10000            0x0168  // MIPS little-endian

#define IMAGE_FILE_MACHINE_WCEMIPSV2         0x0169  // MIPS little-endian WCE v2

#define IMAGE_FILE_MACHINE_ALPHA             0x0184  // Alpha_AXP

#define IMAGE_FILE_MACHINE_POWERPC           0x01F0  // IBM PowerPC Little-Endian

#define IMAGE_FILE_MACHINE_SH3               0x01a2  // SH3 little-endian

#define IMAGE_FILE_MACHINE_SH3E              0x01a4  // SH3E little-endian

#define IMAGE_FILE_MACHINE_SH4               0x01a6  // SH4 little-endian

#define IMAGE_FILE_MACHINE_ARM               0x01c0  // ARM Little-Endian

#define IMAGE_FILE_MACHINE_THUMB             0x01c2

#define IMAGE_FILE_MACHINE_IA64              0x0200  // Intel 64

#define IMAGE_FILE_MACHINE_MIPS16            0x0266  // MIPS

#define IMAGE_FILE_MACHINE_MIPSFPU           0x0366  // MIPS

#define IMAGE_FILE_MACHINE_MIPSFPU16         0x0466  // MIPS

#define IMAGE_FILE_MACHINE_ALPHA64           0x0284  // ALPHA64

#define IMAGE_FILE_MACHINE_AXP64             IMAGE_FILE_MACHINE_ALPHA64

 

 

#2. NumberOfSections

PE 파일은 코드, 데이터, 리소스 등이 각각의 섹션에 나뉘어 저장되는데, NumberOfSections는 바로 그 섹션의 개수를 나타낸다.

(이 값은 반드시 0보다 커야 한다.)

 

정의된 섹션 개수보다 실제 섹션이 적다면 실행 에러가 발생하며,

정의된 섹션 개수보다 실제 섹션이 많다면 정의된 개수만큼만 인식된다.

 

 

#3. SizeOfOptionalHeader

IMAGE_NT_HEADERS 구조체의 마지막 멤버는 IMAGE_OPTIONAL_HEADER32 구조체이다.

SizeOfOptionalHeader 멤버는 IMAGE_OPTIONAL_HEADER32 구조체의 크기를 나타낸다.

 

IMAGE_OPTIONAL_HEADER32 C언어의 구조체이기 때문에 이미 그 크기가 결정되어 있다.

그런데 Windows PE Loader IMAGE_FILE_HEADER SizeOfOptionalHeader 값을 보고 IMAGE_OPTIONAL_HEADER32 구조체의 크기를 인식한다.

 

(IMAGE_DOS_HEADERe_lfanew 멤버와 IMAGE_FILE_HEADERSizeOfOptionalHeader 멤버 때문에 일반적인(상식적인) PE 파일 형식을 벗어나는 일명 '꽈배기' PE파일(PE Patch)을 만드는 것이 가능하다.)

 

 

#4. Characteristics

파일의 속성을 나타내는 값으로써, 실행이 가능한 형태인지(executable or not) 혹은 DLL 파일인지 등의 정보들이 bit OR 형식으로 조합된다.

 

아래는 winnt.h 파일에 정의된 Characteristics 값들이다. (0002h 2000h 의 값을 기억해 두자.)

 

#define IMAGE_FILE_RELOCS_STRIPPED           0x0001  // Relocation info stripped from file.

#define IMAGE_FILE_EXECUTABLE_IMAGE          0x0002  // File is executable 

                                                     // (i.e. no unresolved externel references).

#define IMAGE_FILE_LINE_NUMS_STRIPPED        0x0004  // Line nunbers stripped from file.

#define IMAGE_FILE_LOCAL_SYMS_STRIPPED       0x0008  // Local symbols stripped from file.

#define IMAGE_FILE_AGGRESIVE_WS_TRIM         0x0010  // Agressively trim working set

#define IMAGE_FILE_LARGE_ADDRESS_AWARE       0x0020  // App can handle >2gb addresses

#define IMAGE_FILE_BYTES_REVERSED_LO         0x0080  // Bytes of machine word are reversed.

#define IMAGE_FILE_32BIT_MACHINE             0x0100  // 32 bit word machine.

#define IMAGE_FILE_DEBUG_STRIPPED            0x0200  // Debugging info stripped from

                                                     // file in .DBG file

#define IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP   0x0400  // If Image is on removable media, 

                                                     // copy and run from the swap file.

#define IMAGE_FILE_NET_RUN_FROM_SWAP         0x0800  // If Image is on Net,

                                                     // copy and run from the swap file.

#define IMAGE_FILE_SYSTEM                    0x1000  // System File.

#define IMAGE_FILE_DLL                       0x2000  // File is a DLL.

#define IMAGE_FILE_UP_SYSTEM_ONLY            0x4000  // File should only be run on a UP machine

#define IMAGE_FILE_BYTES_REVERSED_HI         0x8000  // Bytes of machine word are reversed.

 

(PE 파일중에 Characteristics 값에 0002h 가 없는 경우(not executable)가 있을까?

그렇다. 예를 들어 *.obj 와 같은 object 파일이 그런 경우이고, resource DLL 같은 파일이 그런 경우 이다.)

 

마지막으로 IMAGE_FILE_HAEDERTimeDateStamp 멤버에 대해서 알아보자.

이 값은 파일의 실행에 영향을 미치지 않는 값으로써 해당 파일의 빌드 시간을 나타낸 값이다.

, 개발 도구에 따라서 이 값을 세팅해주는 도구(VB, VC++)가 있고, 그렇지 않은 도구(Delphi)도 있다.

(또한 개발 도구의 옵션에 따라서 달라질 수 있다.)

 

이제 실제로 notepad.exe IMAGE_FILE_HEADER를 확인해 보자.

 

 

이를 알아보기 쉽게 구조체 멤버로 표현하면 다음과 같다.

 

[ IMAGE_FILE_HEADER ] - notepad.exe

 

 offset   value   description

------------------------------------------------------------

000000E4     014C machine

000000E6     0003 number of sections

000000E8 48025287 time date stamp (Mon Apr 14 03:35:51 2008)

000000EC 00000000 offset to symbol table

000000F0 00000000 number of symbols

000000F4     00E0 size of optional header

000000F6     010F characteristics

                      IMAGE_FILE_RELOCS_STRIPPED

                      IMAGE_FILE_EXECUTABLE_IMAGE

                      IMAGE_FILE_LINE_NUMS_STRIPPED

                      IMAGE_FILE_LOCAL_SYMS_STRIPPED

                      IMAGE_FILE_32BIT_MACHINE

 

 

'정상을향해 > Program Analysis' 카테고리의 다른 글

Python Hacking Programming (2)  (0) 2013.11.10
Python Hacking Programming (1)  (0) 2013.11.10
PE File Format (4)  (0) 2013.11.10
PE File Format (2)  (0) 2013.11.10
PE File Format (1)  (0) 2013.11.10
Calling Convention  (0) 2013.11.10