Image File Header에는 파일에 대한 대략적인 속성(정보)들을 가지고 있는 구조체이다.


Image_File_Header의 구조체는 다음과 같다.


2567 typedef struct _IMAGE_FILE_HEADER { 
2568 WORD Machine;
2569 WORD NumberOfSections;
2570 DWORD TimeDateStamp;
2571 DWORD PointerToSymbolTable;
2572 DWORD NumberOfSymbols;
2573 WORD SizeOfOptionalHeader;
2574 WORD Characteristics;
2575 MAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;

출처 : source.winehq.org - winnt.h



  • Machine


CPU에 따른 값을 나타낸다. 이 값은 Winnt.h에서 다음과 같이 정의되어 사용한다.


2447 #define IMAGE_FILE_MACHINE_UNKNOWN 0
2448 #define IMAGE_FILE_MACHINE_I860 0x014d
2449 #define IMAGE_FILE_MACHINE_I386 0x014c
2450 #define IMAGE_FILE_MACHINE_R3000 0x0162
2451 #define IMAGE_FILE_MACHINE_R4000 0x0166
2452 #define IMAGE_FILE_MACHINE_R10000 0x0168
2453 #define IMAGE_FILE_MACHINE_WCEMIPSV2 0x0169
2454 #define IMAGE_FILE_MACHINE_ALPHA 0x0184
2455 #define IMAGE_FILE_MACHINE_SH3 0x01a2
2456 #define IMAGE_FILE_MACHINE_SH3DSP 0x01a3
2457 #define IMAGE_FILE_MACHINE_SH3E 0x01a4
2458 #define IMAGE_FILE_MACHINE_SH4 0x01a6
2459 #define IMAGE_FILE_MACHINE_SH5 0x01a8
2460 #define IMAGE_FILE_MACHINE_ARM 0x01c0
2461 #define IMAGE_FILE_MACHINE_THUMB 0x01c2
2462 #define IMAGE_FILE_MACHINE_ARMNT 0x01c4
2463 #define IMAGE_FILE_MACHINE_AM33 0x01d3
2464 #define IMAGE_FILE_MACHINE_POWERPC 0x01f0
2465 #define IMAGE_FILE_MACHINE_POWERPCFP 0x01f1
2466 #define IMAGE_FILE_MACHINE_IA64 0x0200
2467 #define IMAGE_FILE_MACHINE_MIPS16 0x0266
2468 #define IMAGE_FILE_MACHINE_ALPHA64 0x0284
2469 #define IMAGE_FILE_MACHINE_MIPSFPU 0x0366
2470 #define IMAGE_FILE_MACHINE_MIPSFPU16 0x0466
2471 #define IMAGE_FILE_MACHINE_AXP64 IMAGE_FILE_MACHINE_ALPHA64
2472 #define IMAGE_FILE_MACHINE_TRICORE 0x0520
2473 #define IMAGE_FILE_MACHINE_CEF 0x0cef
2474 #define IMAGE_FILE_MACHINE_EBC 0x0ebc
2475 #define IMAGE_FILE_MACHINE_AMD64 0x8664
2476 #define IMAGE_FILE_MACHINE_M32R 0x9041
2477 #define IMAGE_FILE_MACHINE_CEE 0xc0ee

출처 : source.winehq.org - winnt.h


Machine 필드에 정의된 값은 0x8664이니 AMD64 CPU를 쓴다는 것을 알 수 있다.


  • NumberOfSections


섹션의 수를 나타낸다. 이 것은 바로 테이블의 크기를 알 수 있다. 윈도우는 최대 96개의 섹션을 로더 할 수 있다. 섹션의 수는 다음과 같은 규칙을 가지고 있다.


실제 섹션 < 정의된 섹션 : 에러
실제 섹션 > 정의된 섹션 : 정의된 개수 만큼만 인식


현재 보여지는 대로는 6개의 섹션을 가지고 있다.


  • TimeDateStamp


이 부분의 타임 스탬프는 32비트로 표현된다. 이 시간은 링커에 의해 생성 된 날짜 및 시간을 나타내는데 시스템 클럭에 따라 1970년 1월 1일 자정 이후 경과 된 시간을 초 단위로 표시된다. 위와 같은 경우 0x4A5BC9B3이니 이를 10진수로 변경 후 계산해 보면


1247529395 / 60 = 20792156분 35초
20792156 / 60 = 346535시간 56분
346535 / 24 = 14438일 23시
14438 / 365 = 39년 203일
1970년 + 39년 1월 + 203일 23시 56분 35초 = 2009년 7월 13일 23시 56분 35초가 나온다. 


이 시간은 UTC(Universal Time Coordinated) 즉, 협정세계시로 표현한다.


  • PointerToSymbolTable


COFF(Common Object File Format) Symbol 테이블이 존재하는 경우에 이 값은 Symbol 테이블로 향하는 포인터 역할을 한다.


COFF는 수많은 프로그램들을 하나로 합쳐 메모리에 옮기는 과정에서 매우 복잡하고 많은 시간을 요구하는 등의 문제점을 개선하기 위해 미국 AT&T사에서 고안해 낸 규칙이다. 공통된 성질을 가지는 것들을 하나로 합치며, 합쳐진 것을 섹션이라 하고, 섹션은 사용하는 언어에 따라 따로 정해져 있다. COFF 규칙은 프로그램 개수에 상관없이 프로그램을 몇 개의 섹션으로 구분하기 때문에 프로그램 구성적인 측면에서 보면 간단해 진다. 이러한 COFF는 유닉스에서 시작되었기 때문에 PE구조는 유닉스 기반이라고 할 수 있다.


  • NumberOfSymbols


PointerToSymbolTable에 값이 설정되어 Symbol 테이블을 참조하고 있다면, 해당 테이블 안의 Symbol의 개수의 값이 설정된다. 현재는 Symbol의 크기가 커져 따로 파일로 저장되어 사용되기에 PointerToSymbolTable과 NumberOfSymbols는 사용되지 않는다.


  • SizeOfOptionalHeader


IMGE_OPTIONAL_HEADER의 구조체 크기를 나타낸다. 32비트 PE파일인 경우 0xE0 (224바이트)이고, 64비트 PE파일인 경우 0xF0 (240 바이트)이다. OBJ 파일의 경우 0x00 (0바이트)의 값을 가지게 된다.

64비트 컴퓨터의 notepad.exe pe구조를 살펴보았기 때문에 0xF0로 설정되어 있음을 알 수 있다.


  • Characteristics


PE 파일에 대한 특정 정보를 나타내는 플래그이다. 이 값은 논리합(OR연산)으로 구성되어 있다. 이 부분에 대한 정의 또한 winnt.h에서 다음과 같이 정의 되어 있다.


2429 #define IMAGE_FILE_RELOCS_STRIPPED 0x0001 /* No relocation info */
2430 #define IMAGE_FILE_EXECUTABLE_IMAGE 0x0002
2431 #define IMAGE_FILE_LINE_NUMS_STRIPPED 0x0004
2432 #define IMAGE_FILE_LOCAL_SYMS_STRIPPED 0x0008
2433 #define IMAGE_FILE_AGGRESIVE_WS_TRIM 0x0010
2434 #define IMAGE_FILE_LARGE_ADDRESS_AWARE 0x0020
2435 #define IMAGE_FILE_16BIT_MACHINE 0x0040
2436 #define IMAGE_FILE_BYTES_REVERSED_LO 0x0080
2437 #define IMAGE_FILE_32BIT_MACHINE 0x0100
2438 #define IMAGE_FILE_DEBUG_STRIPPED 0x0200
2439 #define IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP 0x0400
2440 #define IMAGE_FILE_NET_RUN_FROM_SWAP 0x0800
2441 #define IMAGE_FILE_SYSTEM 0x1000
2442 #define IMAGE_FILE_DLL 0x2000
2443 #define IMAGE_FILE_UP_SYSTEM_ONLY 0x4000
2444 #define IMAGE_FILE_BYTES_REVERSED_HI 0x8000

출처 : source.winehq.org - winnt.h


현재 위에서 Characteristics 필드의 값은 0x0022이니 IMAGE_FILE_EXECUTABLE_IMAGE와 IMAGE_FILE_LARGE_ADDRESS_AWARE의 정보가 설정되어 있다.

'Information Technology > File Format' 카테고리의 다른 글

IMAGE_NT_HEADER – IMAGE_FILE_HEADER  (0) 2013.05.07
PE 코드섹션 흐름도  (0) 2013.04.25
IMAGE_NT_HEADERS - Signature  (0) 2013.04.24
IMAGE_NT_HEADERS  (0) 2013.04.24
MS-DOS Stub Program  (0) 2013.04.24
IMAGE_DOS_HEADER  (0) 2013.04.24


'Information Technology > File Format' 카테고리의 다른 글

IMAGE_NT_HEADER – IMAGE_FILE_HEADER  (0) 2013.05.07
PE 코드섹션 흐름도  (0) 2013.04.25
IMAGE_NT_HEADERS - Signature  (0) 2013.04.24
IMAGE_NT_HEADERS  (0) 2013.04.24
MS-DOS Stub Program  (0) 2013.04.24
IMAGE_DOS_HEADER  (0) 2013.04.24


Signature는 "PE\0\0"값(=0x50450000h)을 가지는데 이 값은 변경하면 안된다. 이 값을 변경하게 되면 이 데이터 값을 참조하는 IMAGE_DOS_HEADER의 e_lfanew이 변경 되고, PE파일로 인식하지 못하게 된다.


'Information Technology > File Format' 카테고리의 다른 글

IMAGE_NT_HEADER – IMAGE_FILE_HEADER  (0) 2013.05.07
PE 코드섹션 흐름도  (0) 2013.04.25
IMAGE_NT_HEADERS - Signature  (0) 2013.04.24
IMAGE_NT_HEADERS  (0) 2013.04.24
MS-DOS Stub Program  (0) 2013.04.24
IMAGE_DOS_HEADER  (0) 2013.04.24


IMAGE_NT_HEADERS는 DWORD 타입인 Signature와 구조체인 FileHeader, OptionalHeader를 가지고 있다. Signature는 IMAGE_NT_HEADERS의 시작을 부분이며 이 구조체의 총 크기는 0xF8h이다. 


(Signature 0x4h, FileHeader 0x14h, OptionalHeader 0x0h)


2664 typedef struct _IMAGE_NT_HEADERS {
2665 DWORD Signature; /* "PE"\0\0 */ /* 0x00 */
2666 IMAGE_FILE_HEADER FileHeader; /* 0x04 */
2667 IMAGE_OPTIONAL_HEADER32 OptionalHeader; /* 0x18 */
2668 }IMAGE_NT_HEADERS32, *PIMAGE_NT_HEADERS32;

출처 : source.winehq.org - winnt.h [32bit system]


'Information Technology > File Format' 카테고리의 다른 글

PE 코드섹션 흐름도  (0) 2013.04.25
IMAGE_NT_HEADERS - Signature  (0) 2013.04.24
IMAGE_NT_HEADERS  (0) 2013.04.24
MS-DOS Stub Program  (0) 2013.04.24
IMAGE_DOS_HEADER  (0) 2013.04.24
Runtime Data Areas의 구조  (0) 2013.04.18

시작점에서부터 IMAGE_DOS_HEADER의 사이즈인 64Bytes 만큼 떨어진 곳에서 찾을 수 있다. 이 부분은 IMAGE_DOS_HEADER와 같은 구조체가 아닌 이름 그대로 프로그램이다. 일반적인 실행파일처럼 실행한다.


이 프로그램에는 "This program cannot be run in DOS mode."라는 문자열을 볼 수 있다. 32bit 프로그램을 도스(16bit)에서 실행할 때 위의 문자열을 출력(16bit 환경에서 실행 하는 것을 방지하는 역할) 해주는데 쓰인다. 그래서 현재는 사용하지 않는 부분이다.



이 부분은 개발 환경 등에 따라 크기가 가변적이다. (MS-DOS Stub Program의 크기가 가변적이기 때문에 IMAGE_DOS_HEADER의 e_lfanew의 값이 가변적이게 되는 것이다. e_lfanew 필드의 값은 MS-DOS Stub Program 바로 다음의 offset 값을 가지기 때문이다.

'Information Technology > File Format' 카테고리의 다른 글

PE 코드섹션 흐름도  (0) 2013.04.25
IMAGE_NT_HEADERS - Signature  (0) 2013.04.24
IMAGE_NT_HEADERS  (0) 2013.04.24
MS-DOS Stub Program  (0) 2013.04.24
IMAGE_DOS_HEADER  (0) 2013.04.24
Runtime Data Areas의 구조  (0) 2013.04.18

64byte(0x40)의 고정된 크기를 가지며, 디스크상의 첫 부분과 메모리상 ImageBase에 위치하고 있다. ImageBase는 프로세스의 가상 메모리 0 ~ FFFFFFFFh 범위(32bit의 경우)에서 PE파일이 로딩(매핑)되는 시작 주소를 나타내는 부분이다.

DOD Header의 처음 2byte는 DOS Header 구조체의 e_magic 인자로 MZ로 시작한다. 이는 DOS 개발자 가운데 한명인 Mark Zbikowski의 이니셜로 DOS Header의 시그니쳐로 사용하고 있다.

e_magic은 MZ를 나타내는 첫 2bytes 로 DOS Header 의 식별자이고, 마지막의 e_lfanew는 가변적인 값을 가지는 것으로 PE Header(NT header)의 주소를 알아볼 수 있다. e_lfanew의 값은 offset 0x000000XX로 여기에는 "PE"라는 값이 저장된 위치를 가리키고 있으며, 이 값을 통해 이 파일의 구조가 PE형태임을 인식하게 된다.

WORD와 LONG은 각각 2bytes, 4bytes 크기를 가지고 있다. 그래서 이 구조체를 계산해보면 WORD형 데이터 16개, 배열에서 WORD형의 합 14개, LONG형 1개로 (2*30bytes) + 4bytes = 64bytes / 16 = 4 즉 0x40의 고정된 공간을 할당 받게 된다는 것을 알 수 있다.

위 구조는 winnt.h의 2300라인에서 찾아 볼 수 있다.

2300 typedef struct _IMAGE_DOS_HEADER {
2301 WORD e_magic; /* 00: MZ Header signature */
2302 WORD e_cblp; /* 02: Bytes on last page of file */
2303 WORD e_cp; /* 04: Pages in file */
2304 WORD e_crlc; /* 06: Relocations */
2305 WORD e_cparhdr; /* 08: Size of header in paragraphs */
2306 WORD e_minalloc; /* 0a: Minimum extra paragraphs needed */
2307 WORD e_maxalloc; /* 0c: Maximum extra paragraphs needed */
2308 WORD e_ss; /* 0e: Initial (relative) SS value */
2309 WORD e_sp; /* 10: Initial SP value */
2310 WORD e_csum; /* 12: Checksum */
2311 WORD e_ip; /* 14: Initial IP value */
2312 WORD e_cs; /* 16: Initial (relative) CS value */
2313 WORD e_lfarlc; /* 18: File address of relocation table */
2314 WORD e_ovno; /* 1a: Overlay number */
2315 WORD e_res[4]; /* 1c: Reserved words */
2316 WORD e_oemid; /* 24: OEM identifier (for e_oeminfo) */
2317 WORD e_oeminfo; /* 26: OEM information; e_oemid specific */
2318 WORD e_res2[10]; /* 28: Reserved words */
2319 DWORD e_lfanew; /* 3c: Offset to extended header */
2320 } IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;

출처 : source.winehq.org - winnt.h

또한 기본적으로 Little Endian에 대한 지식을 알고 있어야 값을 보다 쉽게 이해할 수 있다.

'Information Technology > File Format' 카테고리의 다른 글

PE 코드섹션 흐름도  (0) 2013.04.25
IMAGE_NT_HEADERS - Signature  (0) 2013.04.24
IMAGE_NT_HEADERS  (0) 2013.04.24
MS-DOS Stub Program  (0) 2013.04.24
IMAGE_DOS_HEADER  (0) 2013.04.24
Runtime Data Areas의 구조  (0) 2013.04.18

Runtime Data Areas는 Process로서의 JVM이 프로그램을 수행하기 위해 OS로부터 할당 받는 메모리 영역이다. Runtime Data Areas는 각각의 목적에 따라 5 개의 영역으로 나뉜다.

  • PC Registers
  • Java Virtual Machine Stacks
  • Native Method Stacks
  • Method Area
  • Heap

이 중에서 앞의 세가지 메모리 영역, 즉 PC Register와 두 개의 Stack 영역은 각 Thread 별로 생성이 되고 Method Area 와 Heap은 모든 Thread에게 공유된다.

'Information Technology > File Format' 카테고리의 다른 글

PE 코드섹션 흐름도  (0) 2013.04.25
IMAGE_NT_HEADERS - Signature  (0) 2013.04.24
IMAGE_NT_HEADERS  (0) 2013.04.24
MS-DOS Stub Program  (0) 2013.04.24
IMAGE_DOS_HEADER  (0) 2013.04.24
Runtime Data Areas의 구조  (0) 2013.04.18

+ Recent posts