Zeroquence
The PE format is the format of Windows executable. EXE files in Windows, DLL files are PE formats. PE is the abbreviation of Portable Executable. Portable means that the format of the PE file is the same for different Windows versions and different CPU types, of course, the CPU is different, and the binary coding of the CPU instruction is different. It is just the same layout in the file.
Figure 1.1
Figure 1.1 is a screenshot of the Explorer.exe in Win2k in JIURL PEDUMP. JIURL PEDUMP is a gadget I wrote. From the DOS Header starting from the file to the section table, after opening the PE file, click the appropriate structure, it will highlight the corresponding part of the file. But there is no sections. Help understand the PE format, you can work well with later introductions. You can go to my homepage http://jium.yeah.net.
A PE file format overview
The overall hierarchical distribution of the PE file structure is shown below
-------------- | DOS MZ Header || -------------- || DOS Stub || ---------- ---- || PE header || -------------- || section Table || -------------- || Section 1 || -------------- || Section 2 || -------------- || section ... || -------- ------ || Section N | --------------
1.1 DOS HEADER
The PE file is the most starting to be a simple DOS MZ HEADER, which is an Image_DOS_HEADER structure. With it, once the program is executed under DOS, DOS can identify this is a valid executive, and then run the DOS STUB following MZ Header.
1.2 dos stub
DOS Stub is a valid DOS program. When the program is shipped in DOS, the prompts like "this program cannot bern dos mode" are output. In Figure 1.1, you can see the string "this program cannot bernot bern dos mode". This is the default STUB program generated by the compiler. You can also specify any valid MS-DOS executables to replace it by linking options / stub: filename.
1.3 pehader
The DOS Stub is PE Header. It is an Image_NT_Headers structure. It contains important domains that require many PE files that are loaded into memory. When executed in the operating system that supports the PE file structure, the PE loader will find the start offset from the DOS MZ HEADER. Therefore, DOS Stub directly locates directly to the real file header PE Header.
1.4 Section Table
PE Header Next Array Structure Section Table. If there are 5 sections in the PE file, there are 5 members in this section Table structure, each member contains the properties of the corresponding section, file offset, virtual offset, and the like. The section table in Figure 1 has four members.
1.5 Sections
The true content of the PE file is divided into a block, called Sections (section). Sections is arranged in their starting order instead of being arranged in its alphabetical order. With information provided by the section table, we can find these sections. There are 4 festivals in Explorer.exe shown in Figure 1.1. The program's code, resources, etc. are placed in these sections.
Structure and its role in the two PE file format
For details, please refer to the following articles, using tools JIURL PEDUMP helps quickly understand. If you don't want to be there, you don't look at it. This article focuses on the last three, this article is just to have an account, and introduce some related content. Note that in Winnt.h, there is a definition of all PE-related structures. The structural definitions we use are from there. Microsoft Portable Executable and Common Object File Format SpecificationMSDN
"Windows95 system program design big mystery Chapter 8 PE and Coff obj file format Matt Pietrek" PE tutorial for Hou Jie iCzelion
PE learning notes (1) Rivershanpe study notes (2) Rivershan
Inside Windows An In-Depth Look Into The Win32 Portable Executable File Format Matt Pietrek has been translated.
INSIDE Windows An In-Depth Look Into The Win32 Portable Executable File Format Matt Pietrek
Three questions to pay attention to
3.1 A large number of blank
The value of member fileAlignment in the OptionalHeader structure in the PE Header structure is the alignment of the file in the file, the unit is byte, which should be 2 N times, range from 512 to 64K. If the value here is 512, the length of the section in the PE file is an integer multiple of 512 bytes, and the content is not enough to populate 0. For example, a PE file FileAlignment is 200h (decimal 512), its first section is at 400h, the length is 100h, then from the file 400h to 500h, the content of this section, and the file pair is 200h, so in order to Make this length of the length of FileAlignment, 500h to 600h will be filled with zero. The start address of the next section is 600h. Open the PE file with the 16-en-editor, you can see this situation, the content of the PE file header is between the first section, and the content in each section is ended to the next section. A lot of gaps. When the VC6 compiles the link, the default fileAlignment is 1000 hours (4K), you can use the link option / align: Number to change this value. For example, when 4K is changed to 512, the size of the generated file can be significantly reduced.
3.2 Big-endian and Little-Endian
The value in the members of the FileHeader in PE Header, according to the definition in Winnt.h, the Intel CPU should be 0x014c. But you open the PE file with the 16-binding editor, and see that this Word is displayed 4C 01. It's not wrong, you've seen 4C 01 0x014c, but because Intel CPU is iTTLE-Endian, it is displayed. For Big-Endian and Little-Endian, please see the example below.
For example, a plastic INT variable. Long is four bytes. The address of this variable is, for example, N. Then, the four bytes of information of this variable are N, N 1, N 2, N 3, respectively. When the value of this plastic variable is 0x12345678, the value of the value of the value of the 0x12 address n 1 in the one of the 0x12 address n 2 in the one of the 0x12 address n 2 in the byte of the address N 0 in the byte of the address N 0. The value of the value of 0x56 address n 3 is 0x78 in the byte of the 0x78 will be displayed as N n 1 n 2 n 3 12 34 56 78 for iTTLE-Endian's address N 0 The value of the value of 0x78 address n 1 in the byte is 0x56 address n 2 in the byte of the 0x34 address n 3 in the byte of the value of 0x12 is as follows It will be displayed as N n 1 n 2 n 3 78 56 34 12INTEL use iTTLE-ENDIAN. A plastic INT variable I, the address is & i, then the four bytes of this i are & I, & I 1, & I 2, & I 3. You can see this with such a program. #include
3.3 RVA (Relative Virtual Address) relative virtual address
RVA is a simple memory offset relative to the PE load point. For example, the PE load point is 0x400000, then address 0x401000 in the code section is (target address) 0x401000 - (Load address) 0x400000 = (RVA) 0x1000. In other words, RVA is 0x1000, the load point is 0x400000, then The actual address of the RVA in memory is 0x401000. Note that the RVA refers to memory, not in the file. Refers to the offset of the load point rather than a memory address, only the address of the RVA plus the load point is an actual memory address. 3.4 Three different addresses
In various structures of PE, many addresses are involved. Some refers to the offset in the file, and some refers to the offset in the memory. Be sure to figure out, this address or offset means that in the file or refers to in memory. The address in the first one, the file. For example, use the 16-en-editor to open the PE file, see the address (offset) is the address in the file, we can find the structure in the file using a file address of a structure. The second, when the file is mapped throughout the memory, for example, some PE analysis software, map the entire PE file to the memory, then the address in the memory, if you know the address in the file, then this The PE file is mapped to the address in the memory after memory, and the address of the memory can be obtained by adding an address in the file to add an address in the structure. In the third, when performing PE, the PE file will be loaded by the loader, and the RVA is often required. For example, knowing a structure of RVA, then load points can get the actual address of the structure in memory. For example, a program, we open it with a 16-binding editor, see the PE Header to display a place to 000000c8 at the 16-binding editor. So we found an OptionalHeader imageBase in the 16-binary editor, the value of 400000H, the value is not used when this program is executed, if the memory is not used in the memory, the program will be loaded there. When I use CreateFilemapping to map this PE file to the memory, the address of the block memory can be obtained from 5505024. For this PE file mapped into memory, we can find this PE's optionalHeader imageBase at 000000fch 05505024H = 5505120 in memory.
3.5 Description of several important structures
The NumberOfsections of PE Header's FileHeader: This is a very important field that is used to determine the number of files in the file.
OptionalHeader of the PE Header IMAGE_DATA_DIRECTORY DataDirectory [IMAGE_NUMBEROF_DIRECTORY_ENTRIES]; # define IMAGE_NUMBEROF_DIRECTORY_ENTRIES 16DataDirectory [IMAGE_NUMBEROF_DIRECTORY_ENTRIES]: an array of IMAGE_DATA_DIRECTORY. So far the length of the array is fixed, there are 16 elements, 16 elements which represent #define IMAGE_DIRECTORY_ENTRY_EXPORT 0 // Export Directory # define IMAGE_DIRECTORY_ENTRY_IMPORT 1 // Import Directory # define IMAGE_DIRECTORY_ENTRY_RESOURCE 2 // Resource Directory # define IMAGE_DIRECTORY_ENTRY_EXCEPTION 3 // Exception Directory # define IMAGE_DIRECTORY_ENTRY_SECURITY 4 // Security Directory # define IMAGE_DIRECTORY_ENTRY_BASERELOC 5 // Base Relocation Table # define IMAGE_DIRECTORY_ENTRY_DEBUG 6 // Debug Directory // IMAGE_DIRECTORY_ENTRY_COPYRIGHT 7 // (X86 usage) #define IMAGE_DIRECTORY_ENTRY_ARCHITECTURE 7 // Architecture Specific Data # define IMAGE_DIRECTORY_ENTRY_GLOBALPTR 8 // RVA of GP # define IMAGE_DIRECTORY_ENTRY_TLS 9 // TLS Directory # define IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG 10 // Load Configuration Directory # define IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT 11 // Bound Import Directory in headers # define IMAGE_DIRECTORY_ENTRY_IAT 12 // Import Address Table # define IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT 13 // Delay Load Import Descriptor # Define Image _Directory_entry_com_descriptor 14 // COM runtime Descriptor Each element is an image_data_directory structure, image_data_directory is defined below. Typedef struct _image_data_directory; dword size;} image_data_directory, * pimage_data_directory; The first field is a RVA, the second field is a size.
The section Table section is followed by OptionalHead, is an array of image_section_header structures. The number of members in the array is determined by the domain value of the NumberOfSections domain in the file header (image_file_header). The member in the section is an image_section_header structure, and the length of the image_section_header structure is fixed, 40 bytes long. The length of the entire section Table is not fixed, equal to Numberofsections * sizeof (Image_section_Header). Image_section_header structure, VirtualAddress: RVA in this section (relative virtual address). PointertorawData: This is the offset based on the file in this section. 3.6 MZ in DOS MZ HEADER
MZ is an abbreviation of the name of the MZ format of Mark Zbikowski.
Finish