为什么PE文件中的MZ DOS Header Signature 0x54AD?
Why is the MZ DOS Header Signature 0x54AD in PE files?
我最近开始使用 PE(Portable Executable)
文件格式,更具体地说 PE/COFF
。我正在阅读 Randy Kath here.
的教程
当我阅读 MZ DOS header 的结构时,我发现 MZ DOS header 是使用 e_magic
字段中的签名验证的。结构如下:
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;
教程说:
All MS-DOS-compatible executable files set this value to 0x54AD,
which represents the ASCII characters MZ.
我的问题也是一样
M
和Z
的ascii值分别是77
和90
,转化为十六进制的4D
和5A
. 0x54AD
如何表示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
)中的最高有效字节在前。
我最近开始使用 PE(Portable Executable)
文件格式,更具体地说 PE/COFF
。我正在阅读 Randy Kath here.
当我阅读 MZ DOS header 的结构时,我发现 MZ DOS header 是使用 e_magic
字段中的签名验证的。结构如下:
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;
教程说:
All MS-DOS-compatible executable files set this value to 0x54AD, which represents the ASCII characters MZ.
我的问题也是一样
M
和Z
的ascii值分别是77
和90
,转化为十六进制的4D
和5A
. 0x54AD
如何表示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
)中的最高有效字节在前。