1. 程式人生 > >PE檔案格式詳解(一)

PE檔案格式詳解(一)

在本文中, 我並不打算大講特講PE檔案的構成是什麼,每個欄位是什麼意思, 這些資料可以說在網上是浩瀚如海,到處都是的, 用google一搜, 開啟一看, 基本講解的都是大同小異。 由於pe檔案的結構比較龐大, 結構中套結構, 有的結構多達30多個欄位, 光看這些欄位都讓人夠暈的, 在加上有的欄位是一個32位的DWORD值, 而每一位都有其特殊的含義,這樣, 光把每個欄位的含義看一遍過來, 估計也得2個小時。 而實際上, 這裡面很多欄位, 我們都不需要去了解, 也不需要去關注, 掌握那些關鍵欄位就行了,所以如果大家有那個欄位不懂的,可以上網搜一下。這次講一下是否PE格式檔案的判斷。

(這個圖我是從魚C論壇轉的)。

首先要明確PE檔案格式的特徵是什麼,這樣我們才能根據這個特徵來判斷是否是PE檔案。PE檔案的格式如上圖所示,那麼我們怎麼判斷呢?PE檔案有DOS檔案頭和PE檔案頭,在DOS檔案頭前兩個位元組是“MZ",PE檔案頭的前4個位元組是“PE”,所以我們可以根據這個特徵來進行判斷,我們怎麼找到“MZ”和“PE”位置呢,PIMAGE_DOS_HEADER的e_magic欄位表示“MZ”,PIMAGE_DOS_HEADER的e_lfanew表示PE頭相對於檔案的偏移。(我用的VS2012編譯環境)

程式碼如下:

/************************************************************************/
/* 
功能:判斷是否是PE檔案。
引數:指向存放檔案資料記憶體首地址
返回:TRUE ;是PE檔案
	  FALSE:不是PE檔案
*/
/************************************************************************/
BOOL IsPEFile(LPVOID lpFileBuf)
{
	//獲取DOS頭並判斷"MZ"標誌
	PIMAGE_DOS_HEADER pDos = (PIMAGE_DOS_HEADER)lpFileBuf;	
	//e_magic exe標誌 "MZ"
	if (IMAGE_DOS_SIGNATURE != pDos->e_magic)
		return FALSE;

	//獲取PE頭,並判斷"PE\0\0"標誌
	//e_lfanew PE頭相對於檔案的偏移地址
	size_t  stPEHeadAddr = (size_t)lpFileBuf + pDos->e_lfanew;
	PIMAGE_NT_HEADERS32 pNT = (PIMAGE_NT_HEADERS32)stPEHeadAddr;
	if (IMAGE_NT_SIGNATURE != pNT->Signature)
	{
		return FALSE;
	}
	return TRUE;
}
int _tmain(int argc, _TCHAR* argv[])
{

	//檔案控制代碼
	HANDLE hFile = INVALID_HANDLE_VALUE;
	//檔案路徑
	LPCTSTR strInPath = _T("G:\\15pb培訓課後作業\\01 VMView\\Debug\\VMView.exe");
	DWORD  dwSize = 0;
	PVOID  lpFillBuf = NULL;

	STARTUPINFO si = {0};
	GetStartupInfo(&si);
	PROCESS_INFORMATION pi = {0};
	if (!CreateProcess(											/* 建立除錯執行緒 */
		strInPath,	//可執行模組路徑
		NULL,													//命令列
		NULL,													//安全描述符
		NULL,													//執行緒屬性是否可繼承
		FALSE,													//否從呼叫程序處繼承了控制代碼
		DEBUG_ONLY_THIS_PROCESS | CREATE_NEW_CONSOLE,			//以“只”除錯的方式啟動
		NULL,													//新程序的環境塊
		NULL,													//新程序的當前工作路徑(當前目錄)
		&si,													//指定程序的主視窗特性
		&pi))													//接收新程序的識別資訊
	{
		printf("CreateProcess Failed!\n");
	}

	//獲取檔案控制代碼
	if (INVALID_HANDLE_VALUE == (hFile = CreateFile(strInPath,	//檔案路徑
		GENERIC_READ,											//訪問許可權
		FILE_SHARE_READ,										//共享模式
		NULL,													//安全描述符
		OPEN_EXISTING,											//建立標誌
		FILE_ATTRIBUTE_NORMAL,									//檔案標誌和屬性
		NULL)))													//臨時檔案控制代碼
	{
		return 0;
	}
	//獲取檔案大小
	if (INVALID_FILE_SIZE == (dwSize = GetFileSize(hFile,NULL)))
	{
		CloseHandle(hFile);
		return  0;
	}
	//開闢一塊記憶體用於存放檔案資料
	if ( NULL == (lpFillBuf =VirtualAlloc(NULL,dwSize,MEM_COMMIT,PAGE_EXECUTE_READWRITE)))
	{
		CloseHandle(hFile);
		return 0;
	}
	//把檔案資料讀取到記憶體中
	DWORD dwRet ;
	if (!ReadFile(hFile,lpFillBuf,dwSize,&dwRet,NULL))
	{
		CloseHandle(hFile);
		VirtualFree(lpFillBuf,0,MEM_RELEASE);
		return 0;
	}

	if (IsPEFile(lpFillBuf))
	{
		MessageBox(NULL,_T("該檔案是PE檔案"),_T("PE檔案格式判斷"),MB_OK);
	}
	else
	{
		MessageBox(NULL,_T("該檔案不是PE檔案"),_T("PE檔案格式判斷"),MB_OK);
	}
	VirtualFree(lpFillBuf,0,MEM_RELEASE);
	CloseHandle(hFile);
	_tsystem(_T("pause"));
	return 0;
}

通過以上就可以進行判斷了。

下面是一個可執行檔案的二進位制截圖,我把IMAGE_DOS_HEADER.e_magic,IMAGE_DOS_HEADER.e_lfanew和IMAGE_NT_HEADER.Signature標記出來了。




相關推薦

PE檔案格式

在本文中, 我並不打算大講特講PE檔案的構成是什麼,每個欄位是什麼意思, 這些資料可以說在網上是浩瀚如海,到處都是的, 用google一搜, 開啟一看, 基本講解的都是大同小異。 由於pe檔案的結構比較龐大, 結構中套結構, 有的結構多達30多個欄位, 光看這些欄位都讓人夠

PE檔案格式

0x00 前言   前面兩篇講到了輸出表的內容以及涉及如何在hexWorkShop中找到輸出表及輸入DLL,感覺有幾個地方還是沒有理解好,比如由資料目錄表DataDirectory[16]找到輸出表表後以為找到輸入DLL就完了,其實這一流程的最終功能是通過輸入DLL找到輸入DLL呼叫的函

PE檔案格式

0x00 前言   前一篇瞭解了區塊虛擬地址和檔案地址轉換的相關知識,這一篇該把我們所學拿出來用用了。這篇我們將瞭解更為重要的一個知識點——輸入表和輸出表的知識。 0x01 輸入表   首先我們有疑問。這個輸入表是啥?為啥有輸入表?其實輸入表就是記錄PE輸入函式相

PE檔案格式

PE檔案格式詳解(四) 0x00 前言   上一篇介紹了區塊表的資訊,以及如何在hexwrokshop找到區塊表。接下來,我們繼續深入瞭解區塊,並且學會檔案偏移和虛擬地址轉換的知識。 0x01 區塊對齊值   首先我們要知道啥事區塊對齊?為啥要區塊對齊?這個問題

PE檔案結構PE匯入表

PE檔案結構詳解(二)可執行檔案頭的最後展示了一個數組,PE檔案結構詳解(三)PE匯出表中解釋了其中第一項的格式,本篇文章來揭示這個陣列中的第二項:IMAGE_DIRECTORY_ENTRY_IMPORT,即匯入表。 也許大家注意到過,在IMAGE_DATA_DIRECTO

PE檔案--資料結構欄位

typedef struct _IMAGE_OPTIONAL_HEADER{//// Standard fields.//+18h WORD Magic; // 標誌字, ROM 映像(0107h),普通可執行檔案(010Bh)+1Ah BYTE MajorLinkerVersion; // 連結程式的主版

PE文件格式

ebs 位置 數位 地址 inf font pe文件 。。 地址轉換 PE文件格式詳解(四) 0x00 前言 上一篇介紹了區塊表的信息,以及如何在hexwrokshop找到區塊表。接下來,我們繼續深入了解區塊,並且學會文件偏移和虛擬地址轉換的知識。 0x01 區塊對齊值

PE文件格式

itme lordpe order 詳解 proc table mil create 實踐 0x00 前言 前面兩篇講到了輸出表的內容以及涉及如何在hexWorkShop中找到輸出表及輸入DLL,感覺有幾個地方還是沒有理解好,比如由數據目錄表DataDirectory[

PE文件格式

msgbox nbsp clas com 類型 結構 size date 是的 PE文件格式詳解(七) Ox00 前言 前面好幾篇在講輸入表,今天要講的是輸出表和地址的是地址重定位。有了前面的基礎,其實對於怎麽找輸出表地址重定位的表已經非常熟悉了。 0x01

Linux常用命令示例-檔案管理

1、touch 命令 使用說明: Linux touch命令用於修改檔案或者目錄的時間屬性,包括存取時間和更改時間。若檔案不存在,系統會建立一個新的檔案。 使用語法: touch [-acfm][-d<日期時間>][-r<參考檔案或目錄>

【SpringBoot學習之路】05.Springboot配置檔案

轉載宣告:商業轉載請聯絡作者獲得授權,非商業轉載請註明出處.原文來自 © 呆萌鍾【SpringBoot學習之路】05.Springboot配置檔案詳解(一)  配置檔案 Spring Boot使用一個全域性的配置檔案 applic

表空間資料檔案

一.表空間的建立 建立表空間: Create tablespace felix Datafile'/u01/app/oracle/oradata/felix/felixtbs.dbf' Size100m autoextendonnext10m maxsize10

GZIP壓縮原理分析04——第三章 gzip檔案格式三02 gzip檔案頭

檔案頭由固定長度的部分和擴充套件部分組成,擴充套件部分不一定存在,尤其是網路傳輸使用的HTTP壓縮,如果使用了gzip格式,那麼對應的壓縮報文一般都不帶擴充套件部分。gzip檔案格式通過將頭部中定長部

BMP檔案格式BMP file format[圖文解說]

BMP檔案格式,又稱為Bitmap(點陣圖)或是DIB(Device-Independent Device,裝置無關點陣圖),是Windows系統中廣泛使用的影象檔案格式。由於它可以不作任何變換地儲存影象畫素域的資料,因此成為我們取得RAW資料的重要來源。Windows的圖

flume-ng配置檔案

1 Avro案例 [root@localhost conf]# vi avro.confagent1.sources = r1 agent1.sinks = k1 agent1.channels = c1   agent1.sources.r1.type = avro a

elastic-job:數據分片

count 任務 不同的 應該 center shc 偶數 int ext 數據分片的目的在於把一個任務分散到不同的機器上運行,既可以解決單機計算能力上限的問題,也能降低部分任務失敗對整體系統的影響。elastic-job並不直接提供數據處理的功能,框架只會將分片項分配至各

JVM的基本結構及其各部分

後臺 棧幀 結束 依次 方法參數 ati 0.00 實例 同時存在 JVM的基本結構及其各部分詳解(一)(轉載) 1 java虛擬機的基本結構如圖: 1)類加載子系統負責從文件系統或者網絡中加載Class信息,加載的類信息存放於一塊稱為方法區的內存空間。除了類的信息外,方

設計模式

att 定義 面向對象設計 設計 sig com 繼承 行為模式 接口 一、設計模式定義 設計模式(Design Pattern)是一套被反復使用、多數人知曉的、經過分類的、代碼設計經驗的總結。 使用設計模式的目的:為了代碼可重用性、讓代碼更容易被他人理解、保證代碼可靠性。

mybatis ------JDBC

jdbc javax 發出 一段 true his 實例 用戶名 移植 1、什麽是MyBatis?   MyBatis 本是apache的一個開源項目iBatis, 2010年這個項目由apache software foundation 遷移到了google code,

Maven------ Maven概述

粘貼 cvs 模塊 strong ron 標準化 pom 標準 只需要 1、引言     你能搜到這個教程,說明你對 Maven 感興趣,但是又不是太理解。那麽接下來這個系列的教程將會詳細講解 Maven 的用法,相信你看完之後,一定能對 Maven 的理解更進一步!