各位大侠:<br>我通过分析可执行文件及动态链接库的pe及ne格式,<br>已经解决了这个问题,不知这两百分该送给谁?附文<br>件格式.<br>1.NE format<br><br>INF: Executable-File Header Format [P_WinSDK]<br><br>3.00<br>WINDOWS<br>PSSONLY | Windows 3 Developers Notes softlib ENDUSER<br><br>Summary:<br><br>Note: This article is part of a set of seven articles, collectively<br>called the "Windows 3.00 Developer's Notes." More information about<br>the contents of the other articles, and procedures for ordering a<br>hard-copy set, can be found in the knowledge base article titled "INF:<br>The Windows 3.00 Developer's Notes" (Q65260).<br><br>This article can be found in the Software/Data Library by searching on<br>the word EXEFMT or S12688. EXEFMT was archived using the PKware<br>file-compression utility.<br><br>More Information:<br><br>Microsoft defined the segmented executable file format for Windows<br>applications and dynamic-link libraries (DLLs). This file format is<br>also referred to as the New Executable Format. This new format is an<br>extension of the existing MS-DOS .EXE format (old-style format). The<br>purpose of the segmented executable format is to provide the<br>information needed to support the dynamic linking and segmentation<br>capabilities of the Windows environment.<br><br>An executable file contains Microsoft Windows code and data, or<br>Windows code, data, and resources. Specific fields have been added to<br>the old-style .EXE format header to indicate the existence of the<br>segmented file format. The old-style header may contain a valid<br>executable program, called a stub program, that will be executed if<br>the program is run on MS-DOS (without Windows). This stub program<br>usually prints a message indicating that Microsoft Windows is required<br>to run the program. The segmented executable format extensions also<br>begin with a header that describes the contents and location of the<br>executable image in the file. The loader uses this header information<br>when it loads the executable segments in memory.<br><br><br>======================================================================<br> OLD-STYLE HEADER EXTENSIONS<br>======================================================================<br><br>The old-style header contains information the loader expects for a DOS<br>executable file. It describes a stub program (WINSTUB) the loader can<br>place in memory when necessary, it points to the new-style header, and<br>it contains the stub programs relocation table.<br><br>The following illustrates the distinct parts of the old-style<br>executable format:<br><br> +-------------------------+<br> 00h | Old-style header info |<br> +-------------------------+<br> 20h | Reserved |<br> +-------------------------+<br> 3Ch | Offset to segmented |<br> | .EXE header |<br> +-------------------------+<br> 40h | Relocation table and |<br> | DOS stub program |<br> +-------------------------+<br> | Segmented .EXE Header |<br> | . |<br> | . |<br> | . |<br><br>The word at offset 18h in the old-style .EXE header contains the<br>relative byte offset to the stub program's relocation table. If this<br>offset is 40h, then the double word at offset 3Ch is assumed to be the<br>relative byte offset from the beginning of the file to the beginning<br>of the segmented executable header. A new-format .EXE file is<br>identified if the segmented executable header contains a valid<br>signature. If the signature is not valid, the file is assumed to be an<br>old-style format .EXE file. The remainder of the old-style format<br>header will describe a DOS program, the stub. The stub may be any<br>valid program but will typically be a program that displays an error<br>message.<br><br>======================================================================<br> SEGMENTED EXE FORMAT<br>======================================================================<br><br>Because Windows executable files are often larger than one segment<br>(64K), additional information (that does not appear in the old-style<br>header) is required so that the loader can load each segment properly.<br>The segmented EXE format was developed to provide the loader with this<br>information.<br><br>The segmented .EXE file has the following format:<br><br> +-----------------+<br> 00h | Old-style EXE |<br> | Header |<br> +-----------------+<br> 20h | Reserved |<br> +-----------------+<br> 3Ch | Offset to | ---+<br> | Segmented Header| |<br> +-----------------+ |<br> 40h | Relocation Table| |<br> | & Stub Program | |<br> +-----------------+ |<br> | | |<br> +-----------------+ |<br> xxh | Segmented EXE | <--+<br> | Header |<br> +-----------------+<br> | Segment Table |<br> +-----------------+<br> | Resource Table |<br> +-----------------+<br> | Resident Name |<br> | Table |<br> +-----------------+<br> | Module Reference|<br> | Table |<br> +-----------------+<br> | Imported Names |<br> | Table |<br> +-----------------+<br> | Entry Table |<br> +-----------------+<br> | Non-Resident |<br> | Name Table |<br> +-----------------+<br> | Seg #1 Data |<br> | Seg #1 Info |<br> +-----------------+<br> .<br> .<br> .<br> +-----------------+<br> | Seg #n Data |<br> | Seg #n Info |<br> +-----------------+<br><br><br>The following sections describe each of the components that make up<br>the segmented EXE format. Each section contains a description of the<br>component and the fields in the structures that make up that<br>component.<br><br>Note: All unused fields and flag bits are reserved for future use and<br>must contain 0 (zero) values.<br><br>======================================================================<br> SEGMENTED EXE HEADER<br>======================================================================<br><br>The segmented EXE header contains general information about the EXE<br>file and contains information on the location and size of the other<br>sections. The Windows loader copies this section, along with other<br>data, into the module table in the system data. The module table is<br>internal data used by the loader to manage the loaded executable<br>modules in the system and to support dynamic linking.<br><br>The following describes the format of the segmented executable header.<br>For each field, the offset is given relative to the beginning of the<br>segmented header, the size of the field is defined, and a description<br>is given.<br><br> Offset Size Description<br> ------ ---- -----------<br><br> 00h DW Signature word.<br> "N" is low-order byte.<br> "E" is high-order byte.<br><br> 02h DB Version number of the linker.<br><br> 03h DB Revision number of the linker.<br><br> 04h DW Entry Table file offset, relative to the beginning of<br> the segmented EXE header.<br> 06h DW Number of bytes in the entry table.<br><br> 08h DD 32-bit CRC of entire contents of file.<br> These words are taken as 00 during the calculation.<br><br> 0Ch DW Flag word.<br> 0000h = NOAUTODATA<br> 0001h = SINGLEDATA (Shared automatic data segment)<br> 0002h = MULTIPLEDATA (Instanced automatic data<br> segment)<br> 2000h = Errors detected at link time, module will not<br> load.<br> 8000h = Library module.<br> The SS:SP information is invalid, CS:IP points<br> to an initialization procedure that is called<br> with AX equal to the module handle. This<br> initialization procedure must perform a far<br> return to the caller, with AX not equal to<br> zero to indicate success, or AX equal to zero<br> to indicate failure to initialize. DS is set<br> to the library's data segment if the<br> SINGLEDATA flag is set. Otherwise, DS is set<br> to the caller's data segment.<br><br> A program or DLL can only contain dynamic<br> links to executable files that have this<br> library module flag set. One program cannot<br> dynamic-link to another program.<br><br> 0Eh DW Segment number of automatic data segment.<br> This value is set to zero if SINGLEDATA and<br> MULTIPLEDATA flag bits are clear, NOAUTODATA is<br> indicated in the flags word.<br><br> A Segment number is an index into the module's segment<br> table. The first entry in the segment table is segment<br> number 1.<br><br> 10h DW Initial size, in bytes, of dynamic heap added to the<br> data segment. This value is zero if no initial local<br> heap is allocated.<br><br> 12h DW Initial size, in bytes, of stack added to the data<br> segment. This value is zero to indicate no initial<br> stack allocation, or when SS is not equal to DS.<br><br> 14h DD Segment number
ffset of CS:IP.<br><br> 18h DD Segment number
ffset of SS:SP.<br> If SS equals the automatic data segment and SP equals<br> zero, the stack pointer is set to the top of the<br> automatic data segment just below the additional heap<br> area.<br><br> +--------------------------+<br> | additional dynamic heap |<br> +--------------------------+ <- SP<br> | additional stack |<br> +--------------------------+<br> | loaded auto data segment |<br> +--------------------------+ <- DS, SS<br><br> 1Ch DW Number of entries in the Segment Table.<br><br> 1Eh DW Number of entries in the Module Reference Table.<br> 20h DW Number of bytes in the Non-Resident Name Table.<br><br> 22h DW Segment Table file offset, relative to the beginning<br> of the segmented EXE header.<br><br> 24h DW Resource Table file offset, relative to the beginning<br> of the segmented EXE header.<br><br> 26h DW Resident Name Table file offset, relative to the<br> beginning of the segmented EXE header.<br><br> 28h DW Module Reference Table file offset, relative to the<br> beginning of the segmented EXE header.<br><br> 2Ah DW Imported Names Table file offset, relative to the<br> beginning of the segmented EXE header.<br><br> 2Ch DD Non-Resident Name Table offset, relative to the<br> beginning of the file.<br><br> 30h DW Number of movable entries in the Entry Table.<br><br> 32h DW Logical sector alignment shift count, log(base 2) of<br> the segment sector size (default 9).<br><br> 34h DW Number of resource entries.<br><br> 36h DB Executable type, used by loader.<br> 02h = WINDOWS<br><br> 37h-3Fh DB Reserved, currently 0's.<br><br><br>======================================================================<br> SEGMENT TABLE<br>======================================================================<br><br>The segment table contains an entry for each segment in the executable<br>file. The number of segment table entries are defined in the segmented<br>EXE header. The first entry in the segment table is segment number 1.<br>The following is the structure of a segment table entry.<br><br> Size Description<br> ---- -----------<br><br> DW Logical-sector offset (n byte) to the contents of the segment<br> data, relative to the beginning of the file. Zero means no<br> file data.<br><br> DW Length of the segment in the file, in bytes. Zero means 64K.<br><br> DW Flag word.<br> 0007h = TYPE_MASK Segment-type field.<br> 0000h = CODE Code-segment type.<br> 0001h = DATA Data-segment type.<br> 0010h = MOVEABLE Segment is not fixed.<br> 0040h = PRELOAD Segment will be preloaded; read-only if<br> this is a data segment.<br> 0100h = RELOCINFO Set if segment has relocation records.<br> F000h = DISCARD Discard priority.<br><br> DW Minimum allocation size of the segment, in bytes. Total size<br> of the segment. Zero means 64K.<br><br><br>======================================================================<br> RESOURCE TABLE<br>======================================================================<br><br>The resource table follows the segment table and contains entries for<br>each resource in the executable file. The resource table consists of<br>an alignment shift count, followed by a table of resource records. The<br>resource records define the type ID for a set of resources. Each<br>resource record contains a table of resource entries of the defined<br>type. The resource entry defines the resource ID or name ID for the<br>resource. It also defines the location and size of the resource. The<br>following describes the contents of each of these structures:<br><br> Size Description<br> ---- -----------<br><br> DW Alignment shift count for resource data.<br><br> A table of resource type information blocks follows. The following<br> is the format of each type information block:<br><br> DW Type ID. This is an integer type if the high-order bit is<br> set (8000h); otherwise, it is an offset to the type string,<br> the offset is relative to the beginning of the resource<br> table. A zero type ID marks the end of the resource type<br> information blocks.<br><br> DW Number of resources for this type.<br><br> DD Reserved.<br><br> A table of resources for this type follows. The following is<br> the format of each resource (8 bytes each):<br><br> DW File offset to the contents of the resource data,<br> relative to beginning of file. The offset is in terms<br> of the alignment shift count value specified at<br> beginning of the resource table.<br><br> DW Length of the resource in the file (in bytes).<br><br> DW Flag word.<br> 0010h = MOVEABLE Resource is not fixed.<br> 0020h = PURE Resource can be shared.<br> 0040h = PRELOAD Resource is preloaded.<br><br> DW Resource ID. This is an integer type if the high-order<br> bit is set (8000h), otherwise it is the offset to the<br> resource string, the offset is relative to the<br> beginning of the resource table.<br><br> DD Reserved.<br><br> Resource type and name strings are stored at the end of the<br> resource table. Note that these strings are NOT null terminated and<br> are case sensitive.<br><br> DB Length of the type or name string that follows. A zero value<br> indicates the end of the resource type and name string, also<br> the end of the resource table.<br><br> DB ASCII text of the type or name string.<br><br><br>======================================================================<br> RESIDENT-NAME TABLE<br>======================================================================<br><br>The resident-name table follows the resource table, and contains this<br>module's name string and resident exported procedure name strings. The<br>first string in this table is this module's name. These name strings<br>are case-sensitive and are not null-terminated. The following<br>describes the format of the name strings:<br><br> Size Description<br> ---- -----------<br><br> DB Length of the name string that follows. A zero value indicates<br> the end of the name table.<br><br> DB ASCII text of the name string.<br><br> DW Ordinal number (index into entry table). This value is ignored<br> for the module name.<br><br><br>======================================================================<br> MODULE-REFERENCE TABLE<br>======================================================================<br><br>The module-reference table follows the resident-name table. Each entry<br>contains an offset for the module-name string within the imported-<br>names table; each entry is 2 bytes long.<br><br> Size Description<br> ---- -----------<br><br> DW Offset within Imported Names Table to referenced module name<br> string.<br><br><br>======================================================================<br> IMPORTED-NAME TABLE<br>======================================================================<br><br>The imported-name table follows the module-reference table. This table<br>contains the names of modules and procedures that are imported by the<br>executable file. Each entry is composed of a 1-byte field that<br>contains the length of the string, followed by any number of<br>characters. The strings are not null-terminated and are case<br>sensitive.<br><br> Size Description<br> ---- -----------<br><br> DB Length of the name string that follows.<br><br> DB ASCII text of the name string.<br><br><br>======================================================================<br> ENTRY TABLE<br>======================================================================<br><br>The entry table follows the imported-name table. This table contains<br>bundles of entry-point definitions. Bundling is done to save space in<br>the entry table. The entry table is accessed by an ordinal value.<br>Ordinal number one is defined to index the first entry in the entry<br>table. To find an entry point, the bundles are scanned searching for a<br>specific entry point using an ordinal number. The ordinal number is<br>adjusted as each bundle is checked. When the bundle that contains the<br>entry point is found, the ordinal number is multiplied by the size of<br>the bundle's entries to index the proper entry.<br><br>The linker forms bundles in the most dense manner it can, under the<br>restriction that it cannot reorder entry points to improve bundling.<br>The reason for this restriction is that other .EXE files may refer to<br>entry points within this bundle by their ordinal number. The following<br>describes the format of the entry table bundles.<br><br> Size Description<br> ---- -----------<br><br> DB Number of entries in this bundle. All records in one bundle<br> are either moveable or refer to the same fixed segment. A zero<br> value in this field indicates the end of the entry table.<br><br> DB Segment indicator for this bundle. This defines the type of<br> entry table entry data within the bundle. There are three<br> types of entries that are defined.<br><br> 000h = Unused entries. There is no entry data in an unused<br> bundle. The next bundle follows this field. This is<br> used by the linker to skip ordinal numbers.<br><br> 001h-0FEh = Segment number for fixed segment entries. A fixed<br> segment entry is 3 bytes long and has the following<br> format.<br><br> DB Flag word.<br> 01h = Set if the entry is exported.<br> 02h = Set if the entry uses a global (shared) data<br> segments.<br> The first assembly-language instruction in the<br> entry point prologue must be "MOV AX,data<br> segment number". This may be set only for<br> SINGLEDATA library modules.<br><br> DW Offset within segment to entry point.<br><br> 0FFH = Moveable segment entries. The entry data contains the<br> segment number for the entry points. A moveable segment<br> entry is 6 bytes long and has the following format.<br><br> DB Flag word.<br> 01h = Set if the entry is exported.<br> 02h = Set if the entry uses a global (shared) data<br> segments.<br><br> INT 3FH.<br><br> DB Segment number.<br><br> DW Offset within segment to entry point.<br><br><br>======================================================================<br> NONRESIDENT-NAME TABLE<br>======================================================================<br><br>The nonresident-name table follows the entry table, and contains a<br>module description and nonresident exported procedure name strings.<br>The first string in this table is a module description. These name<br>strings are case-sensitive and are not null-terminated. The name<br>strings follow the same format as those defined in the resident name<br>table.<br><br><br>======================================================================<br> PER SEGMENT DATA<br>======================================================================<br><br>The location and size of the per-segment data is defined in the<br>segment table entry for the segment. If the segment has relocation<br>fixups, as defined in the segment table entry flags, they directly<br>follow the segment data in the file. The relocation fixup information<br>is defined as follows:<br><br><br> Size Description<br> ---- -----------<br><br> DW Number of relocation records that follow.<br><br> A table of relocation records follows. The following is the format<br> of each relocation record.<br><br> DB Source type.<br> 0Fh = SOURCE_MASK<br> 00h = LOBYTE<br> 02h = SEGMENT<br> 03h = FAR_ADDR (32-bit pointer)<br> 05h = OFFSET (16-bit offset)<br><br> DB Flags byte.<br> 03h = TARGET_MASK<br> 00h = INTERNALREF<br> 01h = IMPORTORDINAL<br> 02h = IMPORTNAME<br> 03h = OSFIXUP<br> 04h = ADDITIVE<br><br> DW Offset within this segment of the source chain.<br> If the ADDITIVE flag is set, then target value is added to<br> the source contents, instead of replacing the source and<br> following the chain. The source chain is an 0FFFFh<br> terminated linked list within this segment of all<br> references to the target.<br><br> The target value has four types that are defined in the flag<br> byte field. The following are the formats for each target<br> type:<br><br> INTERNALREF<br><br> DB Segment number for a fixed segment, or 0FFh for a<br> movable segment.<br><br> DB 0<br><br> DW Offset into segment if fixed segment, or ordinal<br> number index into Entry Table if movable segment.<br><br> IMPORTNAME<br><br> DW Index into module reference table for the imported<br> module.<br><br> DW Offset within Imported Names Table to procedure name<br> string.<br><br> IMPORTORDINAL<br><br> DW Index into module reference table for the imported<br> module.<br> DW Procedure ordinal number.<br><br> OSFIXUP<br><br> DW Operating system fixup type.<br> Floating-point fixups.<br> 0001h = FIARQQ, FJARQQ<br> 0002h = FISRQQ, FJSRQQ<br> 0003h = FICRQQ, FJCRQQ<br> 0004h = FIERQQ<br> 0005h = FIDRQQ<br> 0006h = FIWRQQ<br><br> DW 0<br><br>======================================================================<br><br>Microsoft is a registered trademark and Windows is a trademark of<br>Microsoft Corporation.<br><br>Additional reference words: 3.0<br><br><br><br>2 PE format<br><br><br> PORTABLE EXECUTABLE FORMAT<br><br> Author: Micheal J. O'Leary<br><br><br> Preface<br> <br> This document was edited and released by Microsoft Developer<br> Support. It describes the binary portable executable format for NT.<br> The information is provided at this point because we feel it will<br> make the work of application development easier. Unfortunately, the<br> information in this document may change before the final release of<br> Windows NT. Microsoft is NOT committing to stay with these formats<br> by releasing this document. Questions or follow-ups for any of the<br> information presented here should be posted to CompuServe MSWIN32<br> forum, section 6.<br> --Steve Firebaugh<br> Microsoft Developer Support<br> <br> <br><br>Contents<br><br> 1. Overview<br><br> 2. PE Header<br><br> 3. Object Table<br><br> 4. Image Pages<br><br> 5. Exports<br> 5.1 Export Directory Table<br> 5.2 Export Address Table<br> 5.3 Export Name Table Pointers<br> 5.4 Export Ordinal Table<br> 5.5 Export Name Table<br><br> 6. Imports<br> 6.1 Import Directory Table<br> 6.2 Import Lookup Table<br> 6.3 Hint-Name Table<br> 6.4 Import Address Table<br><br> 7. Thread Local Storage<br> 7.1 Thread Local Storage Directory Table<br> 7.2 Thread Local Storage CallBack Table<br><br> 8. Resources<br> 8.1 Resource Directory Table<br> 8.2 Resource Example<br><br> 9. Fixup Table<br> 9.1 Fixup Block<br><br> 10. Debug Information<br> 10.1 Debug Directory<br><br><br><br>1. Overview<br><br> 谀哪哪哪哪哪哪哪哪目 <哪? <哪哪? Base of Image Header<br> ? DOS 2 Compatible ? ?<br> ? EXE Header ? ?<br> 媚哪哪哪哪哪哪哪哪拇 ?<br> ? unused ? ?<br> 媚哪哪哪哪哪哪哪哪拇 ?<br> ? OEM Identifier ? ?<br> ? OEM Info ? ?<br> ? ? ? DOS 2.0 Section<br> ? Offset to ? ? (for DOS compatibility only)<br> ? PE Header ? ?<br> 媚哪哪哪哪哪哪哪哪拇 ?<br> ? DOS 2.0 Stub ? ?<br> ? Program & ? ?<br> ? Reloc. Table ? ?<br> 媚哪哪哪哪哪哪哪哪拇 <哪?<br> ? unused ?<br> 媚哪哪哪哪哪哪哪哪拇 <哪哪哪哪? Aligned on 8 byte boundary<br> ? PE Header ?<br> 媚哪哪哪哪哪哪哪哪拇<br> ? Object Table ?<br> 媚哪哪哪哪哪哪哪哪拇<br> ? Image Pages ?<br> ? import info ?<br> ? export info ?<br> ? fixup info ?<br> ? resource info?<br> ? debug info ?<br> 滥哪哪哪哪哪哪哪哪馁<br> <br>Figure 1. A typical 32-bit Portable EXE File Layout<br><br><br><br>2. PE Header<br><br> <br> 谀哪哪哪哪哪哪哪哪哪哪哪哪哪履哪哪哪哪哪哪履哪哪哪哪哪哪?<br> ? SIGNATURE BYTES ? CPU TYPE ? # OBJECTS ?<br> 媚哪哪哪哪哪哪哪哪哪哪哪哪哪拍哪哪哪哪哪哪聊哪哪哪哪哪哪?<br> ? TIME/DATE STAMP ? RESERVED ?<br> 媚哪哪哪哪哪哪哪哪哪哪哪哪哪拍哪哪哪哪哪哪履哪哪哪哪哪哪?<br> ? RESERVED ? NT HDR SIZE? FLAGS ?<br> 媚哪哪哪哪哪哪履哪哪穆哪哪哪拍哪哪哪哪哪哪聊哪哪哪哪哪哪?<br> ? RESERVED 矻MAJOR矻MINOR? RESERVED ?<br> 媚哪哪哪哪哪哪聊哪哪牧哪哪哪拍哪哪哪哪哪哪哪哪哪哪哪哪哪?<br> ? RESERVED ? RESERVED ?<br> 媚哪哪哪哪哪哪哪哪哪哪哪哪哪拍哪哪哪哪哪哪哪哪哪哪哪哪哪?<br> ? ENTRYPOINT RVA ? RESERVED ?<br> 媚哪哪哪哪哪哪哪哪哪哪哪哪哪拍哪哪哪哪哪哪哪哪哪哪哪哪哪?<br> ? RESERVED ? IMAGE BASE ?<br> 媚哪哪哪哪哪哪哪哪哪哪哪哪哪拍哪哪哪哪哪哪哪哪哪哪哪哪哪?<br> ? OBJECT ALIGN ? FILE ALIGN ?<br> 媚哪哪哪哪哪哪履哪哪哪哪哪哪拍哪哪哪哪哪哪履哪哪哪哪哪哪?<br> ? OS MAJOR ? OS MINOR 砋SER MAJOR 砋SER MINOR ?<br> 媚哪哪哪哪哪哪拍哪哪哪哪哪哪拍哪哪哪哪哪哪聊哪哪哪哪哪哪?<br> ? SUBSYS MAJOR? SUBSYS MINOR? RESERVED ?<br> 媚哪哪哪哪哪哪聊哪哪哪哪哪哪拍哪哪哪哪哪哪哪哪哪哪哪哪哪?<br> ? IMAGE SIZE ? HEADER SIZE ?<br> 媚哪哪哪哪哪哪哪哪哪哪哪哪哪拍哪哪哪哪哪哪履哪哪哪哪哪哪?<br> ? FILE CHECKSUM ? SUBSYSTEM ? DLL FLAGS ?<br> 媚哪哪哪哪哪哪哪哪哪哪哪哪哪拍哪哪哪哪哪哪聊哪哪哪哪哪哪?<br> ? STACK RESERVE SIZE ? STACK COMMIT SIZE ?<br> 媚哪哪哪哪哪哪哪哪哪哪哪哪哪拍哪哪哪哪哪哪哪哪哪哪哪哪哪?<br> ? HEAP RESERVE SIZE ? HEAP COMMIT SIZE ?<br> 媚哪哪哪哪哪哪哪哪哪哪哪哪哪拍哪哪哪哪哪哪哪哪哪哪哪哪哪?<br> ? RESERVED ? # INTERESTING RVA/SIZES ?<br> 媚哪哪哪哪哪哪哪哪哪哪哪哪哪拍哪哪哪哪哪哪哪哪哪哪哪哪哪?<br> ? EXPORT TABLE RVA ? TOTAL EXPORT DATA SIZE ?<br> 媚哪哪哪哪哪哪哪哪哪哪哪哪哪拍哪哪哪哪哪哪哪哪哪哪哪哪哪?<br> ? IMPORT TABLE RVA ? TOTAL IMPORT DATA SIZE ?<br> 媚哪哪哪哪哪哪哪哪哪哪哪哪哪拍哪哪哪哪哪哪哪哪哪哪哪哪哪?<br> ? RESOURCE TABLE RVA ? TOTAL RESOURCE DATA SIZE ?<br> 媚哪哪哪哪哪哪哪哪哪哪哪哪哪拍哪哪哪哪哪哪哪哪哪哪哪哪哪?<br> ? EXCEPTION TABLE RVA ? TOTAL EXCEPTION DATA SIZE?<br> 媚哪哪哪哪哪哪哪哪哪哪哪哪哪拍哪哪哪哪哪哪哪哪哪哪哪哪哪?<br> ? SECURITY TABLE RVA ? TOTAL SECURITY DATA SIZE ?<br> 媚哪哪哪哪哪哪哪哪哪哪哪哪哪拍哪哪哪哪哪哪哪哪哪哪哪哪哪?<br> ? FIXUP TABLE RVA ? TOTAL FIXUP DATA SIZE ?<br> 媚哪哪哪哪哪哪哪哪哪哪哪哪哪拍哪哪哪哪哪哪哪哪哪哪哪哪哪?<br> ? DEBUG TABLE RVA ? TOTAL DEBUG DIRECTORIES ?<br> 媚哪哪哪哪哪哪哪哪哪哪哪哪哪拍哪哪哪哪哪哪哪哪哪哪哪哪哪?<br> ? IMAGE DESCRIPTION RVA ? TOTAL DESCRIPTION SIZE ?<br> 媚哪哪哪哪哪哪哪哪哪哪哪哪哪拍哪哪哪哪哪哪哪哪哪哪哪哪哪?<br> ? MACHINE SPECIFIC RVA ? MACHINE SPECIFIC SIZE ?<br> 媚哪哪哪哪哪哪哪哪哪哪哪哪哪拍哪哪哪哪哪哪哪哪哪哪哪哪哪?<br> ? THREAD LOCAL STORAGE RVA ? TOTAL TLS SIZE ?<br> 滥哪哪哪哪哪哪哪哪哪哪哪哪哪聊哪哪哪哪哪哪哪哪哪哪哪哪哪?<br> <br>Figure 2. PE Header<br><br>Notes:<br><br> o A VA is a virtual address that is already biased by the Image<br> Base found in the PE Header. A RVA is a virtual address that is<br> relative to the Image Base.<br> <br> o An RVA in the PE Header which has a value of zero indicates the<br> field isn't used.<br> <br> o Image pages are aligned and zero padded to a File Align<br> boundary. The bases of all other tables and structures must be<br> aligned on DWORD (4 byte) boundary. Thus, all VA's and RVA's<br> must be on a 32 bit boundary. All table and structure fields<br> must be aligned on their "natural" boundaries, with the possible<br> exception of the Debug Info.<br> <br>SIGNATURE BYTES = DB * 4.<br>Current value is "PE/0/0". Thats PE followed by two zeros (nulls).<br><br>CPU TYPE = DW CPU Type.<br>This field specifies the type of CPU compatibility required by this<br>image to run. The values are:<br><br> o 0000h __unknown<br> <br> o 014Ch __80386<br> <br> o 014Dh __80486<br> <br> o 014Eh __80586<br> <br> o 0162h __MIPS Mark I (R2000, R3000)<br> <br> o 0163h __MIPS Mark II (R6000)<br> <br> o 0166h __MIPS Mark III (R4000)<br> <br># OBJECTS = DW Number of object entries.<br>This field specifies the number of entries in the Object Table.<br><br>TIME/DATE STAMP = DD Used to store the time and date the file was<br>created or modified by the linker.<br><br>NT HDR SIZE = DW This is the number of remaining bytes in the NT<br>header that follow the FLAGS field.<br><br>FLAGS = DW Flag bits for the image.<br>The flag bits have the following definitons:<br><br> o 0000h __Program image.<br> <br> o 0002h __Image is executable.<br> If this bit isn't set, then it indicates that either errors<br> where detected at link time or that the image is being<br> incrementally linked and therefore can't be loaded.<br> <br> o 0200h __Fixed.<br> Indicates that if the image can't be loaded at the Image Base,<br> then don't load it.<br> <br> o 2000h __Library image.<br> <br>LMAJOR/LMINOR = DB Linker major/minor version number.<br><br>ENTRYPOINT RVA = DD Entrypoint relative virtual address.<br>The address is relative to the Image Base. The address is the<br>starting address for program images and the library initialization<br>and library termination address for library images.<br><br>IMAGE BASE = DD The virtual base of the image.<br>This will be the virtual address of the first byte of the file (Dos<br>Header). This must be a multiple of 64K.<br><br>OBJECT ALIGN = DD The alignment of the objects. This must be a power<br>of 2 between 512 and 256M inclusive. The default is 64K.<br><br>FILE ALIGN = DD Alignment factor used to align image pages. The<br>alignment factor (in bytes) used to align the base of the image pages<br>and to determine the granularity of per-object trailing zero pad.<br>Larger alignment factors will cost more file space; smaller alignment<br>factors will impact demand load performance, perhaps significantly.<br>Of the two, wasting file space is preferable. This value should be a<br>power of 2 between 512 and 64K inclusive.<br><br>OS MAJOR/MINOR = DW OS version number required to run this image.<br><br>USER MAJOR/MINOR # = DW User major/minor version number.<br>This is useful for differentiating between revisions of<br>images/dynamic linked libraries. The values are specified at link<br>time by the user.<br><br>SUBSYS MAJOR/MINOR # = DW Subsystem major/minor version number.<br><br>IMAGE SIZE = DD The virtual size (in bytes) of the image.<br>This includes all headers. The total image size must be a multiple<br>of Object Align.<br><br>HEADER SIZE = DD Total header size.<br>The combined size of the Dos Header, PE Header and Object Table.<br><br>FILE CHECKSUM = DD Checksum for entire file. Set to 0 by the linker.<br><br>SUBSYSTEM = DW NT Subsystem required to run this image.<br>The values are:<br><br> o 0000h __Unknown<br> <br> o 0001h __Native<br> <br> o 0002h __Windows GUI<br> <br> o 0003h __Windows Character<br> <br> o 0005h __OS/2 Character<br> <br> o 0007h __Posix Character<br> <br>DLL FLAGS = DW Indicates special loader requirements.<br>This flag has the following bit values:<br><br> o 0001h __Per-Process Library Initialization.<br> <br> o 0002h __Per-Process Library Termination.<br> <br> o 0004h __Per-Thread Library Initialization.<br> <br> o 0008h __Per-Thread Library Termination.<br> <br>All other bits are reserved for future use and should be set to zero.<br><br>STACK RESERVE SIZE = DD Stack size needed for image.<br>The memory is reserved, but only the STACK COMMIT SIZE is committed.<br>The next page of the stack is a 'guarded page'. When the application<br>hits the guarded page, the guarded page becomes valid, and the next<br>page becomes the guarded page. This continues until the RESERVE SIZE<br>is reached.<br><br>STACK COMMIT SIZE = DD Stack commit size.<br><br>HEAP RESERVE SIZE = DD Size of local heap to reserve.<br><br>HEAP COMMIT SIZE = DD Amount to commit in local heap.<br><br># INTERESTING VA/SIZES = DD Indicates the size of the VA/SIZE array<br>that follows.<br><br>EXPORT TABLE RVA = DD Relative Virtual Address of the Export Table.<br>This address is relative to the Image Base.<br><br>IMPORT TABLE RVA = DD Relative Virtual Address of the Import Table.<br>This address is relative to the Image Base.<br><br>RESOURCE TABLE RVA = DD Relative Virtual Address of the Resource<br>Table. This address is relative to the Image Base.<br><br>EXCEPTION TABLE RVA = DD Relative Virtual Address of the Exception<br>Table. This address is relative to the Image Base.<br><br>SECURITY TABLE RVA = DD Relative Virtual Address of the Security<br>Table. This address is relative to the Image Base.<br><br>FIXUP TABLE RVA = DD Relative Virtual Address of the Fixup Table.<br>This address is relative to the Image Base.<br><br>DEBUG TABLE RVA = DD Relative Virtual Address of the Debug Table.<br>This address is relative to the Image Base.<br><br>IMAGE DESCRIPTION RVA = DD Relative Virtual Address of the<br>description string specified in the module definiton file.<br><br>MACHINE SPECIFIC RVA = DD Relative Virtual Address of a machine<br>specific value. This address is relative to the Image Base.<br><br>TOTAL EXPORT DATA SIZE = DD Total size of the export data.<br><br>TOTAL IMPORT DATA SIZE = DD Total size of the import data.<br><br>TOTAL RESOURCE DATA SIZE = DD Total size of the resource data.<br><br>TOTAL EXCEPTION DATA SIZE = DD Total size of the exception data.<br><br>TOTAL SECURITY DATA SIZE = DD Total size of the security data.<br><br>TOTAL FIXUP DATA SIZE = DD Total size of the fixup data.<br><br>TOTAL DEBUG DIRECTORIES = DD Total number of debug directories.<br><br>TOTAL DESCRIPTION SIZE = DD Total size of the description data.<br><br>MACHINE SPECIFIC SIZE = DD A machine specific value.<br><br><br><br>3. Object Table<br><br>The number of entries in the Object Table is given by the # Objects<br>field in the PE Header. Entries in the Object Table are numbered<br>starting from one. The object table immediately follows the PE<br>Header. The code and data memory object entries are in the order<br>chosen by the linker. The virtual addresses for objects must be<br>assigned by the linker such that they are in ascending order and<br>adjacent, and must be a multiple of Object Align in the PE header.<br><br>Each Object Table entry has the following format:<br><br> 谀哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪?<br> ? OBJECT NAME ?<br> 媚哪哪哪哪哪哪哪哪哪哪哪哪哪履哪哪哪哪哪哪哪哪哪哪哪哪哪?<br> ? VIRTUAL SIZE ? RVA ?<br> 媚哪哪哪哪哪哪哪哪哪哪哪哪哪拍哪哪哪哪哪哪哪哪哪哪哪哪哪?<br> ? PHYSICAL SIZE ? PHYSICAL OFFSET ?<br> 媚哪哪哪哪哪哪哪哪哪哪哪哪哪拍哪哪哪哪哪哪哪哪哪哪哪哪哪?<br> ? RESERVED ? RESERVED ?<br> 媚哪哪哪哪哪哪哪哪哪哪哪哪哪拍哪哪哪哪哪哪哪哪哪哪哪哪哪?<br> ? RESERVED ? OBJECT FLAGS ?<br> 滥哪哪哪哪哪哪哪哪哪哪哪哪哪聊哪哪哪哪哪哪哪哪哪哪哪哪哪?<br> <br>Figure 3. Object Table<br><br>OBJECT NAME = DB * 8 Object name. This is an eight-byte null-padded<br>ASCII string representing the object name.<br><br>VIRTUAL SIZE = DD Virtual memory size. The size of the object that<br>will be allocated when the object is loaded. Any difference between<br>PHYSICAL SIZE and VIRTUAL SIZE is zero filled.<br><br>RVA = DD Relative Virtual Address. The virtual address the object is<br>currently relocated to, relative to the Image Base. Each Object's<br>virtual address space consumes a multiple of Object Align (power of 2<br>between 512 and 256M inclusive. Default is 64K), and immediately<br>follows the previous Object in the virtual address space (the virtual<br>address space for a image must be dense).<br><br>PHYSICAL SIZE = DD Physical file size of initialized data. The size<br>of the initialized data in the file for the object. The physical<br>size must be a multiple of the File Align field in the PE Header, and<br>must be less than or equal to the Virtual Size.<br><br>PHYSICAL OFFSET = DD Physical offset for object's first page. This<br>offset is relative to beginning of the EXE file, and is aligned on a<br>multiple of the File Align field in the PE Header. The offset is<br>used as a seek value.<br><br>OBJECT FLAGS = DD Flag bits for the object. The object flag bits<br>have the following definitions:<br><br> o 000000020h __Code object.<br> <br> o 000000040h __Initialized data object.<br> <br> o 000000080h __Uninitialized data object.<br> <br> o 040000000h __Object must not be cached.<br> <br> o 080000000h __Object is not pageable.<br> <br> o 100000000h __Object is shared.<br> <br> o 200000000h __Executable object.<br> <br> o 400000000h __Readable object.<br> <br> o 800000000h __Writeable object.<br> <br>All other bits are reserved for future use and should be set to zero.<br><br>4. Image Pages<br><br>The Image Pages section contains all initialized data for all<br>objects. The seek offset for the first page in each object is<br>specified in the object table and is aligned on a File Align<br>boundary. The objects are ordered by the RVA. Every object begins<br>on a multiple of Object Align.<br><br><br><br>5. Exports<br><br>A typical file layout for the export information follows:<br><br> 谀哪哪哪哪哪哪哪哪哪哪哪?<br> ? DIRECTORY TABLE ?<br> 媚哪哪哪哪哪哪哪哪哪哪哪?<br> ? ADDRESS TABLE ?<br> ? ?<br> ? ?<br> ? ?<br> ? ?<br> ? ?<br> ? ?<br> 媚哪哪哪哪哪哪哪哪哪哪哪?<br> ? NAME PTR TABLE ?<br> ? ?<br> ? ?<br> ? ?<br> 媚哪哪哪哪哪哪哪哪哪哪哪?<br> ? ORDINAL TABLE ?<br> ? ?<br> ? ?<br> ? ?<br> 媚哪哪哪哪哪哪哪哪哪哪哪?<br> ? NAME STRINGS ?<br> ? ?<br> ? ?<br> 滥哪哪哪哪哪哪哪哪哪哪哪?<br> <br>Figure 4. Export File Layout<br><br>5.1 Export Directory Table<br><br>The export information begins with the Export Directory Table which<br>describes the remainder of the export information. The Export<br>Directory Table contains address information that is used to resolve<br>fixup references to the entry points within this image.<br><br> 谀哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪?<br> ? EXPORT FLAGS ?<br> 媚哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪?<br> ? TIME/DATE STAMP ?<br> 媚哪哪哪哪哪哪哪哪履哪哪哪哪哪哪哪哪?<br> ? MAJOR VERSION ? MINOR VERSION ?<br> 媚哪哪哪哪哪哪哪哪聊哪哪哪哪哪哪哪哪?<br> ? NAME RVA ?<br> 媚哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪?<br> ? ORDINAL BASE ?<br> 媚哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪?<br> ? # EAT ENTRIES ?<br> 媚哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪?<br> ? # NAME PTRS ?<br> 媚哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪?<br> ? ADDRESS TABLE RVA ?<br> 媚哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪?<br> ? NAME PTR TABLE RVA ?<br> 媚哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪?<br> ? ORDINAL TABLE RVA ?<br> 滥哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪?<br> <br>Figure 5. Export Directory Table Entry<br><br>EXPORT FLAGS = DD Currently set to zero.<br><br>TIME/DATE STAMP = DD Time/Date the export data was created.<br><br>MAJOR/MINOR VERSION = DW A user settable major/minor version number.<br><br>NAME RVA = DD Relative Virtual Address of the Dll asciiz Name.<br>This is the address relative to the Image Base.<br><br>ORDINAL BASE = DD First valid exported ordinal.<br>This field specifies the starting ordinal number for the export<br>address table for this image. Normally set to 1.<br><br># EAT ENTRIES = DD Indicates number of entries in the Export Address<br>Table.<br><br># NAME PTRS = DD This indicates the number of entries in the Name Ptr<br>Table (and parallel Ordinal Table).<br><br>ADDRESS TABLE RVA = DD Relative Virtual Address of the Export Address<br>Table.<br>This address is relative to the Image Base.<br><br>NAME TABLE RVA = DD Relative Virtual Address of the Export Name Table<br>Pointers.<br>This address is relative to the beginning of the Image Base. This<br>table is an array of RVA's with # NAMES entries.<br><br>ORDINAL TABLE RVA = DD Relative Virtual Address of Export Ordinals<br>Table Entry.<br>This address is relative to the beginning of the Image Base.<br><br>5.2 Export Address Table<br><br>The Export Address Table contains the address of exported entrypoints<br>and exported data and absolutes. An ordinal number is used to index<br>the Export Address Table. The ORDINAL BASE must be subracted from the<br>ordinal number before indexing into this table.<br><br>Export Address Table entry formats are described below:<br><br> 谀哪哪哪穆哪哪哪哪履哪哪哪穆哪哪哪哪?<br> ? EXPORTED RVA ?<br> 滥哪哪哪牧哪哪哪哪聊哪哪哪牧哪哪哪哪?<br> <br>Figure 6. Export Address Table Entry<br><br>EXPORTED RVA = DD Export address.<br>This field contains the relative virtual address of the exported<br>entry (relative to the Image Base).<br><br>5.3 Export Name Table Pointers<br><br>The export name table pointers array contains address into the Export<br>Name Table. The pointers are 32-bits each, and are relative to the<br>Image Base. The pointers are ordered lexically to allow binary<br>searches.<br><br>5.4 Export Ordinal Table<br><br>The Export Name Table Pointers and the Export Ordinal Table form two<br>parallel arrays, separated to allow natural field alignment. The<br>export ordinal table array contains the Export Address Table ordinal<br>numbers associated with the named export referenced by corresponding<br>Export Name Table Pointers.<br><br>The ordinals are 16-bits each, and already include the Ordinal Base<br>stored in the Export Directory Table.<br><br>5.5 Export Name Table<br><br>The export name table contains optional ASCII names for exported<br>entries in the image. These tables are used with the array of Export<br>Name Table Pointers and the array of Export Ordinals to translate a<br>procedure name string into an ordinal number by searching for a<br>matching name string. The ordinal number is used to locate the entry<br>point information in the export address table.<br><br>Import references by name require the Export Name Table Pointers<br>table to be binary searched to find the matching name, then the<br>corresponding Export Ordinal Table is known to contain the entry<br>point ordinal number. Import references by ordinal number provide<br>the fastest lookup since searching the name table is not required.<br><br>Each name table entry has the following format:<br><br> 谀哪哪哪穆哪哪哪哪履哪哪哪穆哪哪哪哪?<br> ? ASCII STRING ::: :::::::: '/0' ?<br> 滥哪哪哪牧哪哪哪哪聊哪哪哪牧哪哪哪哪?<br> <br>Figure 7. Export Name Table Entry<br><br>ASCII STRING = DB ASCII String.<br>The string is case sensitive and is terminated by a null byte.<br><br><br><br>6. Imports<br><br>A typical file layout for the import information follows:<br><br> 谀哪哪哪哪哪哪哪哪哪哪哪?<br> ? DIRECTORY TABLE ?<br> ? ?<br> ? ?<br> ? ?<br> 媚哪哪哪哪哪哪哪哪哪哪哪?<br> ? NULL DIR ENTRY ?<br> 滥哪哪哪哪哪哪哪哪哪哪哪?<br> <br> 谀哪哪哪哪哪哪哪哪哪哪哪?<br> ? DLL1 LOOKUP TABLE ?<br> ? ?<br> 媚哪哪哪哪哪哪哪哪哪哪哪?<br> ? NULL ?<br> 滥哪哪哪哪哪哪哪哪哪哪哪?<br> <br> 谀哪哪哪哪哪哪哪哪哪哪哪?<br> ? DLL2 LOOKUP TABLE ?<br> ? ?<br> 媚哪哪哪哪哪哪哪哪哪哪哪?<br> ? NULL ?<br> 滥哪哪哪哪哪哪哪哪哪哪哪?<br> <br> 谀哪哪哪哪哪哪哪哪哪哪哪?<br> ? Dll3 LOOKUP TABLE ?<br> ? ?<br> 媚哪哪哪哪哪哪哪哪哪哪哪?<br> ? NULL ?<br> 滥哪哪哪哪哪哪哪哪哪哪哪?<br> <br> 谀哪哪哪哪哪哪哪哪哪哪哪?<br> ? HINT-NAME TABLE ?<br> ? ?<br> 滥哪哪哪哪哪哪哪哪哪哪哪?<br> <br> 谀哪哪哪哪哪哪哪哪哪哪哪?<br> ? DLL1 ADDRESS TABLE ?<br> ? ?<br> 媚哪哪哪哪哪哪哪哪哪哪哪?<br> ? NULL ?<br> 滥哪哪哪哪哪哪哪哪哪哪哪?<br> <br> 谀哪哪哪哪哪哪哪哪哪哪哪?<br> ? DLL2 ADDRESS TABLE ?<br> ? ?<br> 媚哪哪哪哪哪哪哪哪哪哪哪?<br> ? NULL ?<br> 滥哪哪哪哪哪哪哪哪哪哪哪?<br> <br> 谀哪哪哪哪哪哪哪哪哪哪哪?<br> ? DLL3 ADDRESS TABLE ?<br> ? ?<br> 媚哪哪哪哪哪哪哪哪哪哪哪?<br> ? NULL ?<br> 滥哪哪哪哪哪哪哪哪哪哪哪?<br> <br>Figure 8. Import File Layout<br><br>6.1 Import Directory Table<br><br>The import information begins with the Import Directory Table which<br>describes the remainder of the import information. The Import<br>Directory Table contains address information that is used to resolve<br>fixup references to the entry points within a DLL image. The import<br>directory table consists of an array of Import Directory Entries, one<br>entry for each DLL this image references. The last directory entry is<br>empty (NULL) which indicates the end of the directory table.<br><br>An Import Directory Entry has the following format:<br><br> 谀哪哪哪穆哪哪哪哪履哪哪哪穆哪哪哪哪?<br> ? IMPORT FLAGS ?<br> 媚哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪?<br> ? TIME/DATE STAMP ?<br> 媚哪哪哪哪哪哪哪哪履哪哪哪哪哪哪哪哪?<br> ? MAJOR VERSION ? MINOR VERSION ?<br> 媚哪哪哪哪哪哪哪哪聊哪哪哪哪哪哪哪哪?<br> ? NAME RVA ?<br> 媚哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪?<br> ? IMPORT LOOKUP TABLE RVA ?<br> 媚哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪?<br> ? IMPORT ADDRESS TABLE RVA ?<br> 滥哪哪哪牧哪哪哪哪聊哪哪哪牧哪哪哪哪?<br> <br>Figure 9. Import Directory Entry<br><br>IMPORT FLAGS = DD Currently set to zero.<br><br>TIME/DATE STAMP = DD Time/Date the import data was pre-snapped or<br>zero if not pre-snapped.<br><br>MAJOR/MINOR VERSION = DW The major/minor version number of the dll<br>being referenced.<br><br>NAME RVA = DD Relative Virtual Address of the Dll asciiz Name.<br>This is the address relative to the Image Base.<br><br>IMPORT LOOKUP TABLE RVA = DD This field contains the address of the<br>start of the import lookup table for this image. The address is<br>relative to the beginning of the Image Base.<br><br>IMPORT ADDRESS TABLE RVA = DD This field contains the address of the<br>start of the import addresses for this image. The address is<br>relative to the beginning of the Image Base.<br><br>6.2 Import Lookup Table<br><br>The Import Lookup Table is an array of ordinal or hint/name RVA's for<br>each DLL. The last entry is empty (NULL) which indicates the end of<br>the table.<br><br>The last element is empty.<br><br> 3 0<br> 1<br> 谀夷哪哪穆哪哪哪哪履哪哪哪穆哪哪哪哪?<br> ?0? ORDINAL#/HINT-NAME TABLE RVA ?<br> 滥心哪哪牧哪哪哪哪聊哪哪哪牧哪哪哪哪?<br> <br>Figure 10. Import Address Table Format<br><br>ORDINAL/HINT-NAME TABLE RVA = 31-bits (mask = 7fffffffh) Ordinal<br>Number or Name Table RVA.<br>If the import is by ordinal, this field contains a 31 bit ordinal<br>number. If the import is by name, this field contains a 31 bit<br>address relative to the Image Base to the Hint-Name Table.<br><br>O = 1-bit (mask = 80000000h) Import by ordinal flag.<br><br> o 00000000h __Import by name.<br> <br> o 80000000h __Import by ordinal.<br> <br>6.3 Hint-Name Table<br><br>The Hint-Name Table format follows:<br><br> 谀哪哪哪穆哪哪哪哪履哪哪哪穆哪哪哪哪?<br> ? HINT ? ASCII STRING |||?<br> 媚哪哪哪呐哪哪哪哪拍哪哪哪呐哪哪哪哪?<br> 硘||||||||||||||||? '/0' PAD ?<br> 滥哪哪哪牧哪哪哪哪聊哪哪哪牧哪哪哪哪?<br> <br> <br> The PAD field is optional.<br> <br>Figure 11. Import Hint-Name Table<br><br>HINT = DW Hint into Export Name Table Pointers.<br>The hint value is used to index the Export Name Table Pointers array,<br>allowing faster by-name imports. If the hint is incorrect, then a<br>binary search is performed on the Export Name Ptr Table.<br><br>ASCII STRING = DB ASCII String.<br>The string is case sensitive and is terminated by a null byte.<br><br>PAD = DB Zero pad byte.<br>A trailing zero pad byte appears after the trailing null byte if<br>necessary to align the next entry on an even boundary.<br><br>The loader overwrites the import address table when loading the image<br>with the 32-bit address of the import.<br><br><br><br>6.4 Import Address Table<br><br>The Import Address Table is an array of addresses of the imported<br>routines for each DLL. The last entry is empty (NULL) which indicates<br>the end of the table.<br><br>7. Thread Local Storage<br><br>Thread local storage is a special contiguous block of data. Each<br>thread will gets its own block upon creation of the thread.<br><br>The file layout for thread local storage follows:<br> 谀哪哪哪哪哪哪哪哪哪哪哪?<br> ? DIRECTORY TABLE ?<br> 滥哪哪哪哪哪哪哪哪哪哪哪?<br> 谀哪哪哪哪哪哪哪哪哪哪哪?<br> ? TLS DATA ?<br> 滥哪哪哪哪哪哪哪哪哪哪哪?<br> 谀哪哪哪哪哪哪哪哪哪哪哪?<br> ? INDEX VARIABLE ?<br> 滥哪哪哪哪哪哪哪哪哪哪哪?<br> 谀哪哪哪哪哪哪哪哪哪哪哪?<br> ? CALLBACK ADDRESSES ?<br> 滥哪哪哪哪哪哪哪哪哪哪哪?<br><br>Figure 12. Thread Local Storage Layout<br><br>7.1 Thread Local Storage Directory Table<br><br>The Thread Local Storage Directory Table contains address information<br>that is used to describe the rest of TLS.<br><br>The Thread Local Storage Directory Table has the following format:<br><br> 谀哪哪哪穆哪哪哪哪履哪哪哪穆哪哪哪哪?<br> ? START DATA BLOCK VA ?<br> 媚哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪?<br> ? END DATA BLOCK VA ?<br> 媚哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪?<br> ? INDEX VA ?<br> 媚哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪?<br> ? CALLBACK TABLE VA ?<br> 滥哪哪哪牧哪哪哪哪聊哪哪哪牧哪哪哪哪?<br> <br>Figure 13. Thread Local Storage Directory Table<br><br>START DATA BLOCK VA = DD Virtual Address of the start of the thread<br>local storage data block.<br><br>END DATA BLOCK VA = DD Virtual Address of the end of the thread local<br>storage data block.<br><br>INDEX VA = DD Virtual Address of the index variable used to access<br>the thread local storage data block.<br><br>CALLBACK TABLE VA = DD Virtual Address of the callback table.<br><br>7.2 Thread Local Storage CallBack Table<br><br>The Thread Local Storage Callbacks is an array of Virtual Address of<br>functions to be called by the loader after thread creation and thread<br>termination. The last entry is empty (NULL) which indicates the end<br>of the table.<br><br>The Thread Local Storage CallBack Table has the following format:<br><br> 谀哪哪哪穆哪哪哪哪履哪哪哪穆哪哪哪哪?<br> ? FUNCTION1 VA ?<br> 媚哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪?<br> ? FUNCTION2 VA ?<br> 媚哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪?<br> ? ?<br> 媚哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪?<br> ? NULL ?<br> 滥哪哪哪牧哪哪哪哪聊哪哪哪牧哪哪哪哪?<br> <br>Figure 14. Thread Local Storage CallBack Table<br><br>8. Resources<br><br>Resources are indexed by a multiple level binary-sorted tree<br>structure. The overall design can incorporate 2**31 levels, however,<br>NT uses only three: the highest is TYPE, then NAME, then LANGUAGE.<br><br>A typical file layout for the resource information follows:<br> 谀哪哪哪哪哪哪哪哪哪哪哪?<br> ? RESOURCE DIRECTORY ?<br> ? ?<br> ? ?<br> ? ?<br> 媚哪哪哪哪哪哪哪哪哪哪哪?<br> ? RESOURCE DATA ?<br> ? ?<br> ? ?<br> ? ?<br> ? ?<br> ? ?<br> ? ?<br> 滥哪哪哪哪哪哪哪哪哪哪哪?<br> <br>Figure 15. Resource File Layout<br><br><br>The Resource directory is made up of the following tables:<br><br><br><br>8.1 Resource Directory Table<br>谀哪哪哪穆哪哪哪哪履哪哪哪穆哪哪哪哪?<br>? RESOURCE FLAGS ?<br>媚哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪?<br>? TIME/DATE STAMP ?<br>媚哪哪哪哪哪哪哪哪履哪哪哪哪哪哪哪哪?<br>? MAJOR VERSION ? MINOR VERSION ?<br>媚哪哪哪哪哪哪哪哪拍哪哪哪哪哪哪哪哪?<br>? # NAME ENTRY ? # ID ENTRY ?<br>媚哪哪哪哪哪哪哪哪聊哪哪哪哪哪哪哪哪?<br>? RESOURCE DIR ENTRIES ?<br>滥哪哪哪牧哪哪哪哪聊哪哪哪牧哪哪哪哪?<br><br>Figure 16. Resource Table Entry<br><br><br>RESOURCE FLAGS = DD Currently set to zero.<br><br>TIME/DATE STAMP = DD Time/Date the resource data was created by the<br>resource compiler.<br><br>MAJOR/MINOR VERSION = DW A user settable major/minor version number.<br><br># NAME ENTRY = DW The number of name entries.<br>This field contains the number of entries at the beginning of the<br>array of directory entries which have actual string names associated<br>with them.<br><br># ID ENTRY = DW The number of ID integer entries.<br>This field contains the number of 32-bit integer IDs as their names<br>in the array of directory entries.<br><br>The resource directory is followed by a variable length array of<br>directory entries. # NAME ENTRY is the number of entries at the<br>beginning of the array that have actual names associated with each<br>entry. The entires are in ascending order, case insensitive strings.<br># ID ENTRY identifies the number of entries that have 32-bit integer<br>IDs as their name. These entries are also sorted in ascending order.<br><br>This structure allows fast lookup by either name or number, but for<br>any given resource entry only one form of lookup is supported, not<br>both. This is consistent with the syntax of the .RC file and the .RES<br>file.<br><br><br><br>The array of directory entries have the following format:<br> 3 0<br> 1<br>谀哪哪哪穆哪哪哪哪履哪哪哪穆哪哪哪哪?<br>? NAME RVA/INTEGER ID ?<br>媚夷哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪?<br>矱? DATA ENTRY RVA/SUBDIR RVA ?<br>滥心哪哪牧哪哪哪哪聊哪哪哪牧哪哪哪哪?<br><br>Figure 17. Resource Directory Entry<br><br><br>INTERGER ID = DD ID.<br>This field contains a integer ID field to identify a resource.<br><br>NAME RVA = DD Name RVA address.<br>This field contains a 31-bit address relative to the beginning of the<br>Image Base to a Resource Directory String Entry.<br><br>E = 1-bit (mask 80000000h) Unescape bit.<br>This bit is zero for unescaped Resource Data Entries.<br><br>DATA RVA = 31-bits (mask 7fffffffh) Data entry address.<br>This field contains a 31-bit address relative to the beginning of the<br>Image Base to a Resource Data Entry.<br><br>E = 1-bit (mask 80000000h) Escape bit.<br>This bit is 1 for escaped Subdirectory Entry.<br><br>DATA RVA = 31-bits (mask 7fffffffh) Directory entries.<br>This field contains a 31-bit address relative to the beginning of the<br>Image Base to Subdirectory Entry.<br><br><br><br>Each resource directory string entry has the following format:<br>谀哪哪哪穆哪哪哪哪履哪哪哪穆哪哪哪哪?<br>? LENGTH ? UNICODE STRING ?<br>媚哪哪哪呐哪哪哪哪拍哪哪哪呐哪哪哪哪?<br>? ?<br>滥哪哪哪牧哪哪哪哪聊哪哪哪牧哪哪哪哪?<br><br>Figure 18. Resource Directory String Entry<br><br><br>LENGTH = DW Length of string.<br><br>UNICODE STRING = DW UNICODE String.<br><br>All of these string objects are stored together after the last<br>resource directory entry and before the first resource data object.<br>This minimizes the impact of these variable length objects on the<br>alignment of the fixed size directory entry objects. The length needs<br>to be word aligned.<br><br><br><br>Each Resource Data Entry has the following format:<br><br> 谀哪哪哪穆哪哪哪哪履哪哪哪穆哪哪哪哪?<br> ? DATA RVA ?<br> 媚哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪?<br> ? SIZE ?<br> 媚哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪?<br> ? CODEPAGE ?<br> 媚哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪?<br> ? RESERVED ?<br> 滥哪哪哪牧哪哪哪哪聊哪哪哪牧哪哪哪哪?<br> <br>Figure 19. Resource Data Entry<br><br><br><br>DATA RVA = DD Address of Resource Data.<br>This field contains 32-bit virtaul address of the resource data<br>(relative to the Image Base).<br><br>SIZE = DD Size of Resource Data.<br>This field contains the size of the resource data for this resource.<br><br>CODEPAGE = DD Codepage.<br><br>RESERVED = DD Reserved - must be zero.<br><br>Each resource data entry describes a leaf node in the resource<br>directory tree. It contains an address which is relative to the<br>beginning of Image Base, a size field that gives the number of bytes<br>of data at that address, a CodePage that should be used when decoding<br>code point values within the resource data. Typically for new<br>applications the code page would be the unicode code page.<br><br><br><br>8.2 Resource Example<br><br>The following is an example for an app. which wants to use the following data<br>as resources:<br><br> TypeId# NameId# Language ID Resource Data<br> 00000001 00000001 0 00010001<br> 00000001 00000001 1 10010001<br> 00000001 00000002 0 00010002<br> 00000001 00000003 0 00010003<br> 00000002 00000001 0 00020001<br> 00000002 00000002 0 00020002<br> 00000002 00000003 0 00020003<br> 00000002 00000004 0 00020004<br> 00000009 00000001 0 00090001<br> 00000009 00000009 0 00090009<br> 00000009 00000009 1 10090009<br> 00000009 00000009 2 20090009<br><br>Then the Resource Directory in the Portable format looks like:<br>Offset Data<br>0000: 00000000 00000000 00000000 00030000 (3 entries in this directory)<br>0010: 00000001 80000028 (TypeId #1, Subdirectory at offset 0x28)<br>0018: 00000002 80000050 (TypeId #2, Subdirectory at offset 0x50)<br>0020: 00000009 80000080 (TypeId #9, Subdirectory at offset 0x80)<br>0028: 00000000 00000000 00000000 00030000 (3 entries in this directory)<br>0038: 00000001 800000A0 (NameId #1, Subdirectory at offset 0xA0)<br>0040: 00000002 00000108 (NameId #2, data desc at offset 0x108)<br>0048: 00000003 00000118 (NameId #3, data desc at offset 0x118)<br>0050: 00000000 00000000 00000000 00040000 (4 entries in this directory)<br>0060: 00000001 00000128 (NameId #1, data desc at offset 0x128)<br>0068: 00000002 00000138 (NameId #2, data desc at offset 0x138)<br>0070: 00000003 00000148 (NameId #3, data desc at offset 0x148)<br>0078: 00000004 00000158 (NameId #4, data desc at offset 0x158)<br>0080: 00000000 00000000 00000000 00020000 (2 entries in this directory)<br>0090: 00000001 00000168 (NameId #1, data desc at offset 0x168)<br>0098: 00000009 800000C0 (NameId #9, Subdirectory at offset 0xC0)<br>00A0: 00000000 00000000 00000000 00020000 (2 entries in this directory)<br>00B0: 00000000 000000E8 (Language ID 0, data desc at offset 0xE8<br>00B8: 00000001 000000F8 (Language ID 1, data desc at offset 0xF8<br>00C0: 00000000 00000000 00000000 00030000 (3 entries in this directory)<br>00D0: 00000001 00000178 (Language ID 0, data desc at offset 0x178<br>00D8: 00000001 00000188 (Language ID 1, data desc at offset 0x188<br>00E0: 00000001 00000198 (Language ID 2, data desc at offset 0x198<br><br>00E8: 000001A8 (At offset 0x1A8, for TypeId #1, NameId #1, Language id #0<br> 00000004 (4 bytes of data)<br> 00000000 (codepage)<br> 00000000 (reserved)<br>00F8: 000001AC (At offset 0x1AC, for TypeId #1, NameId #1, Language id #1<br> 00000004 (4 bytes of data)<br> 00000000 (codepage)<br> 00000000 (reserved)<br>0108: 000001B0 (At offset 0x1B0, for TypeId #1, NameId #2,<br> 00000004 (4 bytes of data)<br> 00000000 (codepage)<br> 00000000 (reserved)<br>0118: 000001B4 (At offset 0x1B4, for TypeId #1, NameId #3,<br> 00000004 (4 bytes of data)<br> 00000000 (codepage)<br> 00000000 (reserved)<br>0128: 000001B8 (At offset 0x1B8, for TypeId #2, NameId #1,<br> 00000004 (4 bytes of data)<br> 00000000 (codepage)<br> 00000000 (reserved)<br>0138: 000001BC (At offset 0x1BC, for TypeId #2, NameId #2,<br> 00000004 (4 bytes of data)<br> 00000000 (codepage)<br> 00000000 (reserved)<br>0148: 000001C0 (At offset 0x1C0, for TypeId #2, NameId #3,<br> 00000004 (4 bytes of data)<br> 00000000 (codepage)<br> 00000000 (reserved)<br>0158: 000001C4 (At offset 0x1C4, for TypeId #2, NameId #4,<br> 00000004 (4 bytes of data)<br> 00000000 (codepage)<br> 00000000 (reserved)<br>0168: 000001C8 (At offset 0x1C8, for TypeId #9, NameId #1,<br> 00000004 (4 bytes of data)<br> 00000000 (codepage)<br> 00000000 (reserved)<br>0178: 000001CC (At offset 0x1CC, for TypeId #9, NameId #9, Language id #0<br> 00000004 (4 bytes of data)<br> 00000000 (codepage)<br> 00000000 (reserved)<br>0188: 000001D0 (At offset 0x1D0, for TypeId #9, NameId #9, Language id #1<br> 00000004 (4 bytes of data)<br> 00000000 (codepage)<br> 00000000 (reserved)<br>0198: 000001D4 (At offset 0x1D4, for TypeId #9, NameId #9, Language id #2<br> 00000004 (4 bytes of data)<br> 00000000 (codepage)<br> 00000000 (reserved)<br><br>And the data for the resources will look like:<br>01A8: 00010001<br>01AC: 10010001<br>01B0: 00010002<br>01B4: 00010003<br>01B8: 00020001<br>01BC: 00020002<br>01C0: 00020003<br>01C4: 00020004<br>01C8: 00090001<br>01CC: 00090009<br>01D0: 10090009<br>01D4: 20090009<br><br><br>9. Fixup Table<br><br>The Fixup Table contains entries for all fixups in the image. The<br>Total Fixup Data Size in the PE Header is the number of bytes in the<br>fixup table. The fixup table is broken into blocks of fixups. Each<br>block represents the fixups for a 4K page.<br><br>Fixups that are resolved by the linker do not need to be processed by<br>the loader, unless the load image can't be loaded at the Image Base<br>specified in the PE Header.<br><br>9.1 Fixup Block<br><br>Fixup blocks have the following format:<br><br> 谀哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪?<br> ? PAGE RVA ?<br> 媚哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪?<br> ? BLOCK SIZE ?<br> 媚哪哪哪哪哪哪哪哪履哪哪哪哪哪哪哪哪?<br> ? TYPE/OFFSET ? TYPE/OFFSET ?<br> 媚哪哪哪哪哪哪哪哪拍哪哪哪哪哪哪哪哪?<br> ? TYPE/OFFSET ? ... ?<br> 滥哪哪哪哪哪哪哪哪聊哪哪哪哪哪哪哪哪?<br> <br>Figure 20. Fixup Block Format<br><br>To apply a fixup, a delta needs to be calculated. The 32-bit delta<br>is the difference between the preferred base, and the base where the<br>image is actually loaded. If the image is loaded at its preferred<br>base, the delta would be zero, and thus the fixups would not have to<br>be applied. Each block must start on a DWORD boundary. The ABSOLUTE<br>fixup type can be used to pad a block.<br><br>PAGE RVA = DD Page RVA. The image base plus the page rva is added to<br>each offset to create the virtual address of where the fixup needs to<br>be applied.<br><br>BLOCK SIZE = DD Number of bytes in the fixup block. This includes the<br>PAGE RVA and SIZE fields.<br><br>TYPE/OFFSET is defined as:<br><br> 1 1 0<br> 5 1<br> 谀哪囊哪哪哪哪哪哪?<br> 砊YPE? OFFSET ?<br> 滥哪男哪哪哪哪哪哪?<br>Figure 21. Fixup Record Format<br><br>TYPE = 4-bit fixup type. This value has the following definitions:<br><br> o 0h __ABSOLUTE. This is a NOP. The fixup is skipped.<br> <br> o 1h __HIGH. Add the high 16-bits of the delta to the 16-bit field<br> at Offset. The 16-bit field represents the high value of a 32-<br> bit word.<br> <br> o 2h __LOW. Add the low 16-bits of the delta to the 16-bit field<br> at Offset. The 16-bit field represents the low half value of a<br> 32-bit word. This fixup will only be emitted for a RISC machine<br> when the image Object Align isn't the default of 64K.<br> <br> o 3h __HIGHLOW. Apply the 32-bit delta to the 32-bit field at<br> Offset.<br> <br> o 4h __HIGHADJUST. This fixup requires a full 32-bit value. The<br> high 16-bits is located at Offset, and the low 16-bits is<br> located in the next Offset array element (this array element is<br> included in the SIZE field). The two need to be combined into a<br> signed variable. Add the 32-bit delta. Then add 0x8000 and<br> store the high 16-bits of the signed variable to the 16-bit<br> field at Offset.<br> <br> o 5h __MIPSJMPADDR.<br> <br>All other values are reserved.<br><br><br><br>10. Debug Information<br><br>The debug information is defined by the debugger and is not<br>controlled by the portable EXE format or linker. The only data<br>defined by the portable EXE format is the Debug Directory Table.<br><br>10.1 Debug Directory<br><br>The debug directory table consists of one or more entries that have<br>the following format:<br><br> 谀哪哪哪穆哪哪哪哪履哪哪哪穆哪哪哪哪?<br> ? DEBUG FLAGS ?<br> 媚哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪?<br> ? TIME/DATE STAMP ?<br> 媚哪哪哪哪哪哪哪哪履哪哪哪哪哪哪哪哪?<br> ? MAJOR VERSION ? MINOR VERSION ?<br> 媚哪哪哪哪哪哪哪哪聊哪哪哪哪哪哪哪哪?<br> ? DEBUG TYPE ?<br> 媚哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪?<br> ? DATA SIZE ?<br> 媚哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪?<br> ? DATA RVA ?<br> 媚哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪?<br> ? DATA SEEK ?<br> 滥哪哪哪牧哪哪哪哪聊哪哪哪牧哪哪哪哪?<br> <br>Figure 22. Debug Directory Entry<br><br>DEBUG FLAGS = DD Set to zero for now.<br><br>TIME/DATE STAMP = DD Time/Date the debug data was created.<br><br>MAJOR/MINOR VERSION = DW Version stamp.<br>This stamp can be used to determine the version of the debug data.<br><br>DEBUG TYPE = DD Format type.<br>To support multiple debuggers, this field determines the format of<br>the debug information. This value has the following definitions:<br><br> o 0001h __Image contains COFF symbolics.<br> <br> o 0001h __Image contains CodeView symbolics.<br> <br> o 0001h __Image contains FPO symbolics.<br> <br>DATA SIZE = DD The number of bytes in the debug data. This is the<br>size of the actual debug data and does not include the debug<br>directory.<br><br>DATA RVA = DD The relative virtual address of the debug data. This<br>address is relative to the beginning of the Image Base.<br><br>DATA SEEK = DD The seek value from the beginning of the file to the<br>debug data.<br><br>If the image contains more than one type of debug information, then<br>the next debug directory will immediately follow the first debug<br>directory.<br><br>