您的位置:首页 > 其它

PE文件(一)

2016-08-16 19:34 489 查看
PE文件是指某一种格式的文件,exe,dll,sys等等 ,都是PE格式的文件。

PE文件大体可以分为两部分,头和主体,两个部分都会在内部进行细分,头由几个结构体组成,含这个文件一些描述信息,主体由多个段组成,包含文件的可执行代码和一些执行时要使用的资源,数据等等。

下面这张网上找的图作为参考



首先我们来看DOS头,DOS头是用来兼容DOS系统的,定义如下

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;


其中这个好几个成员 只需要记住第一个和最后一个就行,其他的大多已经没什么用了,其内容常年以0居多。

第一个成员 e_magic ,是一个标记,DOS头标志位,其值恒为4D5A ,在系统中用宏定义为 :

#define IMAGE_DOS_SIGNATURE                 0x5A4D      // MZ


这个成员的作用是可以作为判断一个文件是否为PE文件,下面我们来看代码

#include "stdafx.h"
#include <windows.h>
bool IsPeFile(TCHAR Path[])
{
HANDLE hFile =CreateFile(
Path,
GENERIC_READ | GENERIC_WRITE,
NULL,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
BOOL bSuccess = TRUE;
DWORD dwFileSize = GetFileSize(hFile, 0);
DWORD dwReadSize = 0;
PBYTE buf = new BYTE[dwFileSize];
memset(buf, 0, dwFileSize);
ReadFile(hFile, buf, dwFileSize, &dwReadSize, NULL);

PIMAGE_DOS_HEADER pDos = (PIMAGE_DOS_HEADER)buf;
if (pDos->e_magic !=IMAGE_DOS_SIGNATURE)
{
bSuccess = FALSE;
}
PIMAGE_NT_HEADERS pNt = (PIMAGE_NT_HEADERS)(pDos->e_lfanew + buf);//找到NT头
if (pNt->Signature != IMAGE_NT_SIGNATURE)
{
bSuccess = FALSE;
}
CloseHandle(hFile);
delete buf;
buf = nullptr;
return bSuccess;
}

int _tmain(int argc, _TCHAR* argv[])
{

bool bpe = IsPeFile(_T("E:\\FileCleaner2.0.exe"));//需要判断文件的路径
if (bpe)
{
printf("是");
}
else
{
printf("不是");
}
return 0;
}


有了以上的代码就可以判断一个文件是否为PE文件。

最后一个成员 e_lfanew 标识NT头部在文件中的偏移,有了它就可以找到后面NT头在文件中的位置,在上面的代码中其实已经用过了这个成员

在这里:

PIMAGE_NT_HEADERS pNt = (PIMAGE_NT_HEADERS)(pDos->e_lfanew + buf);

上面的代码不但判定了DOS头的标记,还判断了NT头的一个成员Signature,这个成员也是判断PE文件的标记。

下篇文章会讲到。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  PE文件