1. 程式人生 > >PE總結3---PE檔案結構DOS檔案頭

PE總結3---PE檔案結構DOS檔案頭

PE檔案結構DOS檔案頭,會使用到IMAGE_DOS_HEADER結構體,如下

typedef struct _IMAGE_DOS_HEADER {      // DOS .EXE header
    WORD   e_magic;                     // Magic number
    WORD   e_cblp;                      // Bytes on last page of file
    WORD   e_cp;                        // Pages in file
    WORD   e_crlc;                      // Relocations
    WORD   e_cparhdr;                   // Size of header in paragraphs
    WORD   e_minalloc;                  // Minimum extra paragraphs needed
    WORD   e_maxalloc;                  // Maximum extra paragraphs needed
    WORD   e_ss;                        // Initial (relative) SS value
    WORD   e_sp;                        // Initial SP value
    WORD   e_csum;                      // Checksum
    WORD   e_ip;                        // Initial IP value
    WORD   e_cs;                        // Initial (relative) CS value
    WORD   e_lfarlc;                      // File address of relocation table
    WORD   e_ovno;                      // Overlay number
    WORD   e_res[4];                     // Reserved words
    WORD   e_oemid;                     // OEM identifier (for e_oeminfo)
    WORD   e_oeminfo;                   // OEM information; e_oemid specific
    WORD   e_res2[10];                   // Reserved words
    LONG   e_lfanew;                     // File address of new exe header
  } IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;

          第1個成員佔2個位元組,它被用於表示一個MS-DOS相容的檔案型別,他的值是固定的----“4D5A”。 (注意:因為我們是在十六進位制編輯器下寫資料,所以所有的資料格式都是十六進位制式的。但是我們在開發環境中預設 都是十進位制的,所以必須在資料前加 0x ,即:0x4D5A。而我為了方便,就直接寫成“4D5A”,也就是直接輸入到編輯器中的值,是十六進位制,後面的都照此規定書寫。)

          第2個成員到第18個成員總共58個位元組,是對DOS程式環境的初始化等操作。

         第19個成員非常重要,他佔4個位元組,用來表示NT頭部在檔案中的偏移。而從圖中可以看到  “PE”檔案標誌緊隨“MS-DOS 載入模組”其後。


結構體 IMAGE_DOS_HEADER最重要的兩個元素:

         結構體 IMAGE_DOS_HEADER
         第一個引數 e_magic 其值 恆為0x4D5A (MZ) ----- 所以可以使用巨集IMAGE_DOS_SIGNATURE進行判斷
         第19個引數 e_lfanew 其值為NT頭部在檔案中的偏移,新的exe檔案頭部偏移地址 在0x3C位置

我們藉助010Editor,載入一個dll


使用程式碼進行操作,判斷是否是PE檔案

bool  isPE(TCHAR * file)
{
	char* buf = nullptr;
	//得到檔案控制代碼
	HANDLE hFile = CreateFile(
		file, GENERIC_READ | GENERIC_WRITE,
		0,
		NULL,
		OPEN_EXISTING,
		FILE_ATTRIBUTE_NORMAL,
		NULL);
	if (hFile == NULL)
	{
		return false;
	}

	//得到檔案大小
	DWORD dwFileSize =
		GetFileSize(hFile, NULL);
	DWORD ReadSize = 0;
	buf = new char[dwFileSize];
	memset(buf, 0, dwFileSize);
	//將檔案讀取到記憶體
	ReadFile(hFile, buf, dwFileSize, &
		ReadSize, NULL);
	
	
	//判斷是否是DOS頭
	if (((PIMAGE_DOS_HEADER)buf)->e_magic  != IMAGE_DOS_SIGNATURE)
	{
		return false;
	}

	//計算出NT頭
	
	PIMAGE_NT_HEADERS32 pNTHeader = (PIMAGE_NT_HEADERS32)((long)buf + ((PIMAGE_DOS_HEADER)buf)->e_lfanew);

	//判斷是否是NT頭
	if (pNTHeader->Signature != IMAGE_NT_SIGNATURE)
	{
		return false;
	}
}
int _tmain(int argc, _TCHAR* argv[])
{

	TCHAR FileName[] = _T("D:\\MFCLibrary1Dll.dll");
	isPE(FileName);
}



文章中需要使用得  MFCLibrary1Dll.dll  下載地址:http://download.csdn.net/detail/obuyiseng/9296465