How would I change the header whilst still allowing the file to work
as normal?
You can't!
There's a reason the MZ
string (16-bits representing 0x5A4D
) is referred to as a "magic" number, and indeed, is required as per the EXE/PE specification (with roots all the way back to DOS-format executables). The layout of all modern portable executables appears as follows (ref):
In this MSDN article regarding the Portable Executable format, the MS-DOS header is detailed:
The MS-DOS Header
Every PE file begins with a small MS-DOS® executable. The need for this stub executable arose in the early days
of Windows, before a significant number of consumers were running it.
When executed on a machine without Windows, the program could at least
print out a message saying that Windows was required to run the
executable.
The first bytes of a PE file begin with the traditional MS-DOS header,
called an IMAGE_DOS_HEADER
. The only two values of any importance are
e_magic
and e_lfanew
. The e_lfanew
field contains the file offset of
the PE header.
The e_magic
field (a WORD [NB: 16-bits]) needs to be set to the value
0x5A4D
. There's a #define
for this value, named IMAGE_DOS_SIGNATURE
.
In ASCII representation, 0x5A4D
is MZ
, the initials of Mark Zbikowski,
one of the original architects of MS-DOS.
For further information regarding the Windows PE/.EXE format, I highly recommend taking a look at the Windows Executable Files section of the x86 Disassembly Wikibook. It contains an extensive array of low-level information regarding the format.