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.
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;
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;
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;
}
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
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;
}
Running the program now gives us the following.
In this exercise, I learnt that the first part of the PE file contains the Image Dos Signature
.
Top comments (0)