DEV Community

wireless90
wireless90

Posted on • Updated on

Validating the MZ Signature [Windows PE Internals]

Previous Windows PE Internals Writeups

Previously

Previously, we learnt about how to dynamically get a handle to user32.dll. In this article, we will try to get the MZ Signature from the dll.

What is a PE File?

The Portable Executable (PE) format is a file format for executables, object code, DLLs and others used in 32-bit and 64-bit versions of Windows operating systems. The PE format is a data structure that encapsulates the information necessary for the Windows OS loader to manage the wrapped executable code.

Thus, our dll, user32.dll is a PE file as well.

What is a MZ Signature?

The MZ signature is a signature used by the MS-DOS relocatable 16-bit EXE format and its still present in today's PE files for backwards compatibility.

The signature is 0x5a4d. It is the first 2 bytes of our PE file.

image

The entire PE structure can be found here.

Let's begin

Continuing from the previous article, we will now cast our peBase variable to the struct, IMAGE_DOS_HEADER.

The definition can be found here or below.

typedef struct _IMAGE_DOS_HEADER
{
     WORD e_magic;
     WORD e_cblp;
     WORD e_cp;
     WORD e_crlc;
     WORD e_cparhdr;
     WORD e_minalloc;
     WORD e_maxalloc;
     WORD e_ss;
     WORD e_sp;
     WORD e_csum;
     WORD e_ip;
     WORD e_cs;
     WORD e_lfarlc;
     WORD e_ovno;
     WORD e_res[4];
     WORD e_oemid;
     WORD e_oeminfo;
     WORD e_res2[10];
     LONG e_lfanew;
} IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;
Enter fullscreen mode Exit fullscreen mode

We will be using a pointer to the IMAGE_DOS_HEADER. It can be written as IMAGE_DOS_HEADER* or PIMAGE_DOS_HEADER.

The way to cast it will as as follows.

PIMAGE_DOS_HEADER imageDosHeader = (PIMAGE_DOS_HEADER)peBase;
Enter fullscreen mode Exit fullscreen mode

Looking at the IMAGE_DOS_HEADER structure definition above, we can see a property e_magic of type WORD, which is 2 bytes. As expected, this is the MZ signature.

Let's continue with our program to check if the user32.dll has the correct MZ signature.

if (imageDosHeader->e_magic != IMAGE_DOS_SIGNATURE)
{
        MessageBoxA(0, "user32.dll has the wrong Image Dos Signature!", "Error", MB_OK | MB_ICONERROR);
        return 1;
}
Enter fullscreen mode Exit fullscreen mode

The IMAGE_DOS_SIGNATURE is a helpful macro that is already defined for us in winnt.h which has the following definition.

#define IMAGE_DOS_SIGNATURE                 0x5A4D      // MZ
Enter fullscreen mode Exit fullscreen mode

We simply reference it therefore, we do not need to explicitly remember the signature 0x5a4d.

Overall, our program now looks like this.

#include <Windows.h>

int  WinMain(
     HINSTANCE hInstance,
     HINSTANCE hPrevInstance,
     LPSTR     lpCmdLine,
     int       nCmdShow
)
{
    HMODULE peBase = GetModuleHandleA("user32.dll");

    if (peBase == NULL)
    {
        MessageBoxA(0, "Can't load user32.dll", "Error", MB_OK | MB_ICONERROR);
        return 1;
    }

    PIMAGE_DOS_HEADER imageDosHeader = (PIMAGE_DOS_HEADER)peBase;

    if (imageDosHeader->e_magic != IMAGE_DOS_SIGNATURE)
    {
        MessageBoxA(0, "user32.dll has the wrong Image Dos Signature!", "Error", MB_OK | MB_ICONERROR);
        return 1;
    }

    MessageBoxA(0, "user32.dll has the right Image Dos Signature!", "Success", MB_OK | MB_ICONINFORMATION);

    return 0;
}
Enter fullscreen mode Exit fullscreen mode

Running the program now gives us the following.

image

In this exercise, I learnt that the first part of the PE file contains the Image Dos Signature.

Next

Validating the PE Signature

Top comments (0)