《Windows核心编程》---检测PE文件有效性

PE文件是Windows系统中任何可执行模块或者DLL的文件格式。PEPortable Executable,它是Win32环境自身所带的执行文件格式。PE文件是跨Win32平台的,也就是说即使是运行在非intel CPU上的Windows都能够被PE转载器识别和使用该文件格式。

PE文件以64字节的DOS文件头(IMAGE_DOS_HEADER结构)开始,之后是一小段DOS程序,然后是248字节的NT文件头(IMAGE_NT_HEADERS结构)NT文件头的偏移地址由IMAGE_DOS_HEADER结构的e_lfanew成员给出。

所有常见的PE结构定义在winnt.h头文件中。我们谈论两个结构,即IMAGE_DOS_HEADERIMAGE_NT_HEADERS

typedef struct _IMAGE_DOS_HEADER {

         WORD e_magic;   //DOS可执行文件标记,为”MZ”。依此识别DOS头是否有效

         WORD e_cblp;

         WORD e_cp;

         WORD e_crlc;

         WORD e_cparhdr;

         WORD e_minalloc;

         WORD e_maxalloc;

         WORD e_ss;

         WORD e_sp;

         WORD e_csum;

         WORD e_ip;

         WORD e_cs;

         WORD e_lfarlc;

         WORD e_ovno;

         WORD e_res[4];

         WORD e_oemid;

         WORD e_oeminfo;

         WORD e_res2[10];

         LONG e_lfanew;   //IMAGE_NT_HEADERS结构的地址

} IMAGE_DOS_HEADER,*PIMAGE_DOS_HEADER;

 

typedef struct _IMAGE_NT_HEADERS {

         DWORD Signature;       //PE文件标识,为”PE/0/0”。依此识别NT文件头是否有效

         IMAGE_FILE_HEADER FileHeader;

         IMAGE_OPTIONAL_HEADER OptionalHeader;

} IMAGE_NT_HEADERS,*PIMAGE_NT_HEADERS;

 

IMAGE_DOS_HEADER中,e_magicDOS可执行文件标记;e_lfanew是相对实际PE头标的相对偏移量,也就是IMAGE_NT_HEADERS结构的地址。在IMAGE_NT_HEADERS中,我们只使用Signature这个成员,它是PE文件的标识(PE/0/0)

为了方便编程,在winnt.h中位DOS标识和PE标识定义宏:

#define IMAGE_DOS_SIGNATURE 0x5A4D      //MZ

#define IMAGE_NT_SIGNATURE 0x00004550         //PE00

 

检测PE文件有效性程序的步骤:

1)使用CreateFile打开要检测的文件,判断是否是IMAGE_DOS_SIGNATURE来检测是否是有效的DOS头;

2)使用e_lfanew来定位PE头,接着通过判断是否是IMAGE_NT_SIGNATURE来检测文件的有效性;

3)最后使用closeHandle来关闭已打开的文件的句柄。

//定义PE文件中的DOS头和NT

IMAGE_DOS_HEADER dosHeader;

IMAGE_NT_HEADERS ntHeaders;

BOOL bValid = FALSE;

 

//第一步,打开要检测的文件

hFile = CreateFile(FileName, GENERIC_READ, FILE_SHARED_READ, NULL,

                                          OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);

//第二步,检测DOS头部的有效性

ReadFile(hFile, &dosHeader, sizeof(dosHeader), &dwRead, NULL);

if(dwRead == sizeof(dosHeader))

{

       if(IMAGE_DOS_SIGNATURE == dosHeader.e_magic)

       {

              //第三步,定位image_nt_headers的位置

              if(SetFilePointer(hFile, dosHeader.e_lfanew, NULL, FILE_BEGIN))

              {

                     ReadFile(hFile, &ntHeaders, sizeof(ntHeaders), &dwRead, NULL);

                     if(dwRead == sizeof(ntHeaders))

                     {

                            //最后一步,检测PE头部的有效性

                            if(IMAGE_NT_SIGNATURE == ntHeaders.Signature)

                            {

                                   bValid = TRUE;

                            }

                     }

              }

       }

}

 

if(bValid)

       MessageBox("该程序是有效PE文件");

else

       MessageBox("该程序不是有效的PE文件");

 

closeHandle(hFile);

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值