PE文件(一)

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文件的标记。
下篇文章会讲到。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值