Search code examples
c#portable-executable

Why reading EXE as text is showing 'MZ' when printed


String inputFile = "C:\\Users\\Neil\\Desktop\\DCR\\file.exe";
Byte[] bytes = File.ReadAllBytes(inputFile);
String content = Encoding.Default.GetString(bytes);
Console.WriteLine(content);

Output of

MZ?

and when I attempt to do it to another file I get

MZP

What does this mean?


Solution

  • The first few bytes of a windows exe is the DOS header, which has the structure:

    struct DOS_Header 
     {
         char signature[2] = "MZ";
         short lastsize;
         short nblocks;
         short nreloc;
         short hdrsize;
         short minalloc;
         short maxalloc;
         void *ss;
         void *sp;
         short checksum;
         void *ip;
         void *cs;
         short relocpos;
         short noverlay;
         short reserved1[4];
         short oem_id;
         short oem_info;
         short reserved2[10];
         long  e_lfanew;
     }
    

    Reading the file as a string will start with MZ and then vary based on how the following 16 bit integers are interpreted by your encoding. If the high byte on any of those words is 0, that will also null terminate the string, which explains why you get 3 characters of output and nothing else.

    Specifically, the output MZ? will occur when lastsize has a value of 0x3F and MZP when lastsize has a value of 0x50.