Шаг 23 - IMAGE_DOS_HEADER

Эта структура описывает заголовок MS DOS для программ Windows, которые имеют обозначение PE - Portable Executable. Данный заголовок сделан для того, чтобы программы созданные для Windows не запускались из MS DOS. И этого не происходит. Вместо запуска вы видите примерно вот что:

This program cannot be run in DOS mode
Эта программа не может быть запущена в DOS 

Общая структура начала программы для Windows выглядит так:

MS-DOS MZ Сигнатура и заголовок
MS-DOS MS DOS программа 
PE File PE Сигнатура и заголовок 
......

Структура IMAGE_DOS_HEADER как раз и описывает этот заголовок. Этот заголовок используется начиная с MS DOS 2.0. Он занимает 64 байта и вот его описание из WinNT.h:

typedef struct _IMAGE_DOS_HEADER { 
	USHORT e_magic;		// Сигнатура заголовка
	USHORT e_cblp;		// количество байт на последней странице файла
	USHORT e_cp;		// количество страниц в файле
	USHORT e_crlc;		// Relocations
	USHORT e_cparhdr;		// Размер заголовка в параграфах
	USHORT e_minalloc;		// Минимальные дополнительные параграфы
	USHORT e_maxalloc;		// Максимальные дополнительные параграфы
	USHORT e_ss;		// начальное  относительное значение регистра SS
	USHORT e_sp;		// начальное значение регистра SP
	USHORT e_csum;		// контрольная сумма
	USHORT e_ip;		// начальное значение регистра IP
	USHORT e_cs;		// начальное относительное значение регистра CS
	USHORT e_lfarlc;		// адрес в файле на таблицу переадресации
	USHORT e_ovno;		// количество оверлеев
	USHORT e_res[4];		// Зарезервировано
	USHORT e_oemid;		// OEM идентифкатор
	USHORT e_oeminfo;		// OEM информация
	USHORT e_res2[10];		// Зарезервировано
	LONG   e_lfanew;		// адрес в файле нового .exe заголовка (PE)
} IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;

Ну давайте попробуем поработать с этой структурой. Посмотрим, что у нас в заголовке user32.dll. Вот приложение:

// TestAPI.cpp : Defines the entry point for the application.
//

#include "stdafx.h"

int APIENTRY WinMain(HINSTANCE hInstance,
		HINSTANCE hPrevInstance,
		LPSTR lpCmdLine,
		int nCmdShow)
{
	HMODULE hUser32=NULL;
	hUser32=GetModuleHandle("user32");

	if (hUser32==NULL)
	{
		MessageBox(NULL,"Error Load User32","Error",MB_OK);
		return FALSE;
	}

	PIMAGE_DOS_HEADER pDOSHead;
	pDOSHead = (PIMAGE_DOS_HEADER)hUser32; 

	if ( pDOSHead->e_magic != IMAGE_DOS_SIGNATURE ) 
	{
		MessageBox(NULL,"Error Dos Header signature MZ","Error",MB_OK);
		return FALSE;
	}
	return TRUE;
}

Как видите мы получаем модуль. Начало этого модуля - это заголовок MS DOS. Для того, чтобы убедиться, что все правильно мы проверяем сигнатуру MS DOS, которая для EXE файлов должна быть MZ. Сигнатуры описаны в файле WinNt.h:

#define IMAGE_DOS_SIGNATURE		0x4D5A		// MZ
#define IMAGE_OS2_SIGNATURE		0x4E45		// NE
#define IMAGE_OS2_SIGNATURE_LE	0x4C45		// LE
#define IMAGE_NT_SIGNATURE		0x50450000	// PE00

Поле из структуры и сравниваем с одной из этих сигнатур. Заголовок это MS DOS или нет. Если да, то спокойно можно пользоваться полями структуры для получения дополнительной информации.


Предыдущий Шаг | Следующий Шаг | Оглавление
Автор Каев Артем.