MS-DOS head / real mode head
As mentioned above, the first component of the PE file format is the MS-DOS header. In the PE file format, it is not a new concept because it has exactly the same MS-DOS header with MS-DOS 2.0. The main reason for retaining this same structure is that when you try to load a file below Windows 3.1 or more under MS-DOS 2.0 or more, the operating system can read this file and understand that it is incompatible with the current system. . In other words, when you run a Windows NT executable file in MS-DOS 6.0, you will get a message: "This Program Cannot Be Run in dos mode." If the MS-DOS head is not as a PE file format The first part, the operating system will fail when loading the file, and provides some information that is completely useless, for example: "The name specified is not recognized as an internal or cost, Operable Program OR Batch File." MS-DOS The head occupies the head 64 bytes of the PE file, describing the structure of its contents as follows: Winnt.htypedEf struct _image_dos_header {// DOS .exe header ushort e_magic; // Magic Digital Ushort E_CBLP; // File Last page Bytes Ushort E_CP; // File page number ushort e_crlc; // Reconfers the number of elements USHORT E_CPARHDR; / / head size, with paragraphs Ushort E_MINALT E_MAXALLOC; // The maximum additional section ushort e_ss; // initial SS value (relative offset) Ushort E_SP; // The initial SP value ushort e_csum; // verify Ushort E_IP; // Initial IP value USHORT E_CS; // Initial CS value (relative offset) ushort e_lfarlc; // Relocate table file address ushort e_ovno; // Override number ushort e_res [4]; // Reserved Word Ushort E_OEMID; // OEM identifier (relative E_OEminfo USHORT E_OEMINFO; // OEM information ushort e_res2 [10]; // Reserved word long e_lfanew; // New EXE header file address} image_dos_header, * pimage_dos_header; first domain E_MAGIC, is called a magic number, it is Used to represent an MS-DOS compatible file type. All MS-DOS-compatible executables are set to 0x5A4D, indicating ASCII characters MZ. Sometimes the MS-DOS head is called MZ head, which is this. There are also many other domains for the MS-DOS operating system, but for Windows NT, there is only one useful domain in this structure - the last domain E_LFNEW, a 4-byte file offset, PE The file head is positioned by it. For Windows NT's PE files, the PE file header is followed by the MS-DOS header and the real mode program residual.
Real mode residual procedure
Real mode residual procedures are actual programs that can be run by MS-DOS during loading. For an executable image file for an MS-DOS, the application is executed here. For Windows, OS / 2, Windows NT These operating systems, the MS-DOS residence replaces the position of the main program. This residual program is usually nothing, but only outputs a line of text, for example: "This Program Requires Microsoft Windows V3.1 or Greater." Of course, the user can put any residue here, which means you may I often see something like this: "You can't Run A Windows NT Application On OS / 2, IT's Simply NOT POSSIBLE." When building an application for Windows 3.1, the linker will be in your executable Links a default residual program called WinStub.exe. You can replace WINSTUB with a MS-DOS-based active program, and use the STUB module to define a statement to indicate the link, which can replace the default behavior of the linker. Applications developed for Windows NT can be implemented by using -stub: linker options. PE file head and sign
The PE file head is positioned by the E_LFANEW domain of the MS-DOS header. This domain is only given the offset of the file, so determines the actual memory mapping address of the PE header, the memory map of the file needs to be added. . For example, the following macros are included in the pefile.h source file: pefile.h # define ntsignature (a) ((LPVOID) ((Byte *) A / ((pimage_dos_header) A) -> E_LFANEW)) When processing PE file information, I found some locations in the file to be reviewed. Since these locations are just the offset of the file, it is easier to implement these positioning with macro because they have better performance than the function. Note that this macro is getting a PE file mark, not the offset of the head of the PE file. It is because since Windows starts with OS / 2, the .exe file is given the logo of the target operating system. This flag is before the PE file head structure for the PE file format of Windows NT. In some versions of Windows and OS / 2, this flag is the first word of the file header. Similarly, for the PE file format, Windows NT uses a DWORD value. The above macros returned to the offset of the file logo, regardless of which type of executable it is. So, the file head is after the DWORD flag, or at the Word flag is determined by this flag whether the Windows NT file flag is determined. To solve this problem, I have written ImageFileType function (as below), it returns the type of image file: pefile.cdword WinAPI ImageFileType (LPVOID LPFILE) {/ * The first DOS file flag * / if (* (usort *) LPFILE == image_dos_signature) {/ * determines the position of the PE file header by the DOS head * / if (loword (* (* (DWORD *) NTSIGNATURE (LPFILE)) == image_os2_signature || loword (* (DWORD *) NTSIGNATURE (LPFile )) == IMAGE_OS2_SIGNATURE_LE) return (DWORD) LOWORD (* (DWORD *) NTSIGNATURE (lpFile)); else if (* (DWORD *) NTSIGNATURE (lpFile) == IMAGE_NT_SIGNATURE) return IMAGE_NT_SIGNATURE; else return IMAGE_DOS_SIGNATURE;} else / * Unknown file type * / return 0;} The code listed above immediately tells how usefulness of your Ntsignature macro. This macro will make these two things very simple for comparing different file types and return an appropriate file type. Among WINNT.H defined four different file types: WINNT.H # define IMAGE_DOS_SIGNATURE 0x5A4D // MZ # define IMAGE_OS2_SIGNATURE 0x454E // NE # define IMAGE_OS2_SIGNATURE_LE 0x454C // LE # define IMAGE_NT_SIGNATURE 0x00004550 // PE00 First, Windows can The execution file type does not appear in this list, this looks very strange.
However, after a slight study, you can get the reason: In addition to the difference in operating system version specification, there is no difference between Windows executable files and OS / 2 executable. These two operating systems have the same executable file structure. Now turn our attention to Windows NT PE file format, we will find that as long as we get the location of the file logo, there will be 4 bytes following the PE file. The next macro has the head of the PE file: pefile.c # define pefhdroffset (a) ((LPVOID) ((Byte *) A / (pimage_dos_header) A) -> E_LFANEW / SIZE_OF_NT_SIGNATURE) This macro The only difference between a macro is that this macro adds a constant size_of_nt_signature. Unfortunately, this constant is not defined in Winnt.h, so I define it in PeFile.h, it is a DWORD size. Since we know the position of the PE file, you can check the data of the head. We only need to assign this location to a structure, as follows: pfh_file_header pfh; pfh = (pimage_file_header) pefhdroffset (LPFILE); in this example, lpfile indicates a pointer to the executable memory image base address, which is showing Benefits of memory mapping files: I / O does not need to execute files, just use pointer PFH to access information in the file. PE header structure is defined as: WINNT.Htypedef struct _IMAGE_FILE_HEADER {USHORT Machine; USHORT NumberOfSections; ULONG TimeDateStamp; ULONG PointerToSymbolTable; ULONG NumberOfSymbols; USHORT SizeOfOptionalHeader; USHORT Characteristics;} IMAGE_FILE_HEADER, * PIMAGE_FILE_HEADER;