C++Builder Programming Forum
C++Builder  |  Delphi  |  FireMonkey  |  C/C++  |  Free Pascal  |  Firebird
볼랜드포럼 BorlandForum
 경고! 게시물 작성자의 사전 허락없는 메일주소 추출행위 절대 금지
C++빌더 포럼
Q & A
FAQ
팁&트릭
강좌/문서
자료실
컴포넌트/라이브러리
메신저 프로젝트
볼랜드포럼 홈
헤드라인 뉴스
IT 뉴스
공지사항
자유게시판
해피 브레이크
공동 프로젝트
구인/구직
회원 장터
건의사항
운영진 게시판
회원 메뉴
북마크
볼랜드포럼 광고 모집

C++빌더 팁&트릭
C++Builder Programming Tip&Tricks
[119] [팁] PE (Portable Executable) File Format
박지훈.임프 [cbuilder] 8396 읽음    2001-07-26 15:01
이 팁은 담비님(천리안 FREKBS)님이 99년 1월 18일에 천리안 프로그래머포럼에 올리신 것입니다.
담비님으로부터는 전제하여 올리는 데 대해 허락을 받았습니다.
좋은 정보를 공유하도록 허락해주신 담비님께 감사드립니다.

-----------------------------------------------------------------------
안녕하세요! 담비입니다.

본 문서는 32 Bit 실행화일인 Portable Executable형의 포맷에 관한 글입니다.
Tdump를 이용하여 실행화일을 덤프하여 비교하면서 읽어보십시요. 그리고 헥스
에디터를 사용하여 그 내용을 함께 비교하여보세요. 일본판과 영문판을 동시에 보며
해석해서 단어가 제대로 정리되지 않았습니다.
본 문서는 Borland C++ 5.x의 CD에 있는 \DOC\PE.TXT를 번역한것입니다.
또한 이 문서는 MSDN 95 JULY CD NO.4 에도 제공된바 있습니다.
내용상의 오류 혹은 추가 및 변경되어져야 할 사항을 발견하시면 메일 주시면
감사하겠습니다. 보내주신 내용은 검토 후 반영하여 다시 올리도록 하겠습니다.

  frekbs@chollian.net
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
PORTABLE EXECUTABLE FORMAT

Author:  Micheal J. O'Leary


서언

본서는 Microsoft Developer Support에서 편집, 릴리즈한 것이다.
여기에서는, NT지향의 이식성이 높은 실행 가능 프로그램에 대하여 해설한다.
이 문서의 릴리즈는, 앞으로, 본문중의 각 Format을 변경하지 않는 것을보증하지
않는다.

                    --Steve Firebaugh
                      Microsoft Developer Support



목차

1. 개요

2. PE Header

3. Object Table

4. Image Pages

5. Exports
   5.1 Export Directory Table
   5.2 Export Address Table
   5.3 Export Name Table Pointers
   5.4 Export Ordinal Table
   5.5 Export Name Table

6. Imports
   6.1 Import Directory Table
   6.2 Import Lookup Table
   6.3 Hint-Name Table
   6.4 Import Address Table

7. Thread Local Storage
   7.1 Thread Local Storage Directory Table
   7.2 Thread Local Storage CallBack Table

8. Resources
   8.1 Resource Directory Table
   8.2 Resource Example

9. Fixup Table
   9.1 Fixup Block

10. Debug Information
   10.1 Debug Directory
─━─━─━─━─━─━─━─━─━─━─━─━─━─━─━─━─━─━─━─
1. Overview
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
   ┌─────────┐ <─┐<── Base of Image Header
   │ DOS 2 Compatible │    │
   │    EXE Header    │    │
   ├─────────┤    │
   │      unused      │    │
   ├─────────┤    │
   │  OEM Identifier  │    │
   │  OEM Info        │    │
   │                  │    │  DOS 2.0 Section
   │    Offset to     │    │  (for DOS compatibility only)
   │    PE Header     │    │
   ├─────────┤    │
   │   DOS 2.0 Stub   │    │
   │   Program &      │    │
   │   Reloc. Table   │    │
   ├─────────┤ <─┘
   │      unused      │
   ├─────────┤ <──── Aligned on 8 byte boundary
   │    PE Header     │
   ├─────────┤
   │   Object Table   │
   ├─────────┤
   │   Image Pages    │
   │   import info    │
   │   export info    │
   │   fixup info     │
   │   resource info  │
   │   debug info     │
   └─────────┘

Figure 1. A typical 32-bit Portable EXE File Layout

─━─━─━─━─━─━─━─━─━─━─━─━─━─━─━─━─━─━─━─
2. PE Header
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

    ┌─────────────┬──────┬──────┐
    │     SIGNATURE BYTES      │ CPU TYPE   │ # OBJECTS  │
    ├─────────────┼──────┴──────┤
    │      TIME/DATE STAMP     │        RESERVED          │
    ├─────────────┼──────┬──────┤
    │         RESERVED         │ NT HDR SIZE│   FLAGS    │
    ├─────┬───┬───┼──────┴──────┤
    │ RESERVED │LMAJOR│LMINOR│        RESERVED          │
    ├─────┴───┴───┼─────────────┤
    │         RESERVED         │        RESERVED          │
    ├─────────────┼─────────────┤
    │      ENTRYPOINT RVA      │        RESERVED          │
    ├─────────────┼─────────────┤
    │         RESERVED         │       IMAGE BASE         │
    ├─────────────┼─────────────┤
    │      OBJECT ALIGN        │       FILE ALIGN         │
    ├──────┬──────┼──────┬──────┤
    │ OS MAJOR   │ OS MINOR   │USER MAJOR  │USER MINOR  │
    ├──────┼──────┼──────┴──────┤
    │SUBSYS MAJOR│SUBSYS MINOR│        RESERVED          │
    ├──────┴──────┼─────────────┤
    │       IMAGE SIZE         │      HEADER SIZE         │
    ├─────────────┼──────┬──────┤
    │      FILE CHECKSUM       │ SUBSYSTEM  │ DLL FLAGS  │
    ├─────────────┼──────┴──────┤
    │  STACK RESERVE SIZE      │    STACK COMMIT SIZE     │
    ├─────────────┼─────────────┤
    │  HEAP RESERVE SIZE       │    HEAP COMMIT SIZE      │
    ├─────────────┼─────────────┤
    │        RESERVED          │ # INTERESTING RVA/SIZES  │
    ├─────────────┼─────────────┤
    │  EXPORT TABLE RVA        │  TOTAL EXPORT DATA SIZE  │
    ├─────────────┼─────────────┤
    │  IMPORT TABLE RVA        │  TOTAL IMPORT DATA SIZE  │
    ├─────────────┼─────────────┤
    │ RESOURCE TABLE RVA       │ TOTAL RESOURCE DATA SIZE │
    ├─────────────┼─────────────┤
    │ EXCEPTION TABLE RVA      │ TOTAL EXCEPTION DATA SIZE│
    ├─────────────┼─────────────┤
    │ SECURITY TABLE RVA       │ TOTAL SECURITY DATA SIZE │
    ├─────────────┼─────────────┤
    │   FIXUP TABLE RVA        │ TOTAL FIXUP DATA SIZE    │
    ├─────────────┼─────────────┤
    │   DEBUG TABLE RVA        │ TOTAL DEBUG DIRECTORIES  │
    ├─────────────┼─────────────┤
    │ IMAGE DESCRIPTION RVA    │ TOTAL DESCRIPTION SIZE   │
    ├─────────────┼─────────────┤
    │  MACHINE SPECIFIC RVA    │  MACHINE SPECIFIC SIZE   │
    ├─────────────┼─────────────┤
    │ THREAD LOCAL STORAGE RVA │     TOTAL TLS SIZE       │
    └─────────────┴─────────────┘

Figure 2. PE Header

Notes:

    o VA라는 것은, PE Header에 있는 Image Base로 이미 바이어스하고 있는 가상
      주소(virtual address)이다. RVA라는 것은, Image Base로부터의
      상대가상주소이다.
    o RVA가 값이 0인 PE Header에 있을 때에는, Field가 미사용인 것을 의미한다.
    o Image Page는 Field배치경계에 배치되고, 0이 채워진다. 다른 모든 Table 및
      구조체의 Base는,  DWORD(4Byte)경계에 배치되지 않으면 안된다. 따라서, VA
      및 RVA는 모두 32Bit에 없으면 안된다. Table    및 구조체의 모든 Field는,
      '본래의' 경계상에 배치되지않으면 안되고, 예외로 생각되어지는 것은
      디버그정보이다.

SIGNATURE BYTES = DB * 4.
─────────────
현재의 값은 "PE/0/0"이다. 결국, PE뒤에 0(null)이ㅣ 두개 이어진다.

CPU TYPE = DW CPU 종류.
────────────
이 Field에서는, 실행시에 이 Image에서 필요로 하는 CPU호환성의 형을 지정한다.
이하에 값을 나타낸다.

  o  0000h __unknown

  o  014Ch __80386

  o  014Dh __80486

  o  014Eh __80586

  o  0162h __MIPS Mark I (R2000, R3000)

  o  0163h __MIPS Mark II (R6000)

  o  0166h __MIPS Mark III (R4000)

# OBJECTS = DW
────────
오브젝트 엔트리의 수. 이 필드에는 오브젝트 테이블에 있는 엔트리의 수를 지정한다.

TIME/DATE STAMP = DD
──────────
링커로 File의 작성 또는 수정을 한 일시를 격납하기 위해 사용한다.


NT HDR SIZE = DW
────────
이것은 FLAGS필드의 뒤에 있는 NT Header에 있는 남은 Byte수이다.

FLAGS = DW
~~~~~~~~~~
이미지용 플래그 비트이다. 플래그에는 맛쉼?같은 정의가 있다.

  o  0000h __Program image.

  o  0002h __Image is executable.
     이 Bit가 설정되지 않을 때는, 링크시에 Error를 검출했는지, 또는 Image의
     증분 링크 실행중이기 때문에 로드할 수 없다는 것을 나타낸다.

  o  0200h __Fixed.
     Image를 Image Base에서 로드할 수 없을 때는, 그 Image를 로드하지
     않는다는것을 나타낸다..

  o  2000h __Library image.

LMAJOR/LMINOR = DB
─────────
링커의 major/minor 버젼번호이다.

ENTRYPOINT RVA = DD
──────────
Entrypoint의 상대가상주소이다. 주소는 이미지 베이스로부터의 상대주소이다. 주소는
Program Image인 경우는 개시주소, Library Image인 경우는 Library의 초기화 및
종료주소가 된다.

IMAGE BASE = DD
────────
이미지의 가상 베이스이다. 이것은, File의 선두Byte의 가상주소이다(MS-DOS Header).
64K의 배수가 아니면 안된다.

OBJECT ALIGN = DD
─────────
오브젝트의 배치이다. 이것은, 512부터 256M까지의 2자승이 아니면 안된다.
Default는 64K이다.

FILE ALIGN = DD
────────
Image Page를 배치하기 위하여 사용하는 배치요소. (Byte단위의)배치요소를 사용해서,
Image Page의 Base를 배치하고, Object단위의 후속 0메우기의 배열경계Size를
결정한다. 배치요소가 크면 클수록, 보다 큰 File Space가 필요하게 된다.
역으로 배치요소가 작으면 작을수록, 상당한 비율로 로드 요구 퍼포먼스에 영향을
미치게 된다. 이 2가지 중에서 File Space를 효과없이(헛되이) 사용하는 쪽을 권한다.
이 값은, 64K부터 512M까지의 2자승이어야 한다.

OS MAJOR/MINOR = DW
──────────
이 Image를 실행하기 위하여 필요한 OS Version의 번호.

USER MAJOR/MINOR # = DW
────────────
User의 메이저 또는 마이너의 Version 번호. 이것은 Image 또는 다이나믹 링크
Library에서 revision끼리를 구별하는데 도움이된다. 값은 링크시에 User가 지정한다.

SUBSYS MAJOR/MINOR # = DW
─────────────
Sub System의 Image또는 마이너의 revision 번호.

IMAGE SIZE = DD
────────
이미지의 가상크기(바이트단위).이것은 모든 Header을 포함된다.
Image Size 의 합계는 Object배치의 배수여야 한다.

HEADER SIZE = DD
────────
Header 크기의 합계.
MS-DOS Header,PE Header그리고 오브젝트 테이블의 결합된 크기.

FILE CHECKSUM = DD
─────────
File전체의 Check Sum. 링크에 의해 0으로 지정된다.

SUBSYSTEM = DW
───────
이 Image를 실행하기 위하여 필요한 NT Sub System.
다음에 값을 나타낸다.

  o  0000h __Unknown

  o  0001h __Native

  o  0002h __Windows GUI

  o  0003h __Windows Character

  o  0005h __OS/2 Character

  o  0007h __Posix Character

DLL FLAGS = DW
───────
특별한 loader 요건을 나타낸다. 이 플래그는 다음과 같은 값이 있다.

  o  0001h __Per-Process Library Initialization.

  o  0002h __Per-Process Library Termination.

  o  0004h __Per-Thread Library Initialization.

  o  0008h __Per-Thread Library Termination.

다른 Bit는 모두, 앞으로 사용하기 위해 예약되어 있기 때문에 0으로 지정해 주세요.

STACK RESERVE SIZE = DD
────────────
Imag에 필요한  Stack Size.
Memory는 예약되어 있지만, STACK COMMIT SIZE만을 Commit한다.
Stack의 다음 Page는, 'guarded page'이다. 'guarded page'는, Application에서
히트하면 유효가 되고, 그 다음의 Page가 'guarded page'가 된다. 이 처리는 Stack
Size가 RESERVE SIZE에 달할 때까지 반복된다.

STACK COMMIT SIZE = DD
───────────
Stack commit size.

HEAP RESERVE SIZE = DD
───────────
예약대상의 로칼힙의 사이즈

HEAP COMMIT SIZE = DD
───────────
로칼힙에서의 커밋하기위한 양(amount)

# INTERESTING VA/SIZES = DD
──────────────
후속의 VA /SIZE 배열의 사이즈를 표시한다.

EXPORT TABLE RVA = DD
───────────
엑스포트 테이블의 상대가상주소. 이 주소는, Image Base로부터의 상대 주소이다.

IMPORT TABLE RVA = DD
───────────
임포트 테이블의 상대가상 주소. 이 주소는 이미지 베이스로부터의 상대 주소이다.


RESOURCE TABLE RVA = DD
────────────
리소스 테이블의 상대가상 주소. 이 주소는 이미지 베이스로부터의 상대 주소이다.

EXCEPTION TABLE RVA = DD
────────────
예외 테이블의 상대 가상주소이다. 이 주소는 이미지 베이스로부터의 상대 주소이다.

SECURITY TABLE RVA = DD
────────────
보안 테이블의 상대가상 주소이다. 이 주소는 이미지 베이스로부터의 상대 주소이다.

FIXUP TABLE RVA = DD
──────────
픽스업 테이블의 상대가상 주소이다. 이 주소는 이미지 베이스로부터의 상대주소이다.

DEBUG TABLE RVA = DD
───────────
디버그테이블의 상대 가상주소. 이 주소는 이미지 베이스로부터의 상대 주소이다.

IMAGE DESCRIPTION RVA = DD
─────────────
모듈 정의파일(.def)에 지정된 기술문자열의 상대가상주소이다.

MACHINE SPECIFIC RVA = DD
─────────────
기계 고유값의 상대 가상 주소. 이 주소는 이미지 베이스로부터의 상대 주소이다.

TOTAL EXPORT DATA SIZE = DD
──────────────
엑스포트 데이터의 합계 사이즈.

TOTAL IMPORT DATA SIZE = DD
──────────────
임포트 데이터의 합계 사이즈.

TOTAL RESOURCE DATA SIZE = DD
───────────────
리소스 데이터의 합계 사이즈.

TOTAL EXCEPTION DATA SIZE = DD
───────────────
예외 데이터의 합계 사이즈.

TOTAL SECURITY DATA SIZE = DD
───────────────
보안 데이터의 사이즈.

TOTAL FIXUP DATA SIZE = DD
─────────────
픽스업 데이터의 합계 사이즈.

TOTAL DEBUG DIRECTORIES = DD
──────────────
디버그 디렉토리의 총 수.

TOTAL DESCRIPTION SIZE = DD
──────────────
기술데이타의 합계 사이즈.

MACHINE SPECIFIC SIZE = DD
─────────────
기계 고유의 값.

─━─━─━─━─━─━─━─━─━─━─━─━─━─━─━─━─━─━─━─
3. Object Table
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Object Table의 Entry수는, PE Header의 #Object Field로 지정한다. Object Table내의
Entry는, 1부터 번호 붙여진다. PE Header의 직후에 Object Table이 이어진다.
Code 및 Data Memory Object Entry는, 링커에서 선택한 순번으로 되어있다.
Object의 가상 Address는, 연속해서 오름차순이 되도록 링커에서 할당할 필요가 있다.
또, PE Header의 Object배치의 배수여야 한다.

Object Table의 각Entry는, 다음의 형식을 취한다.

    ┌───────────────────────────┐
    │                    OBJECT NAME                       │
    ├─────────────┬─────────────┤
    │      VIRTUAL SIZE        │          RVA             │
    ├─────────────┼─────────────┤
    │     PHYSICAL SIZE        │     PHYSICAL OFFSET      │
    ├─────────────┼─────────────┤
    │       RESERVED           │        RESERVED          │
    ├─────────────┼─────────────┤
    │       RESERVED           │      OBJECT FLAGS        │
    └─────────────┴─────────────┘

Figure 3.  Object Table

OBJECT NAME = DB * 8
──────────
오브젝트명. 이것은 8Byet의 Null메우기ASCII 문자열로, Object명을 나타낸다.

VIRTUAL SIZE = DD
─────────
가상메모리 크기. Object를 로드했을 때에 할당되는 Object의 Size이다.
PHYSICAL SIZE와 VIRTUAL SIZE의 차는 0으로 메운다.

RVA = DD
────
상대가상주소. Object의 현재 재배치선의 가상주소로 Image Base로부터의
상대주소이다. 각Object의 가상 주소공간에서는,  Object배치(512부터 256M의 2자승.
디폴트는 64K)의 배수인 Space를 필요로 하고, 가상주소공간내의 직전 Object에
이어진다(Image용의 가상주소공간은 빈 틈이 없어야 한다).

PHYSICAL SIZE = DD
─────────
초기화가 끝난 Data의 물리 File Size. Object용의 File의 초기화 Data의 Size이다.
물리 Size는, PE Header의 File배치 Field이 배수로, 가상 Size이하이어야 한다.

PHYSICAL OFFSET = DD
──────────
오브젝트의 첫 번째 페이지의 물리 오프셋이다. 이 OffSet은, EXE File의
선두로부터의 상대 주소이고, PE Header의 File배치 Field의 배수로 배치 된다.
이 OffSet은, Seek값으로써 사용된다.

OBJECT FLAGS = DD
─────────
오브젝트 플래그 비트. 다음과 같은 정의가 있다.

  o  000000020h __Code object.

  o  000000040h __Initialized data object.

  o  000000080h __Uninitialized data object.

  o  040000000h __Object must not be cached.

  o  080000000h __Object is not pageable.

  o  100000000h __Object is shared.

  o  200000000h __Executable object.

  o  400000000h __Readable object.

  o  800000000h __Writeable object.

다른 Bit는, 모두 앞으로 사용하기 위해 예약되어 있기때문에, 0으로 설정해 주세요.

─━─━─━─━─━─━─━─━─━─━─━─━─━─━─━─━─━─━─━─
4. Image Pages
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Image Page Section에는, 모든 Object의 초기화 Data가 모두 들어 있다.
각 Object의 첫 번째 페이지의  Seek OffSet은 Object Teble에 지정되고,
File배치경계에 배치된다. Object는, RVA에서 순서가 붙여진다.
Object는, 모두 Object배치의 배수로 시작된다.

─━─━─━─━─━─━─━─━─━─━─━─━─━─━─━─━─━─━─━─
5. Exports
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
다음에, 전형적인 Export정보의 LayOut을 나타낸다.

    ┌───────────┐
    │    DIRECTORY TABLE   │
    ├───────────┤
    │    ADDRESS TABLE     │
    │                      │
    │                      │
    │                      │
    │                      │
    │                      │
    │                      │
    ├───────────┤
    │    NAME PTR TABLE    │
    │                      │
    │                      │
    │                      │
    ├───────────┤
    │    ORDINAL TABLE     │
    │                      │
    │                      │
    │                      │
    ├───────────┤
    │    NAME STRINGS      │
    │                      │
    │                      │
    └───────────┘

Figure 4.  Export File Layout

5.1 Export Directory Table
━━━━━━━━━━━━━
Export정보는, 나머지 Export정보를 기술하는 Export Directory Table로
시작된다. 이 Export Directory Table에는 Address정보가 들어가 있고,
이 정보를 사용하여 해당하는 Image내의 Entry Point로의 FixUp참조를 결정한다.

    ┌─────────────────┐
    │           EXPORT FLAGS           │
    ├─────────────────┤
    │          TIME/DATE STAMP         │
    ├────────┬────────┤
    │ MAJOR VERSION  │  MINOR VERSION │
    ├────────┴────────┤
    │            NAME RVA              │
    ├─────────────────┤
    │          ORDINAL BASE            │
    ├─────────────────┤
    │          # EAT ENTRIES           │
    ├─────────────────┤
    │           # NAME PTRS            │
    ├─────────────────┤
    │        ADDRESS TABLE RVA         │
    ├─────────────────┤
    │       NAME PTR TABLE RVA         │
    ├─────────────────┤
    │        ORDINAL TABLE RVA         │
    └─────────────────┘

Figure 5.  Export Directory Table Entry

EXPORT FLAGS = DD
─────────
현재 0이 설정되어있다.

TIME/DATE STAMP = DD
──────────
엑스포트 데이터를 작성한 날짜와 시간.

MAJOR/MINOR VERSION = DW
────────────
사용자가 설정가능한 메이져 또는 마이너의 버전 번호.

NAME RVA = DD
───────
Dll asciiz이름의 상대가상 주소. 이 주소는 이미지 베이스로부터의 상대 주소이다.

ORDINAL BASE = DD
─────────
엑스포트된 최초의 유효한 서수(序數 - ordinal)이다.
이 필드에는 해당하는 이미지의 엑스포트 주소 테이블의 개시서수(開始序數)를
지정한다. 통상적으로 1로 설정한다.

# EAT ENTRIES = DD
─────────
엑스포트 주소테이블의 엔트리의 수를 표시한다.

# NAME PTRS = DD
────────
이것은 Name Ptr Table으 엔트리의 수를 표시한다.(그리고 parallel Ordinal Table도)

ADDRESS TABLE RVA = DD
───────────
엑스포트 주소 테이블의 상대가상주소이다.
이 주소는 이미지 베이스로부터의 상대 주소이다.

NAME TABLE RVA = DD
──────────
엑스포트 명칭 테이블 포인터의 상대가상주소.
이 주소는 이미지베이스의 선두로부터의 상대주소이다.
이 테이블은 # NAMES 엔트리를가지는 RVA의 배열이다.

ORDINAL TABLE RVA = DD
───────────
엑스포트 서수(序數 - ordinal) 테이블 엔트리의 상대 가상주소이다.
이 주소는 이미지 베이스로부터의 상대 주소이다.

5.2 Export Address Table
━━━━━━━━━━━━
엑스포트 주소 테이블에는 엑스포트한 엔트리 포인트, 데이타 및 절대 주소가 들어있
다. 서수(序數 - ordinal)를 사용해서 엑스포트 주소 테이블을 인덱스(index)한다.
이 테이블 내로 인덱싱을 하기 전에 ORDINAL BASE를 서수(序數 - ordinal)로부터
감산(substracted)되어져야만 한다.

다음에, 엑스포트 주소 테이블 엔트리의 형식을 설명한다.

    ┌───┬───┬────┬────┐
    │          EXPORTED RVA            │
    └───┴───┴────┴────┘

Figure 6.  Export Address Table Entry

EXPORTED RVA = DD
─────────
엑스포트 주소이다. 이 필드에는 엑스포트된 엔트리의 상대 가상 주소가 들어간다.
(이미지 베이스로부터의 가상주소이다.)

5.3 Export Name Table Pointers
━━━━━━━━━━━━━━━
Export Name Table Pointers의 배열에는, Export Name Table Pointers로의 주소가
들어있다. 포인터는 각각 32Bit로, 이미지 베이스로부터의 상대 주소이다.
포인터는 字句(lexicall)의 순번으로 되어 있고, 바이너리검색이 가능하다.

5.4 Export Ordinal Table
━━━━━━━━━━━━
Export Name Table Pointers 및 Export Ordinal Table로 2개의 배열을 형성한다.
이러한 배열은 독립하고 있기 때문에, 본래의 필드 배치를 한다.
Export Ordinal Table의 배열에는, 대응하는 Export Name Table Pointers로 참조하는
이름붙이기 Export와 관련하는 Export Address Table의 序數가 들어 있다.
序數는 각각 16Bit로, Export Directory Table에 저장된 Ordinal Base가 이미
들어있다.

5.5 Export Name Table
━━━━━━━━━━━
Export Name Table에는, Image가 Export된 Entry용으로 생략 가능한 ASCII명이
들어 있다. 이러한 Table을 Export Name Table Pointers의 배열 및 Export 序數의
배열과 병용하고, 일치하는 이름문자열을 검색하는것으로 Procedure명 문자열을
序數로 변환한다. 이 序數를 사용하여, Entry Point 정보를 Export Address Table로
배치한다.

이름에 의한 Import참조에서는, Export 이름 Table Pointer의 Table을
바이너리검색하고 일치하는 이름을 찾을 필요가 있다. 그 후, Table Pointer
序數를 넣기 위해, 대응하는 Export Ordinal Table을 인식한다.
序數에 의한 Import참조에서는, 이름Table을 검색할 필요가 없기 때문에
검색 Speed가 상당히 빨라진다.

각 이름 테이블 엔트리는 다음의 형태를 가지고 있다.

    ┌───┬────┬───┬────┐
    │ASCII STRING ::: ::::::::   '\0'  │
    └───┴────┴───┴────┘

Figure 7.  Export Name Table Entry

ASCII STRING = DB
─────────
ASCII String.
이 문자열은 대/소문자를 구별하고 NULL로 끝나게 된다.

─━─━─━─━─━─━─━─━─━─━─━─━─━─━─━─━─━─━─━─
6. Imports
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
임포트 정보의 대표적인 파일 레이아웃은 아래와 같다.

    ┌───────────┐
    │    DIRECTORY TABLE   │
    │                      │
    │                      │
    │                      │
    ├───────────┤
    │   NULL DIR ENTRY     │
    └───────────┘

    ┌───────────┐
    │  DLL1 LOOKUP TABLE   │
    │                      │
    ├───────────┤
    │        NULL          │
    └───────────┘

    ┌───────────┐
    │  DLL2 LOOKUP TABLE   │
    │                      │
    ├───────────┤
    │        NULL          │
    └───────────┘

    ┌───────────┐
    │  Dll3 LOOKUP TABLE   │
    │                      │
    ├───────────┤
    │        NULL          │
    └───────────┘

    ┌───────────┐
    │   HINT-NAME TABLE    │
    │                      │
    └───────────┘

    ┌───────────┐
    │  DLL1 ADDRESS TABLE  │
    │                      │
    ├───────────┤
    │        NULL          │
    └───────────┘

    ┌───────────┐
    │  DLL2 ADDRESS TABLE  │
    │                      │
    ├───────────┤
    │        NULL          │
    └───────────┘

    ┌───────────┐
    │  DLL3 ADDRESS TABLE  │
    │                      │
    ├───────────┤
    │        NULL          │
    └───────────┘

Figure 8.  Import File Layout

6.1 Import Directory Table
━━━━━━━━━━━━━
Import정보는, 나머지 Import정보를 기술하는 Import Directory Table로
시작된다. 이 Import Directory Table에는 Address정보가 들어 있고,
이 정보를, 사용하여 DLL Image내의 Entry Point로의 FixUp참조를 결정한다.
Import Directory Table은, Import Directory Entry의 배열부터 이루어진다.
해당하는 Image로 참조하는 DLL마다 1개의 Entry가 대응한다.
최후의 Directory Entry는 NULL이고, 이것은 Directory Table의 마지막을
나타낸다.

Import Directory Entry 다음의 형태를 취한다.

    +--------+--------+--------+--------+
    :            IMPORT FLAGS           :
    +-----------------------------------+
    :           TIME/DATE STAMP         :
    +-----------------+-----------------+
    :  MAJOR VERSION  :   MINOR VERSION :
    +-----------------+-----------------+
    :              NAME RVA             :
    +-----------------------------------+
    :      IMPORT LOOKUP TABLE RVA      :
    +-----------------------------------+
    :      IMPORT ADDRESS TABLE RVA     :
    +--------+--------+--------+--------+

Figure 9.  Import Directory Entry

IMPORT FLAGS = DD
─────────
현재 0으로 설정되어 있다.

TIME/DATE STAMP = DD
──────────
Import Data를 미리 스냅한 일시. 스냅하고 있지 않는 경우는 0이 된다.

MAJOR/MINOR VERSION = DW
────────────
참조하는 dll의 major/minor version 번호.

NAME RVA = DD
───────
Dll asciiz Name의 상대 가상 주소이다.
이 주소는 이미지 베이스로부터의 상대 주소이다.

IMPORT LOOKUP TABLE RVA = DD
──────────────
이 Field에는, 해당하는 Image의 Pointer검색 Table의 개시 Address가 들어간다.
이 Address는, Image Base의 시작으로 부터의 상대 Address이다.

IMPORT ADDRESS TABLE RVA = DD
───────────────
이 필드는 해당하는 이미지의 임포트 어드레스의 시작주소를 가지고있다.
이 주소는 이미지 베이스로부터의 상대 주소이다.

6.2 Import Lookup Table
━━━━━━━━━━━━
Import 검색 Table이라는 것은, 각DLL에 대한 序數, 또는 힌트 및 이름의
RVA배열이다. 최후의 Entry는 NULL이고, 이것은 Table의 마지막을 나타낸다.

마지막 요소는 비어있다.

     3                                 0
     1
   ┌─┬──┬───┬────┬────┐
   │0 │ ORDINAL#/HINT-NAME TABLE RVA   │
   └─┴──┴───┴────┴────┘

Figure 10.  Import Address Table Format

ORDINAL/HINT-NAME TABLE RVA = 31-bits (mask = 7fffffffh) Ordinal
Number or Name Table RVA.
────────────────────────────────
序數에 의한 Import일 때는, 이 Field에는 31Bit의 序數가 들어 간다.
이름에 의한 Import일 때에는, 이 Field에는 HINT-NAME TABLE에 대한
Image Base로부터의 상대 31 Bit의 Address가 들어간다.


O = 1-bit (mask = 80000000h) ordinal flag에 의해 임포트된다.

  o  00000000h __Import by name.

  o  80000000h __Import by ordinal.

6.3 Hint-Name Table
━━━━━━━━━━
다음은 Hint-Name Table의 형식을 표현한것이다.

   ┌────┬───┬────┬────┐
   │       HINT     │ ASCII STRING ::::│
   ├────┴───┼────┴────┤
   │::::::::::::::::│  '\0'     PAD    │
   └────────┴─────────┘


    PAD field 는 선택적이다.

Figure 11.  Import Hint-Name Table

HINT = DW
─────
Export Name Table Pointers로의 힌트.
이름에 의한 빠른 Import를 가능하게 하고, 힌트 값를 사용하여 Export Name Table
Pointers의 배열 Index를 작성한다.  힌트가 바르지 않을 경우는, Export Name Ptr
Table로 바이너리 검색이 행해진다.

ASCII STRING = DB
─────────
ASCII String.
이 문자열은 대/소문자를 구별하고 NULL로 끝나게 된다.

PAD = DB
────
0으로 채워진다.
필요에 응하여 후속 NULL Byte의 뒤에 나오는 Byte를 모두 0으로 지정하고,
짝수경계로 다음 Entry를 배치한다.
Import의 32Bit Address로 Image를 인스톨할 때에, 로더에 의해 Import Address가
덮어 씌어 진다.

6.4 Import Address Table
━━━━━━━━━━━━
Import Address Table라는 것은, 각 DLL의 Import되
홍환민.행복 [hhshhm]   2002-11-14 20:50 X
이거 끝부분 짤렸네요..

+ -

관련 글 리스트
119 [팁] PE (Portable Executable) File Format 박지훈.임프 8396 2001/07/26
Google
Copyright © 1999-2015, borlandforum.com. All right reserved.