win32下PE文件分析之DOS頭-創(chuàng)新互聯(lián)

(一).win32下的PE文件:

創(chuàng)新互聯(lián)建站網(wǎng)站建設(shè)由有經(jīng)驗(yàn)的網(wǎng)站設(shè)計(jì)師、開發(fā)人員和項(xiàng)目經(jīng)理組成的專業(yè)建站團(tuán)隊(duì),負(fù)責(zé)網(wǎng)站視覺設(shè)計(jì)、用戶體驗(yàn)優(yōu)化、交互設(shè)計(jì)和前端開發(fā)等方面的工作,以確保網(wǎng)站外觀精美、網(wǎng)站建設(shè)、做網(wǎng)站易于使用并且具有良好的響應(yīng)性。

  PE是Portable Execute的縮寫,是可移植可執(zhí)行的意思,只要文件的數(shù)據(jù)結(jié)構(gòu)遵循PE結(jié)構(gòu),就屬于PE文件,windows中常見的PE文件有

        *.sys驅(qū)動(dòng)類文件

        *.dll動(dòng)態(tài)鏈接庫(kù)文件

        *.exe可執(zhí)行文件

        *.ocx對(duì)象類別擴(kuò)充組建

        *.obj目標(biāo)文件等.

    同樣,linux中使用的是ELF格式,和windows的PE格式有一定的差別,如:

        可重定位文件*.o

        可執(zhí)行文件如/bin/ls等

        共享目標(biāo)文件*.so

        核心轉(zhuǎn)儲(chǔ)文件core

    都遵循ELF數(shù)據(jù)結(jié)構(gòu). unix從system v4開始也使用ELF了,而他們的始祖都是unix system v3的中COFF.如下圖:

win32下PE文件分析之DOS頭

(二).win32中的PE文件二進(jìn)制數(shù)據(jù)結(jié)構(gòu):

    二進(jìn)制數(shù)據(jù)結(jié)構(gòu)如下圖,看起來(lái)就比較復(fù)雜,但是當(dāng)你親自動(dòng)手解析一波,那可能會(huì)改變你的世界觀,前提是初學(xué)者.為了全部顯示出來(lái),看不太清,放附件里了.

win32下PE文件分析之DOS頭

(三).win32中PE的邏輯圖:

    一個(gè)標(biāo)準(zhǔn)的PE文件由DOS頭,stub,NT頭(包含PE標(biāo)識(shí),標(biāo)準(zhǔn)PE頭和可選PE頭三個(gè)成員),節(jié)表,節(jié)的內(nèi)容以及一些為了內(nèi)存對(duì)齊而填充的0.

win32下PE文件分析之DOS頭

以上就是一個(gè)PE文件的大體邏輯圖,它里面的內(nèi)容雖然是二進(jìn)制,但絕不是隨意填充的數(shù)據(jù),而是嚴(yán)格遵循一定格式生成的,比如C語(yǔ)言寫的一段代碼,通過(guò)預(yù)處理, 匯編, 編譯, 鏈接后生成的一個(gè)exe文件(PE文件中的一種),生成過(guò)程是由編譯器來(lái)完成的.

(四).DOS頭中的數(shù)據(jù)結(jié)構(gòu):

    Visual C++ 6.0中winnt頭文件中的定義:

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;

(五).C語(yǔ)言實(shí)現(xiàn)對(duì)win32中notepad.exe的DOS頭的簡(jiǎn)單解析:

    該代碼中只是輸出了DOS頭中兩個(gè)較為有用的數(shù)據(jù),第一個(gè)和最后一個(gè)(e_magic和e_lfanew),代碼如下:

    Dos_Header_Analyze.cpp:

// Dos_Header_Analyze.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "dos.h"		//包含進(jìn)自己寫的dos.h文件

#define filepath "notepad.exe"	//指定好notepad.exe的位置,寫絕對(duì)路徑,或放于源代碼目錄中

int main(int argc, char* argv[])
{
	void* pbuff = NULL;				//方便后面當(dāng)參數(shù)使用
	pbuff = ReadFileToBuff(filepath);
	Output_Dos(pbuff);				//解析DOS頭

	free(pbuff);					//釋放空間
	return 0;
}

    dos.h:

void* ReadFileToBuff(char* file)	//將文件讀取到內(nèi)存
{
	FILE* fp = fopen(file, "rb");	//以二進(jìn)制只讀形式打開文件
	void* buff = NULL;		//用來(lái)指向申請(qǐng)的內(nèi)存緩沖區(qū)
	unsigned long sz = 0;	        //用來(lái)存放文件的大小
	if(!fp)
	{
		printf("Failed to open file \"%s\"\n", file);
		exit(-1);
	}
	fseek(fp, 0, SEEK_END);	      //讓文件指針fp指向文件的末位位置,用于計(jì)算文件的大小
	sz = ftell(fp);		      //獲取當(dāng)前文件指針相對(duì)于起始位置的偏移
	fseek(fp, 0, SEEK_SET);	      //讓文件指針fp指向文件的起始位置
	printf("File \"%s\" size: %ld KB\n", file, sz / 1024);	//輸出文件大小(單位KB)
	buff = malloc(sz);	      //申請(qǐng)一塊與文件大小相等的內(nèi)存,用作文件緩沖區(qū)
	if(!buff)
	{
		printf("Alloc memery failed!\n");
		exit(-2)
	}
	memset(buff, 0, sz);           //置零緩沖區(qū)
	
	//將文件中的數(shù)據(jù)寫入文件緩沖區(qū),每次讀取128字節(jié),讀取sz/128次,正好讀取sz字節(jié)
	if(!fread(buff, 128, sz/128, fp)) 
	{
		printf("Read file \"%s\" error!\n", file);
		exit(-3);
	}
	fclose(fp);			//關(guān)閉剛剛打開的文件

	return buff;			//返回文件緩沖的內(nèi)存地址						
}

//輸出DOS頭的重要信息
void Output_Dos(void* buffer)
{
	void* buf = buffer;
	//定義一個(gè)指向文件緩沖的DOS頭的指針
	IMAGE_DOS_HEADER* pdos = (IMAGE_DOS_HEADER*)buf;
	printf("DOS Header:\n");
	
	//MZ標(biāo)記,用于判斷該文件是否為可執(zhí)行文件(其值與MZ的ascii相對(duì)應(yīng))
	printf("Magic Number:	%#X\n", pdos->e_magic);
	
	//PE標(biāo)識(shí)相對(duì)于文件其實(shí)位置的偏移 (單位字節(jié))	
	printf("PE   Offset:	%#X\n", pdos->e_lfanew);		
}

    stdafx.h:

#if !defined(AFX_STDAFX_H__BBCA9272_49A3_4E1E_9262_9F0211C5BA05__INCLUDED_)
#define AFX_STDAFX_H__BBCA9272_49A3_4E1E_9262_9F0211C5BA05__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#define WIN32_LEAN_AND_MEAN		// Exclude rarely-used stuff from Windows headers

//主要是把相應(yīng)的頭文件包含進(jìn)去
#include <stdio.h>
#include <windows.h>
#include <stdlib.h>
#include <malloc.h>

    執(zhí)行結(jié)果如下圖:

win32下PE文件分析之DOS頭

    如果有空會(huì)繼續(xù)更新.

附件:http://down.51cto.com/data/2366651

另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內(nèi)外云服務(wù)器15元起步,三天無(wú)理由+7*72小時(shí)售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國(guó)服務(wù)器、虛擬主機(jī)、免備案服務(wù)器”等云主機(jī)租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡(jiǎn)單易用、服務(wù)可用性高、性價(jià)比高”等特點(diǎn)與優(yōu)勢(shì),專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場(chǎng)景需求。

網(wǎng)站名稱:win32下PE文件分析之DOS頭-創(chuàng)新互聯(lián)
新聞來(lái)源:http://muchs.cn/article22/iogjc.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供企業(yè)建站、外貿(mào)建站、ChatGPT服務(wù)器托管、靜態(tài)網(wǎng)站、品牌網(wǎng)站制作

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

h5響應(yīng)式網(wǎng)站建設(shè)