溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

win32下PE文件分析之DOS頭

發(fā)布時間:2020-07-04 21:48:01 來源:網絡 閱讀:2021 作者:daye8ku 欄目:安全技術

(一).win32下的PE文件:

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

        *.sys驅動類文件

        *.dll動態(tài)鏈接庫文件

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

        *.ocx對象類別擴充組建

        *.obj目標文件等.

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

        可重定位文件*.o

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

        共享目標文件*.so

        核心轉儲文件core

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

win32下PE文件分析之DOS頭

(二).win32中的PE文件二進制數(shù)據結構:

    二進制數(shù)據結構如下圖,看起來就比較復雜,但是當你親自動手解析一波,那可能會改變你的世界觀,前提是初學者.為了全部顯示出來,看不太清,放附件里了.

win32下PE文件分析之DOS頭

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

    一個標準的PE文件由DOS頭,stub,NT頭(包含PE標識,標準PE頭和可選PE頭三個成員),節(jié)表,節(jié)的內容以及一些為了內存對齊而填充的0.

win32下PE文件分析之DOS頭

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

(四).DOS頭中的數(shù)據結構:

    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語言實現(xiàn)對win32中notepad.exe的DOS頭的簡單解析:

    該代碼中只是輸出了DOS頭中兩個較為有用的數(shù)據,第一個和最后一個(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"		//包含進自己寫的dos.h文件

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

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

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

    dos.h:

void* ReadFileToBuff(char* file)	//將文件讀取到內存
{
	FILE* fp = fopen(file, "rb");	//以二進制只讀形式打開文件
	void* buff = NULL;		//用來指向申請的內存緩沖區(qū)
	unsigned long sz = 0;	        //用來存放文件的大小
	if(!fp)
	{
		printf("Failed to open file \"%s\"\n", file);
		exit(-1);
	}
	fseek(fp, 0, SEEK_END);	      //讓文件指針fp指向文件的末位位置,用于計算文件的大小
	sz = ftell(fp);		      //獲取當前文件指針相對于起始位置的偏移
	fseek(fp, 0, SEEK_SET);	      //讓文件指針fp指向文件的起始位置
	printf("File \"%s\" size: %ld KB\n", file, sz / 1024);	//輸出文件大小(單位KB)
	buff = malloc(sz);	      //申請一塊與文件大小相等的內存,用作文件緩沖區(qū)
	if(!buff)
	{
		printf("Alloc memery failed!\n");
		exit(-2)
	}
	memset(buff, 0, sz);           //置零緩沖區(qū)
	
	//將文件中的數(shù)據寫入文件緩沖區(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);			//關閉剛剛打開的文件

	return buff;			//返回文件緩沖的內存地址						
}

//輸出DOS頭的重要信息
void Output_Dos(void* buffer)
{
	void* buf = buffer;
	//定義一個指向文件緩沖的DOS頭的指針
	IMAGE_DOS_HEADER* pdos = (IMAGE_DOS_HEADER*)buf;
	printf("DOS Header:\n");
	
	//MZ標記,用于判斷該文件是否為可執(zhí)行文件(其值與MZ的ascii相對應)
	printf("Magic Number:	%#X\n", pdos->e_magic);
	
	//PE標識相對于文件其實位置的偏移 (單位字節(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

//主要是把相應的頭文件包含進去
#include <stdio.h>
#include <windows.h>
#include <stdlib.h>
#include <malloc.h>

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


win32下PE文件分析之DOS頭

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


附件:http://down.51cto.com/data/2366651
向AI問一下細節(jié)

免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI