Validating the MZ Signature [Windows PE Internals]
Tags: cybersecurity, security
Published: 2021-04-20 12:51:34

# Previous Windows PE Internals Writeups
- [Creating a Windows Project in Visual Studio](https://dev.to/wireless90/creating-a-windows-project-in-visual-studio-windows-pe-internals-2p6e)
- [Getting a Handle to a Dynamically Linked Library ](https://dev.to/wireless90/getmodulehandlea-windows-pe-internals-1b0l)

# 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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bi1zjxme6wq5fwt54igw.png)

The entire PE structure can be found [here](https://upload.wikimedia.org/wikipedia/commons/1/1b/Portable_Executable_32_bit_Structure_in_SVG_fixed.svg). 

# 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](https://www.nirsoft.net/kernel_struct/vista/IMAGE_DOS_HEADER.html) or below.

```cpp
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;
```

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.

```cpp
PIMAGE_DOS_HEADER imageDosHeader = (PIMAGE_DOS_HEADER)peBase;
```

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.

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

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

```cpp
#define IMAGE_DOS_SIGNATURE                 0x5A4D      // MZ
```

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

Overall, our program now looks like this.

```cpp
#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;
}
```

Running the program now gives us the following.

![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8ndus3hlqnru60x2za9h.png)
 
In this exercise, I learnt that the first part of the PE file contains the `Image Dos Signature`.


# Next

[Validating the PE Signature](https://dev.to/wireless90/validating-the-pe-signature-my-av-flagged-me-windows-pe-internals-2m5o/)