我最近开始使用PE(Portable Executable)文件格式,更具体地说是PE/COFF。我正在阅读Randy Kath here的教程。

当我阅读MZ DOS标头的结构时,发现使用e_magic字段中的签名验证了MZ DOS标头。结构如下:

typedef struct _IMAGE_DOS_HEADER {  // DOS .EXE header
    USHORT e_magic;         // Magic number
    USHORT e_cblp;          // Bytes on last page of file
    USHORT e_cp;            // Pages in file
    USHORT e_crlc;          // Relocations
    USHORT e_cparhdr;       // Size of header in paragraphs
    USHORT e_minalloc;      // Minimum extra paragraphs needed
    USHORT e_maxalloc;      // Maximum extra paragraphs needed
    USHORT e_ss;            // Initial (relative) SS value
    USHORT e_sp;            // Initial SP value
    USHORT e_csum;          // Checksum
    USHORT e_ip;            // Initial IP value
    USHORT e_cs;            // Initial (relative) CS value
    USHORT e_lfarlc;        // File address of relocation table
    USHORT e_ovno;          // Overlay number
    USHORT e_res[4];        // Reserved words
    USHORT e_oemid;         // OEM identifier (for e_oeminfo)
    USHORT e_oeminfo;       // OEM information; e_oemid specific
    USHORT e_res2[10];      // Reserved words
    LONG   e_lfanew;        // File address of new exe header
  } IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;


和教程说:


所有与MS-DOS兼容的可执行文件都将此值设置为0x54AD,
代表ASCII字符MZ。


我的问题是一样的。

MZ的ascii值分别是7790,以十六进制转换为4D5A0x54AD如何表示MZ

这可能是一个愚蠢的问题。但是请帮助我了解它是否太傻了。

谢谢。

最佳答案

首先,声称签名为0x54AD的来源是错误的;十六进制的MZ实际上是0x5A4D(对于低端字节序的体系结构),如以下程序的输出所示:

#include <Windows.h> // for the USHORT type
#include <stdio.h>

int main()
{
    USHORT MZ = ('M' | 'Z' << 8);
    printf("0x%.4X\n", MZ);
    return 0;
}


输出:

0x5A4D


您可能仍然有一个问题,当签名实际上是'Z'时,为什么5A'MZ')的字节优先出现?

这与字节顺序有关,字节顺序是字节存储在各个半字,字,双字等中的顺序。

大字节序将具有最高有效字节的字节存储在最高的存储器地址中,而小字节序则相反,将最高有效字节存储在最低有效存储器的地址中。

x86和x64体系结构是低位字节序的,因此MZ(即Z)中的最高有效字节排在第一位。

10-04 22:01