수안이의 컴퓨터 연구실

  • Mainpage
  • About Me
  • Tags
  • Metapage
  • Notice
  • Location
  • Keywords
  • Guestbook
  • Admin
  • Write an Article
  • Total | 1695031
  • Today | 776
  • Yesterday | 606

Programming/Win32 API2007/01/02 14:35

PE 포맷 분석2

고수닷넷 - 데미소다오렌지님

이 문서는 msdn의 매트 피에트릭의 문서 http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dndebug/html/msdn_peeringpe.asp 를 번역한 것 입니다.

PE 헤더

모든 다른 파일 포맷과 마찬가지로, PE 파일도 파일의 나머지 부분이 어떻게 보일지 정의하는 알려진 (찾기 쉬운) 위치에 있는 필드들을 가지고 있다. 이 헤더는 코드와 데이터 영역의 위치와 사이즈, 운영체제에서 정한것으로 스택 크기와 앞으로 짧게 설명할 다른 중요한 정보 조각들의 정보를 포함하고 있다. 마이크로소프트사에서 만든 다른 실행 포맷처럼, 이 메인 헤더는 파일의 시작 부분에 있지 않다. 전형적인 PE파일의 처음 수백 바이트는 MS-DOS 스텁으로 구성된다. 이 스텁은 "This program cannot be run in MS-DOS mode."라는 것을 출력하고 그러한 효과를 지닌 작은 프로그램이다. 따라서 만약 Win32 기반의 프로그램을 Win32를 지원하지 않는 환경에서 실행하게 되면, 해당 메시지를 출력하게 된다. Win32 로더가 PE 파일을 메모리 맵할때, 메모리 맵 파일의 첫번째 바이트는 MS-DOS 스텁의 첫번째 바이트와 일치한다. 맞다. Win32 기반의 프로그램이 시작할때마다, MS-DOS 기반의 프로그램또한 공짜로 로드되는 것이다.

다른 마이크로소프트 실행 포맷과 같이, 진짜 헤더는 MS-DOS 스텁 헤더에 저장되어져있는 시작 오프셋을 조사해서 찾을수 있다. WINNT.H 파일은 PE 헤더가 어디서 시작하는지 찾기 쉽게 만들기 위해서 MS-DOS 스텁 헤더를 위한 구조체 정의를 포함하고 있다. e_lfanew 필드는 실질적인 PE 헤더에 대한 상대적인 오프셋(RVA) 이다. 메모리에서 PE 헤더를 가리키는 포인터를 얻기 위해서는, 단지 해당 필드의 값을 이미지 베이스 주소에 더하기만 하면 된다.

// Ignoring typecasts and pointer conversion issues for clarity...
pNTHeader = dosHeader + dosHeader->e_lfanew;

메인 PE 헤더에 대한 포인터를 한번 얻고나면, 재미있는 일들이 시작된다. 메인 PE 헤더는 WINNT.H에 정의된 IMAGE_NT_HEADERS라는 타입의 구조체이다. 이 구조체는 DWORD와 두개의 서브 구조체로 구성되고 아래에 나오는 것과 같은 순서로 놓여져있다.

DWORD Signature;
IMAGE_FILE_HEADER FileHeader;
IMAGE_OPTIONAL_HEADER OptionalHeader;

아스키 텍스트로 보여지는 Singnature 필드는 "PE\0\0"이다. 16비트 윈도우의 NE파일에서는 MS-DOS헤더 내에 포함된 e_lfanew 필드를 사용해서 포인터를 구했을때, PE 대신 NE 시그니처를 볼 수 있다. 같은 이치로, 윈도우즈 3.x 가상 디바이스 드라이버 (VxD)에서는 시그니처 필드에 LE가 나타난다.

PE 헤더에서 PE 시그니쳐 DWORD 다음에 따라 나오는것은 IMAGE_FILE_HEADER 타입의 구조체이다. 이 구조체의 필드들은 단순히 파일에 관한 가장 기초적인 정보들만 포함하고 있다. 이 구조체는 오리지널 COFF 구현과 동일한 것으로 보인다. 게다가 PE 헤더의 일부일뿐만 아니라, 그것은 또한 마이크로소프트 Win32 컴파일러가 생성한 COFF OBJ의 시작 부분에도 나타난다. Table 2에 IMAGE_FILE_HEADER의 필드들이 표시되어 있다.

Table 2. IMAGE_FILE_HEADER 필드

WORD Machine
이 파일이 사용되도록 계획된 CPU. 아래의 CPU ID가 정의되어 있다.: 0x14d는 인텔 i860을 의미한다.
0x14c 인텔 i386 (486과 586에도 동일한 ID)
0x162 MIPS R3000
0x166 MIPS R4000
0x183 DEC Alpha AXP

WORD NumberOfSections
파일에 있는 섹션 갯수

DWORD TimeDateStamp
링커(또는 OBJ파일을 생성한 컴파일러)가 파일을 생성한 시간. 이 필드는 1969-12-31 4:00 부터의 초를 카운트하는 숫자이다.

DWORD PointerToSymbolTable
COFF 심볼 테이블의 파일 오프셋
이 필드는 COFF 디버그 정보를 가진 OBJ 파일과 PE파일에서만 사용한다.
PE 파일은 다양한 디버그 포맷을 지원한다. 그래서 디버거는 데이타 디렉토리(후에 정의된) 에 있는IMAGE_DIRECTORY_ENTRY_DEBUG 엔트리를 참조 하기만 하면 된다.

DWORD NumberOfSymbols
COFF 심볼 테이블에 있는 심볼 갯수. 위의 내용 참고.

WORD SizeOfOptionalHeader
이 구조체 다음에 나올 수 있는 추가적인 헤더의 크기.
OBJ 파일에서, 이 필드는 0이다. 실행파일에서는, 이 구조체 뒤에 따라 나오는 IMAGE_OPTIONAL_HEADER 구조체의 크기이다.

WORD Characteristics
파일과 관련된 정보 플래그. 중요한 필드들: 0x0001 이 파일에서는 재배치가 없다.
0x0002 파일은 실행 가능한 이미지이다. (OBJ나 LIB가 아니다.)
0x2000 파일은 프로그램이 아닌 동적 연결 라이브러이다.

WINNT.H에 정의된 다른 필드들
PE 헤더의 세번째 컴포넌트는 IMAGE_OPTIONAL_HEADER 타입의 구조체 이다. PE 파일에서는 이 부분은 확실히 옵션이 아니다. COFF 포맷은 표준 IMAGE_FILE_HEADER와 관련된 추가적인 정보로 구성된 구조체를 정의하기 위해서 개개의 구현을 허용한다. IMAGE_OPTIONAL_HEADER에 있는 필드들은 PE 디자이너들이 IMAGE_FILE_HEADER에 있는 기초적인 정보 이상으로 중요한 정보라고 느낀 것들이다.

IMAGE_OPTIONAL_HEADER의 모든 필드들에 관해서 알 필요는 없다. (Figure 4를 보라) 알고있어야 할 더 중요한 것은 ImageBase와 Subsystem 필드이다. 필드에 관한 설명을 훑어보거나 건너뛰어도 된다.

Table 3. IMAGE_OPTIONAL_HEADER 필드

WORD Magic
어느정도 시그니쳐 워드(WORD)로 보임. 항상 0x010B로 셋팅되어 있다.

BYTE MinorLinkerVersion
이 피알을 생성한 링커의 버전.
숫자는 16진수가 아닌 10진 값으로 출력되어야 한다. 전형적인 링커 버전은 2.23이다.

DWORD SizeOfCode
모든 코드 섹션을 합한 사이즈.
일반적으로, 대부분의 파일은 하나의 코드 섹션을 가지고 있다, 그래서 이 필드는 .text 섹션의 크기와 일치한다.

DWORD SizeOfInitializedData
이것은 초기화된 데이터로 구성된 섹션의 전체 크기로 추정된다. (코드 세그먼트를 포함하지 않은)
그러나, 이것은 파일에서 무엇이 나오는지 일정하지 않다.

DWORD SizeOfUninitializedData
로더가 가상 주소 공간위에 프로그램을 위해서 할당한 영역위에 있는 섹션의 크기, 그러나 디스크 파일에서는 어떠한 공간도 가지지 않는다. 이 섹션들은 프로그램 시작시 특정한 값을 가질 필요가 없다. 그래서 초기화 되지 않은 데이터란 용어를 사용했다. 초기화되지않은 데이터는 일반적으로 .bss로 불리는 섹션으로 통한다.

DWORD AddressOfEntryPoint
로더가 실행을 시작하는 주소. 이것은 RVA이다. 그리고 일반적으로 .text섹션에서 발견된다.

DWORD BaseOfCode
파일의 코드 섹션들이 시작되는 곳의 RVA. 코드 섹션들은 전형적으로 메모리에서 data 섹션들 이전에 나타나며 PE 헤더 이후에 나타난다. 이 RVA는 마이크로소프트 링커가 생성한 EXE들에서는 보통 0x10000이다. 볼랜드의 TLINK32는 이미지 베이스 주소에 첫번째 코드 섹션의 RVA를 더한후에 그것을 이 필드에 저장한다.

DWORD BaseOfData
파일의 데이터 섹션이 시작하는 곳의 RVA. 데이터 섹션은 통상적으로 메모리에서 PE헤더와 코드 섹션 다음의 마지막 부분에 오게 된다.

DWORD ImageBase
링커가 실행 파일을 만들때, 링커는 파일이 메모리의 어느 위치에 메모리 맵될지 가정한다. 그 주소가 이 필드에 저장되어 있다. 로드 주소를 가정하는 것은 링커가 최적화를 할 수 있게한다. 만약 파일이 로더에 의해서 실제로 그 주소로 메모리 맵된다면, 코드는 실행되기 전에 어떠한 패치도 할 필요가 없게 된다. 윈도우 NT를 위해서 생성된 실행파일에서는, 기본 이미지 베이스 주소는 0x1000이다. DLL에서는 기본값이 0x400000이다. 윈도우 95에서는 0x10000주소는 32비트 EXE파일을 로드하는데 사용할 수 없다. 왜냐하면 선형적인 주소공간을 모든 프로세스가 공유해서 사용하기 때문이다. 이러한 이유때문에, 마이크로소프는 Win32 실행 파일의 기본 베이스 주소를 0x400000로 변경했다. 로더가 베이스 주소를 재배치해야할 필요가 있기 때문에, 0x10000을 기본 주소로 가정하고 링크된 오래된 프로그램은 Win95 환경 아래에서는 로드시간이 더 길게 된다.

DWORD SectionAlignment
메모리로 맵될때, 각각의 섹션은 이 값의 배수가 되는 가상 주소에서 시작된다는 것을 보장받는다. 페이징과 같은 목적 때문에, 기본 섹션 정렬 값은 0x1000이다.

DWORD FileAlignment
PE 파일에서, 각각의 섹션은 이 값의 배수가 되는 곳에서 시작하도록 보장받는데 합의한 값. 기본 값은 0x200 바이트이다. 아마도 섹션은 항상 디스크 섹터(이것 또한 0x200 바이트)의 시작 지점에서 시작한다는 것을 보장해야 하기 때문일 것이다. 이 필드는 NE 파일의 세그먼트/리소스 정렬 크기와 같다. NE 파일과는 다르게, PE 파일은 전형적으로 수백개의 섹션을 가지지 않는다. 따라서 파일 섹션 정렬때문에 낭비되는 공간은 아주 작다.

WORD MajorOperatingSystemVersion
WORD MinorOperatingSystemVersion
이 실행 파일을 실행하는데 요구되는 최소한의 운영체제 버전. 이 필드는 다소 난해하다. 서브시스템 필드(추후에 소개될)또한 같은 목적으로 예약된 것처럼 보이기 때문이다. 현재까지 모든 Win32 Exe 파일에서 이 필드의 기본값은 1.0이다.

WORD MajorImageVersion
WORD MinorImageVersion
사용자가 정의할 수 있는 필드이다. 이것은 EXE나 DLL을 다른 버전으로 만들 수 있게 허용한다. 링커의 /VERSION 스위치를 사용해서 이 필드를 설정할 수 있다. 예를 들면, "LINK /VERSION:2.0 myobj.obj".

WORD MajorSubsystemVersion
WORD MinorSubsystemVersion
실행 파일을 실행하는데 요구되는 서브시스템의 최소 버전번호를 포함하고 있다. 이 필드의 일반적인 값은 3.10이다. (윈도우 NT 3.1을 의미한다.)

DWORD Reserved1
항상 0으로 설정하는 것으로 보인다.

DWORD SizeOfImage
로더가 걱정하는 이미지 일부의 전체 크기로 추정된다. 이것은 이미지의 베이스 주소에서 시작해서 마지막 섹션 끝까지의 영역의 크기를 말한다. 마지막 섹션의 끝은 섹션 정렬의 배수 근처에 있게 된다.

DWORD SizeOfHeaders
The size of the PE header and the section (object) table. The raw data for the sections starts immediately after all the header components. PE 헤더와 (오브젝트) 테이블 섹션의 크기이다. 이 섹션의 바이너리 데이터는 모든 헤더 구성 요소 다음에 바로 위치한다.

DWORD CheckSum
아마도 파일의 CRC 체크섬인 것 같다. 다른 마이크로소프트의 실행 파일 포맷에서 이 필드는 0으로 설정되고 무시된다. 이 방법이 통하지 않는 한가는 예외는 신뢰된 서비스이다. 이 EXE 파일은 반드시 정확한 체크섬 값을 가지고 있어야 한다.

WORD Subsystem
실행 파일이 유저 인터페이스로 사용하는 서브시스템 타입. WINNT.H는 다음과 같은 값들을 정의하고 있다.
NATIVE 1 서브시스템을 요구하지 않는다.(디바이스 드라이버 같은것들)
WINDOWS_GUI 2 윈도우 GUI 서브시스템에서 실행된다.
WINDOWS_GUI 3 윈도우 문자 서브시스템에서 실행된다. (콘솔 애플리케이션)
OS2_CUI 5 OS/2 문자 서브시스템에서 실행된다. (OS/2 1.x 애플리케이션만 적용된다.)
POSIX_CUI 7 Posix 문자 서브시스템에서 실행된다.

WORD DllCharacteristics
DLL의 초기화 함수(DllMain과 같은)가 호출되는 환경과 관련된 플래그 집합. 이 값은 항상 0으로 설정되는 것으로 보인다. 그러나 운영체제는 여전히 DLL 초기화 함수를 항상 모든 4가지 이벤트에 맞추어서 호출한다. 아래와 같은 값들이 정의되어 있다.
1. DLL이 프로세스 주소 공간으로 처음 로딩될 때.
2. 쓰레드가 종료될 때.
3. 쓰레드가 시작될 때.
4. DLL이 종료될 때.

DWORD SizeOfStackReserve
초기 쓰레드의 스택을 위해서 예약해야할 가상 메모리의 크기. 다음 필드를 참고해 보면 이 메모리 전부가 실제 메모리로 사용되지 않는다는 것을 알 수 있다. 이 필드의 기본값은 0x100000 (1MB) 이다. 만약 CreateThread에서 스택 크기를 0으로 설정했다면 그 결과과 만들어진 쓰레드는 이것과 동일한 크기의 스택을 가지게 된다.

DWORD SizeOfStackCommit
초기 쓰레드의 스택을 위해서 사용하는 실제 메모리의 크기. 마이크로소프트 링커는 기본적으로 이 필드를 0x1000(1페이지) 바이트로 설정된다. 반면에 TLINK32는 2 페이지로 만든다.

DWORD SizeOfHeapReserve
초기 프로세스의 힙으로 예약해야할 가상 메모리의 크기. 이 힙 핸들은 GetProcessHeap함수를 호출해서 얻을 수 있다. 이 메모리 모두가 실제 메모리로 사용되지 않는다. (다음 필드를 보라)

DWORD SizeOfHeapCommit
초기 프로세스 힙으로 사용될 실제 메모리의 크기. 기본적으로 1페이지가 설정된다.

DWORD LoaderFlags
WINNT.H에 의하면 이것은 디버깅 지원과 관련된 필드로 보인다. 나는 이제껏 한번도 이 비트를 활성화 시켜둔 실행 파일을 본적이없을 뿐 아니라, 링커가 이 필드를 설정하게 하는 방법또한 확실치 않다. 다음과 같은 값들이 정의되어져 있다.

1. 프로세스를 시작하기 전에 브레이크 포인트 명령을 실행한다.
2. 프로세스가 로드된 이후에 디버거를 실행한다.

DWORD NumberOfRvaAndSizes
DataDirectory 배열 (아래에 나오는)에 있는 엔트리 갯수. 이 값은 현재까지 툴에서는 항상 16으로 설정한다.

IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]

IMAGE_DATA_DIRECTORY 구조체의 배열이다. 배열의 초기 값은 실행 파일의 중요한 부분의 RVA 시작 지점과 크기을 포함하고 있다. 배열 끝의 몇가지 항목은 현재까지는 사용되지 않는다. 배열의 첫번째 요소는 항상 익스포트 함수 테이블(만약 존재한다면) 의 주소와 크기를 가지고 있다. 두번째 배열의 항목은 임포트된 함수 테이블의 주소와 크기를 가지고 있다. 정의된 배열 항목에 대한 완전한 리스트는 WINNT.H에서 #define으로 선언된 IMAGE_DIRECTORY_ENTRY_XXX를 참고하면 된다. 이 배열은 각각의 이미지 섹션을 순회하면서 같은 이름이 있는지 비교하지 않고 로더가 이미지의 특정한 섹션을 빨리 찾을 수 있도록 도와준다. (예를들면, 임포트된 함수 테이블과 같은 것이다.) 대부분의 배열 항목은 전체 섹션 데이터에 대한 정보를 가지고 있다. 그러나, IMAGE_DIRECTORY_ENTRY_DEBUG 항목은 .rdata 섹션의 일부 바이트만을 포함한다.

"Win32 API" 카테고리의 다른 글
  • XP 프로그램 호환성 정보 얻기 (0)2007/01/02
  • PE 포맷 분석3 (0)2007/01/02
  • PE 포맷 분석2 (0)2007/01/02
  • PE 포맷 분석1 (0)2007/01/02
  • command 출력 리디렉션 시키기. (0)2006/12/29
2007/01/02 14:35 2007/01/02 14:35
Posted by webdizen
Tags Portable Executable File Format
No Trackback No Comment

Trackback URL : http://www.webdizen.net/blog/trackback/2538

Leave your greetings.

[로그인][오픈아이디란?]

«Prev  1 ... 705 706 707 708 709 710 711 712 713 ... 3009  Next»

RSS HanRSS
Blog Image
webdizen
이곳은 컴퓨터에 대해 연구하고, 공유하고, 소통하기 위한 연구실입니다. 개인적으로는 OLAP, Data Mining, Semantic Web, Data Modeling에 대해서 연구하고 있습니다.

Categories

전체 (3009)
Webdizen (141)
Life (6)
Diary (16)
Blog (9)
IDEA (2)
Travel (10)
Book (16)
Photo (7)
Movie (8)
Music (14)
Leisure Sports (10)
Funny (6)
Hardware (121)
Software (120)
Windows (5)
Unix & Linux (120)
Installation (5)
Kernel (10)
System (34)
Develop (22)
X-Window (0)
Applicaton (31)
Security (4)
Framework (2)
Hadoop (2)
Programming (804)
Algorithm & Data Structure (1)
Assembly (38)
UNIX/Linux C (95)
C++ (128)
STL (4)
Java (38)
Win32 API (92)
ATL/COM (44)
MFC (151)
.NET (26)
WCF/WPF (4)
C# (28)
Network Programming (17)
Database Programming (12)
OpenGL / DirectX (13)
Multimedia Programming (0)
Game Programming (21)
Parallel Distributed Progra... (0)
Reverse Engineering (0)
Debugging (9)
Python (1)
Ruby (1)
Ruby on Rails (1)
QT (4)
GTK (0)
JSP (0)
PHP (6)
ASP.NET (6)
ASP (2)
Development (28)
Useful Library (2)
Data Modeling (0)
Database (105)
Oracle (4)
MSSQL (41)
MySQL (2)
Data Warehouse (2)
Data Mining (4)
Network (66)
Web (79)
DHTML (4)
XHTML (1)
Javascript (1)
CSS (1)
AJAX (9)
XML (11)
Flex (1)
Silverlight (3)
Security (91)
DoS (1)
Kernel (10)
Scanning (3)
Sniffing (0)
Spoofing (4)
Overflow (28)
Web (11)
Shell (10)
Format String (14)
Window (2)
Embedded (70)
Multimedia (27)
Mobile (14)
Graphic (24)
Management (633)
Knowledge (581)
Hadoop (0)

Notice

  • 메타 블로그 사이트에 등록
  • 새해 맞이 블로그의 변화
  • 블로그 명칭 변경
  • 도메인(www.webdizen.net) 구...
  • TEXTCUBE 1.6.1로 업그레이드...

Tags

  • 데이타 바인딩
  • 데이터 전처리
  • RSS
  • Kprobes
  • 영상바이오관
  • Utilities
  • 시스템 사양
  • 마주앙 샤도네이
  • lower_bound
  • 지식
  • 코드 성능 향상
  • RADIUS
  • Objects
  • 썬라이즈 페파민트
  • CreateDirectory
  • TLS
  • 도메인
  • RC0
  • Hadoop
  • Filtering

Recent Articles

  • 트위터(Twitter)의 시작!.
  • 청년 리더의 조건.
  • 애플의 타블렛 PC - 아이패드....
  • 미래의 인터페이스 - 육감 기....
  • 기초발성법 동영상 강좌.

Recent Comments

  • 경청... 너무나 중요한데.......
    webdizen 14:59
  • 학교 과제물중 쓰레드에 대하....
    장진혁 03/17
  • 관리자만 볼 수 있는 댓글입....
    비밀방문자 03/12
  • 상대방의 이야기를 열심히 경....
    DoNuts 03/03
  • 좋은글 잘 보고 갑니다..
    Und_hacker 01/08

Recent Trackbacks

  • printf,scanf를 이용한 형식....
    yundream의 프로그래밍 이야기 03/10
  • 파일 열기/저장하기 CFileDialog.
    은마군의 나태블록 2009
  • World IT Show 2008.
    상우 :: Oranzie's BLOG 2008
  • cvs서버 설치하기.
    3인3색 2008
  • 속속 공개되는 Google Chart....
    PHP와 Web 2.0 2007

Archive

  • 2010/02 (1)
  • 2010/01 (6)
  • 2009/12 (5)
  • 2009/09 (3)
  • 2009/08 (1)

Calendar

«   2010/03   »
일 월 화 수 목 금 토
  1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31      

Bookmarks

    • Administration
      • IIS.NET
      • NTFAQ
      • OS의 모든 것
      • 리눅스포털
    • Database
      • SQL Server Central
      • SQL Team
    • Development
      • .NET Heaven
      • ASP Alliance
      • ASP.NET 2.0
      • Bullog.net
      • C# Corner
      • C++ (C PlusPlus.com)
      • C++ Reference
      • CodeGuru
      • CodePlex
      • DebugLab
      • Dev Articles
      • Devpia
      • DotNet Junkies
      • DotNet Zone
      • Driver Online
      • GOSU.NET
      • HOONS 닷넷
      • Joinc 팀블로그
      • KOSR
      • MSDN Home Page
      • OSR Online
      • Sky.ph - 개발자 커뮤니...
      • TAEYO.NET
      • The Code Project
      • WindowsClient.net
      • 김상욱의 개발자 Side
      • 조인시 위키
    • Human Networks
      • belief21c's e-space
      • I think I can
      • Invisible Rover's Blog :D
      • Polarux - Linuxing
      • Rodman®
      • 까만 나비
      • 나를 가꾸는 시간.
      • 단녕
      • 상우 :: Oranzie's BLOG
    • Information Technology
      • Microsoft TechNet
      • 지디넷코리아 - 글로벌...
    • Security
      • FoundStone
      • milw0rm
      • NewOrder
      • OpenRCE
      • Phrack.org
      • Reverse Engineering b1...
      • Reverse Engineering Team
      • RootKit
      • SecurityFocus
      • SecurityXploded by Nag...
      • Wow Hacker
      • Zone-H
Textcube
Louice Studio Inc.
Powered by Textcube. Original designed by Tistory.