Initially, I attempted to develop a program that could differentiate between 16-bit DOS and 32/64-bit Windows executables.
After reading another answer, I learned that an executable could be categorized based on its first two bytes, which are typically “MZ/…”.
However, when I compared various executables that I had created in assembly and compiled using TASM for 16-bit, and ones from my computer’s C:\Windows\System32 for 32/64-bit, I discovered that they all began with “MZ”.
I am wondering if there is a specific explanation for this or if I am doing something incorrectly. Additionally, I am curious if there is a more precise method for identifying an executable.
The MZ Header in Executables
The MZ header is a signature that identifies an executable file. It is typically the first two bytes of an executable file and is followed by the DOS executable header. The MZ header is named after Mark Zbikowski, who developed the header for MS-DOS.
The MZ header is present in all Windows executable files, regardless of whether they are 16-bit or 32/64-bit. The header is used by the operating system to determine whether the file is a valid executable file and to load the file into memory.
16-bit DOS and 32/64-bit Windows Executables
In the early days of computing, executable files were typically 16-bit programs that ran on MS-DOS. These programs used the MZ header and the DOS executable header to load and run the program.
As computing evolved, the need for 32/64-bit programs arose, and the operating system changed to support these programs. However, the MZ header remained in use to maintain backward compatibility with older programs.
Today, all Windows executable files, regardless of their bitness, use the MZ header. The header is followed by the PE header, which contains information about the program’s architecture and other details.
Identifying an Executable
The MZ header is a reliable way to identify an executable file. However, it is not the only way to do so. There are other methods for identifying an executable, such as checking the file extension or using a file identification tool.
Checking the file extension can be a quick way to determine if a file is an executable. Most executable files have a .exe extension, although this is not always the case.
File identification tools, such as the Unix file command or the Windows file properties dialog, can provide detailed information about a file, including its type and architecture.
Creating Executable Files
If you are creating executable files, it is important to understand the structure of the file and how it will be loaded and executed by the operating system.
When creating a 16-bit DOS executable, you will need to include the MZ header and the DOS executable header. These headers provide the information that the operating system needs to load and execute the program.
When creating a 32/64-bit Windows executable, you will need to include the MZ header and the PE header. The PE header contains information about the program’s architecture and other details that are used by the operating system to load and execute the program.
The MZ header is a signature that identifies an executable file. It is present in all Windows executable files, regardless of their bitness. While it is a reliable way to identify an executable, there are other methods for doing so.
When creating executable files, it is important to understand the structure of the file and how it will be loaded and executed by the operating system. By including the appropriate headers, you can ensure that your program is loaded and executed correctly.
The MZ header you are seeing at the beginning of every executable is the magic number for executables in the DOS and Windows operating systems. The MZ header is used to identify the file as an executable and to determine the location of the program’s entry point, which is the starting address of the program’s code when it is loaded into memory.
It is important to note that the MZ header is not specific to 16-bit or 32/64-bit executables. It is used by executables of all bitnesses in the DOS and Windows operating systems.
To determine the bitness of an executable, you can use a tool such as the
file command on Unix-like systems or the
dumpbin command on Windows. These tools can provide information about the architecture of the executable, including its bitness. You can also use specialized tools such as
pefile (a Python library) to parse the Portable Executable (PE) headers of the executable and extract information about its architecture.
Alternatively, you can use the
GetBinaryType function in the Windows API to determine the bitness of an executable. This function returns a
BINARY_TYPE value indicating the bitness of the executable.
I hope this helps! Let me know if you have any further questions.